【问题标题】:Openlayers 3 Circle radius in metersOpenlayers 3圆半径以米为单位
【发布时间】:2015-08-25 11:35:23
【问题描述】:

如何获得Circle 以米为单位的半径 可能这是现有的问题,但我没有得到正确的结果。我正在尝试在 postgis 中创建具有相同半径和中心的多边形,从 openlayers 圈获得。

为了获得以米为单位的半径,我关注了this。 运行示例link

var radiusInMeters = circleRadius * ol.proj.METERS_PER_UNIT['m'];

在获得中心、半径(以米为单位)后,我正在尝试使用 postgis(服务器作业)生成多边形(WKT)并在地图中绘制该特征,例如 this

select st_astext(st_buffer('POINT(79.25887485937808 17.036647682474722 0)'::geography, 365.70644956827164));

但两者都没有覆盖同一区域。任何人都可以让我知道我做错了什么。

基本上,我对 Circle 的输入/输出将仅以米为单位。

【问题讨论】:

    标签: postgis openlayers-3


    【解决方案1】:

    ol.geom.Circle 可能不代表圆

    OpenLayers 圆形几何图形在投影平面上定义。这意味着它们在地图上始终是圆形的,但所覆盖的区域可能并不代表地球上的实际圆形。圆圈所覆盖区域的实际形状和大小将取决于所使用的投影。

    这可以通过 Tissot 的指示线来可视化,它显示了地球上的圆形区域在投影到平面上时是如何变换的。使用投影 EPSG:3857,这看起来像:

    图片来自OpenLayer 3's Tissot example,显示的区域半径均为 800 000 米。如果将这些圆圈绘制为ol.geom.Circle,半径为 800000(使用 EPSG:3857),它们在地图上的大小都相同,但更靠近两极的圆圈代表地球上更小的区域。

    对于大多数使用 OpenLayers 几何图形的事物来说都是如此。几何图形的半径、长度或面积都在投影平面中报告。

    因此,如果您有ol.geom.Circle,则获取实际表面半径将取决于投影和特征位置。对于某些投影(例如 EPSG:4326),不会有准确的答案,因为几何图形甚至可能不代表圆形区域。

    但是,假设您使用的是 EPSG:3857 并且没有画出非常大的圆圈或非常靠近两极,那么圆圈将很好地表示圆形区域。

    ol.proj.METERS_PER_UNIT

    ol.proj.METERS_PER_UNIT 只是米和其他一些单位之间的转换表。 ol.proj.METERS_PER_UNIT['m'] 将始终返回 1,因为单位 'm' 是米。 EPSG:3857 使用米作为单位,但如前所述,它们向两极方向扭曲。

    解决方法(阅读理解以上内容后使用)

    要获得ol.geom.Circle 的实际地面半径,您必须找到圆心与边缘上的点之间的距离。这可以使用ol.Sphere

    var center = geometry.getCenter()
    var radius = geometry.getRadius()
    var edgeCoordinate = [center[0] + radius, center[1]];
    var wgs84Sphere = new ol.Sphere(6378137);
    var groundRadius = wgs84Sphere.haversineDistance(
        ol.proj.transform(center, 'EPSG:3857', 'EPSG:4326'), 
        ol.proj.transform(edgeCoordinate, 'EPSG:3857', 'EPSG:4326')
    );
    

    更多选项

    如果您想在地球上添加一个表示圆形区域的几何图形,您应该考虑使用上面 Tissot 示例中使用的方法。也就是说,定义一个具有足够多点的正多边形以使其看起来平滑。这将使它可以在投影之间转移,并且似乎是您在服务器端所做的事情。 OpenLayers 3 通过ol.geom.Polygon.circular 实现了这一点:

    var circularPolygon = ol.geom.Polygon.circular(wgs84Sphere, center, radius, 64);
    

    还有ol.geom.Polygon.fromCircle,它接受ol.geom.Circle并将其转换为代表同一区域的多边形。

    【讨论】:

      【解决方案2】:

      我的回答是对 Alvin 出色回答的补充。

      假设您想围绕一个点要素绘制一个给定半径(以米为单位)的圆。在我的特殊情况下,围绕移动的车辆绕 200m 圈。

      如果这个圆的直径很小(

      这是我的风格功能:

      private pointStyle(feature: Feature, resolution: number): Array<Style> {
        const viewProjection = map.getView().getProjection();      
        const coordsInViewProjection = (<Point>(feature.getGeometry())).getCoordinates();
        const longLat = toLonLat(coordsInViewProjection, viewProjection);
        const latitude_rad = longLat[1] * Math.PI / 180.;
        const circle = new Style({
           image: new CircleStyle({
                stroke: new Stroke({color: '#7c8692'});,
                radius: this._circleRadius_m / (resolution / viewProjection.getMetersPerUnit() * Math.cos(latitude_rad)),
              }),
            });
         
        return [circle];
      }
      

      诀窍是按纬度余弦缩放半径。这将“局部”禁用我们可以在 Tissot 示例中观察到的失真效果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-27
        • 2018-11-29
        • 1970-01-01
        • 2015-10-12
        • 1970-01-01
        • 2017-08-14
        • 1970-01-01
        相关资源
        最近更新 更多