1.引言
在ArcGIS API中查詢功能是非常常用的,Esri給我們提供了三個類用於實現矢量數據查詢功能。FindTask
,QueryTask
,IdentifyTask
,他們之間的區別為:
FindTask
只能進行屬性查詢,QueryTask
,IdentifyTask
兩個類既可以進行屬性查詢也可以進行空間查詢。- 對於
QueryTask
,IdentifyTask
兩個類,QueryTask
只可應用於一個單獨的圖層,IdentifyTask
可應用於地圖服務和多個圖層 QueryTask
可以進行簡單的統計功能。
2.需求
2.1利用FindTask實現簡單的屬性查詢
在本實例中。我們利用http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer
中的教學樓圖層,
我們將name屬性為J4的教學樓查詢出來,在頁面上顯示J4是哪一個學院?(機電學院),並且將J4的樓高亮顯示
2.1.1.代碼實現
- 在頁面加入一個地圖(略)
- 在頁面添加一個button和一個div(button用於屬性查詢,div用於顯示樓層的名字)
<input type="button" value="屬性查詢" id="Btn"/> <div id="divShowResult"></div>
- 創建屬性查詢對象並給button綁定點擊事件
//地圖服務的URL var MapServer = "http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"; //創建屬性查詢對象 var findTask = new FindTask(MapServer); //創建屬性查詢參數 var findParams = new FindParameters(); on(dom.byId("Btn"),"click",function(){ //是否返回給我們幾何信息 findParams.returnGeometry = true; //對哪一個圖層進行屬性查詢 findParams.layerIds = [1]; //查詢的字段 findParams.searchFields = ["name"]; //searchText和searchFields結合使用,即查詢name=J4 findParams.searchText = "J4"; //執行查詢對象 findTask.execute(findParams, ShowFindResult); })
- 處理屬性查詢返回給我們的數據
function ShowFindResult(queryResult) { //創建線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 3); //創建面符號 var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol); if (queryResult.length == 0) { dom.byId("divShowResult").innerHTML = ""; return; } var htmls = ""; if (queryResult.length >= 1) { htmls = htmls + "<table style=\"width: 100%\">"; htmls = htmls + "<tr><td>名稱</td></tr>"; for (var i = 0; i < queryResult.length; i++) { //獲得圖形graphic var graphic = queryResult[i].feature; //賦予相應的符號 graphic.setSymbol(fill); //將graphic添加到地圖中,從而實現高亮效果 map.graphics.add(graphic); //獲得教學樓名稱(此處是和shp屬性表對應的) var ptName = graphic.attributes["alias"]; if (i % 2 == 0) htmls = htmls + "<tr>"; else htmls = htmls + "<tr bgcolor=\"#F0F0F0\">"; htmls = htmls + "<td><a href=\"#\" \">" + ptName + "</a></td>"; htmls = htmls + "</tr>"; } htmls = htmls + "</table>"; //將屬性綁定在divShowResult上面 dom.byId("divShowResult").innerHTML = htmls; } }
2.2.2全部代碼
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>FindTask</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> <style type="text/css"> .MapClass{ width:100%; height:600px; border:1px solid #000; } </style> <script type="text/javascript"> require(["esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "dojo/on", "dojo/dom", "esri/tasks/FindTask", "esri/tasks/FindParameters", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/graphic", "dojo/domReady!"], function (Map, ArcGISDynamicMapServiceLayer,on,dom, FindTask, FindParameters, SimpleLineSymbol,SimpleFillSymbol,Graphic) { var map = new esri.Map("mapDiv"); //地圖服務的URL var MapServer = "http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"; var layer = new esri.layers.ArcGISDynamicMapServiceLayer(MapServer); map.addLayer(layer) //創建屬性查詢對象 var findTask = new FindTask(MapServer); //創建屬性查詢參數 var findParams = new FindParameters(); on(dom.byId("Btn"),"click",function(){ //是否返回給我們幾何信息 findParams.returnGeometry = true; //對哪一個圖層進行屬性查詢 findParams.layerIds = [1]; //查詢的字段 findParams.searchFields = ["name"]; //searchText和searchFields結合使用,即查詢name=J4 findParams.searchText = "J4"; //執行查詢對象 findTask.execute(findParams, ShowFindResult); }) function ShowFindResult(queryResult) { //創建線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 3); //創建面符號 var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol); if (queryResult.length == 0) { dom.byId("divShowResult").innerHTML = ""; return; } var htmls = ""; if (queryResult.length >= 1) { htmls = htmls + "<table style=\"width: 100%\">"; htmls = htmls + "<tr><td>名稱</td></tr>"; for (var i = 0; i < queryResult.length; i++) { //獲得圖形graphic var graphic = queryResult[i].feature; //賦予相應的符號 graphic.setSymbol(fill); //將graphic添加到地圖中,從而實現高亮效果 map.graphics.add(graphic); //獲得教學樓名稱(此處是和shp屬性表對應的) var ptName = graphic.attributes["alias"]; if (i % 2 == 0) htmls = htmls + "<tr>"; else htmls = htmls + "<tr bgcolor=\"#F0F0F0\">"; htmls = htmls + "<td><a href=\"#\" \">" + ptName + "</a></td>"; htmls = htmls + "</tr>"; } htmls = htmls + "</table>"; //將屬性綁定在divShowResult上面 dom.byId("divShowResult").innerHTML = htmls; } } }); </script> </head> <body> <div id="mapDiv" class="MapClass"></div> <input type="button" value="屬性查詢" id="Btn"/> <div id="divShowResult"></div> </body> </html>
運行之后的結果為:
2.2利用QueryTask實現空間查詢
此時的的需求是:我們在地圖上畫一個圖形,然后和圖形相交的教學樓選擇出來。
分析:
1.使用draw交互繪制幾何形狀
2.根據geometry形狀構建空間查詢參數
3.執行空間分析對象
4.處理空間分析的結果
2.2.1代碼實現
- 創建一個button和一個div(button用於激活繪圖工具,div用戶顯示用戶選擇的教學樓的名稱)
<input type="button" value="空間查詢" id="Btn"/> <div id="divShowResult"></div>
- 1
- 2
- 1
- 2
- 給button綁定事件(激活繪圖工具)
//定義一個繪圖工具 var toolBar = new Draw(map); //給button綁定事件 on(dom.byId("Btn"),"click",function(){ //激活繪圖工具,我要繪制一個面圖形 toolBar.activate(Draw.POLYGON); })
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 給繪圖工具綁定繪圖完成事件,繪圖完成執行
queryGraphic
函數,並將繪制的geometry傳入函數
on(toolBar, "draw-complete", function (result) { //獲得繪圖得到的面 var geometry=result.geometry; //關閉繪圖工具 toolBar.deactivate(); queryGraphic(geometry); });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 編寫
queryGraphic
函數
function queryGraphic(geometry) { //創建查詢對象,注意:服務的后面有一個編號,代表對那一個圖層進行查詢 var queryTask = new QueryTask("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer/1"); //創建查詢參數對象 var query = new Query(); //空間查詢的幾何對象 query.geometry = geometry; //服務器給我們返回的字段信息,*代表返回所有字段 query.outFields = ["*"]; //空間參考信息 query.outSpatialReference = map.spatialReference; //查詢的標准,此處代表和geometry相交的圖形都要返回 query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS; //是否返回幾何信息 query.returnGeometry = true; //執行空間查詢 queryTask.execute(query, showQueryResult); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 處理返回的結果信息
function showQueryResult(queryResult) { //創建線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 3); //創建面符號 var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol); if (queryResult.features.length == 0) { dom.byId("divShowResult").innerHTML = ""; return; } var htmls = ""; if (queryResult.features.length >= 1) { htmls = htmls + "<table style=\"width: 100%\">"; htmls = htmls + "<tr><td>名稱</td></tr>"; for (var i = 0; i < queryResult.features.length; i++) { //得到graphic var graphic = queryResult.features[i]; //給圖形賦予符號 graphic.setSymbol(fill); //添加到地圖從而實現高亮效果 map.graphics.add(graphic); //獲得教學樓的名稱信息,此處應和shp的屬性表對應 var ptName = graphic.attributes["alias"]; if (i % 2 == 0) htmls = htmls + "<tr>"; else htmls = htmls + "<tr bgcolor=\"#F0F0F0\">"; htmls = htmls + "<td><a href=\"#\"\">" + ptName + "</a></td>"; htmls = htmls + "</tr>"; } htmls = htmls + "</table>"; //將教學樓的名稱信息和divShowResult綁定 dom.byId("divShowResult").innerHTML = htmls; } }
2.2.2全部代碼
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>QueryTask</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> <style type="text/css"> .MapClass{ width:100%; height:600px; border:1px solid #000; } </style> <script type="text/javascript"> require(["esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "dojo/dom", "dojo/on", "esri/tasks/QueryTask", "esri/toolbars/draw", "esri/tasks/query", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/graphic", "dojo/domReady!"], function (Map, ArcGISDynamicMapServiceLayer,dom, on, QueryTask, Draw, Query, SimpleLineSymbol,SimpleFillSymbol,Graphic) { var map = new Map("mapdiv"); var layer = new ArcGISDynamicMapServiceLayer ("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"); map.addLayer(layer) //定義一個繪圖工具 var toolBar = new Draw(map); //給button綁定事件 on(dom.byId("Btn"),"click",function(){ //激活繪圖工具,我要繪制一個面圖形 toolBar.activate(Draw.POLYGON); }) on(toolBar, "draw-complete", function (result) { //獲得繪圖得到的面 var geometry=result.geometry; //關閉繪圖工具 toolBar.deactivate(); queryGraphic(geometry); }); function queryGraphic(geometry) { //創建查詢對象,注意:服務的后面有一個編號,代表對那一個圖層進行查詢 var queryTask = new QueryTask("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer/1"); //創建查詢參數對象 var query = new Query(); //空間查詢的幾何對象 query.geometry = geometry; //服務器給我們返回的字段信息,*代表返回所有字段 query.outFields = ["*"]; //空間參考信息 query.outSpatialReference = map.spatialReference; //查詢的標准,此處代表和geometry相交的圖形都要返回 query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS; //是否返回幾何信息 query.returnGeometry = true; //執行空間查詢 queryTask.execute(query, showQueryResult); } function showQueryResult(queryResult) { //創建線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 3); //創建面符號 var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol); if (queryResult.features.length == 0) { dom.byId("divShowResult").innerHTML = ""; return; } var htmls = ""; if (queryResult.features.length >= 1) { htmls = htmls + "<table style=\"width: 100%\">"; htmls = htmls + "<tr><td>名稱</td></tr>"; for (var i = 0; i < queryResult.features.length; i++) { //得到graphic var graphic = queryResult.features[i]; //給圖形賦予符號 graphic.setSymbol(fill); //添加到地圖從而實現高亮效果 map.graphics.add(graphic); //獲得教學樓的名稱信息,此處應和shp的屬性表對應 var ptName = graphic.attributes["alias"]; if (i % 2 == 0) htmls = htmls + "<tr>"; else htmls = htmls + "<tr bgcolor=\"#F0F0F0\">"; htmls = htmls + "<td><a href=\"#\"\">" + ptName + "</a></td>"; htmls = htmls + "</tr>"; } htmls = htmls + "</table>"; //將教學樓的名稱信息和divShowResult綁定 dom.byId("divShowResult").innerHTML = htmls; } } }); </script> </head> <body> <div id="mapdiv" class="MapClass"></div> <input type="button" value="空間查詢" id="Btn"/> <div id="divShowResult"></div> </body> </html>
運行之后的結果為:
2.3利用QueryTask進行屬性查詢
利用QueryTask進行屬性查詢和空間查詢代碼差不多。因此我就直接將全部代碼貼出來了。
2.3.1全部代碼
代碼:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>QueryTask</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> <style type="text/css"> .MapClass{ width:100%; height:600px; border:1px solid #000; } </style> <script type="text/javascript"> require(["esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "dojo/dom", "dojo/on", "esri/tasks/QueryTask", "esri/tasks/query", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/graphic", "dojo/domReady!"], function (Map, ArcGISDynamicMapServiceLayer,dom, on, QueryTask, Query, SimpleLineSymbol,SimpleFillSymbol,Graphic) { //根據div的id屬性創建地圖 var map = new Map("mapDiv"); //定義一個動態地圖服務 var layer = new ArcGISDynamicMapServiceLayer ("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"); //將圖層添加到地圖 map.addLayer(layer) //給屬性查詢按鈕添加click事件 on(dom.byId("Btn"),"click",function(e){ //定義查詢對象 var queryTask = new QueryTask ("http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer/1"); //定義查詢參數對象 var query = new Query(); //查詢條件,類似於sql語句的where子句 query.where = "name = 'J4'";; //返回的字段信息:*代表返回全部字段 query.outFields = ["*"]; //是否返回幾何形狀 query.returnGeometry = true; //執行屬性查詢 queryTask.execute(query, showQueryResult); }) //屬性查詢完成之后,用showQueryResult來處理返回的結果 function showQueryResult(queryResult) { //創建線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 3); //創建面符號 var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol); if (queryResult.features.length == 0) { dom.byId("divShowResult").innerHTML = ""; return; } var htmls = ""; if (queryResult.features.length >= 1) { htmls = htmls + "<table style=\"width: 100%\">"; htmls = htmls + "<tr><td>名稱</td></tr>"; for (var i = 0; i < queryResult.features.length; i++) { //獲得圖形graphic var graphic = queryResult.features[i]; //賦予相應的符號 graphic.setSymbol(fill); //將graphic添加到地圖中,從而實現高亮效果 map.graphics.add(graphic); //獲得教學樓名稱(此處是和shp屬性表對應的) var ptName = graphic.attributes["alias"]; if (i % 2 == 0) htmls = htmls + "<tr>"; else htmls = htmls + "<tr bgcolor=\"#F0F0F0\">"; htmls = htmls + "<td><a href=\"#\" \">" + ptName + "</a></td>"; htmls = htmls + "</tr>"; } htmls = htmls + "</table>"; //將屬性綁定在divShowResult上面 dom.byId("divShowResult").innerHTML = htmls; } } }); </script> </head> <body> <div id="mapDiv" class="MapClass"></div> <input type="button" value="屬性查詢" id="Btn"/> <div id="divShowResult"></div> </body> </html>
運行之后的結果:
2.4利用IdentifyTask實現空間查詢
IdentifyTask的使用與QueryTask十分類似,唯一不同的是IdentifyTask可以作用於多個圖層,而QueryTask是作用於一個圖層的。
2.4.1全部代碼
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>WebGIS</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> <style type="text/css"> .MapClass{ width:100%; height:600px; border:1px solid #000; } </style> <script type="text/javascript"> require(["esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "dojo/on", "dojo/dom", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "esri/toolbars/draw", "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol", "esri/graphic", "dojo/domReady!"], function (Map, ArcGISDynamicMapServiceLayer, on, dom, IdentifyTask, IdentifyParameters, Draw, SimpleFillSymbol, SimpleLineSymbol, Graphic ) { var map = new Map("mapDiv"); //地圖服務的url MapServer = "http://localhost:6080/arcgis/rest/services/Test/MyService/MapServer"; //定義一個動態地圖服務 var layer = new ArcGISDynamicMapServiceLayer(MapServer); map.addLayer(layer) //定義繪圖對象 var toolBar = new Draw(map); //綁定點擊事件 on(dom.byId("Btn"),"click",function(e){ //激活繪圖工具:繪制面 toolBar.activate(esri.toolbars.Draw.POLYGON); }) //給繪圖工具綁定繪圖完成事件 on(toolBar, "draw-complete", function (result) { //獲得繪圖得到的面 var geometry=result.geometry; //關閉繪圖工具 toolBar.deactivate(); //執行空間查詢 identifyQuery(geometry); }); function identifyQuery(geometry) { //定義空間查詢對象,注意他的參數是整個地圖服務,而不是單個圖層 var identifyTask = new IdentifyTask(MapServer); //定義空間查詢參數對象 var params = new IdentifyParameters(); //容差 params.tolerance = 5; //是否返回幾何信息 params.returnGeometry = true; //空間查詢的圖層,此時是兩個圖層 params.layerIds = [1,3]; //空間查詢的條件 params.layerOption = IdentifyParameters.LAYER_OPTION_ALL; params.width = map.width; params.height = map.height; //空間查詢的幾何對象 params.geometry = geometry; params.mapExtent = map.extent; //執行空間查詢 identifyTask.execute(params,showQueryResult); } //通過此函數處理查詢之后的信息 function showQueryResult(idResults) { //創建線符號 var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 3); //創建面符號 var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol); if (idResults.length > 0) { var htmls = "<table style=\"width: 100%\">"; htmls = htmls + "<tr bgcolor=\"#E0E0E0\"><td> 圖層 </td><td> 名 稱</td></tr>"; for (var i = 0; i < idResults.length; i++) { var result = idResults[i]; //獲得圖形graphic var graphic = result.feature; //設置圖形的符號 graphic.setSymbol(fill); //獲得教學樓的名稱信息 var namevalue = result.feature.attributes.alias; if (i % 2 == 1) { htmls = htmls + "<tr bgcolor=\"#E0E0E0\"><td>" + result.layerName + "</td><td>" + namevalue + "</td></tr>"; } else { htmls = htmls + "<tr><td>" + result.layerName + "</td><td>" + namevalue + "</td></tr>"; } map.graphics.add(graphic); } htmls = htmls + "</table>"; document.getElementById("divShowResult").innerHTML = htmls; } else { document.getElementById("divShowResult").innerHTML = ""; } } }); </script> </head> <body> <div id="mapDiv" class="MapClass"></div> <input type="button" value="空間查詢---多邊形" id="Btn"/> <div id="divShowResult"></div> </body> </html>
運行之后的結果: