【问题标题】:Android: MapController.zoomToSpan : Make span given a distance and centrepointAndroid:MapController.zoomToSpan:在给定距离和中心点的情况下设置跨度
【发布时间】:2012-02-24 21:47:38
【问题描述】:

我一直在 Google 和 SO 上对此进行研究,但我被困住了,我认为我缺少一些基本的东西。我见过的大多数 examples 不处理任意 mapWidth 和单个点,只是覆盖的跨度。

我有一个地图点数据库,一个MapView 和一个Geocoder。我可以在我的应用中搜索邮政编码,然后我的Geocoder 返回一个Address

使用这个Address,我可以构建一个GeoPoint 并搜索我的数据库并获取附近点的列表。问题来自尝试使用从返回的Address 点和到数据库中最近点的距离构造的跨度来缩放ToSpan。

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

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 使用最接近我返回的AddressGeoPoint 称为:current)顶部的位置对这个列表进行排序列表。

然后我根据最接近的设置spanWidth的值,并尝试从中找出跨度。

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

【问题讨论】:

    标签: android android-maps


    【解决方案1】:

    在很长很长一段时间后,我终于意识到我并没有考虑一些重要的信息,其中主要是 Android 上的距离是使用 WGS84 椭球计算的。

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

    我的方法基本上归结为以下几点。它可能可以优化很多,直到一个简单的 SQL 查询,但这里是出于我的目的,其中listingDisplay 是数据库检索的自定义LocationNode 对象的数组,GeoPoint 当前是直接创建的来自标准 Android 地理编码器的返回 Address

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      相关资源
      最近更新 更多