Algorithm 从旧的+n米计算新的经度和纬度

Algorithm 从旧的+n米计算新的经度和纬度,algorithm,geolocation,Algorithm,Geolocation,我想创建2个新的经度和2个新的纬度,基于坐标和米的距离,我想在某个点周围创建一个漂亮的边界框。它是城市的一部分,最大为±1500米。因此,我认为地球的曲率不必考虑在内 所以我有50.0452345 x和4.3242234 y,我想知道x+500米,x-500米,y-500米,y+500米 我发现了许多算法,但几乎所有的算法似乎都处理点之间的距离。你检查过了吗: 这些计算充其量也很烦人,我做过很多。哈弗森配方奶粉将是你的朋友 一些参考资料:每度经度的公里数约为 (pi/180) * r_earth

我想创建2个新的经度和2个新的纬度,基于坐标和米的距离,我想在某个点周围创建一个漂亮的边界框。它是城市的一部分,最大为±1500米。因此,我认为地球的曲率不必考虑在内

所以我有50.0452345 x和4.3242234 y,我想知道x+500米,x-500米,y-500米,y+500米

我发现了许多算法,但几乎所有的算法似乎都处理点之间的距离。

你检查过了吗:

这些计算充其量也很烦人,我做过很多。哈弗森配方奶粉将是你的朋友


一些参考资料:

每度经度的公里数约为

(pi/180) * r_earth * cos(theta*pi/180)
式中,θ为纬度,单位为度,r_地球约为6378公里


每个纬度的公里数在所有位置大致相同,约

(pi/180) * r_earth = 111 km / degree 
因此,您可以:

new_latitude  = latitude  + (dy / r_earth) * (180 / pi);
new_longitude = longitude + (dx / r_earth) * (180 / pi) / cos(latitude * pi/180);

只要dx和dy与地球半径相比很小,并且你不会太靠近两极。

公认的答案是完全正确的。我做了一些调整,变成了这样:

double meters = 50;

// number of km per degree = ~111km (111.32 in google maps, but range varies
   between 110.567km at the equator and 111.699km at the poles)
// 1km in degree = 1 / 111.32km = 0.0089
// 1m in degree = 0.0089 / 1000 = 0.0000089
double coef = meters * 0.0000089;

double new_lat = my_lat + coef;

// pi / 180 = 0.018
double new_long = my_long + coef / Math.cos(my_lat * 0.018);
希望这也有帮助。

对于latitude,请执行以下操作:

var earth = 6378.137,  //radius of the earth in kilometer
    pi = Math.PI,
    m = (1 / ((2 * pi / 360) * earth)) / 1000;  //1 meter in degree

var new_latitude = latitude + (your_meters * m);
对于经度,请执行以下操作:

var earth = 6378.137,  //radius of the earth in kilometer
    pi = Math.PI,
    cos = Math.cos,
    m = (1 / ((2 * pi / 360) * earth)) / 1000;  //1 meter in degree

var new_longitude = longitude + (your_meters * m) / cos(latitude * (pi / 180));

你的米的变量可以包含正值或负值。

我花了大约两个小时来计算@nibot的解,我只需要一种方法来创建一个边界框,给定它的中心点和宽度/高度或半径(以公里为单位):

var meters = 50;
var coef = meters * 0.0000089;
var new_lat = map.getCenter().lat.apply() + coef;
var new_long = map.getCenter().lng.apply() + coef / Math.cos(new_lat * 0.018);
map.setCenter({lat:new_lat, lng:new_long});
我在数学/地理上不理解这个解。 我通过反复尝试来调整解决方案,以获得四个坐标:

北:

private static Position FromKmToNPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_latitude = p.Lat + (km / r_earth) * (180 / pi);
    return new Position(new_latitude, p.Long);
}
东部:

南方:

private static Position FromKmToSPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_latitude = p.Lat - (km / r_earth) * (180 / pi);
    return new Position(new_latitude, p.Long);
}
西:


如果你不需要非常精确的话:每10000米的纬度和经度大约是0.1。 例如,我想从我的数据库中加载点A周围3000米的位置:

double newMeter =  3000 * 0.1 / 10000;
double lat1 = point_A.latitude - newMeter;
double lat2 = point_A.latitude + newMeter;
double lon1 = point_A.longitude - newMeter;
double lon1 = point_A.longitude + newMeter;
Cursor c = mDb.rawQuery("select * from TABLE1  where lat >= " + lat1 + " and lat <= " + lat2 + " and lon >= " + lon1 + " and lon <= " + lon2 + " order by id", null);
在简易/简易地图上解决国家间距离问题时,请参见下面的官方谷歌地图文档链接:

