我正在参加「掘金·启航计划」
上一篇文章咱们讲了 arcgis js 的基础知识,然后大致讲了下常用模块都有哪些。不过毕竟 arcgis 体量在这摆着,大部分人应该都是只留下了模糊的印象。这篇文章我们就顺着目录把常用模块的细节和平时开发时经常会接触到的 api 都过一下,让你了解 arcgis js 都可以提供哪些功能以及如何实现这些功能。
如果你没读过上一篇的话,推荐先读一下,链接在这里:arcgis js 入门:科普介绍与文档导读。
API 文档介绍
先打开 API 文档,上一篇文章里我们通过中间的快速索引大致了解了下常用模块。这篇文章换个方向,咱们从左边的目录入手,来看一下更细节的东西。
首先要说的是,这个目录里很多东西都是用不到的,起码不会马上就用到。因为有很多的东西都是核心类(比如 Layer、Graphic)上的某个属性,所以对于不常用的我只会简单介绍下是干嘛的,等大家实际开发时有需要了再回来研究。
下面的具体模块我会大致按顺序来讲,同时会给出每个模块的优先级,最高五颗 ⭐,越早学习越好,最低一颗 ⭐,不看也没啥关系。
esri 基础功能
优先级:⭐⭐⭐⭐
首先是最上面的 esri,这个包里都是一些比较基础的模块,比如老朋友 Map 就在这里:
我们以此为例,讲一下怎么了解新模块,首先看最上面的引入方法:
可以看到有两个,AMD 格式和 ESM 格式,这里先讲一下这个的历史渊源。
arcgis js 一开始是基于 dojo 框架开发,使用时通过 requirejs 引入到项目里(就是上面的 AMD 方案)。而自从 vue、react 之类的前端框架兴起之后,这种接入方式就比较麻烦了。所以 arcgis js 在 4.0 版本进行了一次大规模重构,目的之一就是为了支持更现代化的 ESM 方式引入。
如果你现在就在用 vue react,想找怎么接入 arcgis ,第一个示例里就有最小模板工程,基于 vite + ts 开发的。项目我给你复制过来了 点击 就能下载。你也可以在 这里 找到:
arcgis js 在 4.0 之前接入现代前端项目比较麻烦,因为只能选择兼容之前的 dojo 格式。所以诞生了不少第三方包来解决这个问题,比如 esri-loader-react,esri-loader。而 4.0 可以直接 import 之后这些包就不再需要了。不过网上还是有不少中文文档基于这些老方案的,记得擦亮眼睛,别走弯路了。
而 AMD 引入大多是用在 DEMO 开发上,比如官方文档里的示例项目基本都是 AMD 引入的,因为纯 HTML 就能用,很方便。所以平时学习或者测试某个功能基本都是用这种方式。
聊完了这个咱们继续往下看,会看到这些信息:
这三个也比较重要,第一个是它的继承树,第二个是它都派生出了什么子类,第三个是这个东西是什么时候发布可用的。arcgis js 的模型抽象做的很好,所以说接触一个新模块的时候可以先看一下这个继承树,很快就能了解到这个东西大致是干什么的。
这里可以从子类里看到 Map 派生出了 WebMap 和 WebScene,不知道你对这两个还有没有印象,上一篇我们介绍了这两个是用来加载网络上的在线地图的,从这个继承关系可以看出,这两者实际就是 Map 的一个“特殊用例”,本质上没有区别。
再往下是对这个模块的介绍,一般都会附带一小段使用示例:
Map 的功能其实很简单,我们平时和它的交互一般都是创建了一个图层,塞进去,创建了另一个图层,塞进去。你可以把它当作是一个吉祥物,平时用的不多,但是又不可或缺。
其实上面这一段翻译了看看就好,看不懂也没关系,重头戏是下面这个 See also:
接触新模块时,简单看一遍介绍,然后就在 See also 里找带 Sample 的链接看。arcgis 里常用的模块都会有使用示例,而越常用的模块示例越多。这种示例都带完整的源码,对学习新模块非常有帮助。
详情页再往下就是这个模块的具体 API 介绍了,比如构造函数、属性、方法等。反正也记不住,一般都是有不认识的再回来查。
config 地图配置
优先级:⭐⭐⭐
讲完了如何查阅详情页面之后,咱们回头继续讲左边的目录,在 esri 包里还有一个 config 模块也很常用,这个东西其实就是一个对象,上面有很多的键值对,值基本都是一个字符串,用来控制某种资源从哪加载。要修改也很简单,直接赋值就行了:
Graphic 图形
优先级:⭐⭐⭐⭐⭐
然后是上一篇文章里说很重要的 Graphic:
一般用来干两种事:
- 把后端传过来的地理信息转换成对象塞到图层里
- 在地图上画各种各样的东西(比如用户当前位置,多边形范围,文本信息等等)
第一种咱们放到后面 FeatureLayer 的时候一起讲,先讲第二种。在实际业务开发时经常会出现需要自己画 Graphic 的时候,而创建 Graphic 一般需要这三种东西:
然后把这三者组装起来 new 一个 Graphic 就行了,最后把这个图形塞到视图上:
view.graphics.add(polylineGraphic);
上面这个 view 就是实例化的 MapView,这个对象会自带一个 graphics,也是一个图层,图形创建好了塞这里就可以看到了。
举个例子:比如要显示一个不断移动的小车,实际开发的时候就是这么个流程:
- 先创建一个 Graphic,geometry 是一个点,坐标是小车的经纬度、symbol 是 UI 给的小车图片、attributes 里存小车的其他属性(没有就无视)
- 再创建一个 Graphic,geometry 一样,symbol 是一个文本,值是小车名字,文本配置里设置下偏移,防止名字盖住小车。
- 小车移动时直接更新这两个图形对象的 geometry 属性,画面上小车就跑起来了。
除此以外你可能还注意到了下面这么个东西:
这个是因为 arcgis js 支持两种写法,一种是指定一个 type,后面实例化的时候会按照你这个 type 把对应的属性也实例化成指定类型的对象。另一种就是你直接手动实例化对应的参数。两种都可以,第二种的 typescript 类型推导会更舒服点,但是要写很多的 import 语句。
esri 包里咱们就讲这三个,其他的用的不多,总之就是都比较基础,有兴趣的自己了解一下。
esri/analysis 测量工具包
优先级:⭐
然后是第二部分,这个包里的东西都是用来进行一些地理信息测量的,比如看下面积多大啊、距离多长啊、视线能看到哪里啊,一般都是用在 3D 地图里的,大家看看就好,2D 地图里用 geometryEngine 就够了。
esri/core 核心工具包
优先级:⭐
这个模块包含了两部分内容,arcgis js 的核心基类以及一些常用的工具包:
红框里的就是核心基类,你可以点 Accessor 看一下,几乎所有的类都是从它派生出来的,这玩意其实就是一个 getter/setter 模型。Collection 则是提供了集合的管理能力,比如 layer 管理啊,layer 内的 graphic 管理啊就是靠它实现的。
下面的 promiseUtils 就比较常用了,这个提供了对异步事件的处理能力,比如迭代、filter、防抖等。而 reactiveUtils 则是响应式数据管理工具,跟 vue 差不多,arcgis js 正是通过 Accessor + reactiveUtils 实现了 直接修改属性就可以更新视图 的功能。还记得我们刚才举的小车移动的例子么,里面修改小车图形的 geometry 属性,然后小车图标位置就会变就是用了这个特性。
不过话说回来,这些东西里能用到的也就是 promiseUtils,其他的大家了解就好。
esri/form 表单组件库
优先级:⭐⭐
是的 arcgis js 提供了一套完整的表单组件库。你可以通过 new 一堆东西的方式来在地图里创建一个表单。
这个说实话也用的不多,基本都是 react 或者 vue 代劳了。
不过最上面的 ExpressionInfo 需要介绍下,arcgis js 里有很多地方都用到了这个,作用和 echarts 里的 formatter 差不多,基本都是用来把一堆属性格式化成文本显示出来的,不同的地方在于这个的输出不一定是字符串,也有可能是对象之类的东西。
esri/geometry 几何
优先级:⭐⭐⭐⭐⭐
几何信息,这个挺重要,比如圆、点、多个点、多边形、折线这种几何信息都在这里,但是要注意,这里只是几何信息,没有样式信息。比如你可以通过中心点、半径创建一个圆,但是你不能设置这个圆的外貌,比如填充、边框之类的。样式这部分信息是 symbol 负责的。
也就是说,geometry 只是抽象的几何概念,包含了这个几何的信息、geometry 是没有样子的。必须要装进 graphic,然后才能通过 graphic 的 symbol 属性显示出来。
很多新手都有这个疑问:我把后端给的坐标实例化成一个 geometry,但是咋配置它的样式啊。原因就是这个,我在 上一篇文章 里着重说了这个概念,还有疑惑的可以再回去看看。
除了这些之外,这个包里还有两个很重要的工具:geometryEngine 和 geodesicUtils。前者是用来处理多个几何对象的空间关系的,比如是否相交、包含。而后者是用来计算地理信息、比如面积、长度、点与点的距离等。
这两个工具很趁手,请务必记住。
esri/identity 在线服务凭证
优先级:⭐
这个是用来连接 arcgis 在线服务的,一般用不着,就不介绍了。
esri/layers 图层
优先级:⭐⭐⭐⭐
这里有很多不同类型的图层,咱们就挑最常用的 TileLayer 和 FeatureLayer 讲,其他的用法大差不差,有需要的时候再看就行。什么时候有需要呢?什么时候客户给的数据类型之前没用过,再来这里找一下。
TileLayer 很简单,一般都是放底图的时候用,直接把底图服务的地址塞进去就可以了:
let layer = new TileLayer({
url: "https://services.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer"
});
底图服务一般都是以 MapServer 的链接结尾的,比如国内常用的 ChinaOnlineCommunity_Mobile (MapServer) (arcgisonline.cn)。
顺便一提,arcigs server 一般以 arcgis/rest/services/ 开头。
而 FeatureLayer 之前说过,是用来存放要素的,一般来说会有两种用法:Server-side / Client-side。什么意思呢?刚才讲 TileLayer 的时候不是用 url 连了一个在线的 arcgis server 服务么。arcgis server 也支持提供 FeatureLayer 服务。比如这个 Layer (arcgisonline.com)。
通过类似的方式,可以直接连接一个在线的 FeatureLayer,有查询操作就会直接发到这个后端服务,然后服务给你返回结果,这种用法就被称为 Server-side。
而 Client-side 就与之对应,在前端获取需要的参数,然后手动组装一个 FeatureLayer,即所有的操作都是客户端进行的。本地创建一个 FeatureLayer 需要三个素材:
- source:一个数组,包含了这个图层里所有的要素,每个要素都是一个 Graphic(不需要 symbol 属性)。
- renderer:渲染器,控制了以何种方式渲染要素。
- fields:一个数组,显式声明要素的字段名称和类型,便于查询和渲染。
source 我们刚才讲 Graphic 提到过了,就是一个数组,没事好讲的。而 renderer 是 arcgis js 里特别重要的概念,它直接控制了底图元素的显示效果,通过不同的 renderer 可以做出来千差万别的地图效果。source 里边的 Graphic 不需要 symbol 属性也是因为这个,renderer 接管了整个图层的渲染工作,里边的图形符号都是 renderer 统一处理的。
arcgis 里有一个专门的大类叫做 Data Visualization(数据可视化),里边的效果几乎都是各种 renderer 做出来的。
而 fields 涉及到地方比较多,这里就简单理解成描述了要素的具体属性即可。
FeatureLayer 的应用主要有两种,一种是查询:通过 layer.queryFeatures
传入一个类似与 SQL 的字符串,然后就可以查询出指定的信息,有些 poi 搜点就是通过这种方式实现的。
另一种应用是可视化(Data Visualization),是指如何把要素以需要的形式显示出来,主要就是靠 renderer。这里还要提到 FeatureLayer 的另一个属性叫 featureReduction,它可以控制如何“减少”要显示的要素,比如我们说的 “点位聚合” 就是其中的的一种,arcgis js 里叫做 FeatureReductionCluster。还有一种叫做 FeatureReductionBinning,一般称之为分箱,具体效果可以点链接进去看看,就不展开讲了。
FeatureLayer 可以说是 arcgis js 里的核心图层。相关内容要是展开讲的话篇幅就收不住了。所以咱们这里就先打住。在 FeatureLayer文档 的介绍了就包含上面提到的这三部分内容:创建、查询和可视化,有需要的话可以先去瞅瞅。
esri/renderers 图层渲染器
优先级:⭐⭐⭐⭐⭐
讲完了图层,咱们就来讲一下紧密相关的渲染器,刚才也说了,renderer 就是用来把要素显示出来的,不同的 renderer 会有不同的显示效果,而最常见的是下面这两种:
SimpleRenderer 简单渲染器:你可以指定一个 symbol,图层里的要素都会渲染成对应的样子
但是不要觉得它很简单,可以通过一些配置来实现下面这种连续过渡的显示效果(注意右上角的图例,要素会根据某个属性值自动从这个连续色带中挑选颜色)。
UniqueValueRenderer 值渲染器:你可以提供一个列表,列表项是不同的 symbol 以及对应的字段值,当要素的字段值匹配上了之后,就会显示对应的符号,最常用,五星推荐。
ClassBreaksRenderer 范围渲染器:和值渲染器类似,不过匹配方式换成了范围,不同的范围显示不同的符号。
上面三个渲染器堪称三大金刚,非常常用,除此之外还有一些特殊用途的渲染器也会用到:
DotDensityRenderer 点密度渲染:常用在面要素图层里,用于显示一些具体位置不那么重要的信息,比如一片区域里有多少人、多少树。会根据要素的属性值在范围内随机撒点。
FlowRenderer 流体渲染:风场,不解释了,效果很常见。
VectorFieldRenderer 矢量数据渲染:另一种风场。
HeatmapRenderer 热力图渲染:渲染点图层,可以自动在点与点之间创建平滑的过度。
这些渲染器出的效果比较好看,所以可以研究一下,客户可能更喜欢这种“有个性”的地图,不过要注意不同的渲染器支持的图层类型也不一样,介绍里都会注明:
可以看到,通过不同的配置项搭配不同的配置项,可以创造出各式各样、丰富多彩、千奇百怪的地图效果,所以再次强调,这部分内容很重要,推荐上面提到的每个渲染器都点进去看看效果。
esri/smartMapping 智能制图
优先级:⭐⭐
趁热打铁,顺便再讲一下这个东西,很多同学看到这个名字就有点摸不着头脑,实际上这玩意用起来挺简单的。你可以把 smartMapping 理解成 renderer 生成器。你给他传递一个图层,它就能自动生成合适的渲染器,然后你把生成的渲染器再怼到图层上就能用了。
不过这部分优先级不高,大部分场景通过配置上面的 renderer 就可以了,这部分内容闲的时候可以研究一下。
esri/symbols 符号
优先级:⭐⭐⭐⭐
然后就到了我们的老朋友 symbol 了。这部分内容虽然多,但是其实都不复杂,说白了就是一堆样式配置项,前端应该都挺熟悉,毕竟老本行了。所以这里我就只指个路,把常用的几个符号介绍下。总之需要改样式了就看这个,准没错。
- PictureMarkerSymbol 图标:往一个点上贴图片,最常用
- SimpleMarkerSymbol 点:如果一个点样子很简单就用这个,这个也可以调尺寸变成个大圆。
- SimpleFillSymbol 填充:一般用来给面要素上色。
- SimpleLineSymbol 线条:用于折线之类的
- TextSymbol 文本:显示标签或者在地图上放一些标注信息,注意,如果要素在图层里的话就不用手动搞这个,图层基本都有个属性叫做 labelingInfo。配置它就可以控制整个图层的标签显示。
esri/widgets 组件
优先级:⭐⭐⭐
UI 组件,这一部分有些尴尬,有很多组件直接用前端框架来实现反而效果更好,维护起来也更方便一点。所以这里讲一些用前端框架不太好搞的组件:
- Attribution:底部属性条,这里会显示底图的信息和 powered by esri。默认会放在 view.ui 里,可以关掉。
- ScaleBar:比例尺,传递给他一个 view,他会根据你地图的缩放等级自动跟随比例尺
- Locate:当前位置定位,这个按钮继承了 h5 的地理 api,点一下就能获取当前用户位置,挺方便的。
- Measurement:测量距离或者区域大小,DEMO 在这里 Measurement widget,加载比较慢,要等一会才能看到效果。
- Zoom 放大缩小按钮。
除了这几个之外,还有两个比较重要的:
这两个都是比较重要的地图交互手段,Editor 用于从用户侧收集数据,比如让用户制定出行方案。而 Sketch 则相反,用于更好的查询数据,例如划线查距离,框选查询,圆圈范围查询。
尤其是 Sketch,平时开发里很常用,需要尽早学习。
esri/popup 弹窗
优先级:⭐⭐⭐
弹出框,里边包含了各种类型的弹框,不过用的比较少。因为还有个东西叫做 PopupTemplate,很多类上面都有这个属性,故名思意这个东西就是一个弹框模板,你可以通过 {字段名}
的方式把要素的值插入到弹窗里,然后通过点击之类的操作触发这个弹窗。
所以在日常开发中,基本都是通过 PopupTemplate 来配置弹窗,而 esri/popup 则负责做一些单独的弹窗信息展示。关于 PopupTemplate 的更多信息可以看这里:PopupTemplate | API Reference。
esri/views 视图
优先级:⭐⭐⭐⭐⭐
最后咱们再来介绍一下 esri/views,这个包负责咱们最直观能看到的地图容器,包括交互、手势、事件监听、UI、跳转等功能。比如你想禁用鼠标右击旋转这个功能,那就应该到这里瞅瞅(顺带一提,禁用右键旋转的方法是设置 view.constraints.rotationEnabled = false
)。
这里咱们以渲染 2D 视图的 MapView 为例(其实是因为我用的比较多),上面常用的属性包括:center(中心点)、rotation(地图旋转角度)、scale(缩放等级)、ui(咱们上面讲的 ui 组件最终就会被放到这里)、graphics(一个用来放图形的集合)、focused(地图是否获取了浏览器焦点)
常用的方法包括:goTo()(动画跳转到指定位置)、hitTest()(检测指定点位命中了哪些元素)、on()(设置事件监听)、when()(当视图准备好时触发,业务代码一般都会放在这个回调里触发)
其实 MapView 上还包含很多其他的属性,推荐有空把它的文档通读一遍。而上面列举的属性是 几乎每次开发都会用到的,直接背下来都不为过。
view 还有个概念叫做“屏幕点位(ScreenPoint)”,屏幕点位是相对于视图窗口来看的,只有 x 和 y 两个坐标。也就是说,随着地图的拖动,相同的屏幕点位可能对应着不同的地图点位。
view 提供了 toMap() 方法来把一个屏幕点位转换成对应位置的地图点位,也可以用 toScreen() 把地图点位转换成其所在的屏幕坐标。
而 on 方法设置的事件回调接受的都是屏幕点位(所有事件列表点这里),然后通过 hitTest 方法就可以获取到这个屏幕点位上都有哪些具体的地图元素。平时最常用的是下面两个事件:
- click,用于处理鼠标的点击事件,比如点击后弹窗执行后续的业务等。
- pointer-move:用于处理鼠标的悬停效果,比如悬停到某个图标上然后显示详细数据或者高亮同类型的其他图标。
需要再次强调的是,上面的事件只能获取到相对于屏幕的点击坐标,不能直接获取到点到了那个地图元素,基本都是触发事件回调后使用 hitTest() 方法根据事件找到命中的地图元素。
MapView 这个类非常常用,因为它负责了地图的视图层逻辑,平时开发中实现地图交互几乎都要和 MapView 打交道(另一部分是和 SketchViewModel 打交道)。
小结
其实,除了上面这几个之外还有一些包没有讲,比如专门负责和 arcgis server 交互的 esri/rest,用来连接 esri 在线地图的 esri/portal。不过这些都不那么常见,至少新手不太会接触得到,所以这里就先跳过吧。
最后总结一下上文中比较重要的内容:
-
不同的图层用来承载不同的地理数据,并且使用渲染器(Renderer)把自己携带的数据显示出来的,不同的 Renderer 有不同的效果。
-
视图(MapView)很重要,可以用它来控制地图和监听事件,Sketch 和很重要,它和 MapView 可以实现绝大多数地图交互效果。
至于其他的一时半会记不住也没关系,本篇的内容还是比较杂的,所以也没必要上来就记住所有的内容。我比较推荐点个收藏,如果有什么功能不知道该怎么做了,就翻出来再看一遍,说不定就有新收获呢。
下一篇就是这个小系列的最后一篇文章,我会带着大家把示例列表里比较重要的过一遍,可以说只要看完了这几个 DEMO,那上手 arcgis js 开发就不在话下了,链接在这里: