我需要从一个绑定地面覆盖的矩形中获取NW LatLng。使用mOverlay.getBounds()将获得旋转前我需要的点(getBounds忽略旋转)。
这是地面覆盖,我需要的确切LatLng是红色的点。当它完全位于北/南(图像左侧)时,我可以使用getBounds()获得该点没问题。在旋转图像之后,我现在需要的是任何点,即朝南/朝南的矩形的NW角,其包含我的旋转地面覆盖(右侧图像的红点)。
答案 0 :(得分:2)
我不得不假设你正在使用'承载'旋转叠加图像,图像的锚点是中心。此外,由于地图是一个球体建模,当你说矩形时,我们确实假设一个二维平面与图像中心的球体相切(非旋转)。
这种解释简化了旋转角度小于pi / 2弧度并且在顺时针方向的假设。
这些都不是新的,所以没有信用 - 但我尽力适应你的问题。
总之,这种方法将WGS-84坐标系中的原始矩形(非旋转)转换为x / y坐标系(以原点为中心),使用trig计算旋转的新x / y,选择角,导出x超矩形左上角的/ y,将结果转换回WGS-84球面坐标系。
// convert your rotation value (bearing clockwise) to radians
// Using the bounding rectangle (which is of the non-rotated image) compute distance
// between nw and ne corner (width) and nw and sw corner (height) (in meters).
// The purpose of this is to establish an x/y coordinate system with origin being
// the center of the non-rotated image.
// Compute the corner coordinates of original bounding rectangle in an x/y coordinate
// system using the center as the origin (0,0) e.g. divide NW-NE width by 2 change sign as needed. Units are meters
// Compute rotated NW corner (x`,y`) (in x/y system) using original NW corner(x/y)
// and bearing:
// x` = x * cos(bearingInRadians) + y * sin(bearingInRadians) and y` = -(x * sin(bearingInRadians)) + y * cos(bearingInRadians)
// Compute the y-distance from original NW corner (x/y) to new NW corner (x`,y`)
// (subtract the y's)
// Compute latitude of super-bounding by using SphericalUtil.computeOffset using
// original NW lat-lng as 'from', and y-distance (meters) as distance and heading as 0 (north-up).
// Compute the rotated SW corner(x``,y``) (in x/y system) in the same manner
// as the NW corner above.
// Compute the x-distance from original SW corner (x/y) to new SW corner
// Compute longitude of super-bounding rectangle by using
// SphericalUtil.computeOffset using original NW lat-lng as 'from', and
// x-distance (meters) as distance and heading as 270.
克服简化意味着选择要使用的角落,并将其映射到纬度和经度。
我希望这样的事情已经实施,但希望这有助于解释所需要的内容。快乐的狩猎。
这是以上的实现:
GroundOverlayOptions goo = new GroundOverlayOptions();
BitmapDescriptor bd = BitmapDescriptorFactory.fromResource(R.drawable.rectangle);
goo.image(bd);
goo.position(latLng, 1000F);
GroundOverlay go = mMap.addGroundOverlay(goo);
LatLngBounds llb = go.getBounds();
LatLng ne = llb.northeast;
LatLng sw = llb.southwest;
PolylineOptions po = new PolylineOptions().add(new LatLng(llb.northeast.latitude,llb.southwest.longitude))
.add(llb.northeast)
.add(new LatLng(llb.southwest.latitude,llb.northeast.longitude))
.add(llb.southwest)
.add(new LatLng(llb.northeast.latitude,llb.southwest.longitude));
Polyline polyline = mMap.addPolyline(po);
MarkerOptions mo = new MarkerOptions();
mo.position(new LatLng(ne.latitude,sw.longitude));
mMap.addMarker(mo);
goo.bearing(25.0F);
GroundOverlay go2 = mMap.addGroundOverlay(goo);
double rads = Math.toRadians(25.0);
float[] result = new float[1];
Location.distanceBetween(llb.northeast.latitude, llb.southwest.longitude, llb.northeast.latitude, llb.northeast.longitude, result);
float width = result[0];
Location.distanceBetween(llb.northeast.latitude, llb.northeast.longitude, llb.southwest.latitude, llb.northeast.longitude, result);
float height = result[0];
float upperLeftX = -(width / 2);
float upperLeftY = (height / 2);
float lowerLeftX = upperLeftX;
float lowerLeftY = -upperLeftY;
double newX = (upperLeftX * cos(rads) + upperLeftY * sin(rads));
double newY = (-(upperLeftX * sin(rads)) + upperLeftY * cos(rads));
double deltaY = abs(newY - upperLeftY);
LatLng newLat = SphericalUtil.computeOffset(llb.northeast, deltaY, 0.0);
double newX2 = (lowerLeftX * cos(rads) + lowerLeftY * sin(rads));
double newY2 = (lowerLeftX * Math.sin(rads) + lowerLeftY * cos(rads));
double deltaX = abs(newX2 - lowerLeftX);
LatLng newLng = SphericalUtil.computeOffset(llb.southwest, deltaX, 270.0);
MarkerOptions mo2 = new MarkerOptions();
mo2.position(new LatLng(newLat.latitude, newLng.longitude));
mMap.addMarker(mo2);
结果:
注释
参考文献: