09 ArcGIS JS API 4.15渲染后台接口返回的数据,并进行点选查询

问题描述

出差的某一天晚上在宾馆没事干瞎想,突然想到白天做过的项目功能的时候,有个点选查询的功能引起了我的注意。在项目中为了实现点选查询,是在ArcGIS Server里面发布了一个要素服务,然后将其添加到地图上渲染,并实现了鼠标的点选查询功能,那这个功能可不可以不通过发布服务来实现呢?想到这,打开电脑仔细翻看了了一下ArcGIS JS API的官方文档,发现好像是可以,所以就立即动手了,幸运的是,我成功了,先给大家上一张效果图:

上图中的鼠标点选查询,并出现弹窗的功能实现的数据来源并不是一个发布的要素服务,而是我模拟了六个数据点,将它们保存成了一个数组,这个数组就代表我从后台拿到的数据,因为我不可能为了这样一个小功能再自己去写一个后台吧。好了,现在讲讲主要的实现步骤。

实现步骤

1、首先呢,这个demo是基于Vue来写的,所以我先初始化了一个Vue的demo,当然了,你直接弄成一个HTML页面文件是没有任何问题的,看自己喜好。然后我再项目里安装了esri-loader插件,因为要在Vue的demo里要使用ArcGIS JS API,所以要用到这东西,如果大家对这个过程不了解的话请移步至另一篇文章《【番外】 Vue中使用ArcGIS JS API 4.14开发》,在这里不做详细介绍。

2、初始化完demo,安装完插件之后,接下来我们引入esri-loader,并实例化一个基础的二维地图,代码如下:

	_createMapview: function() {
            const _self = this;
            const option = {
                url: 'https://js.arcgis.com/4.15/init.js',
                css: 'https://js.arcgis.com/4.15/esri/themes/light/main.css',
            };

            loadModules(['esri/Map', 'esri/views/MapView', 'esri/layers/FeatureLayer'], option)
                .then(([Map, MapView, FeatureLayer]) => {
                    let map = new Map({
                        basemap: 'osm',
                    });
                    let view = new MapView({
                        container: 'mapview',
                        map: map,
                        zoom: 10,
                        center: [104.071308, 30.663028],
                    });

                    console.log(view);
                })
                .catch((err) => {
                    console.log('地图创建失败:', err);
                });
        },

3、地图初始化完成之后,我们引入我们的数据,这个过程就相当于是你用AJAX从后台拿到数据了,因为我的数据我单独放在了一份JS文件里。数据引入之后,我们对它进行一下处理,因为你有可能从后台拿到的数据里面,关于经纬度信息是字符串,而不是数值类型,代码如下:

数据文件:

let defaultData = [
    {
        address: '2号线地铁人民公园旁边',
        time: '9:30——18:00',
        coordinate: '[104.06369,30.663774]',
        name: '人民公园',
        phone: '028-86080000',
    },
    {
        address: '2号线地铁天府广场',
        time: '9:30——18:00',
        coordinate: '[104.07235,30.663245]',
        name: '天府广场',
        phone: '028-86080000',
    },
    {
        address: '3号线地铁春熙路站',
        time: '9:30——22:00',
        coordinate: '[104.08586,30.65958]',
        name: '春熙路',
        phone: '028-86080000',
    },
    {
        address: '四川科技馆背后',
        time: '9:30——18:00',
        coordinate: '[104.073787,30.669334]',
        name: '成都体育中心',
        phone: '028-86080000',
    },
    {
        address: '天府大道北段',
        time: '9:30——18:00',
        coordinate: '[104.070095,30.575247]',
        name: '环球中心',
        phone: '028-86080000',
    },
    {
        address: '4号线宽窄巷子地铁站',
        time: '9:30——18:00',
        coordinate: '[104.056441,30.671462]',
        name: '宽窄巷子',
        phone: '028-86080000',
    },
];

export default defaultData;

处理数据函数:

		//处理经纬度数据,返回features
        _translateLonLat: function(data) {
            const _self = this;
            if (data.length > 0) {
                data.map((value, key) => {
                    let lonlatStr = value.coordinate.split(',');
                    let lonStr = lonlatStr[0].split('[')[1];
                    let latStr = lonlatStr[1].split(']')[0];

                    _self.geodata.push({
                        geometry: {
                            type: 'point',
                            x: Number(lonStr),
                            y: Number(latStr),
                        },
                        attributes: {
                            ObjectID: key,
                            address: value.address,
                            time: value.time,
                            name: value.name,
                            phone: value.phone,
                        },
                    });
                });
            }

            return _self.geodata;
        },

