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

作者:allenlu2008

空间查询与模糊搜索

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

空间查询效果:

这里写图片描述

模糊搜索效果:

这里写图片描述

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);
        }
    });
}
发表评论

0个评论

我要留言×

技术领域:

我要留言×

留言成功,我们将在审核后加至投票列表中!

提示x

搜索引擎知识库已成功保存至我的图谱现在你可以用它来管理自己的知识内容了

删除图谱提示×

你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?

删除节点提示×

无法删除该知识节点,因该节点下仍保存有相关知识内容!

删除节点提示×

你确定要删除该知识节点吗?