如何在Leaflet中绘制天梭的椭圆(Tissot's indicatrix)

时间:2015-11-04 16:13:01

标签: javascript leaflet openlayers ellipse

OpenLayers原生支持tissot's ellipses by adding a sphere to the circular() method

不幸的是Leaflet L.circle()不支持此功能。

如何使用Leaflet绘制Tissot的椭圆?

2 个答案:

答案 0 :(得分:1)

编辑3:

使用leaflet-geodesy的新命题似乎非常适合您的需要。它免于Turf的错误(见下面的编辑2)。

API非常简单:

LGeo.circle([51.441767, 5.470247], 500000).addTo(map);

([纬度,经度]度的中心位置,以米为单位的半径)

演示:http://jsfiddle.net/ve2huzxw/61/

与nathansnider的解决方案进行快速比较:http://fiddle.jshell.net/58ud0ttk/2/

(表明两个代码产生相同的结果区域,唯一的区别在于用于近似区域的分段数量)

编辑:一个很好的页面,将Leaflet-geodesy与标准L.Circle进行比较:https://www.mapbox.com/mapbox.js/example/v1.0.0/leaflet-geodesy/

编辑2:

不幸的是,Turf使用JSTS Topology Suite来构建缓冲区。看起来JSTS中的此操作不适合像地球表面这样的非平面几何体。

报告错误here,截至今天,主要的Turf库没有完整的解决方法。

所以以下答案(编辑1)会产生错误的结果

有关在点附近构建缓冲区的解决方法,请参阅nathansnider's answer

编辑1:

您可以使用Turf轻松构建描述的多边形。它提供turf.buffer方法,该方法创建一个围绕给定特征具有指定距离的多边形(可能是一个简单的点)。

所以你可以这样做:

var pt = {
  "type": "Feature",
  "properties": {},
  "geometry": {
    "type": "Point",
    "coordinates": [5.470247, 51.441767]
  }
};

var buffered = turf.buffer(pt, 500, 'kilometers');

L.geoJson(pt).addTo(map);
L.geoJson(buffered).addTo(map);

演示:http://jsfiddle.net/ve2huzxw/41/

原始答案:

不幸的是,目前似乎没有Leaflet插件可以这样做。

目前还不清楚天梭的指标应代表什么:

  1. 一个真正的椭圆,表示无限小圆的变形(即单点处的失真),或
  2. 圆形的形状,表示地球表面有限尺寸圆的变形,就像您链接的OpenLayers演示一样?
  3. 在该演示中,EPSG中的形状:4326不是椭圆形,垂直轴的长度在较高纬度下与形状的另一半相比减小。

    如果您正在寻找第二个选项,那么您必须手动构建一个表示球体和地球表面交点的多边形。如果我的理解是正确的,这就是OL演示所做的。如果这是您的选项,也许您可​​以在那里生成多边形并将它们作为GeoJSON功能导入Leaflet? : - )

答案 1 :(得分:1)

因为turf.buffer目前似乎有一个错误,这里有一个与turf.js不同的方法,这次使用turf.destination旋转一系列轴承来创建一个真正的圆圈:

//creates a true circle from a center point using turf.destination
//arguments are the same as in turf.destination, except using number of steps 
//around the circle instead of fixed bearing. Returns a GeoJSON Polygon as output.

function tissotish(center, radius, steps, units) {
    var step_angle = 360/steps;
    var bearing = -180;
    var tissot = { "type": "Polygon",
    "coordinates": [[]]
    };
    for (var i = 0; i < steps + 1; ++i) {
        var target =  turf.destination(center, radius, bearing, units);
        var coords = target.geometry.coordinates;
        tissot.coordinates[0].push(coords);
        bearing = bearing + step_angle;
    }
    return tissot;
}

这并不会产生一个真正的天梭指数(它应该在一个点上测量失真),但它确实产生了一个真正的圆圈,从你的其他评论中看起来似乎就是你&# 39;无论如何都要寻找。这是一个例子中的小提琴:

http://fiddle.jshell.net/nathansnider/58ud0ttk/

为了进行比较,我在此处添加了与上面ghybs's answer应用的相同的测量线。 (当你点击这些线条时,他们确实说高纬度地区的水平距离大于500公里,但那是因为,我创建它们的方式,它们最终在圆圈外略微延伸,而我懒得裁剪它们。)