(六)ArcGIS API For Javascript之查詢功能
阿新 • • 發佈:2019-01-31
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>
- 給button繫結事件(啟用繪圖工具)
//定義一個繪圖工具
var toolBar = new Draw(map);
//給button繫結事件
on(dom.byId("Btn"),"click",function(){
//啟用繪圖工具,我要繪製一個面圖形
toolBar.activate(Draw.POLYGON);
})
- 給繪圖工具繫結繪圖完成事件,繪圖完成執行
queryGraphic
函式,並將繪製的geometry傳入函式
on(toolBar, "draw-complete", function (result) {
//獲得繪圖得到的面
var geometry=result.geometry;
//關閉繪圖工具
toolBar.deactivate();
queryGraphic(geometry);
});
- 編寫
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);
}
- 處理返回的結果資訊
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>
執行之後的結果: