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

GoogleMap GroundOverlayOptions: Squeeze image to four LatLngBounds

我正在尝试使用 Google 地图 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 进行倾斜:

If the bounds do not match the original aspect ratio, the image will be skewed.

仅使用 LatLng swne

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

不知道怎么才能算出准确的 LatLng西南和东北,所以我有兴趣一种定义多边形并使用四个 LatLng 作为锚点以某种方式将图像挤压到其中的方法。使用四个 LatLng 目前看起来像这样。使用 LatLng swnenwse

你永远不会使用 LatLngBounds 实现你想要的,因为你试图旋转你的 GroundOverlay。

你需要做的是使用方位角(旋转)和width/height的地面覆盖。 假设您的建筑物旋转了 -20 度并且宽高为 40-20(只有您知道这些值。 1- 获取建筑物中心的 LatLng,即找到上面代码中四个坐标的中心。 该值将是您的 "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);

这应该可行,显然您必须计算值或逐步尝试不同的值。

希望对您有所帮助

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

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

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