ArcGIS API for Javascript 高级开发2019
开发模式
核心模块
- esri/core/Accessor
- esri/core/==Promise
- esri/core/Loadable
- esri/core/Collection
Accessor

Accessor方法-属性访问
//属性赋值
layer.opacity = 0.5;
layer.title = '图层1';
// 对多个属性赋值
layer.set({
opacity: 0.5,
title: "图层2"
});
// 使用get, set方法访问多层级属性
view.get("map.basemap.title");
view.set("map.basemap.title", "new title");
Accessor方法-属性监听
mapView.watch("scale",
(newValue, oldValue, property, object) => {
console.log("scale changed: ${newValue} ");
});
mapView.watch("map.basemap.title",
(newValue, oldValue, property, object) => {
console.log("new basemap title: ${newValue}");
});
mapView.watch("ready, stationary",
(newValue, oldValue, property, object) => {
console.log("property ${property}: ${newValue} ");
});
watchUtils.whenTrue(view, "stationary", () => {
console.log("view is stationary");
});
Accessor 统一的对象构造方式
var map = new Map({
basemap: new Basemap({
baseLayers: new Collection([new TileLayer("...")])
}),
layers: [
new FeatureLayer("...")
]
});
Accessor 自动映射/Autocast
// 4.x
{
type: "simple-marker",
style: "square",
color: "red",
size: 10,
outline: {
color: "rgba(255, 255, 255, 0.5)",
width: 4
}
}
// 3.x
new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE,10,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([255, 0, 0]),4),
new Color([255, 255, 255, 0.5])
);
Accessor使用
var Person = Accessor.createSubclass({
properties: {
firstName: { value: "John" }, // 默认值为John
lastName: { value: "Doe" }, // 默认值为Doe
fullName: {
readOnly: true, // 只读属性
dependsOn: ["firstName","lastName"], // 依赖关系
get: function() { // get()方法重构
return this.firstName + " " + this.lastName;
}
}
}
});
Promise -> then()
异步处理不在依靠事件监听
map.on(“load”,function(){})
view.when(function(){})
基本模式:
layer.queryFeatures(query)
.then(handleResult)
.catch(handleError);
rendererCreator.createRenderer(params)
.then(handleResult);
.catch(handleError);
链式Promise
view.when(() => {
return view.whenLayerView(map.findLayerById("awesomeLayer"));
}).then(layerView => {
return watchUtils.whenFalseOnce(layerView, "updating");
}).then(result => {
const layerView = result.target;
return layerView.queryFeatures();
}).then(doSomethingWithFeatures)
.catch(errorHandler);
Loadables
3.x:图层实例化后会自动加载
4.x:图层加载需要调用对应方法load()
WebMap / WebScene 需要加载:
- 门户中的item
- 图层的模块
- 图层对应的item
MapView / SceneView 需要加载:
- 地图
- 图层

const webmap = new WebMap({
portalItem: {id: 'affa021c51944b5694132b2d61fe1057'}
});
webmap.load() //创建webmap属性basemap & layers
.then(() => { //加载图层
return webmap.getLayer('myFeatureLayerId').load();
})
.then(featureLayer => {
return featureLayer.queryFeatures({
where: 'OBJECTID = 1'
});
})
.then(result => {displayDetails(result.features[0]);})
.catch(error => {console.error(error);});
本质上就是一个数组/Array
有array的所有方法,如:
- push()
- pop()
- filter()
- reduce()
- map()
添加了其他方法&事件,使操作数组更加简单: - addMany()
- reorder()
- remove()
- on()
可定义Collection中的数据类型 - Collection.ofType(FeatureLayer)
Map.layers & GraphicsLayer.graphics都是Collection对象
核心API
Map & View


