安卓智能地图开发与实施十二:空间查询与模糊搜索 - ArcGIS Runtime SDK for Android(Version 100.0.0)

0
分享 2017-08-21
空间查询与模糊搜索
对空间查询的使用每个人都有自己的见解。从项目的角度,一般会进行单图层查询和多图层查询。移动端查询方式主要为触摸查询和文字搜索查询。

空间查询效果:




模糊搜索效果:




MapQueryResult,包含了FeatureLayer和一组Feature。FeatureLayer是当前查询的图层,一组Feature是查询的结果。

MapQueryClass,包含了回调接口IQueryResult,一组查询结果MapQueryResult,当进行单图层查询时,结果为包含一个MapQueryResult的数组。

Identify方法
1)利用MapView的identifyLayersAsync 2)利用FeatureLayer的queryFeaturesAsync 3)在2)的基础查询多个,按图层顺序返回
/*** * 通过MapView对象上的鼠标点击,查询MapView对象中的可见图层 * @param mainMapView * @param screenPoint * @param screenTolerance * @param iQueryResult */
public void Identify(MapView mainMapView,
Point screenPoint,
int screenTolerance,
IQueryResult iQueryResult) {
mainMapQueryResult = new ArrayList<MapQueryResult>();
mainQueryResultReturn = iQueryResult;
final ListenableFuture<List<IdentifyLayerResult>> identifyFuture =
mainMapView.identifyLayersAsync(screenPoint, screenTolerance, false, 100);
identifyFuture.addDoneListener(new Runnable() {
@Override
public void run() {
try {
List<IdentifyLayerResult> identifyLayersResults = identifyFuture.get();
for (IdentifyLayerResult identifyLayerResult : identifyLayersResults) {
MapQueryResult mapQueryResult = new MapQueryResult();
mapQueryResult.featureLayer = (FeatureLayer) identifyLayerResult.getLayerContent();
mapQueryResult.features = new ArrayList<Feature>();
for (GeoElement identifiedElement : identifyLayerResult.getElements()) {
identifyLayerResult.getLayerContent();
if (identifiedElement instanceof Feature) {
Feature identifiedFeature = (Feature) identifiedElement;
mapQueryResult.features.add(identifiedFeature);
}
}
mainMapQueryResult.add(mapQueryResult);
}
mainQueryResultReturn.getQuery();
}
catch (Exception e) {
}
}
});
}
/*** * 通过Geometry对象,查询一组FeatureLayer对象中的要素 * @param featureLayers * @param geometry * @param iQueryResult */
public void Identify(List<FeatureLayer> featureLayers,
Geometry geometry,
IQueryResult iQueryResult) {
final List<FeatureLayer> mainFeatureLayer = featureLayers;
TotalCount = featureLayers.size();
mainMapQueryResult = new ArrayList<MapQueryResult>();
mainQueryResultReturn = iQueryResult;
QueryParameters query = new QueryParameters();
query.setGeometry(geometry);
try {
for (final FeatureLayer featureLayer : featureLayers
) {
final ListenableFuture<FeatureQueryResult> featureQueryResult
= featureLayer.getFeatureTable().queryFeaturesAsync(query);
featureQueryResult.addDoneListener(new Runnable() {
@Override
public void run() {
try {
FeatureQueryResult result = featureQueryResult.get();
Iterator<Feature> iterator = result.iterator();
MapQueryResult mapQueryResult = new MapQueryResult();
mapQueryResult.features = new ArrayList<Feature>();
Feature feature;
while (iterator.hasNext()) {
feature = iterator.next();
mapQueryResult.features.add(feature);
}
mapQueryResult.featureLayer = featureLayer;
mainMapQueryResult.add(mapQueryResult);
LoadedCount++;
if (LoadedCount == TotalCount) {
List<MapQueryResult> mainNewMapQueryResult =
new ArrayList<MapQueryResult>();
for (int i = 0; i < mainFeatureLayer.size(); i++) {
for (MapQueryResult mapQueryResult1 : mainMapQueryResult
) {
if (mapQueryResult1.featureLayer.equals(mainFeatureLayer.get(i))) {
if (mapQueryResult1.features.size() > 0) {
mainNewMapQueryResult.add(mapQueryResult1);
}
break;
}
}
}
mainMapQueryResult = mainNewMapQueryResult;
mainQueryResultReturn.getQuery();
}
} catch (Exception e) {

}
}
});
}

} catch (Exception e) {

}
}
/*** * 通过Geometry对象,查询一个FeatureLayer对象中的要素 * @param featureLayer * @param geometry * @param iQueryResult */
public void Identify(FeatureLayer featureLayer,
Geometry geometry,
IQueryResult iQueryResult) {
try {
final FeatureLayer mainFeatureLayer = featureLayer;
mainMapQueryResult = new ArrayList<MapQueryResult>();
mainQueryResultReturn = iQueryResult;
QueryParameters query = new QueryParameters();
query.setGeometry(geometry);
if(featureLayer.getFeatureTable().getGeometryType() == GeometryType.POLYGON)
{
query.setSpatialRelationship(QueryParameters.SpatialRelationship.INTERSECTS);
}
final ListenableFuture<FeatureQueryResult> featureQueryResult
= featureLayer.getFeatureTable().queryFeaturesAsync(query);
featureQueryResult.addDoneListener(new Runnable() {
@Override
public void run() {
try {
FeatureQueryResult result = featureQueryResult.get();
Iterator<Feature> iterator = result.iterator();
MapQueryResult mapQueryResult = new MapQueryResult();
mapQueryResult.features = new ArrayList<Feature>();
Feature feature;
while (iterator.hasNext()) {
feature = iterator.next();
mapQueryResult.features.add(feature);
}
mapQueryResult.featureLayer = mainFeatureLayer;
mainMapQueryResult.add(mapQueryResult);
mainQueryResultReturn.getQuery();
} catch (Exception e) {
}
}
});
} catch (Exception e) {

}
}

