Google Maps Android API:根据GroundOverlay的PNG

时间:2016-04-22 10:02:53

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

我正在使用Google Maps Android API在Google地图上添加一个PNG文件作为自己的平面图,其代码如下:

GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions();
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset("building-d.png");
groundOverlayOptions.image(bitmapDescriptor);
groundOverlayOptions.anchor(0, 1);

LatLng buildingSW = new LatLng(47.014815, 8.305098);
LatLng buildingNE = new LatLng(47.015148, 8.305440);
LatLng buildingNW = new LatLng(47.015168, 8.305144);
LatLng buildingSE = new LatLng(47.014792, 8.305385);

Location swLoc = locationFromLatLng(buildingSW);
Location seLoc = locationFromLatLng(buildingSE);
Location nwLoc = locationFromLatLng(buildingNW);
Location neLoc = locationFromLatLng(buildingNE);

float angle = swLoc.bearingTo(nwLoc);
groundOverlayOptions.bearing(angle);

float width = swLoc.distanceTo(seLoc);
groundOverlayOptions.position(buildingSW, width);

mMap.addGroundOverlay(groundOverlayOptions);

现在我知道在PNG中有一个像素坐标为422 / 301,708 / 301,422 / 10和708/10的房间(那些是角落)。我想在覆盖那个房间的GroundOverlay上绘制一个多边形。我该怎么办?我是否需要将像素坐标转换为LatLng,如果是,请如何转换?

顺便说一句:我是否真的必须为GroundOverlay使用PNG,并且没有其他支持的矢量格式,如eps,pdf,......?

2 个答案:

答案 0 :(得分:1)

你应该这样工作: 您的室内地图位置应该相对于特定点(BOTTOM-LEFT是0,0让我们说),然后所有其他位置将相对于该点以米为单位,因此您将以100米以下的值结束

有了这个,你必须移动,旋转和缩放"关于世界的室内地图。 只需在不是LAT / LNG的桌面上拍摄地图,找到你所拥有的相同室内点的坐标(通常我们得到左下和右上位置的真实和室内位置),这样你就可以找到它应该在哪里在世界上。 另请查看缩放系数(取决于纬度,必须缩放地图) https://en.wikipedia.org/wiki/Mercator_projection#Scale_factor

我们通过做1 / cos(latitudeINradians)

之类的东西来计算这个值
public static double getScalingFactor(double latitude) {
        return 1 / (Math.cos(Math.toRadians(latitude)));
    }

如果您能找到方法,请告诉我,否则我会搜索并尝试删除我们的代码

答案 1 :(得分:1)

看过你对其他答案的评论后,让我完成一些代码:

设置"起源"在latlng 47.014816,8.305098中,你必须将这些坐标转换为mercator,你可以做类似下面的事情:

<div class='container'>
  <div class='header'>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas at libero ut arcu tincidunt porta. Vestibulum in ex nec neque rutrum vestibulum a nec eros. Morbi accumsan nisl in justo viverra, non euismod libero sagittis. Aenean vulputate tortor
    molestie metus iaculis ornare. Vestibulum posuere, mauris eget tempor tincidunt, arcu risus eleifend felis, ac fringilla mauris lorem sit amet risus. Ut id ante eu nisl hendrerit tincidunt ac ut velit. Sed efficitur ante in neque mollis feugiat. Nulla
    sed erat nec ipsum fermentum tristique. Sed auctor dolor quis fringilla ullamcorper. Duis luctus ligula nibh, ac facilisis eros dapibus at. Aliquam eget vestibulum sem, a euismod ante. Quisque at arcu arcu. Nunc massa tellus, imperdiet in facilisis
    vitae, maximus at neque. Maecenas et dictum enim.</div>
  <div class='content'>
    Nam vehicula tempor est et ultrices. Cras elementum, mi ac pellentesque ultricies, dui urna rutrum risus, quis tristique ante eros in tellus. Quisque sit amet varius erat. Aliquam dapibus eros augue, et blandit nulla volutpat nec. Duis nibh lacus, scelerisque
    in interdum in, hendrerit eget justo. Pellentesque finibus nisi sed fermentum aliquet. Mauris feugiat, magna in sagittis dapibus, neque justo convallis risus, eget rutrum metus tellus eget lorem. Suspendisse at turpis faucibus eros dapibus feugiat
    vel at elit. Sed ac arcu tempor, molestie elit ut, eleifend dolor. Morbi fringilla enim ac lectus lobortis, ac convallis orci mollis. Ut tempus quam sodales, tincidunt dolor non, dapibus neque. Fusce elementum magna dolor, non suscipit est imperdiet
    at. Vivamus mattis augue vestibulum, ultricies dui ac, finibus erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi. Curabitur id cursus sapien. Phasellus placerat finibus vehicula. Donec
    sit amet nisi eget risus venenatis euismod. Curabitur quis felis tempus, egestas ante eget, efficitur dolor. Duis ullamcorper commodo massa, a efficitur turpis finibus nec. Cras eget dui purus.
  </div>
</div>

public static double getScalingFactor(double latitude){         return 1 /(Math.cos(Math.toRadians(latitude)));     }

所以你可以调用方法:

public boolean initializeByTwoCouplesOfCooordsAndScale(double[] coordAreal, double[] coordBreal, double[] coordAvirtual, double[] coordBvirtual, double scalingFactor) {
    if (coordAreal[0] == coordBreal[0] && coordAvirtual[1] == coordBvirtual[1] && coordAreal[1] == coordBreal[1] && coordAvirtual[0] == coordBvirtual[0]) {
        System.err.println("Coordinates must not be the same!");
        return false;
    }
    // aPoint is considered the "origin" point (0,0)
    aPoint = coordAreal;
    bPoint = coordAvirtual;
    // now calculate the angle of the Real world coordinate for the points
    double deltaRy = coordBreal[1] - coordAreal[1];
    double deltaRx = coordBreal[0] - coordAreal[0];
    double aR = Math.atan2(deltaRy, deltaRx);
    // Now calculate the angle of the virtual world coordinates
    double deltaVy = coordBvirtual[1] - coordAvirtual[1];
    double deltaVx = coordBvirtual[0] - coordAvirtual[0];
    double aV = Math.atan2(deltaVy, deltaVx);
    // Set the transformation angle as the difference between the real and the virtual angles.
    mPhi= (aR - aV);
    // Set the scaling factor as the provided one
    mScale = (scalingFactor);//scaling factor is in function below
    // Calculate the scaling factor error correction using the distances of the two systems.
    return true;
}

然后你可以使用这个函数进行转换:

initializeByTwoCouplesOfCooordsAndScale(new double[]{MERCATOR_LNG,MERCATOR_LAT},//real coordinates for point A REMEMBER: LNG,LAT = x,y!
new double[]{0d,0d}, //Virual coordinates for point A
new double[]{MERCATOR_POINT_B_LNG, MERCATOR_POINT_B_LAT},//real point B
new double[]{X_METERS,Y_METERS},//coordinates in meters of point B in virtual map
getScalingFactor(47.014816));

你可以在网上找到一种将latlng转换为mercator的方法,它只是一堆数学;)