arcgis api for 4.x 开发笔记-在Vue 2.X项目中开发arcgis api for javascript 4.x(三)—— geoJson数据的渲染(方式一)...

这种方式实现的主要原理就是 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();
        }
    }
}

后面优化的时候发现可以有另一种实现方式,利用Bolb生成url创建GeoJSONLayer(推荐使用)

上一篇:arcgis api for 4.x 开发笔记-在Vue 2.X项目中开发arcgis api for javascript 4.x(二)—— 图层统计查询(outStatistics )..._u012917880的博客-CSDN博客

下一篇(推荐使用):arcgis api for 4.x 开发笔记-在Vue 2.X项目中开发arcgis api for javascript 4.x(四)—— geoJson数据的渲染(方式二)..._u012917880的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端程序员_花姐夫Jun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值