以下內容,是我在學習Api開發過程中的初始積累,點點滴滴。
1. require([reference package...],function(Class declaration){code...})方法中的引用部分的順序,必須與function中的類聲明的順序 必須一致,否則找不到對應的類對象,不會報錯,但程序無效。
require(["esri/Map", "esri/views/SceneView", "esri/Basemap", "esri/Ground", "esri/layers/WebTileLayer", "esri/layers/ElevationLayer", "esri/layers/FeatureLayer", "dojo/domReady!"], function (Map, SceneView, Basemap, Ground, WebTileLayer, ElevationLayer, FeatureLayer) {
2. 經過幾天摸索,仍然無法實現用ArcGis Api for Javascript4.0 來加載ArcGIS Server中發布好的GlobeServer服務,而且網上的示例幾乎都是關於利用API來操作MapServer/ImageServer等其它類型的服務,最后不得已求助ESRI北京技術支持,得到答案是,ArcGis Api for Javascript4.0目前還不支持在B/S頁面端實現對GlobeServer的操作,只有ArcEngine、ArcObject等C/S端的二次開發才支持GlobeServer。要實現對3D效果的B/S應用,解決方案就是在ArcGIS Server服務端分別將影像圖層發布為一個MapService(可包括多個影像圖層),DEM高程圖層發布為一個ImageService(可包括多個高程圖層),然后利用Api在B/S端分別讀取MapServer和ImageServer,通過basemap和ground等Map屬性來實現三維效果的渲染。
PS:突然想起來還有個WebScene類,其中就講到了將可以將三維效果場景發布在 ArcGIS Pro或者ArcGIS Online 上,然后通過SceneView來調用,只是在調用的時候,需要指定一個id(如下圖代碼示例)。
var scene = new WebScene({ // autocasts as esri/portal/PortalItem portalItem: { id: "affa021c51944b5694132b2d61fe1057" // ID of the WebScene on arcgis.com } }); var view = new SceneView({ map: scene, // The WebScene instance created above container: "viewDiv" });
在ArcGis 開發者網站的 Api Reference部分,還介紹了web scenes有兩種:global or local,其中Global scenes把地球描述為球體,而Local scenes
在一個平的表面來描述地球, Global web scenes 通過WebMercator 或者GCS WGS84空間投影來創建,而 local web scenes可以是任何坐標投影,可以在這讀取更多關於choosing global or local scenes.
那么就此說來,存在Global web scenes,這就與我通過ArcGlobe發布的GlobeSevice相近,下回研究一下再來發表感想。
ps:這兩天又接着查看API Reference的過程中,講到了SceneView的Viewing modes內容模塊,提出分為Globe Scene和Local Scene兩種視圖模式。
3. 在服務器上發布地圖服務,一共有三種方式:1.利用ArcCatalog;2.利用Service Manager發布;3. 在ArcMap的菜單Share As 中選擇Service進行發布。
4. 關於Viewpoint的解釋,API Reference中是這樣說的:
Describes a point of view for a 2D or 3D view. In a 2D view, the viewpoint is determined using a center point and scale value. In a 3D view, it is determined using a camera position. The Viewpoint can be bookmarked for later use, or used for navigation purposes.
翻譯理解為:在2D地圖MapView 應用中,通常采用Center:[lon,lat]和scale:value屬性來設定一個點的視圖位置;而在3D SceneView應用中,則通常采用Camera對象,通過設定用camera的position:[lon,lat,z-value]屬性和scale屬性來定義定一個點的視圖位置。
在項目中,我就遇到一個問題,我需要在地圖窗口增加一個按鈕,用戶在操作地圖窗口后,單擊按鈕可回到初始地圖視圖狀態。
(1) 新建一個初始視圖控件:
var homeWidget = new Home({ view: mainView }); mainView.ui.add(homeWidget, "manual");
然后運行頁面,發現單擊按鈕后,回到的初始視圖狀態是地圖上方正攝影像方式,而不是我最開始設定的地圖初始狀態。初始地圖設置參數如下代碼:
mainView.then(function() { //設置主地圖窗口的初始視圖 mainView.goTo({ center: [114.532, 31.138], scale: 50000, heading: 35, tilt: 70 }, { animate: true //允許goTo動作以動畫形式展現 }); });
查了API Reference,SceneView.goTo()方法中可以定義視圖定位到一個viewPoint或camera對象,於是我就想是否可以創建一個viewpoint,然后通過指定地圖視圖goTo到這個viewpoint位置,我將viewpoint的參數定義到和初始視圖位置一樣。
var initialViewpoint = new Viewpoint({ camera: { position: [114.532, 31.138], heading: 35, tilt: 70 }, scale:5000, });
(3)在homeWidget的click事件處理函數中設定地圖視圖goTo到這個viewPoint位置。
on(homeWidget, "click", function () { mainView.then(function () { mainView.goTo(initialViewpoint, { animate: true }); }); });
運行后,單擊初始視圖按鈕,切換位置不是我要的位置,而且地圖比例尺縮放到很大。
后來我又發現 homeWidget也有一個viewpoint屬性,我設定homeWidget.viewpoint = initialViewpoint;也不行,還是不是回到我要的視圖狀態。
我自己想了很久,終於發現問題所在。原來我的需求是單擊按鈕,回到初始視圖,而我初始視圖狀態參數是在mainView.goTo()方法中定義的,如下:
mainView.then(function() { //設置主地圖窗口的初始視圖 mainView.goTo({ center: [114.532, 31.138], scale: 50000, heading: 35, tilt: 70 }, { animate: true //允許goTo動作以動畫形式展現 }); });
視圖狀態主要通過center、scale、heading、tilt等屬性來設定的,其中center[lat,lon]屬性與viewpoint對象的camera屬性中指定的position[lat,lon]屬性應該是有區別的,才造成我單擊按鈕后,切換視圖位置不是我要的初始視圖效果。思前想后,我想明白了,原來viewpoint對象是指視點,也就是地圖觀察者的位置,所以才會出現viewpoint對象中含有camera屬性(兩者直接的區別是:viewpoint對象包括了camera對象級屬性以及scale等其它屬性,對象級別更大),SceneView.goTo(target,option)方法中的target對象列舉了viewpoint或camera,而我如果把viewpoint或camera作為SceneView.goTo()的target,則試圖效果應該是以[lat, lon]為視點的觀察視圖,並不等同於SceneView.goTo()方法參數中的center[lat,lon]屬性的概念。我們要明白,SceneView.goTo()方法中為設置center[lat,lon]屬性,是設定地圖顯示以[lat, lon]為視圖中心,配合heading和tilt來確定地圖視圖效果。而goTo(target,option)方法中的參數target不僅包括viewpoint或camera等對象級屬性,也包括了center/scale/zoom/heading/tilt/position等參數屬性。如果target參數中設定了viewpoint或camera等對象,則是去設定地圖視圖定位到某個視點(用戶觀察點)或相機的位置,而這里的center屬性,就是SceneView.center屬性,它的定義是用來定義地圖視圖的中心位置的。

結果豁然開朗,修改homeWidget控件的click事件處理函數,果斷實現效果。
//為homeWidget增加click事件處理 on(homeWidget, "click", function () { mainView.goTo({ center: [114.532, 31.138], scale: 50000, heading: 35, tilt: 70 }, { animate: true //允許goTo動作以動畫形式展現 }); });
總結:深刻理解Api Reference中對於每個對象語法定義和用法,雖然都是英文,但還是需要深刻理解,否則理解錯誤了,就用不好這個對象。
5. 關於TileLayer和MapImageLayer的認識:
參考API Reference: https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-TileLayer.html#
The TileLayer allows you work with a cached map service exposed by the ArcGIS Server REST API and add it to a Map as a tile layer. A cached service accesses tiles from a cache instead of dynamically rendering images. Because they are cached, tiled layers render faster than MapImageLayers. To create an instance of TileLayer, you must reference the URL of the cached map service.
理解為:TileLayer是用於一個緩存化的地圖服務,通過 ArcGIS Server REST APIl作為 接口,給地圖添加一個瓦片式圖層。這與動態描述的影像圖層不同,因為緩存花的瓦片圖層事先在服務器端已經存儲好,B/S客戶端只需要直接調用已經緩存好的圖片即可。通過REST URL地址來進行調用和訪問。
To display a map service as a dynamic layer, see MapImageLayer.
理解為:作為動態描述圖層,MapImageLayer則把未緩存成瓦片的圖層,作為一個動態影像圖層來加載,