Select方法
1)利用FeatureLayer的selectFeaturesAsync 2)在1)的基础查询多个,按图层顺序返回
/*** * 通过Geometry对象,选择一个FeatureLayer对象中的要素 * @param featureLayer * @param geometry * @param iQueryResult */
public void Select(FeatureLayer featureLayer,
Geometry geometry,
IQueryResult iQueryResult) {
try {
final FeatureLayer mainFeatureLayer = featureLayer;
mainMapQueryResult = new ArrayList<MapQueryResult>();
mainQueryResultReturn = iQueryResult;
QueryParameters query = new QueryParameters();
query.setGeometry(geometry);
if(featureLayer.getFeatureTable().getGeometryType() == GeometryType.POLYGON
|| featureLayer.getFeatureTable().getGeometryType() == GeometryType.POLYLINE)
{
query.setSpatialRelationship(QueryParameters.SpatialRelationship.INTERSECTS);
}
final ListenableFuture<FeatureQueryResult> featureQueryResult
= featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW);
featureQueryResult.addDoneListener(new Runnable() {
@Override
public void run() {
try {
mainFeatureLayer.clearSelection();
FeatureQueryResult result = featureQueryResult.get();
Iterator<Feature> iterator = result.iterator();
MapQueryResult mapQueryResult = new MapQueryResult();
mapQueryResult.features = new ArrayList<Feature>();
Feature feature;
while (iterator.hasNext()) {
feature = iterator.next();
mapQueryResult.features.add(feature);
}
mapQueryResult.featureLayer = mainFeatureLayer;
mainMapQueryResult.add(mapQueryResult);
mainQueryResultReturn.getQuery();
} catch (Exception e) {
}
}
});
} catch (Exception e) {

}
}

/*** * 通过Geometry对象,选择一组FeatureLayer对象中的要素 * @param featureLayers * @param geometry * @param iQueryResult */
public void Select(List<FeatureLayer> featureLayers,
Geometry geometry,
IQueryResult iQueryResult) {
final List<FeatureLayer> mainFeatureLayer = featureLayers;
TotalCount = featureLayers.size();
mainMapQueryResult = new ArrayList<MapQueryResult>();
mainQueryResultReturn = iQueryResult;
QueryParameters query = new QueryParameters();
query.setGeometry(geometry);
try {
for (final FeatureLayer featureLayer : featureLayers
) {
final ListenableFuture<FeatureQueryResult> featureQueryResult
= featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW);
featureQueryResult.addDoneListener(new Runnable() {
@Override
public void run() {
try {
featureLayer.clearSelection();
FeatureQueryResult result = featureQueryResult.get();
Iterator<Feature> iterator = result.iterator();
MapQueryResult mapQueryResult = new MapQueryResult();
mapQueryResult.features = new ArrayList<Feature>();
Feature feature;
while (iterator.hasNext()) {
feature = iterator.next();
mapQueryResult.features.add(feature);
}
mapQueryResult.featureLayer = featureLayer;
mainMapQueryResult.add(mapQueryResult);
LoadedCount++;
if (LoadedCount == TotalCount) {
List<MapQueryResult> mainNewMapQueryResult =
new ArrayList<MapQueryResult>();
for (int i = 0; i < mainFeatureLayer.size(); i++) {
for (MapQueryResult mapQueryResult1 : mainMapQueryResult
) {
if (mapQueryResult1.featureLayer.equals(mainFeatureLayer.get(i))) {
if (mapQueryResult1.features.size() > 0) {
mainNewMapQueryResult.add(mapQueryResult1);
}
break;
}
}
}
mainMapQueryResult = mainNewMapQueryResult;
mainQueryResultReturn.getQuery();
}
} catch (Exception e) {

}
}
});
}

} catch (Exception e) {

}
}

