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;
        },
    },
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章