地图服务 ArcGIS API for JavaScript基础用法全解析
前言
在接触ArcGIS之前,开发web在线地图时用过Leaflet来构建地图应用,作为一个轻量级的开源js库,在我使用下来Leaflet还有易懂易用的API文档,是个很不错的选择。在接触使用ArcGIS后,我发现其API文档的阅读体验很不尽人意。尽管它提供了详尽的接口描述和参数说明,但由于文档的复杂性和缺乏直观的示例,对于初学者来说可能难以理解和应用,经过几天的努力,手写了多个helloworld,并终于整理出了地图的基本用法。包括,地图打点、自定义点popup,折线栅栏、区域覆盖物、热力图、以及地图上的操作(区域多边形圈选、地图绘制)。demo已上传git,具体源码可直接查看:gitee.com/fcli/arcgis...
地图初始化
1、首先我们需要准备一个地图服务地址,安装@arcgis/core依赖包
sql
yarn add @arcgis/core
2、初始化一个地图
arduino
import MapView from '@arcgis/core/views/MapView';
let map = new Map();
const view: any = new MapView({
container: 'viewDiv',
map: map,
zoom: 4
});
3、设置地图中心点、通过地图服务创建基础图层
ini
view.when(() => {
let pt = new Point({
x: -3385.861498285485,
y: -4869.908083566152,
spatialReference: view.spatialReference
});
// 定位到中心点
view.goTo({
center: pt,
zoom: 2
});
//基础图层
let layerUrl = 'http://xxx.xxx.xxx.xxx/arcgis/rest/services/BaseMap/MapServer'; //地图服务URL
let layer = new TileLayer({ url: layerUrl, title: 'baseMap' });
mapLayers.value = layer;
map.layers.add(layer);
地图增加marker点
根据预先配置的测试点,通过Graphic对象包装point点,最终添加到图层上。
typescript
//撒点
const renderPoint = () => {
let pointGraphicArr: any = [];
pointList.forEach((item: any) => {
// First create a point geometry
let point = {
type: 'point', // autocasts as new Point()
longitude: item.COORDX,
latitude: item.COORDY,
spatialReference: myMapView.spatialReference
};
//点样式,(可设置图片,或者自定义颜色的marker,参考symbol)
let markerSymbol = {
// type: 'picture-marker',
// url: img,
// width: 5,
// height: 5
type: 'simple-marker',
color: [226, 119, 40]
};
// 创建点的属性
let attributes = {
Name: item.ADDRESS,
Owner: item.TASKID
};
// Create a graphic and add the geometry and symbol to it
let pointGraphic = new Graphic({
geometry: point,
symbol: markerSymbol,
attributes: attributes
});
pointGraphicArr.push(pointGraphic);
});
pointGraphics = pointGraphicArr;
//自定义渲染popup
setTimeout(() => {
renderPopup();
}, 500);
return pointGraphics;
}
撒点上图
ini
view.graphics.addMany(renderPoint());
绘制多变形
与绘制marker点类似,将polyline对象添加到Graphic中,最后都通过view.graphics.addMany
添加到地图图层上。具体代码实现如下:
ini
//多边形折线
const rendPolyline = () => {
const polyline = {
//线的坐标信息
type: 'polyline', // autocasts as new Polyline()
paths: [
[-4466.80859375, -8273.7109375],
[-3475.872802734375, -6549.30810546875],
[-4307.0634765625, -5647.63525390625],
[-4466.80859375, -8273.7109375]
],
spatialReference: myMapView.spatialReference
};
const lineSymbol = {
//线的样式
type: 'simple-line',
color: [226, 119, 40],
width: 2
};
const lineAtt = {
//线的属性
Name: 'Keystone Pipeline',
Owner: 'TransCanada',
Length: '3,456 km'
};
const polylineGraphic = new Graphic({
//创建线对象并且绑定属性以及弹出框信息
geometry: polyline,
symbol: lineSymbol,
attributes: lineAtt
});
return [polylineGraphic];
}
绘制多边形覆盖物
可自定义覆盖面的样式,包括背景颜色,边框等属性。
ini
//绘制多边形覆盖层面
const rendPolygon = () => {
const rings = [
[-4226.57763671875, -10710.984375],
[-5061.92724609375, -8761.8974609375],
[-5428.50244140625, -10374.7802734375]
];
const polygon = {
//面的坐标信息
type: 'polygon',
rings: rings,
spatialReference: myMapView.spatialReference
};
const fillSymbol = {
//面的样式
type: 'simple-fill',
color: [227, 139, 79, 0.8],
outline: {
// autocasts as new SimpleLineSymbol()
color: [255, 255, 255],
width: 1
}
};
const polygonGraphic = new Graphic({
//创建面图斑
geometry: polygon,
symbol: fillSymbol
});
//数组
return [polygonGraphic];
}
热力图实现
首先定义热力图render的值,根据不同的权重占比渲染不同的颜色,注意ObjectID必须需要,然后通过FeatureLayer添加到地图图层上,此处根据count作为权重字段。
css
//热力图
const rendHeatmap = () => {
//热力图渲染
var heatmapRenderer = new HeatmapRenderer({
//设置渲染器
field: 'count', //设置的权重字段
colorStops: [
{ color: 'rgba(0, 255, 150, 0)', ratio: 0 },
{ color: '#32C5E9', ratio: 0.083 },
{ color: '#67E0E3', ratio: 0.166 },
{ color: '#9FE6B8', ratio: 0.249 },
{ color: '#FFDB5C', ratio: 0.332 },
{ color: '#ff9f7f', ratio: 0.415 },
{ color: '#fb7293', ratio: 0.498 },
{ color: '#E062AE', ratio: 0.581 },
{ color: '#E690D1', ratio: 0.664 },
{ color: '#e7bcf3', ratio: 0.747 },
{ color: '#9d96f5', ratio: 0.83 },
{ color: '#8378EA', ratio: 0.913 },
{ color: '#96BFFF', ratio: 1 }
],
radius: 10,
maxDensity: 0.01625,
minDensity: 0
});
let features: any = [];
pointList.forEach((item: any, index: number) => {
features.push({
geometry: {
type: 'point',
x: item.COORDX,
y: item.COORDY,
spatialReference: myMapView.spatialReference
},
attributes: {
count: 1,
ObjectID: index //重要!!!
}
});
});
const hfields = [ new Field({ name: 'count', alias: 'count', type: 'string' }) ];
var featureLayer = new FeatureLayer({
id: '热力图',
source: features, //点数据集
title: '热力图',
objectIdField: 'ObjectID',
fields: hfields, //权重字段
renderer: heatmapRenderer
});
myMap.add(featureLayer);
}
绘制点、线、面、圈、矩形
原理都是通过监听鼠标事件,依赖Draw对象的到不同的地图操作效果
创建Draw
arduino
//自定义绘制点、线、面
const draw = new Draw({
view: view
});
划线:
ini
var action = draw.create('polyline', {
mode: 'click'
});
画多边形面
csharp
var action = draw.create('polygon', {
mode: 'click' //点击方式加点
});
画点
csharp
var action = draw.create('point', {
mode: 'click' //点击方式加点
});
画圆
csharp
var action = draw.create('circle', {
mode: 'click' //点击方式加点
});
画矩形
csharp
var action = draw.create('rectangle', {
mode: 'click' //点击方式加点
});
具体实现请参考源码,此处不一一列出
自定义实现展示多个popup
由于官方的popup弹出层只能展示一个,而且不能自定义html内容,所以通过自定义实现。 通过view.toScreen
能够获取到地图上点距离屏幕top、left的距离,因此,只需要将自定义的popup层在地图进行缩放,移动时动态改变popup的位置,就能实现popup跟随地图移动。
ini
<div class="popup-content" v-for="(item, index) in popupData" :key="index"
:style="{ top: item.y - 24 + 'px', left: item.x - 30 + 'px' }">自定义弹出层</div>
//自定义渲染popup
const renderPopup = () => {
let popupDataArr: any = [];
pointGraphics.forEach((item: any) => {
let screen = myMapView.toScreen(item.geometry);
popupDataArr.push(screen);
});
popupData.value = popupDataArr;
}
view.on('resize', () => {
renderPopup();
});
view.on('drag', () => {
renderPopup();
});
//滚轮事件
view.on('mouse-wheel', () => {
setTimeout(() => {
renderPopup();
}, 200);
});
最后
由于ArcGIS API for JavaScript 是英文文档,对于英文不好的同学来说实在不友好,example也比较少不够直观,网上相关资料也不多,各位掘友们路过点赞收藏,说不定以后用到呢。源码可直接查看:gitee.com/fcli/arcgis...