图层
已支持图层:https://developers.arcgis.com/javascript/latest/apireference/esri-layers-Layer.html
自定义图层
- 需要连接当前JS API尚不支持的服务
- 需要在客户端展示数据前进一步加工处理
- 在线示例:
– Custom TileLayer
– Custom BlendLayer
– Custom LERC Layer
– Custom DynamicLayer
– Custom ElevationLayer - Exaggerating elevation
– Custom ElevationLayer - Thematic data as elevation
– Custom WebGL layer view
自定义图层
图层BaseClass Hooks
- BaseDynamicLayer
• getImageUrl(extent, width, height)
指定范围,宽度和高度,返回ImageURL
• fetchImage(extent, width, height)
指定的范围和大小,返回影像。 - BaseTileLayer
• getTileUrl(level, row, col)
指定级别,行和列,返回切片URL
• fetchTile(level, row, col)
指定级别,行和列,返回切片 - BaseElevationLayer
• fetchTile(level, row, column)
指定级别,行和列,返回切片
图层视图 (LayerView
作用:可以访问绘制到屏幕上的数据
- FeatureLayerView#queryFeatures()
- GraohicsLayerView#queryGraphics()
- ImageryLayerView#pixelData
在LayerView加载完成后再使用 updating为false
view.whenLayerView(layer).then(function(layerView) {
layerView.watch("updating", function(value) {
//对layerview进行操作
})
)}
自定义图层视图
可通过自定义图层的视图来扩展定制更多的UI呈现
- BaseLayerView2D (Beta)
attach() 在开始绘制LayerView前调用
render() 可以获取HTML canvas 2D context,自定义绘制内容
detach() 在图层移除后调用,通常用于释放资源 - BaseLayerViewGL2D ( Beta & experimental)
与BaseLayerView类似,但有WebGL的渲染能力
渲染
//提前渲染:WebMap/WebSence
var webmap = new WebMap({
portalItem: { id: "57a33a18ad93400682ff6faadfac0d9f"}
});
//自定义渲染:Renderer
var renderer = {
type: "simple",
symbol: {
type: "simple-line",
color: "#ef37ac",
width: "0.5px",
style: "solid"
}}
//智能制图:SmartMapping
rendererCreator.createRenderer(params)
控件/Widgets
即拿即用的控件:Popup, Legend, Scalebar, Compass, Measure, Print, …
(30+)
4.10新增Sketch、Slice、量测控件
4.11新增编辑控件
响应式设计
控件组成:View + ViewModel
控件模块开发:
- TypeScript:JavaScript类型的超集,它可以编译成纯JavaScript
- JSX:JavaScript的语法扩展,用于描述UI
- esri/core/Accessor:Widget基类
Widget生命周期:
- constructor (params) 在控件创建时调用,负责处理初始化时的各种参数
- postInitialize() 在控件已被创建后,未绘制到UI前调用
- render() 用于绘制控件的UI
- destroy() 释放控件实例
TypeScript 装饰器 - @subclass 与declared结合使用,用于创建与dojo.declare兼容的子类
- @property 用于定义Accessor的属性,该属性可使用set(),get(),及
watch()方法 - @renderable 用于在属性值变化时,自动调用render函数重绘UI,与
@property结合使用
样式/Styling
即拿即用的主题颜色
- light
- light-blue
- light-green
- light-red
- light-purple
- dark
- dark-blue
- dark-green
- dark-red
- dark-purple
框架的使用
以Map为核心将框架/库加载到ArcGIS API for Javascript应用中
window.dojoConfig = {
packages: [
{
name: "vue",
location: "https://unpkg.com/vue/dist/",
main: "vue"
}
]
};
以框架为核心
- 将ArcGIS API for Javascript加载到用某框架构建的应用中
配置要点
//配置文件webpack.config.js
const ArcGISPlugin = require("@arcgis/webpack-plugin");
module.exports = {
plugins: [
new ArcGISPlugin(), //添加ArcGIS Webpack plugin
],
node: {
process: false, //忽略nodejs process
global: false, //忽略nodejs 全局对象
fs: "empty" //nodejs fs返回空值
}
};