4、接下来我们拿到处理过后的数据,其实这就是一个features,用来实例化要素图层的。然后我们用它去实例化一个要素图层,并将它添加到地图上:

//实例化featurelayer
let layer = new FeatureLayer({
	source: resultData,
	objectIdField: 'ObjectID',          
});
view.map.add(layer);

5、到此为止呢,我们的数据点其实已经添加到地图上了,但这时候还不能点击查询,所以我们要配置一个pupoptemplate,代码如下:

					//实例化弹窗
                    let template = {
                        title: '{name}',
                        content: [
                            {
                                type: 'fields',
                                fieldInfos: [
                                    {
                                        fieldName: 'address',
                                        label: '地址',
                                    },
                                    {
                                        fieldName: 'time',
                                        label: '开放时间',
                                    },
                                    {
                                        fieldName: 'phone',
                                        label: '相关电话',
                                    },
                                ],
                            },
                        ],
                    };

				//给要素图层实例化的属性中配置pupoptemplate
                    let layer = new FeatureLayer({
                        source: resultData,
                        objectIdField: 'ObjectID',
                        fields: [
                            {
                                name: 'OBJECTID',
                                type: 'oid',
                            },
                            {
                                name: 'time',
                                type: 'string',
                            },
                            {
                                name: 'address',
                                type: 'string',
                            },
                            {
                                name: 'phone',
                                type: 'string',
                            },
                            {
                                name: 'name',
                                type: 'string',
                            },
                        ],
                        popupTemplate: template,
                    });
                    view.map.add(layer);

6、这样一来我们就直接通过后台返回的数据实例化了一个要素图层,并实现了鼠标点击查询功能了。

附:

完整代码:

import { loadModules } from 'esri-loader';
import defaultData from '../assets/data';

export default {
    name: 'HelloWorld',
    data: function() {
        return {
            geodata: [],
        };
    },
    mounted: function() {
        this._createMapview();
    },
    methods: {
        _createMapview: function() {
            const _self = this;
            const option = {
                url: 'https://js.arcgis.com/4.15/init.js',
                css: 'https://js.arcgis.com/4.15/esri/themes/light/main.css',
            };

            loadModules(['esri/Map', 'esri/views/MapView', 'esri/layers/FeatureLayer'], option)
                .then(([Map, MapView, FeatureLayer]) => {
                    let map = new Map({
                        basemap: 'osm',
                    });
                    let view = new MapView({
                        container: 'mapview',
                        map: map,
                        zoom: 10,
                        center: [104.071308, 30.663028],
                    });

                    console.log(view);
                    let resultData = _self._translateLonLat(defaultData);

                    //实例化弹窗
                    let template = {
                        title: '{name}',
                        content: [
                            {
                                type: 'fields',
                                fieldInfos: [
                                    {
                                        fieldName: 'address',
                                        label: '地址',
                                    },
                                    {
                                        fieldName: 'time',
                                        label: '开放时间',
                                    },
                                    {
                                        fieldName: 'phone',
                                        label: '相关电话',
                                    },
                                ],
                            },
                        ],
                    };

                    //实例化featurelayer
                    let layer = new FeatureLayer({
                        source: resultData,
                        objectIdField: 'ObjectID',
                        fields: [
                            {
                                name: 'OBJECTID',
                                type: 'oid',
                            },
                            {
                                name: 'time',
                                type: 'string',
                            },
                            {
                                name: 'address',
                                type: 'string',
                            },
                            {
                                name: 'phone',
                                type: 'string',
                            },
                            {
                                name: 'name',
                                type: 'string',
                            },
                        ],
                        popupTemplate: template,
                    });
                    view.map.add(layer);
                })
                .catch((err) => {
                    console.log('地图创建失败:', err);
                });
        },

        //处理经纬度数据,返回features
        _translateLonLat: function(data) {
            const _self = this;
            if (data.length > 0) {
                data.map((value, key) => {
                    let lonlatStr = value.coordinate.split(',');
                    let lonStr = lonlatStr[0].split('[')[1];
                    let latStr = lonlatStr[1].split(']')[0];

                    _self.geodata.push({
                        geometry: {
                            type: 'point',
                            x: Number(lonStr),
                            y: Number(latStr),
                        },
                        attributes: {
                            ObjectID: key,
                            address: value.address,
                            time: value.time,
                            name: value.name,
                            phone: value.phone,
                        },
                    });
                });
            }

            return _self.geodata;
        },
    },
};

猜你喜欢

转载自blog.csdn.net/qq_35117024/article/details/106607389