ArcGIS API for Javascript 高级开发2019

开发模式


核心模块

  • esri/core/Accessor
  • esri/core/==Promise
  • esri/core/Loadable
  • esri/core/Collection

Accessor

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

  1. BaseDynamicLayer
    • getImageUrl(extent, width, height)
    指定范围,宽度和高度,返回ImageURL
    • fetchImage(extent, width, height)
    指定的范围和大小,返回影像。
  2. BaseTileLayer
    • getTileUrl(level, row, col)
    指定级别,行和列,返回切片URL
    • fetchTile(level, row, col)
    指定级别,行和列,返回切片
  3. 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返回空值
	}
};