其他分享
首页 > 其他分享> > Android:MapController.zoomToSpan:给出距离和中心点的跨度

Android:MapController.zoomToSpan:给出距离和中心点的跨度

作者:互联网

我一直在Google和SO上研究这个问题,但是我被卡住了,我想我错过了一些基本的东西.我见过的大多数examples都不处理任意mapWidth和单点,只是Overlay的跨度.

我有一个地图点数据库,一个MapView和一个Geocoder.我可以在我的应用程序中搜索邮政编码,并通过我的地理编码器返回一个地址.

使用此地址,我可以构建一个GeoPoint并搜索我的数据库并获取附近点的列表.问题来自于尝试使用从返回的地址点构造的跨度以及到数据库中最近点的距离来设置zoomToSpan.

我只希望跨度包含最近的两个点(如果可用).这是相关的代码:

Collections.sort(listingDisplay, mComparator);
    listingDisplayAdapter.notifyDataSetChanged();

    float spanWidth =0;

    if (listingDisplay.size() > 1) {

        spanWidth = (float) (2 * distanceFromPoint(listingDisplay.get(1),
                current));

    } else if (listingDisplay.size() == 1) {

        spanWidth = (float) (2 * distanceFromPoint(listingDisplay.get(0),
                current));

    }

    Log.v(TAG, "SpanWidth: " + spanWidth);

    // Create span
    int minLat = (int) (current.getLatitudeE6() - (spanWidth * 1E6) / 2);
    int maxLat = (int) (current.getLatitudeE6() + (spanWidth * 1E6) / 2);
    int minLong = (int) (current.getLongitudeE6() - (spanWidth * 1E6) / 2);
    int maxLong = (int) (current.getLongitudeE6() + (spanWidth * 1E6) / 2);

        // Zoom against span. This appears to create a very small region that doesn't encompass the points
mapController.setCenter(current);
mapController.zoomToSpan(Math.abs( minLat - maxLat ), Math.abs( minLong - maxLong ));

ListingDisplay包含一个最近点的列表,带有一个比较器,mComparator将此列表排序为最靠近我返回的地址的位置(GeoPoint名为:current)位于列表顶部.

然后我根据最接近的值设置spanWidth的值,并尝试从中找出范围.

我的问题是,如何从给定的距离和中心点构建跨度?

解决方法:

经过很长一段时间后,我终于意识到我没有考虑一些重要的信息,主要是他们之间的事实是Android上的距离是使用WGS84椭球计算的.

我最终使用了Jan Matuschek’s excellent and simple GeoLocation class中的辅助方法,它对所涉及的概念进行了非常详尽的解释.

我的方法基本归结为以下几点.它可能优化得很好,直到简单的SQL查询,但这里是出于我的目的,其中listingDisplay是数据库检索的自定义LocationNode对象的数组,并且GeoPoint当前直接从返回的地址创建标准的Android Geocoder.

public void setRegionForGeoPoint(GeoPoint current) {

    // Earth radius in KM
    final double EARTH_RADIUS = 6371.01;

    // Dummy span distance in KM for initial search; distance buffer is in M
    final double DISTANCE_BUFFER = 50;
    final double dummyDistance = 100.0;
//Create a list to store distances
    List<Double> distancesList = new ArrayList<Double>();


    // Loop through and modify LocationNodes with distance from user
    for (LocationNode location : listingDisplay) {
        location.setDistance((float) distanceFromUser(location));

        // Dynamically calculate distance from our current point (epicentre)
        distancesList.add(distanceFromPoint(location, current));
    }

    // Sort distances
    Collections.sort(distancesList);

    // Calculate regional span
    float spanWidth = (float) dummyDistance;
    double distance = 0;

    if (distancesList.size() > 0) {
        if (distancesList.size() > 1) {

            distance = distancesList.get(1);
            spanWidth = (float) (distance + DISTANCE_BUFFER);

        } else if (distancesList.size() == 1) {

            distance = distancesList.get(0);
            spanWidth = (float) (distance + DISTANCE_BUFFER);

        }

        //Obtain the spanwidth in metres.
        double spanWidthInKM = (double) spanWidth / 1000;

        // Create span
        GeoLocation[] boundingBoxSpan = currentGeoLocation
                .boundingCoordinates(spanWidthInKM, EARTH_RADIUS);

        //Create min/max values for final span calculation
        int minLatSpan = (int) (boundingBoxSpan[0].getLatitudeInDegrees() * 1E6);
        int maxLatSpan = (int) (boundingBoxSpan[1].getLatitudeInDegrees() * 1E6);
        int minLongSpan = (int) (boundingBoxSpan[0].getLongitudeInDegrees() * 1E6);
        int maxLongSpan = (int) (boundingBoxSpan[1].getLongitudeInDegrees() * 1E6);

        //Finally calculate span
        int latSpanE6 = Math.abs(minLatSpan - maxLatSpan);
        int lonSpanE6 = Math.abs(minLongSpan - maxLongSpan);

        // Set center
        mapController.setCenter(current);

        // Zoom to span
        mapController.zoomToSpan(latSpanE6, lonSpanE6);

    } else {

        //TODO: Handle the case when we have no distance values to use
    }
}


public double distanceFromPoint(LocationNode location, GeoPoint point) {

    // Calculate distance from user via result
    Location locationA = new Location("point A");
    locationA.setLatitude(location.getLatitude());
    locationA.setLongitude(location.getLongitude());

    Location locationB = new Location("point B");
    locationB.setLatitude((double) (point.getLatitudeE6() / 1E6));
    locationB.setLongitude((double) (point.getLongitudeE6() / 1E6));
    double distance = locationA.distanceTo(locationB);
    Log.v(TAG, "Calculated Distance: " + distance);
    return distance;
}

标签:android,android-maps
来源: https://codeday.me/bug/20190621/1250957.html