【问题标题】:Scaling a polygon on a map- the latitude refuses to scale在地图上缩放多边形 - 纬度拒绝缩放
【发布时间】:2016-07-15 02:30:28
【问题描述】:

问题:

我正在尝试在地图上缩放多边形,它似乎在水平(经度)上工作, 但垂直(纬度)保持不变。

我是如何处理它的

包含以下步骤的转换:

1)将经纬度转换为笛卡尔点

2)通过对每个点和多边形质心进行差异来将点移动到对象空间

3)将每个点按一个因子缩放

4) 通过添加回质心将它们移回世界空间。

可能的原因:

在平移和缩放期间,我只处理 x 和 y 值。由于 缩放只是二维形状我认为可以忽略它,但也许我需要操纵 它也在过程中的某个地方。

我的代码:主执行堆栈,后面是他们使用的所有函数。

var originalLatLngs = [{lat:45.250589,lon:-116.653149},{lat:45.250603,lon:-116.651856},{lat:45.250269,lon:-116.651845},{lat:45.250261,lon:-116.653146}];
var cartesianPoints = bounds.map(function(bound){
  return toCartesian(bound.lat,bound.lon);
});
var centriod = getPolygonCentroid(cartesianPoints);
var objectCoordinates = toObjectSpace(centriod,cartesianPoints);
var scaledCoordinates = scaleCoordinates(2,objectCoordinates);
var marginCoordinates = toWorldSpace(centriod,scaledCoordinates);
var newLatLngs = marginCoordinates.map(function(marginCoordinate){
  return toLatLng(marginCoordinate.x,marginCoordinate.y,marginCoordinate.z);
});


function getPolygonCentroid(vertices){
  var centroid = {x:0,y:0};
  var signedArea = 0;
  var x0 = 0; 
  var y0 = 0; 
  var x1 = 0; 
  var y1 = 0; 
  var a = 0;  

  for (var i=0; i<vertices.length-1; i++){
      x0 = vertices[i].x;
      y0 = vertices[i].y;
      x1 = vertices[i+1].x;
      y1 = vertices[i+1].y;
      a = x0*y1 - x1*y0;
      signedArea += a;
      centroid.x += (x0 + x1)*a;
      centroid.y += (y0 + y1)*a;
  }
  x0 = vertices[i].x;
  y0 = vertices[i].y;
  x1 = vertices[0].x;
  y1 = vertices[0].y;
  a = x0*y1 - x1*y0;
  signedArea += a;
  centroid.x += (x0 + x1)*a;
  centroid.y += (y0 + y1)*a;

  signedArea *= 0.5;
  centroid.x /= (6.0*signedArea);
  centroid.y /= (6.0*signedArea);

  return centroid;
}

function toObjectSpace(centroid,worldCoordinates){
  var objectCoordinates = [];
  worldCoordinates.forEach(function(worldCoordinate){
    var newXCoordinate = worldCoordinate.x - centroid.x;
    var newYCoordinate = worldCoordinate.y - centroid.y;
    var orginalZCoordinate = worldCoordinate.z;
    objectCoordinates.push({x:newXCoordinate,y:newYCoordinate,z:originalZCoordinate});
  });
  return objectCoordinates;
}

function scaleCoordinates(factor,coordinates){
  var scaledCoordinates = [];
  coordinates.forEach(function(coordinate){
    var newXCoordinate = coordinate.x * factor;
    var newYCoordinate = coordinate.y * factor;
    var orginalZCoordinate = coordinate.z;
    scaledCoordinates.push({x:newXCoordinate,y:newYCoordinate,z:originalZCoordinate});
  });
  return scaledCoordinates;
}

function toWorldSpace(centroid,objectCoordinates){
  var worldCoordinates = [];
  objectCoordinates.forEach(function(objectCoordinate){
    var newXCoordinate = objectCoordinate.x + centroid.x;
    var newYCoordinate = objectCoordinate.y + centroid.y;
    var orginalZCoordinate = objectCoordinate.z;
    worldCoordinates.push({x:newXCoordinate,y:newYCoordinate,z:originalZCoordinate});
  });
  return worldCoordinates;
}

var toCartesian = function(lat,lon){
  const R = 6371;

  var x = R * Math.cos(deg2rad(lat)) * Math.cos(deg2rad(lon));
  var y = R * Math.cos(deg2rad(lat)) * Math.sin(deg2rad(lon));
  var z = R * Math.sin(deg2rad(lat));

  return {
    x: x,
    y: y,
    z: z
  }
}

var toLatLng = function(x,y,z){
  const R = 6371;
  var lat = Math.asin(z / R);
  var lon = Math.atan2(y, x);
  return {
    lat:rad2deg(lat),
    lon:rad2deg(lon)
  }
}

var deg2rad = function(deg) {
  return deg * (Math.PI/180)
}

var rad2deg = function(radians) {
  return radians * 180 / Math.PI;
};

【问题讨论】:

  • 您检查过toCartesian 之后的值吗?您正在使用 3D 点,就像它们是 2D 点一样

标签: dictionary geometry geospatial latitude-longitude affinetransform


【解决方案1】:

您可能需要的是 SLERP(球面线性插值):https://en.wikipedia.org/wiki/Slerp。只需使用参数t 作为缩放因子,在多边形的每个点和选定的放大中心“之间”滑动。

【讨论】:

    猜你喜欢
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多