vue地圖可視化 ArcGIS篇(3)

ArcGIS for javascript開發心得

本次實例中採用ArcGIS for javascript3.24版本,由於版本3與4在API等存在較大區別,就不一一列舉,詳細區別看官方解釋
arcgis for js4.7版本能夠自動創建layer、graphs等類,而不像3.24版本需要在圖形渲染前重新new 新的類。然而,查找大量文件資料,網上有關ArcGIS forjavascript的資料甚少,更不用說通過vueJS+arcGIS開發出一套可視化平臺,在不斷查看官方文檔和實際操作,總結自己的構思和使用心得。

技術採用:vueJS + vuetify + axios + arcGIS3.24 + echarts

clipboard.png

如圖所示:可視化界面採用三層三文治結構,從server(後臺,非online server)讀取數據,vueJS負責數據驅動,ArcGIS與echarts負責數據的圖形化。同時引入瀏覽器的web sql db本地數據庫進行海量數據緩存

ArcGIS API for Javascript 是由美國 Esri 公司推出, 基於 dojo框架和 REST 格式的一套編程接口(目前最新版本爲 3.3, dojo1.8。 通過 ArcGIS API for Javascript可以對 ArcGIS for Server 進行訪問調用,並將 ArcGIS for Server 提供的地圖資源和其它資源online加載到Web應用中。

基礎知識

Dojo

Dojo 是一個強大的面向對象 Javascript 框架。主要由三大模塊組成: Core、 Dijit、 DojoX。 其中 Core提供 Ajax、 events、 packaging、 CSS-based querying、 animations、 JSON 等相關操作 API。 Dijit 是一個可更換皮膚,基於模板的 WEB UI 控件庫。 DojoX 包括一些創新/新穎的代碼和控件: DateGrid、 charts、離線應用、 跨瀏覽器矢量繪圖等。
Dojo 的特點可從下面幾部分譸起:
1、 Dojo 是一個純 Javascript 庫,後臺只要提供相應的接口就能夠將數據以 Json 的格式輸出給前臺。
2、 Dojo 自身定了完整的函數庫,屏蔽了瀏覽器的差異。
3、 Dojo 自身定了界面組件庫,其組件代碼採用了面向對象的思想,便於繼承及擴展。
4、 對前端界面聯動需求較爲複雜的時候,基於 dojo 的頁面組件將是首選,因爲其可以將界面中
某一個具有共性的區域抽象出來,封裝返這一區域的界面行爲以及數據,採用模塊式的方式完成複雜頁面的開發。

熱力圖

一、實現地圖熱力圖操作
熱力圖,是以特殊高亮的形式顯示訪客熱衷的頁面區域或訪客所在的地理區域的圖示。常用的熱力圖統計分成樣方計數法(Quadrate Analysis)和核密度法(Kernel Density Estimation)。
核密度法基於密度的點模式分析方法,因此事件之間的相對位置和距離具有決定作用

clipboard.png

樣方計數法其事件之間的絕對位置具有決定作用,單位面積的事件、數量在空間上具有比較明確的變化。如:空間對象的平均值/密度。

clipboard.png

例子裏,我們採用第二種分析方法來展示區域性的人口密度
然而多次嘗試發現,官方給出的熱力圖基於heatMap並不能滿足我們的需求,而且online service的解決方案不符合要求
最後,我們通過esri提供FeatureLayer類創建圖層,以座標繪製圖形,權重區分色值來還原熱力圖

ArcGIS for javascript

效果圖

圖片描述

clipboard.png

涉及到arcgis 基礎地圖、geometry、FeatureLayer、graphic等API的使用

模塊引入

vue引入arcgis for js模塊
Install

npm install --save esri-loader

or

yarn add esri-loader

在文件中引入ersi

import * as esriLoader from 'esri-loader'

加載樣式 在加載地圖前,需要先加載對應版本的樣式表
@import url('https://js.arcgis.com/3.24/es...');
or
esriLoader.loadCss('https://js.arcgis.com/3.24/es...')


到這裏我們解決完成vue項目引入arcgis的問題,但在實際開發過程,會發現國內使用arcgis有兩個嚴重不足的問題:
第一個是底圖地圖服務差,加載慢
第二個是arcgis for js的提供的api接口偶爾出現無法加載的問題
因此,在開發階段,爲優化用戶體驗,通過切換國內地圖服務和本地JS-SDK部署解決上述的問題(後面會介紹這兩個方案的解決過程)

加載需要的地圖模塊
1.通過DOJO loader 加載地圖api類
2.通過map加載地圖(4.7中將地圖渲染分成WebMap和MapView/SceneView視圖)

const options = {
    url: 'https://js.arcgis.com/3.24/'
}
esriLoader.loadModules([
    'esri/map',
     'dojo/domReady!'
], options).then(([Map]) => {
    let map = new Map('YouMapDOM', {
        basemap: 'topo',
        center: [113.3209952545166, 23.090055306224895],
        zoom: 15
    })
}).catch (err => {})

到這裏我們已經成功加載arcgis地圖

map

map:底圖,負責底圖渲染
Map類創建地圖容器和所需的DOM結構,用於添加圖層、圖形、信息窗口和其他的導航控件

創建地圖是arcgis最基本的操作,在3.x中通過map創建地圖

new Map(YouMapDOM, option)

地圖打點操作,繪製圖形範圍等覆蓋物是地圖可視化的基本操作
clipboard.png

屬性
map屬性是可以自定義配置,如backgroundColor、height、width等

方法
map層作爲arcgis最重要的元素,繼承了衆多的方法,例如
addLayer 地圖添加Esri圖層
centerAndZoom(mapPoint,levelOrFactor) 居中並縮放地圖
destroy() 銷燬地圖實例
...

map.setBasemap(url)

clipboard.png

事件
我們不單止通過map的方法進行必要層與層間操作,同時也可以在map上綁定事件,官方解釋如下

All On Style event listeners receive a single event object.
Additionally, the event object also contains a 'target' property whose
value is the object which fired the event.

常用的如
basemap-change
click
dbl-click
key-down / key-up
load
mouse-down/drag/move
zoom
...
通過監聽不同類型的鼠標鍵盤等事件來觸發我們所需的操作,例如通過map綁定click事件,只要我們點擊地圖,如提示、地點、graphic層等等,都能觸發。

map.on('click', (event) => {
    if (event.graphic.symbol && event.graphic.symbol.type === 'simplefillsymbol') {}
    if (event.graphic.symbol && event.graphic.symbol.type === 'textsymbol') {}
    if (event.graphic.symbol && event.graphic.symbol.type === 'simplemarkersymbol') {}
}

ersi官網提供多種默認底圖地圖樣式(如下圖),然而引入官方地圖國內存在較爲嚴重的穩定性問題,因此後期可以將地圖換成國內通用地圖,如天地圖等

注意:轉換地圖服務可能存在一定的偏差,具體參考問題3

clipboard.png

this.map.setBasemap(baseMap)

  {
    name: '中國灰色版',
    url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer'
  },
  {
    name: '中國午夜版',
    url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer'
  },
  {
    name: '中國彩色版',
    url: 'https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetWarm/MapServer'
  },
  {
    name: '中國彩色POI版',
    url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer'
    }
 

clipboard.png

FeatureLayer

FeatureLayer:圖形圖層,可用於地圖服務或地圖要素服務中顯示單個圖層要素。也通過isEditable=true編輯圖層要素
FeatureLayer默認從ArcGIS Server中獲取圖層信息進行渲染,然鵝全文的例子不採用服務器渲染的模式,而是直接本地數據渲染圖層
熱力圖的渲染及操作

      let featureLayers = new FeatureLayer(featureCollection, {
        id: 'flickrLayer',
        outFields: ['*'],
        opacity: 0.5,
        showLabels: true
      })
      map.on('layers-add-result', (results) => {
        loading.close()
        let features = []
        res.forEach(function (item, i) {
          let arrt = {
            title: item.cellId,
            flowCount: item.flowCount,
            groupCount: item.groupCount,
            cellId: item.cellId,
            cityId: item.cityId,
            distId: item.distId
          }
          let geometry = new Polygon(item.rings)
          let graphic = new Graphic(geometry)
          graphic.setAttributes(arrt)
          features.push(graphic)
        })
        featureLayers.applyEdits(features, null, null)
      })
      map.addLayers([featureLayers])

通過featureLayers.applyEdits()類添加網格圖層
featureLayer.on()綁定的事件,如click、dbl-click、graphic-add等事件類型進行圖層交互,如對圖層進行高亮、彈窗

featureLayers.on('click', (event) => {})

graphic

graphic圖形繪製

let geometry = new Polygon(rings)
let newGraphic = new Graphic(geometry)
map.graphics.add(newGraphic)

地圖上有多樣的覆蓋物可以採用graphic繪製圖形,如高亮網格Polygon、圓形範圍Circle、打點point、標誌物createSymbol等

let gl = new GraphicsLayer({ id: 'circles2' })
map.addLayer(gl)
let symbol = new SimpleFillSymbol().setColor().outline.setColor([0, 142, 255])
centerPoints.forEach(e => {
   let circleGeometry = new Circle({
       center: e,
       radius: radius,
       geodesic: true
   })
   let circleGraphics = new Graphic(circleGeometry, symbol)
   gl.add(circleGraphics)
})

持續修改更新...

問題

1、4.7中WebMap、MapView的區別
4.0版本由於加入3D元素,Map和Layers不再處理圖形的繪製,而是交給Views完成
View視圖是4.0版本提出的概念,包括MapView(2D)和SceneView(3D)兩個類
在4.X中底圖和底圖操作層分離的
2、離線部署
(1)國內地圖服務
(2)JS-SDK本地部署
考慮到國內的用戶會出現地圖訪問慢甚至無法正常加載的問題,因此ArcGIS for js 的離線部署是非常有必要的
1、註冊arcgis開發者賬號
2、進入官方api-sdk下載界面選擇你需要的版本
https://developers.arcgis.com...

clipboard.png
稍等片刻後
3、需要準備一臺可以正常訪問的服務器(以Linux-tomcat arcgis_js_api3.2.4爲例)
將下載的arcgis_js_api文件複製到tomcat的/usr/local/example/webapps目錄下
修改arcgis_js_api/library/3.24/3.24/init.js文件中[HOSTNAME_AND_PATH_TO_JSAPI]爲<myserver>/arcgis_js_api/library/3.24/3.24/
修改arcgis_js_api/library/3.24/3.24/dojo/dojo.js 文件中[HOSTNAME_AND_PATH_TO_JSAPI]爲<myserver>/arcgis_js_api/library/3.24/3.24/
4、完成上面修改即可正常訪問自己服務器上的SDK接口

3、座標偏差
我們常用的座標有三種,分別是國際座標系、火星座標系、百度座標系
地球座標系——WGS84:GCS_WGS_1984,常見於 GPS 設備,Google地圖、arcGIS地圖等國際標準的座標體系。
火星座標系——GCJ-02:中國國內使用的被強制加密後的座標體系,高德座標採用這種座標體系。
百度座標系——BD-09:百度地圖所使用的座標體系,是在火星座標系的基礎上又進行了一次加密處理。

clipboard.png

座標偏差依賴於地圖底圖服務,上面將默認的英文地圖轉化成國內常用的天地圖(默認火星座標),這裏就產生問題。
1、不建議底圖選擇中存在兩種不同座標體系,如下圖座標存在明顯的偏差,火星座標在採用WGS84座標系的地圖上位置偏上
彩色中國天地圖
clipboard.png

全球衛星地圖
clipboard.png

2、例如我們使用arcGIS的search類進行查找,返回的數據都是國際座標,因此必須進行偏差糾正。
我們可以使用高德地圖提供的座標變換AMap.convertFrom()進行座標轉換

AMap.convertFrom(lnglat, type, function (status, result) {
    if (result.info === 'ok') {
        var resLnglat = result.locations[0];
        m = new AMap.Marker({
            position: resLnglat,
        });
        map.add(m);
     }
});

或者也可以自定義轉換方法
https://blog.csdn.net/Admin_y...(網上隨便搜的參考)

備註:本文中提到的總結可能存在不足和錯誤,多多包容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章