我正在尝试使用Google地图ground overlay,但我们缺少GPS位置。
我们在Google地图屏幕截图上绘制了一个叠加地图。从这张截图中我们记录了左上角和中心位置。
我们要求右下角位置准确地覆盖这些图像。见下文:
初步思考是找到两点之间的差异并将其添加到中心点。
在JavaScript中:
var topLeft = [-32.8830055, 151.686214];
var centerCenter = [-32.9293803, 151.756686];
var difference1 = centerCenter[0] - ( (topLeft[0] - centerCenter[0] ) ) ;
var difference2 = centerCenter[1] - ( (topLeft[1] - centerCenter[1] ) ) ;
// being bottom right this should be "bigger" than above values
// outputs [-32.97575509999999, 151.827158];
var bottomRight = [difference1 , difference2];
然而,看起来这就是地球的曲线抛出简单数学出门的地方。我猜测下面发生的是为什么。
所以给定我有一个矩形叠加,我知道左上角和中心点我可以计算出右下角的纬度和经度 I.e X在上图中。注意我不知道这个矩形的真实世界距离。
注意:我也知道我必须将这些更改为NW / SE以使用地面叠加。
答案 0 :(得分:3)
方法(使用几何库):
计算从西北到中心的航向
google.maps.geometry.spherical.computeHeading(northwest, center);
计算从西北到中心的距离
google.maps.geometry.spherical.computeDistanceBetween(northwest, center);
使用
计算东南google.maps.geometry.spherical.computeOffset(center,
calculatedDistance,
calculatedHeading);
function initialize() {
var nw = new google.maps.LatLng(62.400471, -150.287132),
center = new google.maps.LatLng(62.341145, -150.14637),
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 9,
center: center
}),
heading, distance, se;
heading = google.maps.geometry.spherical.computeHeading(nw, center);
distance = google.maps.geometry.spherical.computeDistanceBetween(nw, center);
se = google.maps.geometry.spherical.computeOffset(center, distance, heading);
new google.maps.Marker({
map: map,
position: center
});
new google.maps.Marker({
map: map,
position: nw
});
new google.maps.Marker({
map: map,
position: se
});
new google.maps.GroundOverlay(
'https://developers.google.com/maps/documentation/' +
'javascript/examples/full/images/talkeetna.png', {
north: nw.lat(),
south: se.lat(),
west: nw.lng(),
east: se.lng()
}, {
map: map
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map_canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry"></script>
答案 1 :(得分:2)
您是否反对使用已经支持Haversine计算中心点的库? (通过测试启动)
查看Geolib:https://github.com/manuelbieh/Geolib
var center = geolib.getCenter([
{latitude: 52.516272, longitude: 13.377722},
{latitude: 51.515, longitude: 7.453619},
{latitude: 51.503333, longitude: -0.119722}
]);
console.log(center);
// Output:
//
// {
// "latitude": "52.009802",
// "longitude": "6.629000",
// "distance": 932.209
// }
您可以使用的codepen演示:http://codepen.io/anon/pen/grbGrz/?editors=1010
您可以随时将其削减到您需要的功能。
答案 2 :(得分:1)
您可能需要Haversine公式才能进行此类计算。所涉及的数学显然比SO答案的典型水平更高,所以你的问题可能实际上属于gis或数学堆栈交换,其中一些更有经验的SO用户可能能够给你一个更详细的答案/例子。
答案 3 :(得分:1)
以免从查询开始。你有两个latlng,现在你想得到矩形的latlng。
我们首先使用计算部分,然后再编程部分。假设是 -
中心点= e
左上角= A
右上角= B
右下角= C
左下角= D
AD = f
的中点AB = g
的中点计算部分
location g parameters- lat-A.lat,long-e.long
位置f参数 - lat-e.lat,long-A.long
A与g的距离= A.distanceTo(g)
A到f的距离= A.distanceTo(f)
B点距离A
点C = 2Af来自B
从A
点D = 2Af编程部分
LatLng A = null, B = null, C = null, D = null, e = null, f = null, g = null,temp=null;
e.latitude = your center latitude value;
e.longitude = your center longitude value;
A.latitude=your top left point latitude value;
A.longitude=your top left point longitude value;
f.latitude = e.latitude;
f.longitude = A.longitude;
g.latitude = A.latitude;
g.longitude = e.longitude;
double[] Ag = new double[1];
double[] Af = new double[1];
Location.distanceBetween(A.latitude, A.longitude, g.latitude, g.longitude, Ag);
Location.distanceBetween(A.latitude, A.longitude, f.latitude, f.longitude, Af);
temp=getDestinationPoint(A,90,(2*Ag));
B.latitude=temp.latitude;
B.longitude=temp.longitude;
temp=getDestinationPoint(B,180,(2*Af));
C.latitude=temp.latitude;
C.longitude=temp.longitude;
temp=getDestinationPoint(A,180,(2*Af));
D.latitude=temp.latitude;
D.longitude=temp.longitude;
private LatLng getDestinationPoint (LatLng source,double brng, double dist){
dist = dist / 6371;
brng = Math.toRadians(brng);
double lat1 = Math.toRadians(source.latitude), lon1 = Math.toRadians(source.longitude);
double lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) +
Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));
double lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) *
Math.cos(lat1),
Math.cos(dist) - Math.sin(lat1) *
Math.sin(lat2));
if (Double.isNaN(lat2) || Double.isNaN(lon2)) {
return null;
}
return new LatLng(Math.toDegrees(lat2), Math.toDegrees(lon2));
}
<强>解释强>
点f和g分别是AD和AB线的中点。我们可以通过改变A和e点的纬度和长值来得到它。通过这两个长度(Af和Ag),我们可以根据需要获得矩形的四个latlng点。
谢谢
答案 4 :(得分:0)
使用下面的 javascript 函数获取基于中心和距离的矩形的经纬度列表。latLngArr 是矩形点的列表。
Number.prototype.degreeToRadius = function () {
return this * (Math.PI / 180);
};
Number.prototype.radiusToDegree = function () {
return (180 * this) / Math.PI;
};
function getBoundingBox(fsLatitude, fsLongitude, fiDistanceInKM) {
if (fiDistanceInKM == null || fiDistanceInKM == undefined || fiDistanceInKM == 0)
fiDistanceInKM = 1;
var MIN_LAT, MAX_LAT, MIN_LON, MAX_LON, ldEarthRadius, ldDistanceInRadius, lsLatitudeInDegree, lsLongitudeInDegree,
lsLatitudeInRadius, lsLongitudeInRadius, lsMinLatitude, lsMaxLatitude, lsMinLongitude, lsMaxLongitude, deltaLon;
// coordinate limits
MIN_LAT = (-90).degreeToRadius();
MAX_LAT = (90).degreeToRadius();
MIN_LON = (-180).degreeToRadius();
MAX_LON = (180).degreeToRadius();
// Earth's radius (km)
ldEarthRadius = 6378.1;
// angular distance in radians on a great circle
ldDistanceInRadius = fiDistanceInKM / ldEarthRadius;
// center point coordinates (deg)
lsLatitudeInDegree = fsLatitude;
lsLongitudeInDegree = fsLongitude;
// center point coordinates (rad)
lsLatitudeInRadius = lsLatitudeInDegree.degreeToRadius();
lsLongitudeInRadius = lsLongitudeInDegree.degreeToRadius();
// minimum and maximum latitudes for given distance
lsMinLatitude = lsLatitudeInRadius - ldDistanceInRadius;
lsMaxLatitude = lsLatitudeInRadius + ldDistanceInRadius;
// minimum and maximum longitudes for given distance
lsMinLongitude = void 0;
lsMaxLongitude = void 0;
// define deltaLon to help determine min and max longitudes
deltaLon = Math.asin(Math.sin(ldDistanceInRadius) / Math.cos(lsLatitudeInRadius));
if (lsMinLatitude > MIN_LAT && lsMaxLatitude < MAX_LAT) {
lsMinLongitude = lsLongitudeInRadius - deltaLon;
lsMaxLongitude = lsLongitudeInRadius + deltaLon;
if (lsMinLongitude < MIN_LON) {
lsMinLongitude = lsMinLongitude + 2 * Math.PI;
}
if (lsMaxLongitude > MAX_LON) {
lsMaxLongitude = lsMaxLongitude - 2 * Math.PI;
}
}
// a pole is within the given distance
else {
lsMinLatitude = Math.max(lsMinLatitude, MIN_LAT);
lsMaxLatitude = Math.min(lsMaxLatitude, MAX_LAT);
lsMinLongitude = MIN_LON;
lsMaxLongitude = MAX_LON;
}
return [
lsMinLatitude.radiusToDegree(),
lsMinLongitude.radiusToDegree(),
lsMaxLatitude.radiusToDegree(),
lsMaxLongitude.radiusToDegree()
];
};
使用下面的代码生成一个 lat/long 矩形数组。
var lsRectangleLatLong = getBoundingBox(parseFloat(latitude), parseFloat(longitude), lsDistance);
if (lsRectangleLatLong != null && lsRectangleLatLong != undefined) {
latLngArr.push({ lat: lsRectangleLatLong[0], lng: lsRectangleLatLong[1] });
latLngArr.push({ lat: lsRectangleLatLong[0], lng: lsRectangleLatLong[3] });
latLngArr.push({ lat: lsRectangleLatLong[2], lng: lsRectangleLatLong[3] });
latLngArr.push({ lat: lsRectangleLatLong[2], lng: lsRectangleLatLong[1] });
}