有人問我怎么這個系列沒有寫自己做的東西呢?
大哥大姐,這是“學習筆記”啊!當然主要以解讀和筆記為主咯。
也有人找我要實例代碼(不是示例),我表示AJS尚未成熟,現在數據編輯功能才簡略地在AJS 4.3中出現,4.2是沒有的,widget和分析功能也不是很完善,還是再等等吧,先學着基礎,其他的以后再說。
本節我會緊隨這個例子學習一下Query這個類,作為圖層查詢方法的重要參數,它起了傳遞查詢用的信息的作用。
本例對應官方的例子是:Query a SceneLayer's linked FeatureLayer
這個例子操作起來很簡單,等地圖加載完成后,點擊對應的3D白色模型,會出現一個popupTemplate彈窗,顯示一個表格,為這個大樓的信息。如下圖:
換個視角:
那我們就開始吧!
給出引用
require([ "esri/Map", "esri/views/SceneView", "esri/layers/SceneLayer", "esri/layers/FeatureLayer", "esri/tasks/support/Query", "dojo/domReady!" ], function(Map, SceneView, SceneLayer, FeatureLayer, Query){ ... } )
數據方面,用到了場景圖層和要素圖層;
查詢方面,用到了Query模塊。
函數參數
function(Map, SceneView, SceneLayer, FeatureLayer, Query){ var map = new Map({...}); var view = new SceneView({...}); var sceneLayer = new SceneLayer({...}); map.add(sceneLayer); var featureLayer = new FeatureLayer({...}); featureLayer.load().then(attributesReady); function attributesReady(){ ... } }
套路,先把大骨架弄出來,然后逐個擊破。
多了一個場景圖層,多了一個要素圖層,在要素圖層加載完成后進行一個異步操作attributesReady()。
還算簡單,先把map和view的代碼看看(太基礎了對於看到這里的人來說,我就縮起來了)

