有一段时间又没有发表博客记录学习经过了,有点懈怠啊,学习之路还要坚持才行呢。
话不多说,进入今天的正题:arcgis的空间和属性查询
arcgis js api 有三种常见的查询:QueryTask、FindTask、IdentifyTask
三者的区别:
- FIndTask 只能进行属性查询,QueryTask和IdentityTask既可以进行属性查询也可以进行空间查询
- 对于QueryTask,IdentityTask两个类,QueryTask只可应用于一个单独的图层,IdentityTask可应用于地图服务和多个图层
- QueryTask可以进行简单的统计功能。
具体实现:
一、QueryTask:
只可在某个地图服务的某个子图层进行查询,它查询的地图服务并不必须加载到Map中进行显示,执行QueryTask需要两个先决条件:1.需要查询的图层的url ,精确到layerId;2.查询的过滤条件
核心代码:
1.1 利用QueryTask进行空间查询(常见的有拉框查询、圆形和多边形查询)
用到的类:
"esri/toolbars/draw",
"esri/geometry/Extent",
"esri/SpatialReference",
"esri/geometry/Point",
"esri/geometry/Polyline",
"esri/geometry/Polygon",
"esri/geometry/Circle","esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/PictureMarkerSymbol","esri/tasks/query",
"esri/tasks/QueryTask",
先上代码在进行讲解吧。。。
var toolbar_1=new Draw(map);
$(".spatialSearch").on("click","button",function(){
map.setMapCursor("pointer");//鼠标变为pointer
var val =$(this).attr("id");
switch (val) {
case "拉框":
toolbar_1.activate(Draw.RECTANGLE);
break;
case "圆形":
toolbar_1.activate(Draw.CIRCLE);
break;
case "多边形":
toolbar_1.activate(Draw.POLYGON);
break;
}
})
toolbar_1.on("draw-complete",searchCompleate);
var url =companyServer;
function searchCompleate(evt) {
var point = new Point(evt.geometry.getExtent().getCenter());
map.centerAndZoom(point,12);
toolbar_1.deactivate();
map.setMapCursor("default");
var url_1 =url+"/0";
var queryTask =new QueryTask(url_1);
var query =new Query();
query.returnGeometry=true;//返回空间查询到geometry,方便把返回值结果以图标形式叠加在地图上
query.outFields =["*"];//返回的字段名称
query.outSpatialReference = map.spatialReference;
query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
query.geometry = evt.geometry;//设置绘制框选图形的范围
queryTask.execute(query, showQueryResult);
}
function showQueryResult(featureSet) {
var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([2, 166, 51]), 1);
var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol,new dojo.Color([164, 212, 178]));
if (featureSet.features.length == 0) {
layer.msg('未查询到结果!');
return;
}
for (var i = 0; i < featureSet.features.length; i++) {
var graphic = featureSet.features[i];
//console.log(graphic.attributes);
/**
*这里进行你对查询到的信息渲染和其他的一些操作
*
*
*/
}
}
首先我们不管是进行空间拉框还是多边形时,都是利用画图工具来做的,所以我们需要先构造一个Draw对象 即:
var toolbar_1=new Draw(map);
随后当我们点击不同的查询条件时,我们需要激活画图工具 即:
toolbar_1.activate(Draw.RECTANGLE);
后面携带的参数是指不同图形的类型,有矩形、圆形和多边形等等,
接着,画图完成后我们需要回调一个方法,对这个我们画出的范围内的geometry进行什么样的操作,即:
toolbar_1.on("draw-complete",searchCompleate);
在 searchCompleate 方法里,我做了如下的操作:
先获取画图范围的中心点,地图缩放到我画的范围里,
然后进行我们的核心操作,查询---
var queryTask =new QueryTask(url_1);
var query =new Query();
其中url_1 是指你需要查询的地图服务的地址,但是这里只能针对这个地图服务的一个 layer (图层),
所以在上面我定义了一个 var url_1 =url+"/0";(url指地图服务地址);
后面接着就是query携带的参数了,这里需要注意下坐标系的问题,(我有时查不出来就坐标系的问题)
接着就可以进行查询了
queryTask.execute(query, showQueryResult);
其中 showQueryResult 是查询完成回调的方法,其中参数 featureSet 是你查出来的结果
但是真正的 graphic 是 featureSet.features ,千万不要弄混淆,相比其他两个查询,这里都是不同的
1.2 进行属性查询(即携带参数 、属性信息对图层进行查询)
//利用query进行属性查询
function doQuery(xzqbm,ctime,bzpmc,zrr) {
var geometry;
var query =new Query();
var queryTask=new QueryTask(MapServer+"/0");
//遍历行政区范围数组,找到对应的行政区范围
for (var i = 0; i < XZQExtent.length; i++) {
if(XZQExtent[i]["xzq"]==xzqbm){
geometry=XZQExtent[i]["geo"];
}
}
//如果有范围查,在范围内查找
if(geometry!=null){
//定义查询的范围
query.geometry = geometry;
}else {
query.geometry =map.extent;
}
//查询统计时间
if(ctime!=''){
var date1 =ctime+"-01-01";
var date2=ctime+"-12-30";
query.where="CTIME >= date'"+date1+"'AND CTIME <= date'"+date2+"'";
}
//查询标志牌名称
if(bzpmc!=''){
query.where="BZPMC like'%"+bzpmc+"%'";
}
//查询保护责任人
if(zrr!=''){
query.where="BHZRR like '%"+zrr+"%'";
}
if(bzpmc==''&&ctime==''&&geometry==null&&zrr==''){
query.where="1=1";
if(!flag1){
layer1.show();
}
}
//返回所有字段
query.outFields=["*"];
//空间参考信息
query.outSpatialReference=map.SpatialReference;
//是否返回几何信息
query.returnGeometry=true;
//执行查询
queryTask.execute(query,ShowFindResult);
}
附上我之前写的带属性的查询,
以及:http://help.arcgis.com/zh-cn/arcgisdesktop/10.0/help/index.html#//00s500000033000000
其实就是加一个query.where = xxx ;
二、FIndTask
FindTask是在某个地图服务中进行属性查询的功能类,FindTask以FindParameters对象为参数,能查询同一个地图服务的一个或多个图层,并且可以在多个字段中进行查询,FindTask仅仅用于属性信息的查询,在FindTask执行结束后,可以从其返回结果中获取查询的对象来自哪个图层和哪个字段
引用的模块:
"esri/tasks/FindTask",
"esri/tasks/FindParameters",
核心代码:
//创建属性查询对象
var findTask = new FindTask(MapServer);
//创建属性查询参数
var findParams = new FindParameters();
findParams.returnGeometry = true;
//对哪一个图层进行属性查询
findParams.layerIds = [0];
//查询的字段
findParams.searchFields = ["DLMC"];
//searchText和searchFields结合使用
// findParams.searchText = "水田";
findParams.searchText = val;
//执行查询对象
findTask.execute(findParams, ShowFindResult);
function ShowFindResult(queryResult) {
//先清空已渲染的图层
clearGra();
//创建线符号
var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASH, new dojo.Color([2, 166, 51]), 1);
//创建面符号
var fill=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, lineSymbol,new dojo.Color([164, 212, 178]));
if (queryResult.length == 0) {
return;
}
if (queryResult.length >= 1) {
for (var i = 0; i < queryResult.length; i++) {
//获得图形graphic
var graphic = queryResult[i].feature;
//赋予相应的符号
graphic.setSymbol(fill);
//设置属性
var infoTemplate = new InfoTemplate("地块信息","标识码:"+graphic.attributes["BSM"]+"</br>地类编号:"+graphic.attributes["DLBM"]+"</br>地类名称:"+graphic.attributes["DLMC"] +
"<br/>权属性质:"+graphic.attributes["QSXZ"]+" <br/>权属单位名称:"+graphic.attributes["QSDWMC"]+"</br>面积:"+graphic.attributes["TBMJ"]+"平方米");
graphic.setInfoTemplate(infoTemplate);
//console.log(graphic);
//将graphic添加到地图中,从而实现高亮效果
// map.graphics.add(graphic);
gl.add(graphic);
}
}
}
(仅供参考,不可拿来就用的)
三、IdentifyTask
IdentifyTask是在某个地图服务中进行空间查询,IdentifyTask以IdentifyParameters对象作为参数,能查询同一个地图服务的一个或者多个图层,IdentifyTask仅仅用于空间信息查询
引用的模块:
"esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters",
核心代码:
var identifyTask = new IdentifyTask(bzpLayers[0].url);
//定义空间查询参数对象
var params = new IdentifyParameters();
//容差
params.tolerance = 3;
//是否返回几何信息
params.returnGeometry = true;
//空间查询的图层bzpLayers[0].visibleLayers
params.layerIds = bzpLayers[0].visibleLayers;
params.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
params.width = map.width;
params.height = map.height;
// console.log(map.extent);
params.geometry = map.extent;
params.mapExtent = map.extent;
identifyTask.execute(params,showAllBZP);
//注意上面可能会因为地图的参考系问题查不出来
function showAllBZP(results) {
if (results.length>0) {
var graphic = results[i].feature;
.
.
.
.
.
}else {
/*layer.msg('未查询到相关要素!');*/
}
}
如下图,参数的属性可能就变了
对了,关于查询的时候需要用到 layerId 但是你不知道地图服务有具体多少个图层时:附带一个demo(获取图层的信息)
直接拷贝下就可以用哦~~~
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>获取图层信息</title>
<style type="text/css">
@import "http://serverapi.arcgisonline.com/jsapi/arcgis/1.5/js/dojo/dijit/themes/tundra/tundra.css";
</style>
<script type="text/javascript">
var djConfig = { isDebug: (window.location.search.indexOf("debug")>-1) };
</script>
<script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.5"></script>
<script type="text/javascript" src="js/InfoExtends.js"></script>
<script type="text/javascript">
dojo.require("esri.map");
var layer, layerUrl;
function init() {
var map = new esri.Map("mapDiv");
layerUrl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer";
layer = new esri.layers.ArcGISDynamicMapServiceLayer(layerUrl);
map.addLayer(layer);
dojo.connect(map, "onLoad", getLayerScales);
}
dojo.addOnLoad(init);
function getLayerScales() {
for (var i = 0; i < layer.layerInfos.length; i++) {
getLayerJson(layerUrl, i);
}
}
function getLayerJson(url, id) {
dojo.io.script.get({
callbackParamName: "callback", //provided by the jsonp service
url: layerUrl + "/" + id + "/?f=json",
load: function(response, ioArgs) {
setLayerScale(response);
},
error: function(response, ioArgs) {
console.log(response);
return response;
}
});
}
function setLayerScale(layerJson) {
var layerInfo = layer.layerInfos[layerJson.id]; /* get the layer object somehow */
if (layerInfo)
layerInfo.setScale(layerJson.minScale, layerJson.maxScale);
}
function showLayerInfos() {
alert(dojo.toJson(layer.layerInfos));
}
</script>
</head>
<body class="tundra">
<input type="button" onclick="showLayerInfos()" value="显示子图层信息" />
<div id="mapDiv" style="position:relative; width:100%; height:100%; border:1px solid #000;">
</div>
</body>
</html>