(三)ArcGIS API For Javascript之呼叫動態地圖服務
阿新 • • 發佈:2019-01-11
1.引言
在本篇部落格中主要記錄一下在ArcGIS API如何呼叫自己釋出的動態地圖服務,利用動態地圖服務我們可以完成哪一些需求等等。
注:(如何利用ArcGIS Server釋出動態地圖服務請看部落格ArcGIS Server釋出動態地圖服務),
2.呼叫動態地圖服務
在ArcGIS API 中給我們提供了一個類叫做ArcGISDynamicMapServiceLayer
利用這個類,我們可以獲得釋出的地圖服務。呼叫動態地圖服務一般只需要兩步:
- 通過地圖服務的URL建立一個
ArcGISDynamicMapServiceLayer
物件 - 將動態地圖服務的物件新增到地圖容器中
程式碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"/>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />
<script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.17/3.17/init.js"></script>
<script>
require(["esri/map","esri/layers/ArcGISDynamicMapServiceLayer",
"dojo/domReady!" ],
function(Map,ArcGISDynamicMapServiceLayer){
var map = new Map("mapDiv");
//利用url建立一個動態地圖服務物件
var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
//將地圖服務物件新增到地圖容器中
map.addLayer(layer);
})
</script>
</head>
<body class="tundra">
<div id="mapDiv" style="width:900px; height:600px; border:1px solid #000;"></div>
</body>
</html>
點選執行,執行之後如圖所示:
注:
- 在ArcGIS API中與ArcMap不同的是:一個服務圖層相當於一組圖層的集合(即多個圖層)。
3.需求
在真實開發過程中,動態地圖服務可以幫助我們完成很多的功能需求,例如:
- 根據需求隱藏服務中的某一個圖層(動態地圖服務可以實現,但是切片地圖服務就不能實現)
- 通過屬性查詢地圖服務中的資訊
- 通過空間查詢地圖服務中的資訊(包括點查詢,線查詢,面查詢等等)
3.1.根據需求隱藏服務中的某一個圖層
我們釋出的地圖服務中有四個圖層
在本需求中。我們主要是給頁面新增一個按鈕,然後將地圖服務中的road2隱藏
程式碼為:
require(["esri/map","dojo/dom","dojo/on","esri/layers/ArcGISDynamicMapServiceLayer",
"dojo/domReady!"],
function(Map,dom,on,ArcGISDynamicMapServiceLayer){
var map = new Map("mapDiv");
var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
map.addLayer(layer);
//給id為btn的按鈕繫結click事件
on(dom.byId("btn"),"click",function()
{
layer.setVisibleLayers([1,2,3]);
})
})
3.1.1程式碼解釋:
- 此程式碼功能的實現非常簡單,只利用了
setVisibleLayers
方法,告訴服務,我要顯示圖層編號為1,2,3
的圖層。 - 在
require
中載入了一個新的模組dojo/dom
模組,此模組給我們提供了一個方法dom.byId(id)
,我們可以通過id獲得dom物件,類似於document.getElementById()
方法。 - 在
require
中載入了一個新的模組dojo/on
模組,在dojo中on
是用來繫結事件的,on(target,type,listener)
的第一個引數是給哪一個物件繫結事件,第二個引數是事件的型別,第三個是引數是回撥函式。
3.2.通過屬性查詢地圖服務中的資訊
在開發過程中,經常有這樣的需求:
- 根據屬性查詢出我們想要的要素圖形,然後將該圖形高亮(在本事例中查詢教學樓的資訊,例如根據教學樓的名稱將該樓層成高亮)
教學樓圖層的屬性表資訊:
在實現這個功能的時候我們分幾步開始考慮:
- 在網頁上新建一個文字框
- 將文字框中的教學樓名稱獲取,並建立屬性查詢物件
- 將查詢到的樓層資訊(幾何資訊)獲取,利用
graphics
高亮顯示
3.2.1.程式碼實現
- 建立一個文字框
Name:<input class="nm" type="text">
<input type="button" value="查詢">
- 將文字框中的教學樓名稱獲取,並建立屬性查詢物件
query("#btn").on("click",function(){
//獲得教學樓的名稱
var name=query(".nm")[0].value;
//例項化查詢引數
var findParams = new esri.tasks.FindParameters();
findParams.returnGeometry = true;
findParams.layerIds = [3];
findParams.searchFields = ["name"];
findParams.searchText = name;
//例項化查詢物件
var FindTask = new esri.tasks.FindTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
//進行查詢
FindTask.execute(findParams,ShowFindResult)
})
- 將查詢到的樓層資訊(幾何資訊)獲取,利用
graphics
高亮顯示
function showFindResult(queryResult)
{
if (queryResult.length == 0) {
alert("沒有該元素");
return;
}
for (var i = 0; i < queryResult.length; i++) {
//獲得該圖形的形狀
var graphic = queryResult[i].feature;
var geometry = graphic.geometry;
//定義高亮圖形的符號
//1.定義面的邊界線符號
var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
//2.定義面符號
var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
//建立客戶端圖形
var graphic = new Graphic(geometry, PolygonSymbol);
//將客戶端圖形新增到map中
map.graphics.add(graphic);
}
}
- 檢視結果
屬性查詢前:
屬性查詢後:
完整程式碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"/>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />
<script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.17/3.17/init.js"></script>
<script>
require(["esri/map","dojo/query","dojo/on",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/tasks/FindTask",
"esri/tasks/FindParameters",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/Color",
"esri/graphic",
"dojo/domReady!"],
function(Map,query,on,ArcGISDynamicMapServiceLayer,FindTask,FindParameters,SimpleLineSymbol,SimpleFillSymbol,Color,Graphic){
var map = new Map("mapDiv");
var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
map.addLayer(layer);
query("#btn").on("click",function(){
//獲得教學樓的名稱
var name=query(".nm")[0].value;
//例項化查詢引數
var findParams = new FindParameters();
findParams.returnGeometry = true;
findParams.layerIds = [3];
findParams.searchFields = ["name"];
findParams.searchText = name;
//例項化查詢物件
var findTask = new FindTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
//進行查詢
findTask.execute(findParams,showFindResult)
});
function showFindResult(queryResult)
{
if (queryResult.length == 0) {
alert("沒有該元素");
return;
}
for (var i = 0; i < queryResult.length; i++) {
//獲得該圖形的形狀
var feature= queryResult[i].feature;
var geometry = feature.geometry;
//定義高亮圖形的符號
//1.定義面的邊界線符號
var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
//2.定義面符號
var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
//建立客戶端圖形
var graphic = new Graphic(geometry, PolygonSymbol);
//將客戶端圖形新增到map中
map.graphics.add(graphic);
}
}
})
</script>
</head>
<body class="tundra">
<div id="mapDiv" style="width:900px; height:580px; border:1px solid #000;"></div>
Name:<input class="nm" type="text">
<input id="btn" type="button" value="查詢">
</body>
</html>
3.2.2程式碼解釋
FindTask
是Esri提供的一個屬性查詢的類,他所對應的引數為:FindParameters
,FindTask
只能用於屬性查詢,不能用於空間查詢FindTask
類中有一個方法叫做execute
,execute
的第一個引數是屬性查詢的引數,第二個引數是一個回撥函式(即是一個非同步函式),當伺服器返回資料時,此函式才會被觸發。dojo/query
是dojo
提供的一個DOM選擇器,他的功能非常強大,與JQuery
中的$
符一樣強大,可以根據id選擇query("#id")
,也可以根據類名選擇query(".classname")
,query
方法還有很多強大的地方,具體可以參考官方文件query("#btn").on()
是dojo提供給我們第二種繫結事件的方式。graphic
esri提供給我們使用的客戶端圖層,利用graphic
,我們可以完成很多操作,graphic
具體的使用,將在Draw
工具時說明。
3.3通過空間查詢地圖服務中的資訊
相信大家都遇到過這種問題,當我點選地圖時,將我點選的圖形進行高亮顯示,此時就用到了空間查詢。為了實現該功能我們可以分為以下幾步:
- 因為要點選地圖,所以首先我們給地圖繫結點選事件
- 獲得點選的地圖座標(點座標),並建立空間查詢引數物件
- 將教學樓與點相交的樓層查詢出來,然後利用
graphic
進行高亮顯示
注:此事例查詢是教學樓圖層
3.3.1程式碼實現
- 給地圖繫結點選事件
map.on("click",mapClick);
- 獲得點選的地圖座標(點座標),並建立空間查詢引數物件
function mapClick(e){
//獲得使用者點選的地圖座標
var point=e.mapPoint;
//例項化查詢引數
query=new Query();
query.geometry = point;
query.outFields = ["*"];
query.outSpatialReference = map.spatialReference;
query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
query.returnGeometry = true;
//例項化查詢物件
var queryTask = new QueryTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer/3");
//進行查詢
queryTask.execute(query,showFindResult)
}
- 將教學樓與點相交的樓層查詢出來,然後利用
graphic
進行高亮顯示
function showFindResult(queryResult)
{
if (queryResult.features == 0) {
alert("沒有該元素");
return;
}
for (var i = 0; i < queryResult.features.length; i++) {
//獲得該圖形的形狀
var feature = queryResult.features[i];
var geometry = feature.geometry;
//定義高亮圖形的符號
//1.定義面的邊界線符號
var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
//2.定義面符號
var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
//建立客戶端圖形
var graphic = new Graphic(geometry, PolygonSymbol);
//將客戶端圖形新增到map中
map.graphics.add(graphic);
}
}
- 檢視結果
滑鼠點選前:
滑鼠點選後:
- 完整程式碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"/>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />
<script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.17/3.17/init.js"></script>
<script>
require(["esri/map","dojo/query","dojo/on",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/tasks/QueryTask",
"esri/tasks/query",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/Color",
"esri/graphic",
"dojo/domReady!"],
function(Map,query,on,ArcGISDynamicMapServiceLayer,QueryTask,Query,SimpleLineSymbol,SimpleFillSymbol,Color,Graphic){
var map = new Map("mapDiv");
var layer=new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer");
map.addLayer(layer);
map.on("click",mapClick);
function mapClick(e){
//獲得使用者點選的地圖座標
var point=e.mapPoint;
//例項化查詢引數
query=new Query();
query.geometry = point;
query.outFields = ["*"];
query.outSpatialReference = map.spatialReference;
query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
query.returnGeometry = true;
//例項化查詢物件
var queryTask = new QueryTask("http://localhost:6080/arcgis/rest/services/Test/MyServer/MapServer/3");
//進行查詢
queryTask.execute(query,showFindResult)
}
function showFindResult(queryResult)
{
if (queryResult.features == 0) {
alert("沒有該元素");
return;
}
for (var i = 0; i < queryResult.features.length; i++) {
//獲得該圖形的形狀
var feature = queryResult.features[i];
var geometry = feature.geometry;
//定義高亮圖形的符號
//1.定義面的邊界線符號
var outline= new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,new Color([255, 0, 0]), 1);
//2.定義面符號
var PolygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, outline,new Color([0, 255, 0, 1]));
//建立客戶端圖形
var graphic = new Graphic(geometry, PolygonSymbol);
//將客戶端圖形新增到map中
map.graphics.add(graphic);
}
}
})
</script>
</head>
<body class="tundra">
<div id="mapDiv" style="width:900px; height:580px; border:1px solid #000;"></div>
</body>
</html>
3.3.2程式碼解釋
QueryTask
是esri提供給我們的一個工具類,可用於屬性查詢,也可用於空間查詢,QueryTask
只能作用於地圖服務的某一個圖層,而不能作用於一整個地圖服務(IdentifyTask
類可作用於一整個地圖服務)Query
類是QueryTask
引數類,用於設定空間查詢的引數。QueryTask
類中有一個方法叫做execute
,execute
的第一個引數是查詢的引數,第二個引數是一個回撥函式(即是一個非同步函式),當伺服器返回資料時,此函式才會被觸發
3.4補充
繫結事件之後,在某些情況下也解除事件的繫結,下面提供幾種方法解除事件繫結
- 直接通過事件控制代碼解除(dojo新版本)
//繫結事件
var handle=map.on("click",mapClick);
//解除事件
handle.remove();
- 通過老版本的方法解除
//繫結事件
var handle=map.on("click",mapClick);
//解除事件
dojo.disconnect(handle)