var map = new Map({ basemap: "dark-gray", ground: "world-elevation" }); var view = new SceneView({ container: "viewDiv", map: map, camera: { position: { x: -8241580, y: 4964925, z: 2311, spatialReference: 3857 }, heading: 32.5, tilt: 64.9 } });
對於view,可以看到除了camera屬性外還多了兩個屬性,這里不作為重點,可以參考API。
看看兩個layer:
var sceneLayer = new SceneLayer({ url: "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/New_York_LoD2_3D_Buildings/SceneServer/layers/0", popupEnabled: false }); map.add(sceneLayer); var featureLayer = new FeatureLayer({ url: "https://services2.arcgis.com/z2tnIkrLQ2BRzr6P/arcgis/rest/services/New_York_OBJECTID/FeatureServer/0", outFields: ["*"], popupTemplate: { title: "...", content: [{type: "fields"}], fieldInfos: [{...}, {...}, {...}, {...}] } });
在我的理解中,sceneLayer應該是綠色的圓錐體,而featureLayer則是用於支持空間查詢的數據圖層。看得出這里都是使用了ArcGIS Server上的服務。
featureLayer的彈窗模板較為復雜,不是這里討論的內容,我就把源代碼換成了省略號以精簡頁面,大概意思就是從featureLayer中獲取fields作為彈窗的content,而fieldInfos則是對應字段的輸出格式。
重點應該是下面這個方法體:
featureLayer.load().then(attributesReady); function attributesReady() { view.on("click", function(event){ var screenPoint = {...}; view.hitTest(screenPoint)
.then(function(response){...}) .then(function(graphic){...}) .then(function(results){...}) .otherwise(function(err){...}) }) }
逐個擊破,首先是的view的click事件,觸發該事件后立刻獲取當前點擊的點screenPoint,並將點傳遞到hitTest方法中,緊接着就是四層異步操作。
第一層:
.then(function(response) { var result = response.results[0]; if (result && result.graphic) { return result.graphic; } })
似乎是獲取results[0]后判斷其是否為空或者其幾何屬性是否為空,如果不是空,返回其幾何屬性。
這里就要查一下了,這個response 是什么東西?而results[0]又是什么?
通過查閱SceneView的hitTest()方法,可以得知results[0]也就是result變量就是hitTest的返回值。
該result變量擁有兩個屬性,一個是mapPoint,為Point類型;
另一個是graphic,為Graphic類型。
前一個屬性代表了點擊的那個點位置,后面則為點擊的要素的幾何體。
如果都不為空,返回幾何體,傳入下一個then:
.then(function(graphic) { var objectid = graphic.attributes.objectid; var query = new Query(); //設置query的參數 query.where = "objectid = " + objectid; query.returnGeometry = false; query.outFields = ["NAME", "CNSTRCT_YR", "LSTMODDATE", "LSTSTATYPE", "NUM_FLOORS" ]; //執行查詢 return featureLayer.queryFeatures(query); })
傳入的graphic,獲取其objectid屬性
然后實例化一個Query對象名為query,設置好where查詢語句(應該是SQL語句吧)、是否返回幾何體(否)、輸出字段信息,就可以執行查詢。
featureLayer的queryFeatures()方法接受Query對象,返回一個類型為FeatureSet的Promise對象。
這個FeatureSet對象傳遞給下一個then:
.then(function(results) { if (results && results.features.length > 0) { view.popup.open({ features: results.features, location: event.mapPoint }); } })
不要放棄啊!
因為馬上后面就沒有代碼了~那個otherwise只是Promise對象除了then之外的另一個而已~出錯了就用otherwise來處理異常~
這個then,如果傳入的FeatureSet不為空或者FeatureSet里面的features個數>0
那么就按照featureLayer里寫好的格式彈窗顯示信息~完事。
總結一下
這個例子就是獲取點擊點——使用query對象進行空間查詢——返回FeatureSet——輸出其預置好的Popup即可~
沒有上一個那么難了吧~~~
文章的最后,我來對Query這個對象進行學習:
Query對象的學習
查詢API得知:
繼承自Accessor,分類在esri/tasks/support/Query下。
需要注意的是,使用Query類需要在ArcGIS Online或者ArcGIS Server服務的支持下進行。
翻譯官方的解釋,意思就是:
Query對象是一些空間查詢的參數,它作用於layer對象,通過參數的設置,可以篩選出layer中需要的要素。
可以使用QueryTask類的excute()方法進行空間查詢,也可以在圖層實例的queryFeatures()方法中使用Query對象。
使用它,通常返回結果是FeatureSet對象。
Query類擁有非常多的參數,方法只有一個toJSON(),這個方法是將這個類的實例序列化成JSON而存在的,不做重點介紹。
參數就摘幾個吧:
distance(Number類型)、geometry(Geometry類型)、num(Geometry類型)、outFields(String[])、outSpatialReference(SpatialReference)、returnGeometry(Boolean)、units(String)、where(String)
distance是緩沖區分析的距離;
geometry是用於空間查詢用的幾何體;
num是查詢得到的要素個數;
outFields是查詢結果要素集的字段信息;
outSpatialReference是查詢結果要素集的空間參考信息;
returnGeometry是一個布爾變量,如果為真,那么返回的要素集中每一個要素就會包含幾何體;
units是緩沖區分析的單位;
where是空間查詢用的SQL語句。如:query.where = "NAME = '" + stateName + "'";
如何用它呢?
給個簡單的例子,使用QueryTask的(接下來幾篇博文會用到這個):
require(["esri/tasks/QueryTask", "esri/tasks/support/Query"], function(QueryTask, Query){ //用URL實例化一個QueryTask,應該是一個服務類型 var queryCitiesTask = new QueryTask({ url: "..." }); //實例化一個Query對象 var query = new Query(); query.geometry = mapPoint; query.distance = 100; query.units = "miles"; query.spatialRelationship = "intersects"; queryCitiesTask.execute(query).then(function(result){ //對返回的FeatureSet進行操作 }); });
如果是圖層的queryFeatures()方法,各位看官請往上翻一翻啦~
ps:轉載請注明出處。http://www.cnblogs.com/onsummer/p/6421503.html