Search方法
1)利用FeatureLayer的queryFeaturesAsync 2)在1)的基础查询多个,按图层顺序返回 注:可设定空间范围进行查询
/*** * 通过输入的文本(数字),查询一个FeatureLayer对象中的要素 * @param featureLayer * @param search * @param iQueryResult */
public void Search(FeatureLayer featureLayer,
String search,
IQueryResult iQueryResult){
Search(featureLayer,search,iQueryResult,null);
}

/*** * 通过输入的文本(数字),查询一个FeatureLayer对象中指定范围内的要素 * @param featureLayer * @param search * @param iQueryResult * @param geometry */
public void Search(FeatureLayer featureLayer,
String search,
IQueryResult iQueryResult,
Geometry geometry) {
final FeatureLayer mainFeatureLayer = featureLayer;
mainMapQueryResult = new ArrayList<MapQueryResult>();
mainQueryResultReturn = iQueryResult;
QueryParameters query = new QueryParameters();
String whereStr = GetWhereStrFunction(featureLayer,search);
query.setWhereClause(whereStr);
if(geometry != null)
{
query.setGeometry(geometry);
}
final ListenableFuture<FeatureQueryResult> featureQueryResult
= featureLayer.getFeatureTable().queryFeaturesAsync(query);
featureQueryResult.addDoneListener(new Runnable() {
@Override
public void run() {
try {
FeatureQueryResult result = featureQueryResult.get();
Iterator<Feature> iterator = result.iterator();
MapQueryResult mapQueryResult = new MapQueryResult();
mapQueryResult.features = new ArrayList<Feature>();
Feature feature;
while (iterator.hasNext()) {
feature = iterator.next();
mapQueryResult.features.add(feature);
}
mapQueryResult.featureLayer = mainFeatureLayer;
mainMapQueryResult.add(mapQueryResult);
mainQueryResultReturn.getQuery();
} catch (Exception e) {

}
}
});
}
/*** * 通过输入的文本(数字),查询一组FeatureLayer对象中的要素 * @param featureLayers * @param search * @param iQueryResult */
public void Search(List<FeatureLayer> featureLayers,
String search,
IQueryResult iQueryResult){
Search(featureLayers,search,iQueryResult,null);
}
/*** * 通过输入的文本(数字),查询一组FeatureLayer对象中指定范围内的要素 * @param featureLayers * @param search * @param iQueryResult * @param geometry */
public void Search(List<FeatureLayer> featureLayers,
String search,
IQueryResult iQueryResult,
Geometry geometry) {
final List<FeatureLayer> mainFeatureLayer = featureLayers;
TotalCount = featureLayers.size();
mainMapQueryResult = new ArrayList<MapQueryResult>();
mainQueryResultReturn = iQueryResult;

try {
for (final FeatureLayer featureLayer : featureLayers
) {
QueryParameters query = new QueryParameters();
String whereStr = GetWhereStrFunction(featureLayer,search);
query.setWhereClause(whereStr);
if(geometry != null)
{
query.setGeometry(geometry);
}
final ListenableFuture<FeatureQueryResult> featureQueryResult
= featureLayer.getFeatureTable().queryFeaturesAsync(query);
featureQueryResult.addDoneListener(new Runnable() {
@Override
public void run() {
try {
FeatureQueryResult result = featureQueryResult.get();
Iterator<Feature> iterator = result.iterator();
MapQueryResult mapQueryResult = new MapQueryResult();
mapQueryResult.features = new ArrayList<Feature>();
Feature feature;
while (iterator.hasNext()) {
feature = iterator.next();
mapQueryResult.features.add(feature);
}
mapQueryResult.featureLayer = featureLayer;
mainMapQueryResult.add(mapQueryResult);
LoadedCount++;
if (LoadedCount == TotalCount) {
List<MapQueryResult> mainNewMapQueryResult =
new ArrayList<MapQueryResult>();
for (int i = 0; i < mainFeatureLayer.size(); i++) {
for (MapQueryResult mapQueryResult1 : mainMapQueryResult
) {
if (mapQueryResult1.featureLayer.equals(mainFeatureLayer.get(i))) {
if (mapQueryResult1.features.size() > 0) {
mainNewMapQueryResult.add(mapQueryResult1);
}
break;
}
}
}
mainMapQueryResult = mainNewMapQueryResult;
mainQueryResultReturn.getQuery();
}
} catch (Exception e) {

}
}
});
}

} catch (Exception e) {

}
}