我建议使用此解决方案来轻松/简单地解决边界问题,这样您就可以知道您在哪个领域解决的边界问题不是全球推荐的

注:

纬度线向东西延伸,并标记点的南北位置。纬度线称为平行线,总共有180度的纬度。每个纬度之间的距离约为69英里110公里

经度之间的距离越远离赤道就越窄。赤道经度之间的距离与纬度相同,大约69英里110公里。北纬45度或南纬45度时,两者之间的距离约为49英里79公里。经线在极点处会聚时,经度之间的距离达到零

查看他们的代码部分,了解他们如何解决距离中心+10公里+/-0.1度的问题

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: { lat: 50.064192, lng: -130.605469 },
      zoom: 3,
    }
  );
  const card = document.getElementById("pac-card") as HTMLElement;
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
  const center = { lat: 50.064192, lng: -130.605469 };

  // Create a bounding box with sides ~10km away from the center point
  const defaultBounds = {
    north: center.lat + 0.1,
    south: center.lat - 0.1,
    east: center.lng + 0.1,
    west: center.lng - 0.1,
  };

  const input = document.getElementById("pac-input") as HTMLInputElement;
  const options = {
    bounds: defaultBounds,
    componentRestrictions: { country: "us" },
    fields: ["address_components", "geometry", "icon", "name"],
    origin: center,
    strictBounds: false,
    types: ["establishment"],
  };

如果你在一个相当小的区域工作,仅仅做纬度-0.09和经度-0.0148来获得大约一平方公里的面积真的不好吗?我认为这不是很坏。只要你正在处理的Lat/Lng是十进制的,那么这个水平的平方公里不会被地球的曲率所扭曲。@BenjaminUdinktenCate将在阿姆斯特丹工作,但在世界其他地方将是不准确的。做经度-0.0148只会让你在赤道上走大约0.16公里。要将度转换成弧度,你需要乘以py,再除以180。但你写的是coslatitude*180/pi@josch:接得好。试着在下次修改答案,而不是简单地提出修改。许多人只是简单地从StackOverflow复制和粘贴代码,认为它是正确的,可以使用。好的,方向是什么?我的意思是,如果我想增加50米,它将被添加到哪里?右、左、上或下?地球不是完美的球形,因此使用单个半径值是一种近似值。维基百科说,从表面上的点到中心的距离从6353公里到6384公里不等。它还说,将地球建模为一个球体的几种不同方法,每种方法的平均半径为6371公里,这表明了你的价值。事实上,如果此修正在应用中非常重要,那么无论如何,您应该使用更好的算法。对于那些不确定r_earth变量应以米为单位且应等于大约6371000.00.0000089的人?尽量避免使用神奇的数字,没有人会理解这一点。这是代码中地球直径和圆周率数字的简短版本。不是魔法。如果没有人知道如何复制这个数字,它仍然是魔法。你为什么不把完整的计算结果写进你的代码里呢?谷歌地图上的1度等于111.32公里。1度=111.32公里。1公里的度数=1/111.32=0.008983。1M学位=0.000008983。你应该在回答中发表评论,把它放在评论中是没有帮助的。请添加
对你的答案进行一些解释。如果你想将地图对象移动到当前地图中心附近50米处,那么你可以使用带+,-数字的代码替换+50
double newMeter =  3000 * 0.1 / 10000;
double lat1 = point_A.latitude - newMeter;
double lat2 = point_A.latitude + newMeter;
double lon1 = point_A.longitude - newMeter;
double lon1 = point_A.longitude + newMeter;
Cursor c = mDb.rawQuery("select * from TABLE1  where lat >= " + lat1 + " and lat <= " + lat2 + " and lon >= " + lon1 + " and lon <= " + lon2 + " order by id", null);
public double MeterToDegree(double meters, double latitude)
{
    return meters / (111.32 * 1000 * Math.Cos(latitude * (Math.PI / 180)));
}
function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: { lat: 50.064192, lng: -130.605469 },
      zoom: 3,
    }
  );
  const card = document.getElementById("pac-card") as HTMLElement;
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
  const center = { lat: 50.064192, lng: -130.605469 };

  // Create a bounding box with sides ~10km away from the center point
  const defaultBounds = {
    north: center.lat + 0.1,
    south: center.lat - 0.1,
    east: center.lng + 0.1,
    west: center.lng - 0.1,
  };

  const input = document.getElementById("pac-input") as HTMLInputElement;
  const options = {
    bounds: defaultBounds,
    componentRestrictions: { country: "us" },
    fields: ["address_components", "geometry", "icon", "name"],
    origin: center,
    strictBounds: false,
    types: ["establishment"],
  };