vue地圖視覺化 ArcGIS篇(3)

楊健YJohn發表於2019-03-04

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本地資料庫進行海量資料快取。

vue地圖視覺化 ArcGIS篇(3)

 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(`js.arcgis.com/3.24/esri/c…`);
or
esriLoader.loadCss(`js.arcgis.com/3.24/esri/c…`)

到這裡我們解決完成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下載介面選擇你需要的版本
developers.arcgis.com/downloads/a…

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);
     }
});複製程式碼

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

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

上一篇文章: vue 地圖視覺化(2) mapbox篇

相關文章