这种方式实现的主要原理就是 geoJson 通过数据的转换,生成 graphic 添加到GraphicsLayer,最后添加到 Map。
如果是加载geoJson文件或者是geoJson服务的话是直接生成GeoJSONLayer ,例如:
const geoJSONLayer = new GeoJSONLayer({
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson",
copyright: "USGS Earthquakes",
});
map.add(geoJSONLayer); // adds the layer to the map
但是如果是要直接加载 geoJson 格式的数据的话,我查了官网 API 和其他一些平台都是说arcgis api for js 不支持直接加载 geoJson 数据,要将 geoJson 数据转化成为arcgisJson 才能用。既然不能直接使用 geoJson 数据,就只能自己动手解决啦。
步骤如下:
1、geoJson转arcgisJson(网上找到一个好东西,terraformer提供了将geoJson和arcgisJson互转的函数)
安装 terraformer
npm install @terraformer/arcgis
使用
import { geojsonToArcGIS } from "@terraformer/arcgis"
geojsonToArcGIS({
"type": "Point",
"coordinates": [45.5165, -122.6764]
})
>> { "x":-122.6764, "y":45.5165, "spatialReference": { "wkid": 4326 } }
注意:输出的arcgisJson数据里面缺少type,比如当前例子type:"point";{"x":-122.6764,"y":45.5165,type:"point","spatialReference":{"wkid":4326}}
2、自定义一个处理geoJson数据的geoJsonLayerService
/**
* @描述: 自定义geoJsonLayerService
* @作者: 花姐夫JUN
* @创建时间: 2021-10-27 10:11:45
*/
import Color from '@arcgis/core/Color';
import Graphic from '@arcgis/core/Graphic';
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer';
import SpatialReference from '@arcgis/core/geometry/SpatialReference';
import { geojsonToArcGIS } from '@terraformer/arcgis';
export default class GeoJsonLayerService {
// 当前geoJson数据
data;
// 当前操作的layer
layer;
private readonly spatialReference = null;
// 所有geometry需要的symbol
private symbols = {
point: null,
multipoint: null,
polyline: null,
polygon: null,
extent: null,
};
constructor(options: any = { graphicsLayerId: 'geoJson_GraphicsLayer', symbols: {}, data: undefined }) {
this.setDefaultSymbols();
const { graphicsLayerId, symbols, data } = options;
this.symbols = { ...this.symbols, ...symbols };
this.layer = new GraphicsLayer({ id: graphicsLayerId });
this.spatialReference = new SpatialReference({ wkid: 4326 }); // Data must be in Geographic Coordinates
if (data) {
this.data = data;
this.addGeoJsonToGraphicsLayer(this.data);
}
}
// 设置默认symbol
private setDefaultSymbols() {
const getRandomColor = (mainColor, transparency) => {
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
let color;
switch (mainColor) {
case 'red':
color = new Color([getRandomInt(150, 255), getRandomInt(0, 255), getRandomInt(0, 255), transparency]);
break;
case 'green':
color = new Color([getRandomInt(0, 155), getRandomInt(150, 255), getRandomInt(0, 155), transparency]);
break;
case 'blue':
color = new Color([getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(150, 255), transparency]);
break;
default:
break;
}
return color;
};
const simplePointSym = {
type: 'simple-marker',
color: getRandomColor('blue', 0.5),
outline: {
color: getRandomColor('blue', 0.75),
width: '0.5px',
},
};
const simpleLineSym = {
type: 'simple-line',
color: 'lightblue',
width: '2px',
style: 'short-dot',
};
const simplePolygonSym = {
type: 'simple-fill',
color: [51, 51, 204, 0.9],
style: 'solid',
outline: {
color: 'white',
width: 1,
},
};
this.symbols = {
point: simplePointSym,
multipoint: simplePointSym,
polyline: simpleLineSym,
polygon: simplePolygonSym,
extent: simplePolygonSym,
};
}
// 生成Graphic
generateGraphic(arcgisJson) {
const graphic: any = new Graphic(arcgisJson);
graphic.symbol = this.symbols[graphic.geometry.type];
graphic.geometry.spatialReference = this.spatialReference;
return graphic;
}
addGeoJsonToGraphicsLayer(geoJsonData, graphicsLayer = this.layer) {
if (!graphicsLayer) {
graphicsLayer = new GraphicsLayer();
}
const { type, features } = geoJsonData;
// 格式是否正确
if (type !== 'FeatureCollection' || !features) {
console.error('GeoJsonLayer Error: Invalid GeoJSON FeatureCollection. Check url or data structure.');
return;
}
const graphics = features.map((feature_geoJson: any) => {
const { geometry } = feature_geoJson;
// 转换GeoJSON为ArcGIS JSON
const arcgisJson: any = geojsonToArcGIS(feature_geoJson);
// 转化后的arcgisJson的geometry里面缺少type,所以要添加
arcgisJson.geometry.type = geometry.type.toLowerCase();
// 添加graphic到layer
const graphic = this.generateGraphic(arcgisJson);
return graphic;
});
graphicsLayer.addMany(graphics);
}
// 清空所有的graphics
clearAllGraphics() {
if (this.layer) {
this.layer.removeAll();
}
}
destroyLayer() {
if (this.layer) {
this.layer.destroy();
}
}
}
3、调用自定义的geoJsonLayerService
import { Vue, Component } from 'vue-property-decorator';
import VueMixins from '@/views/queryInfoDisplay/mixins/vueMixins';
import GeoJsonLayerService from '@/views/map/services/geoJsonLayerService';
@Component({ name: 'VueMapMixins' })
export default class VueMapMixins extends VueMixins {
// geoJson数据处理的service
geoJsonLayerService;
//要渲染的geoJson数据
geoJsonData = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
coordinates: [
100.00294,
23.921136,
],
type: 'Point',
},
properties: {
name: 'test',
},
},
{
type: 'Feature',
geometry: {
coordinates: [
100.004024,
23.918178,
],
type: 'Point',
},
properties: {
name: 'test',
},
},
{
type: 'Feature',
geometry: {
coordinates: [
100.022149,
25.622177,
],
type: 'Point',
},
properties: {
name: 'test',
},
},
{
type: 'Feature',
geometry: {
coordinates: [
100.022528,
25.622042,
],
type: 'Point',
},
properties: {
name: 'test',
},
},
{
type: 'Feature',
geometry: {
coordinates: [
100.022658,
25.621685,
],
type: 'Point',
},
properties: {
name: 'test',
},
},
{
type: 'Feature',
geometry: {
coordinates: [
100.022754,
25.622388,
],
type: 'Point',
},
properties: {
name: 'test',
},
},
{
type: 'Feature',
geometry: {
coordinates: [
100.086973,
27.726744,
],
type: 'Point',
},
properties: {
name: 'test',
},
},
],
};
// 图层添加
addLayers(layers) {
this.$_emitEventBus(this.allEvents.map.addMany, layers);
}
// 高亮显示geoJson数据
highlightFeaturesByGeoJsonData(geoJsonData) {
this.geoJsonLayerService.clearAllGraphics();
this.geoJsonLayerService.addGeoJsonToGraphicsLayer(geoJsonData);
}
created() {
if (!this.geoJsonLayerService) {
this.geoJsonLayerService = new GeoJsonLayerService({
symbols: {
point: {
type: 'picture-marker',
url: '/image/map/green_point_marker.svg',
width: '24px',
height: '24px',
},
},
});
if (this.geoJsonLayerService?.layer) {
//将图层添加到map
this.addLayers([this.geoJsonLayerService.layer]);
}
}
//渲染geoJson数据
this.highlightFeaturesByGeoJsonData(geoJsonData);
}
//页面销毁的时候destroyed当前渲染geoJson的layer
destroyed() {
if (this.geoJsonLayerService?.layer) {
this.geoJsonLayerService.destroyLayer();
}
}
}