如何从给定的坐标中获取中心坐标?
how can I get the center coordinate from the given coordinates?
我正在使用 vue2 google 地图包,我有这样的数组对象:
markers:[
{ lat: 14.692734621176195, lng: 120.9642877585083 },
{ lat: 14.691963317641529, lng: 120.9715473253784 },
{ lat: 14.702160611177580, lng: 120.9621292582138 }
]
此外,对象 markers 是动态的,因此它可以包含 more/less 个对象而不是 3 个对象。
问题:google 地图在渲染时没有居中对齐,因为我不知道如何找到中心坐标。任何解决方法或建议如何使 google 地图居中对齐?
This website提供找坐标中心的功能
function findCenter(markers) {
let lat = 0;
let lng = 0;
for(let i = 0; i < markers.length; ++i) {
lat += markers[i].lat;
lng += markers[i].lng;
}
lat /= markers.length;
lng /= markers.length;
return {lat: lat, lng: lng}
}
输出为
{
lat: 14.695619516665102,
lng: 120.96598811403351
}
编辑坐标形成的任意形状
正如tao提到的,这个公式对于“任何类型的坐标数组”都不完美。 and this 链接对如何实现您想要的内容有更好的解释和公式。
如果您想做的是适合屏幕上的当前标记选择,您可能正在寻找 fitBounds 方法。另见这两个答案:
- Center/Set Zoom of Map to cover all visible Markers?
- Calculate the center point of multiple latitude/longitude coordinate pairs
谢谢@MrUpsidown。
如果您有兴趣在不更改缩放级别的情况下找到标记选择的“中间”,这是我的原始答案:
“寻找中心”可能是一个复杂的几何问题,但在您的情况下,您似乎想要找到包含所有点的最小 NS/EW 矩形的对角线交点。
这意味着您应该获取 lat
和 lng
数组的 min
和 max
,并为每个数组找到这些限制的中值。
// this fails when polygon crosses 180th meridian!
function findCenter(markers) {
const lats = markers.map(m => m.lat);
const lngs = markers.map(m => m.lng);
return {
lat: (Math.min(...lats) + Math.max(...lats)) / 2,
lng: (Math.min(...lngs) + Math.max(...lngs)) / 2
};
}
但是,正如@MrUpsidown 指出的那样,对于穿过第 180 条子午线的多边形,上述代码会产生 错误的结果 。包含这种情况的正确代码是:
function getMiddle(prop, markers) {
let values = markers.map(m => m[prop]);
let min = Math.min(...values);
let max = Math.max(...values);
if (prop === 'lng' && (max - min > 180)) {
values = values.map(val => val < max - 180 ? val + 360 : val);
min = Math.min(...values);
max = Math.max(...values);
}
let result = (min + max) / 2;
if (prop === 'lng' && result > 180) {
result -= 360
}
return result;
}
function findCenter(markers) {
return {
lat: getMiddle('lat', markers),
lng: getMiddle('lng', markers)
}
}
// tests:
console.log(findCenter([
{ lat: 14.692734621176195, lng: 120.9642877585083 },
{ lat: 14.691963317641529, lng: 120.9715473253784 },
{ lat: 14.702160611177580, lng: 120.9621292582138 },
]));
// => { "lat": 14.697061964409555, "lng": 120.96683829179611 }
console.log(findCenter([
{ lat: 50, lng: 45 },
{ lat: 0, lng: 125 },
{ lat: -50, lng: -100 }
]))
// => { "lat": 0, "lng": 152.5 }
我的答案(绿色)和 (blue) is depicted graphically here: https://q2k0r.csb.app/
的区别
正如@mrupsidown 所指出的,Google 地图 API 提供实用程序来计算点集合的中心:
- 创建一个
LatLngBounds
对象并从标记集合中扩展它
- 在创建的边界对象上使用
.getCenter()
。
我正在使用 vue2 google 地图包,我有这样的数组对象:
markers:[
{ lat: 14.692734621176195, lng: 120.9642877585083 },
{ lat: 14.691963317641529, lng: 120.9715473253784 },
{ lat: 14.702160611177580, lng: 120.9621292582138 }
]
此外,对象 markers 是动态的,因此它可以包含 more/less 个对象而不是 3 个对象。
问题:google 地图在渲染时没有居中对齐,因为我不知道如何找到中心坐标。任何解决方法或建议如何使 google 地图居中对齐?
This website提供找坐标中心的功能
function findCenter(markers) {
let lat = 0;
let lng = 0;
for(let i = 0; i < markers.length; ++i) {
lat += markers[i].lat;
lng += markers[i].lng;
}
lat /= markers.length;
lng /= markers.length;
return {lat: lat, lng: lng}
}
输出为
{
lat: 14.695619516665102,
lng: 120.96598811403351
}
编辑坐标形成的任意形状
正如tao提到的,这个公式对于“任何类型的坐标数组”都不完美。
如果您想做的是适合屏幕上的当前标记选择,您可能正在寻找 fitBounds 方法。另见这两个答案:
- Center/Set Zoom of Map to cover all visible Markers?
- Calculate the center point of multiple latitude/longitude coordinate pairs
谢谢@MrUpsidown。
如果您有兴趣在不更改缩放级别的情况下找到标记选择的“中间”,这是我的原始答案:
“寻找中心”可能是一个复杂的几何问题,但在您的情况下,您似乎想要找到包含所有点的最小 NS/EW 矩形的对角线交点。
这意味着您应该获取 lat
和 lng
数组的 min
和 max
,并为每个数组找到这些限制的中值。
// this fails when polygon crosses 180th meridian!
function findCenter(markers) {
const lats = markers.map(m => m.lat);
const lngs = markers.map(m => m.lng);
return {
lat: (Math.min(...lats) + Math.max(...lats)) / 2,
lng: (Math.min(...lngs) + Math.max(...lngs)) / 2
};
}
但是,正如@MrUpsidown 指出的那样,对于穿过第 180 条子午线的多边形,上述代码会产生 错误的结果 。包含这种情况的正确代码是:
function getMiddle(prop, markers) {
let values = markers.map(m => m[prop]);
let min = Math.min(...values);
let max = Math.max(...values);
if (prop === 'lng' && (max - min > 180)) {
values = values.map(val => val < max - 180 ? val + 360 : val);
min = Math.min(...values);
max = Math.max(...values);
}
let result = (min + max) / 2;
if (prop === 'lng' && result > 180) {
result -= 360
}
return result;
}
function findCenter(markers) {
return {
lat: getMiddle('lat', markers),
lng: getMiddle('lng', markers)
}
}
// tests:
console.log(findCenter([
{ lat: 14.692734621176195, lng: 120.9642877585083 },
{ lat: 14.691963317641529, lng: 120.9715473253784 },
{ lat: 14.702160611177580, lng: 120.9621292582138 },
]));
// => { "lat": 14.697061964409555, "lng": 120.96683829179611 }
console.log(findCenter([
{ lat: 50, lng: 45 },
{ lat: 0, lng: 125 },
{ lat: -50, lng: -100 }
]))
// => { "lat": 0, "lng": 152.5 }
我的答案(绿色)和
正如@mrupsidown 所指出的,Google 地图 API 提供实用程序来计算点集合的中心:
- 创建一个
LatLngBounds
对象并从标记集合中扩展它 - 在创建的边界对象上使用
.getCenter()
。