处理模糊搜索
public static String GetWhereStrFunction(FeatureLayer featureLayer, String search) {
StringBuilder stringBuilder = new StringBuilder();
List<Field> fields = featureLayer.getFeatureTable().getFields();
boolean isNumber = AttributeMethodsClass.isNumberFunction(search);
for (Field field : fields
) {
switch (field.getFieldType()) {
case TEXT:
stringBuilder.append(" upper(");
stringBuilder.append(field.getName());
stringBuilder.append(") LIKE '%");
stringBuilder.append(search.toUpperCase());
stringBuilder.append("%' or");
break;
case SHORT:
case INTEGER:
case FLOAT:
case DOUBLE:
case OID:
if(isNumber == true)
{
stringBuilder.append(" upper(");
stringBuilder.append(field.getName());
stringBuilder.append(") = ");
stringBuilder.append(search);
stringBuilder.append(" or");
}
break;
case UNKNOWN:
case GLOBALID:
case BLOB:
case GEOMETRY:
case RASTER:
case XML:
case GUID:
case DATE:
break;
}
}
String result = stringBuilder.toString();
return result.substring(0,result.length()-2);
}

判断文本是否数字
public static boolean isNumberFunction(String string)
{
boolean result = false;
Pattern pattern = Pattern.compile("^[-+]?[0-9]");
if(pattern.matcher(string).matches()){
//数字
result = true;
} else {
//非数字
}
//带小数的
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('^');
stringBuilder.append('[');
stringBuilder.append("-+");
stringBuilder.append("]?[");
stringBuilder.append("0-9]+(");
stringBuilder.append('\\');
stringBuilder.append(".[0-9");
stringBuilder.append("]+)");
stringBuilder.append("?$");
Pattern pattern1 = Pattern.compile(stringBuilder.toString());
if(pattern1.matcher(string).matches()){
//数字
result = true;
} else {
//非数字
}
return result;
}

使用示例
protected void StartMapTouchFunction(){
mainMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this,mainMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
android.graphics.Point screenPoint =
new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()));
final MapQueryClass mapQueryClass = new MapQueryClass();
mapQueryClass.Identify(
mainMapView,
screenPoint,
5,
new IQueryResult() {
@Override
public void getQuery() {
List<MapQueryClass.MapQueryResult> mapQueryResults= mapQueryClass.getMapQueryResult();
for (MapQueryClass.MapQueryResult mapQueryResult:mapQueryResults
) {
}
}
}
);
return super.onSingleTapConfirmed(e);
}
});
}

 
 安卓智能地图开发与实施一:配置离线SDK - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3304
 安卓智能地图开发与实施二:开发环境准备 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3303
 安卓智能地图开发与实施三:创建第一个地图程序 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3302
 安卓智能地图开发与实施四:二维地图的MapView与Layers - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3305
 安卓智能地图开发与实施五:在线基础底图 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3309
 安卓智能地图开发与实施六:离线基础底图 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3299
 安卓智能地图开发与实施七:在线业务图层(浏览查询) - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3298
 安卓智能地图开发与实施八:离线业务图层(浏览查询) - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3297
 安卓智能地图开发与实施九:地图缩放与旋转 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3296
 安卓智能地图开发与实施十:图层管理 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3295
 安卓智能地图开发与实施十一:业务数据查询 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3294
 安卓智能地图开发与实施十二:空间查询与模糊搜索 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3293
 安卓智能地图开发与实施十三:空间查询与展示 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3308
 安卓智能地图开发与实施十四:业务数据编辑 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3307
 安卓智能地图开发与实施十五:离线与同步 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3306
 安卓智能地图开发与实施十六:三维地图 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3289
 安卓智能地图开发与实施十七:使用天地图 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3288
 安卓智能地图开发与实施十八:空间要素绘制 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3287
 安卓智能地图开发与实施十九:符号与渲染器 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3286
文章来源:http://blog.csdn.net/allenlu2008/article/details/72673917

1 个评论

这位大哥,要搜索多个图层有什么好的办法没有?难道真的用你代码里的for循环,那样子如果有几十个图层需要同时搜索,单次发起几十个网络请求,这样子是不是不太好!
有没有其他好办法呢?我最近一直在苦恼这个问题!

要回复文章请先登录注册