java – 在Android的地图上绘制地理上准确的弧

我想画一个中心GPS点和两个终点GPS点的弧.我可以使用任何可以与 android搭配使用的地图软件.

到目前为止,我已经尝试过Google Maps for Android. Android的MapBox ARCGIS for Android.他们似乎都不能做这个简单的任务.

我猜想我需要一些叠加层?


解决方法

首先,您必须更改地理数据表示.

由此:

36°46'02.5"S    174°50'03.6"E    GRC
36°56'18.3"S    174°33'09.7"E    CWA    36°52'19.2"S    174°29'23.5"E    5.0'    NM
36°48'19.8"S    174°25'37.7"E    GRC
36°41'06.1"S    174°37'32.9"E    CCA    36°39'54.5"S    174°38'40.7"E    1.5'    NM
36°41'00.3"S    174°39'57.1"E    GRC
36°39'49.4"S    174°41'32.3"E    CCA    36°38'43.5"S    174°40'15.7"E    1.5'    NM
36°39'17.5"S    174°41'59.7"E    GRC
36°39'38.6"S    174°44'37.7"E    GRC
36°37'08.8"S    174°47'27.4"E    CWA    36°42'03.8"S    174°46'17.0"E    5.0'    NM

为此:

-36.76736    174.83433    GRC
-36.93842    174.55269    CWA    -36.87200    174.48986    0.08333    NM
-36.80550    174.42714    GRC
-36.68503    174.62581    CCA    -36.66514    174.64464    0.02500    NM
-36.68342    174.66586    GRC
-36.66372    174.69231    CCA    -36.64542    174.67103    0.02500    NM
-36.65486    174.69992    GRC
-36.66072    174.74381    GRC
-36.61911    174.79094    CWA    -36.70106    174.77139    0.08333    NM

然后,您可以使用它们来构建路径(例如,SVG path):

<svg
  ...>
  <g
     transform="matrix(1250,1250,46206.909,-217995.49)"
     ...>
    <path
       d=" M -36.76736,174.83433 L -36.93842,174.55269 A 0.08333,0.08333 0 0,1 -36.80550,174.42714 L -36.68503,174.62581 A 0.02500,0.02500 0 0,0 -36.68342,174.66586 L -36.66372,174.69231 A 0.02500,0 -36.65486,174.69992 L -36.66072,174.74381 L -36.61911,174.79094 A 0.08333,1 -36.76736,174.83433 Z"
       .../>
  </g>
</svg>

实际上,没有API可以在GMaps / OSMDroid中创建曲线,弧等,所以你应该画几条小线.这意味着做一些数学,但这个数学可以由GeographicLib library做出:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    MapView map = (MapView) findViewById(R.id.map);
    map.setTileSource(TileSourceFactory.MAPNIK);
    map.setBuiltInZoomControls(true);
    map.setMultiTouchControls(true);


    IMapController mapController = map.getController();
    mapController.setZoom(9);
    GeoPoint startPoint = new GeoPoint(-36.66372,174.69231);
    mapController.setCenter(startPoint);

    polygon polyline = new polygon(this);
    List<GeoPoint> points = new LinkedList<>();

    // I filled the data manually,but it can be done more cLever,of course.
    GRC(points,new GeoPoint(-36.76736,174.83433));
    CWA(points,new GeoPoint(-36.93842,174.55269),new GeoPoint(-36.87200,174.48986),new GeoPoint(-36.80550,174.42714),0.08333);
    CCA(points,new GeoPoint(-36.68503,174.62581),new GeoPoint(-36.66514,174.64464),new GeoPoint(-36.68342,174.66586),0.02500);
    CCA(points,new GeoPoint(-36.66372,174.69231),new GeoPoint(-36.64542,174.67103),new GeoPoint(-36.65486,174.69992),0.02500);
    GRC(points,new GeoPoint(-36.66072,174.74381));
    CWA(points,new GeoPoint(-36.61911,174.79094),new GeoPoint(-36.70106,174.77139),174.83433),//close shape going to the start point
                0.08333);

    polyline.setPoints(points);
    polyline.setFillColor(0xA0FF00FF);
    polyline.setstrokeColor(Color.BLACK);
    polyline.setstrokeWidth(2f);
    map.getoverlays().add(polyline);
    map.invalidate();
}

private void CCA(List<GeoPoint> points,GeoPoint startPoint,GeoPoint centerPoint,GeoPoint endPoint,double radius) {
    points.add(startPoint);

    GeodesicData f = Geodesic.wgs84.Inverse(centerPoint.getLatitude(),centerPoint.getLongitude(),startPoint.getLatitude(),startPoint.getLongitude());
    GeodesicData t = Geodesic.wgs84.Inverse(centerPoint.getLatitude(),endPoint.getLatitude(),endPoint.getLongitude());

    double ffaz = f.azi1;
    double tfaz = t.azi1;

    final int decrement = 1;
    while (Math.abs((int)ffaz) != Math.abs((int)tfaz)) {
        GeodesicData llb = Geodesic.wgs84.Direct(centerPoint.getLatitude(),ffaz,f.s12);
        points.add(new GeoPoint(llb.lat2,llb.lon2));
        ffaz -= decrement;
        if (ffaz <0) {
            ffaz += 360;
        }
    }

    points.add(endPoint);
}

private void CWA(List<GeoPoint> points,endPoint.getLongitude());

    double ffaz = f.azi1;
    double tfaz = t.azi1 > 0 ? t.azi1 : 360 + t.azi1;

    final int increment = 1;
    while (Math.abs((int)ffaz) != Math.abs((int)tfaz)) {
        GeodesicData llb = Geodesic.wgs84.Direct(centerPoint.getLatitude(),llb.lon2));
        ffaz += increment;
        if (ffaz>360) {
            ffaz -= 360;
        }
    }

    points.add(endPoint);
}

private void GRC(List<GeoPoint> points,GeoPoint geoPoint) {
    points.add(geoPoint);
}

我使用osmdroid OSMBonusPack,但代码是相当普遍的,可以轻松地与Google地图一起使用.

The full source code.

结果:

另外,你会介意告诉你发布了哪个地理数据?地图上的形状看起来像一个允许的飞行区域,我猜.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...