如何从给定坐标中获取中心坐标? [关闭]

Posted

技术标签:

【中文标题】如何从给定坐标中获取中心坐标? [关闭]【英文标题】:how can I get the center coordinate from the given coordinates? [closed] 【发布时间】:2021-10-23 10:05:08 【问题描述】:

我正在使用 vue2 谷歌地图包,我有这样的数组对象:

markers:[
  lat: 14.692734621176195, lng: 120.9642877585083 ,
  lat: 14.691963317641529, lng: 120.9715473253784 ,
  lat: 14.702160611177580, lng: 120.9621292582138 
]

此外,对象 ma​​rkers 是动态的,因此它可以包含多于/少于 3 个对象。

问题:谷歌地图在渲染时没有对齐中心,因为我不知道如何找到中心坐标。有什么解决方法或建议如何将谷歌地图居中对齐?

【问题讨论】:

这里的“中心坐标”是什么? 你可以在这里看到这两种方法的区别:q2k0r.csb.app。您将蓝色方法标记为正确的“中心”。 重复Center/Set Zoom of Map to cover all visible Markers? @MrUpsidown,从技术上讲,这个问题并不要求fitBounds,这意味着更改缩放级别。它只要求一个公式来找到一组标记的中心点。您指出的问题不包含这样的公式。 从技术上讲,这个问题很模糊,没有提供任何背景或细节。 fitBounds通常是前往地图上“中心”标记的方式。 【参考方案1】:

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

jsfiddle

编辑坐标生成的任意形状 正如 tao 所提到的,这个公式对于“任何类型的坐标数组”并不完美。 This 和 this 链接对如何实现您想要的有更好的解释和公式。

【讨论】:

那个方法不对,它计算的是中位数。假设您有 9 个点,lat10 和一个 lat 的点 20 的“中心”,根据您的公式将有一个 lat11。但实际上应该是15。您需要一个函数,它可以获取latlng 数组的minmax,并获取这些限制之间的中间值。这就是“中心”。 @tao 是的,你说得有道理。我再次检查过,似乎当“坐标创建三角形或正多边形”时,这种方法被告知可以正常工作。见gis.stackexchange.com/questions/12120/… 和en.wikipedia.org/wiki/Centroid#By_geometric_decomposition 这是一个失败的三角形示例:[lat: 10, lng: 120, lat: 10, lng: 130, lat: 20, lng: 120]。您的方法返回lat: 13.333333333333334, lng: 123.33333333333333。正确的结果是 lat: 15, lng: 125 您的公式计算所谓的“质心”或“重心”或“质心”。这意味着如果您有更多点靠近一侧,它们会将“重心”拉向那一侧。而我们不想要这个。我们只想找到包含所有点的屏幕中间(矩形),而不管有多少点靠近一侧。 我制作了一个代码框,以提供我上面的 cmets 的图形(更直观)解释:q2k0r.csb.app。蓝色(重心)是您答案中的方法,绿色(限制中位数)是我在答案中概述的方法。编码愉快!【参考方案2】:

如果您想做的是适合屏幕上的当前标记选择,您可能正在寻找fitBounds 方法。另请参阅这两个答案:

Center/Set Zoom of Map to cover all visible Markers? Calculate the center point of multiple latitude/longitude coordinate pairs

谢谢你,@MrUpsidown。


如果您有兴趣在不更改缩放级别的情况下找到标记选择的“中间”,这是我的原始答案:


“寻找中心”可能是一个复杂的几何问题,但在您的情况下,您似乎想要找到包含所有点的最小 NS/EW 矩形的对角线的交点。

这意味着您应该获取latlng 数组的minmax,并为每个数组找到这些限制的中值。

// 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 

我的答案(绿色)和tugrul's answer(蓝色)之间的区别在此处以图形方式描述:https://q2k0r.csb.app/


正如@mrupidown 所指出的,Google 地图 API 提供了计算点集合中心的实用程序:

创建一个LatLngBounds 对象并从标记集合中扩展它 在创建的边界对象上使用.getCenter()

【讨论】:

如果您发现任何失败的案例,我将非常乐意改进它。感谢您的调查。 jsfiddle.net/upsidown/sj8v7phc - 黄色中心标记是用边界对象计算的 - 蓝色是你的函数 - 红色矩形是边界对象。我认为 issue 仅与矩形外边缘上考虑的点有关。地球是圆的... 公平点,我会用免责声明更新。毕竟,世界是圆的 :) 为什么不添加您自己的答案?公平地说,我应该认为地图 API 应该有一些实用程序来解决这个问题。 LatLng 对象所做的另一件事是,它会限制纬度并包裹经度以处理错误/超出范围的值,如 here 所述。 @MrUpsidown,我知道谷歌地图很棒。我的回答和谷歌地图没有做的一件小事是,它提供了一种有用的方法来为任何地图产品(mapbox、传单、openstreetmaps、maplibre)的用户获取“中心”。但你是对的,我的自定义方法不适用于无效坐标。感谢您提供宝贵的反馈和建议。

以上是关于如何从给定坐标中获取中心坐标? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Android中百度地图如何重新获取坐标

如何在iphone中获取gmsmapview的坐标中心

给定中心坐标(纬度/经度)、半径(米)和中心角(度)的球体(地球)上的圆弧面积 [关闭]

如何在sencha touch 2中获取地图(Ext.map)的中心坐标?

如何从(0,0)开始以长度和角度获取2D坐标

百度android地图如何获取地图中心点的经纬坐标