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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
點擊運行,運行之後如圖所示:
注:
- 在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]);
})
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
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="查詢">
- 1
- 2
- 1
- 2
- 將文本框中的教學樓名稱獲取,並創建屬性查詢對象
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)
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 將查詢到的樓層信息(幾何信息)獲取,利用
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 查看結果
屬性查詢前:
屬性查詢後:
完整代碼:
<!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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
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);
- 1
- 1
- 獲得點擊的地圖座標(點座標),並創建空間查詢參數對象
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)
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 將教學樓與點相交的樓層查詢出來,然後利用
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 查看結果
鼠標點擊前:
鼠標點擊後:
- 完整代碼
<!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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
3.3.2代碼解釋
QueryTask
是esri提供給我們的一個工具類,可用於屬性查詢,也可用於空間查詢,QueryTask
只能作用於地圖服務的某一個圖層,而不能作用於一整個地圖服務(IdentifyTask
類可作用於一整個地圖服務)Query
類是QueryTask
參數類,用於設定空間查詢的參數。QueryTask
類中有一個方法叫做execute
,execute
的第一個參數是查詢的參數,第二個參數是一個回調函數(即是一個異步函數),當服務器返回數據時,此函數纔會被觸發
3.4補充
綁定事件之後,在某些情況下也解除事件的綁定,下面提供幾種方法解除事件綁定
- 直接通過事件句柄解除(dojo新版本)
//綁定事件
var handle=map.on("click",mapClick);
//解除事件
handle.remove();
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 通過老版本的方法解除
//綁定事件
var handle=map.on("click",mapClick);
//解除事件
dojo.disconnect(handle)
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
(function () { ('pre.prettyprint code').each(function () {
var lines =
for (i = 1; i <= lines; i++) {
};
$numbering.fadeIn(1700);
});
});