GoogleMap GroundOverlayOptions:将图像压缩为四个LatLngBounds

时间:2016-04-14 19:38:44

标签: android google-maps google-maps-android-api-2

我尝试使用Google Maps Android API v2将图片添加到Google地图中:

mMap = googleMap;
LatLng sw = new LatLng(47.01377857060625, 8.305519705172628);
LatLng ne = new LatLng(47.01395211967171, 8.306270482717082);
LatLng nw = new LatLng(47.014014755501165, 8.305559697328135);
LatLng se = new LatLng(47.01370751919609, 8.306236284552142);
LatLngBounds latLngBounds = new LatLngBounds(sw, ne).including(nw).including(se);
GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions();
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset("t2c.png");
groundOverlayOptions.image(bitmapDescriptor);
groundOverlayOptions.positionFromBounds(latLngBounds);
mMap.addGroundOverlay(groundOverlayOptions);

不幸的是,LatLng值不是100%准确,因此背景图片不会旋转但是根据Google的说法会偏斜:

  

如果边界与原始高宽比不匹配,图像将会歪斜。

仅使用LatLng swne

https://developers.google.com/maps/documentation/android-api/groundoverlay#use_latlngbounds_to_position_an_image

With two LatLng

我不知道如何能够找出西南和东北的完全 LatLng,所以我对a感兴趣定义一个多边形的方法,并用四个LatLng作为锚点以某种方式将图像压缩到其中。使用四个LatLng目前看起来像这样。使用LatLng swnenwse

With four LatLng

2 个答案:

答案 0 :(得分:0)

you will never achieve what you want using LatLngBounds because you are trying to rotate your GroundOverlay.

What you need to do is to use bearing (rotation) and width/height of the ground overlay. Let's say your building in -20 degrees rotated and has width-height of 40-20 (only you know these values. 1- Get the LatLng of the center of the building, which is finding the center of the four coordinates in your code above. That value will be your "centerLocation"

GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions();
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset("t2c.png");
groundOverlayOptions.image(bitmapDescriptor);
groundOverlayOptions.position(centerLocation,widthInMeters,heightInMeters);
groundOverlayOptions.bearing(rotated);//the value is clockwise and rotation is about anchor point (which should be by default 0.5,0.5 of your image
mMap.addGroundOverlay(groundOverlayOptions);

This should work, obviously you have to calculate values or go step by step trying different values.

Hope it helps

答案 1 :(得分:0)

第一个答案是什么对你有用。我将详细写出我的解决方案,这样就可以很容易地复制粘贴代码并完成它...

第一步,如果你有四个边界,得到它们的中心,你可以使用下面的函数

 private LatLng computeCentroid(List<LatLng> points) {
        double latitude = 0;
        double longitude = 0;
        int n = points.size();

        for (LatLng point : points) {
            latitude += point.latitude;
            longitude += point.longitude;
        }

        return new LatLng(latitude/n, longitude/n);
    }

Second get the width and height in meters. Here are method to get distance between two points in meters.



private double distance(double lat1, double lon1, double lat2, double lon2) {
        double theta = lon1 - lon2;
        double dist = Math.sin(deg2rad(lat1))
                * Math.sin(deg2rad(lat2))
                + Math.cos(deg2rad(lat1))
                * Math.cos(deg2rad(lat2))
                * Math.cos(deg2rad(theta));
        dist = Math.acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60 * 1.1515;
        return dist * 1609.34;
    }

    private double deg2rad(double deg) {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(double rad) {
        return (rad * 180.0 / Math.PI);
    }

最后只使用这些值并完成

double height=distance(selectedFloorPlan.getGeoData().get(0).getLat(), selectedFloorPlan.getGeoData().get(0).getLng(),selectedFloorPlan.getGeoData().get(1).getLat(), selectedFloorPlan.getGeoData().get(1).getLng());


    double width=distance(selectedFloorPlan.getGeoData().get(0).getLat(), selectedFloorPlan.getGeoData().get(0).getLng(),selectedFloorPlan.getGeoData().get(3).getLat(), selectedFloorPlan.getGeoData().get(3).getLng());

GroundOverlayOptions newarkMap = new GroundOverlayOptions()
                .image(images.get(0))
                .position(centerPoint,(float)width,(float)height)
                .bearing(-67.18571490414709f);

        imageOverlay = map.addGroundOverlay(newarkMap);