前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ArcGIS JS API 4.15渲染后台接口返回的数据,并进行点选查询

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

作者头像
X北辰北
发布2022-02-22 15:53:06
1.9K0
发布2022-02-22 15:53:06
举报
文章被收录于专栏:ArcGIS JS API开发ArcGIS JS API开发

本文主要介绍下如何使用ArcGIS JS API对后台接口返回的数据进行渲染,文章中的后台返回数据使用单独的配置文件来处理,详情请看文章内容。

问题描述

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

img
img

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

实现步骤

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

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

代码语言:javascript
复制
_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文件里。数据引入之后,我们对它进行一下处理,因为你有可能从后台拿到的数据里面,关于经纬度信息是字符串,而不是数值类型,代码如下:

数据文件:

代码语言:javascript
复制
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;

处理数据函数:

代码语言:javascript
复制
//处理经纬度数据,返回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,用来实例化要素图层的。然后我们用它去实例化一个要素图层,并将它添加到地图上:

代码语言:javascript
复制
//实例化featurelayer
let layer = new FeatureLayer({
    source: resultData,
    objectIdField: 'ObjectID',          
});
view.map.add(layer);

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

代码语言:javascript
复制
    //实例化弹窗
    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、这样一来我们就直接通过后台返回的数据实例化了一个要素图层,并实现了鼠标点击查询功能了。

附:

完整代码:
代码语言:javascript
复制
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;
        },
    },
};
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-072,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 实现步骤
  • 附:
    • 完整代码:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档