欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Arcgis(14)、FeatureLayer之范围查询

程序员文章站 2022-05-21 09:34:15
...

今天无意中看到李文星的相关新闻,很是震惊。希望各位小伙伴在找工作的时候,多留个心眼。远离传销!

Android Arcgis入门(五)、FeatureLayer加载本地shp文件与要素查询,这篇文章中,我们知道如何去查找要素。现在有一个需求,查找某点5000米范围的要素,那如何来做呢?首先我们需要在地图上画个5000米半径的圆,然后根据QueryParameters来查询相关要素。具体如下:

一、画个5000米半径的圆

1.确定中心点:centerPoint
2.半径为5000
3.将一个圆分为120个点(当然可以细分更多),比如第一个点角度为0,求出sin与cos值,再分别求出经度与纬度:

  纬度= 中心点的纬度+半径*cos值*每米的纬度偏移量

   经度= 中心点的经度+半径*sin值*每米的经度偏移量

相关代码如下 :

//纬度每米偏移量(存在误差)
    public static final double ONE_METER_OFFSET = 0.00000899322;
    //计算当前纬度时经度的偏移量
    public static double calcLongitudeOffset(double latitude) {
        return ONE_METER_OFFSET / Math.cos(latitude * Math.PI / 180.0f);
    }
    //获取一个圆
    private Polygon addGraphicCricle(Point centerPoint,double meter) {
        List<Point> points = new ArrayList<Point>();
        double sin;
        double cos;
        double lon;
        double lat;
        for (double i = 0; i < 120; i++) {
            //sin值
            sin = Math.sin(Math.PI * 2 * i / 120);
            //cos值
            cos = Math.cos(Math.PI * 2 * i / 120);
            //纬度= 中心点的纬度+半径*cos值*每米的纬度偏移量
            lat = centerPoint.getY() + meter*cos* ONE_METER_OFFSET;
            //经度= 中心点的经度+半径*sin值*每米的经度偏移量
            lon = centerPoint.getX() + meter *sin* calcLongitudeOffset(lat);
            Point p = new Point(lon,lat);
            points.add(p);
        }
        Polygon polygon = new Polygon();

        for (int i = 0; i < points.size(); i++) {
            if (i==0) {
                polygon.startPath(points.get(i));
            }else{
                polygon.lineTo(points.get(i));
            }
        }

        return polygon;
    }

将上面的Polygon添加到GraphicsLayer中:

SimpleFillSymbol fillSymbol = new SimpleFillSymbol(Color.parseColor("#88ff0000"));
                fillSymbol.setOutline(new SimpleLineSymbol(Color.TRANSPARENT, 0));
                Graphic g = new Graphic(polygon, fillSymbol);
                mLayer.addGraphic(g);

效果如下:
Android Arcgis(14)、FeatureLayer之范围查询
分别计算polygon的面积与长度:

double area = GeometryEngine.geodesicArea(polygon, SpatialReference.create(SpatialReference.WKID_WGS84), new AreaUnit(AreaUnit.Code.SQUARE_METER));
                Log.e("huang", "area==="+area);
                double length = GeometryEngine.geodesicLength(polygon, SpatialReference.create(SpatialReference.WKID_WGS84), new LinearUnit(LinearUnit.Code.METER));
                Log.e("huang", "area==="+length);

结果值为与实际计算值有偏差,但偏差不是很大。

//面积:78128662.10079278
//长度:31343.779712156855

二、通过圆polygon来查询FeatureLayer在此范围内的要素

代码如下:

private void queryFeature(Geometry geometry) {
        try {
            QueryParameters args = new QueryParameters();
            args.setReturnGeometry(true);// 是否返回Geometry
            args.setGeometry(geometry); // 查询范围面
            args.setInSpatialReference(SpatialReference
                    .create(SpatialReference.WKID_WGS84));
            args.setSpatialRelationship(SpatialRelationship.WITHIN);
            //获取查询结果result
            Future<FeatureResult> result = featureLayer.getFeatureTable()
                    .queryFeatures(args, null); 

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

三、思考

其实FeatureLayer的getFeatureIDs(float x, float y, int tolerance)与
getFeatureIDs(float x, float y, int tolerance, int numberOfResults)、

GraphicsLayer中的getGraphicIDs(float x, float y, int tolerance)与
getGraphicIDs(float x, float y, int tolerance, int numberOfResults)
这几个查询方法也是通过范围去查询,只不过x,y是屏幕坐标,相当于中心坐标,而tolerance相当于半径,范围的大小由tolerance决定。那5dp的查找范围相当于多少范围呢?
可以获取当前地图的比例尺*查找半径获取到。