Angular(4)中載入Arcgis for JavaScript地圖
背景
近期我司專案的需要,採用Angular(4)+SpringBoot前後端分離的架構。並且在需要在專案中實現Arcgis地圖。
本人之前有過Arcgis for JavaScript的小小填坑經驗,並且在公司一直有前後端都會做點的,所以我的任務自然明瞭。
尋尋覓覓
像我這種菜雞遇到這種沒有幹過的事情肯定是先問百度和谷歌,兩個關鍵詞敲下。幾乎搜尋的內容裡很少有兩個關鍵字共存的。但是我這慧眼識得好程式碼,於是發現了這: https://github.com/Esri/angular-esri-map
Esri是美國環境系統研究所公司,多年來,ESRI公司始終將GIS視為一門科學.也就是說這是官方例項呀。
這樣就完了嗎?不,事情總是沒那麼簡單的。我以負八級的英文水平開始看這個專案的README,第一行。心都碎了[手動心碎]他是這樣說的。
A collection of directives to help you use Esri maps and services in your AngularJS v1.x applications.
wtf?==>AngularJS v1.x applications,我的專案用的可是4.x,這不扯淡?
在這裡我嘗試將他的專案clone到本地,的確可以跑起來,並且可以看到地圖,但嘗試獲取核心程式碼但是在包下載的時候就出現了很多問題於是放棄了[真的是無限差包]。
撥雲見霧
因為之前看到是2.x版本就機遇嘗試便沒有仔細閱讀本專案的說明文件。回去看他的說明文件並把Resources
節點下的東西都挨個看了一遍,發現了其中一項貌似很有用:
- Example of how to use the ArcGIS API for JavaScript in an angular-cli application
- 【譯】如何在 Angular CLI 程式中使用ArcGIS API for JavaScript的示例
於是開始閱讀這個示例的說明文件,他在文中提到:
This repository is an example of one way to use the ArcGIS API for JavaScript in an application generated with angular-cli.
此儲存庫是在使用angular-cli生成的應用程式中使用ArcGIS API for JavaScript的一種方法的示例
還有一句:
Adding the ArcGIS API to your own angular-cli application
將ArcGIS API新增到您自己的Angular-cli應用程式Rather than clone this repository, you should create your own application with the angular-cli and then follow the instructions below to add the above libraries:
而不是克隆此儲存庫,您應該使用angular-cli建立自己的應用程式,然後按照以下說明新增以上庫:
下面的是說明:
- angular2-esri-loader - a low level service needed to load and use ArcGIS modules (v3.x or v4.x) in your Angular applications
- 在Angular應用程式中載入和使用ArcGIS模組(v3.x或v4.x)所需的低階服務
- angular-esri-components - a set of reusable components for use with v4.x (only) of the ArcGIS API
- 一組(僅)可用於ArcGIS API v4.x的可重用元件
上面的意思已經很清楚。這個專案不建議clone,而是使用angular2-esri-loader 來載入ArcGIS模組,angular-esri-components元件是隻能在Arcgis4.x版本中使用的。
當點開angular2-esri-loader這個模組的時候,會很清楚的看到如何安裝這個Angular的gis載入庫,並且寫了示例程式。對於angular有一定的瞭解的話,這些程式碼或許就能很清晰的表達出它在做什麼。
示例的程式碼就不列出,可以到github上閱讀。大體流程是:
- npm安裝angular-esri-loader,Angular版本不同則安裝的命令和庫也會存在差異
- EsriLoaderModule模組載入到程式中
- 使用EsriLoaderService元件載入地圖
- 文件中載入的是基礎圖層,但一般開發時會載入快取地圖服務或者其他型別地圖服務。這將在我的的示例專案中看到
專案效果:
差異對比
你如果看過Arcgis for JavaScript的程式碼。那麼JavaScript程式碼,如何轉換為Angular(TypeScript)的程式碼,這裡我也沒有做過多的瞭解,只是照葫蘆畫瓢寫的一些:
這裡推薦去看一下阮一峰的:ES6標準入門可以提供一些參考
下面將做出原生的Arcgis for JavaScript程式碼和Angular中的書寫對比。
變數宣告:
// 有可能你需要在地圖初始化前首先宣告變數,以便你在任何地方都是可用的
var map; // js
map: any; // ts
地圖的模組載入,Arcgis的api是基於dojo框架的,如下:
- JavaScript中載入地圖模組
var map;
require(["esri/map", "dojo/domReady!"], function(Map) {
var map = new Map("map", {
center: [-118, 34.5],
zoom: 8,
basemap: "topo"
});
});
- Angular中載入地圖(基於angular-esri-loader載入器)
// 這裡程式碼並不全,具體請檢視上面的示例專案
.. 省略匯入
@ViewChild('map') mapEl: ElementRef;
map: any;
ngOnInit() {
return this.esriLoader.load({
// 在js中是不管這個url的,因為它在html中已經引入對應的版本
url: '//js.arcgis.com/3.18/'
}).then(() => {
this.esriLoader.loadModules(['esri/map']).then(([Map]) => {
this.map = new Map(this.mapEl.nativeElement, {
center: [-118, 34.5],
zoom: 8,
basemap: 'topo'
});
});
});
}
dojo事件新增:
...
// dojo點選事件新增 by JavaScript
dojo.connect(map, 'onClick', function(evt){
var emp = evt.mapPoint;
var cur_wkid = emp.spatialReference.wkid;
... more code
...
});
...
...
// dojo點選事件新增 by Angular
dojo.connect(this.map, 'onClick', (evt) => {
const emp = evt.mapPoint;
const cur_wkid = emp.spatialReference.wkid;
... more code
...
});
...
這裡實際上就是一個箭頭函式的區別還有變數的宣告區別。
滿地黃花
這就結束了?
不不不,遠遠還不只這些。不論是Angular還是Arcgis,很多東西都沒有做過多的瞭解和深入。不知道那行程式碼存在隱患。所以革命尚未成功,還得加倍學習和實踐鞏固。