【问题标题】:Cannot get circle radius correct in OpenLayers在 OpenLayers 中无法正确获取圆半径
【发布时间】:2020-03-31 11:36:56
【问题描述】:

我在下面有一个 jsfiddle,我尝试在其中创建一个半径为 1600 米的圆圈。我不认为我的投影正确,因为这个圆肯定小于1600米。在谷歌地图上测量,我认为它大约是 1000 米。请问我该怎么做才能纠正这个问题>

谢谢。

var centerLongitudeLatitude = ol.proj.fromLonLat([-1.733014, 51.982989]);
var layer = new ol.layer.Vector({
  source: new ol.source.Vector({
    projection: 'EPSG:4326',
    features: [new ol.Feature(new ol.geom.Circle(centerLongitudeLatitude, 1600))]
  }),
  style: [
    new ol.style.Style({
      stroke: new ol.style.Stroke({
        color: 'blue',
        width: 3
      }),
      fill: new ol.style.Fill({
        color: 'rgba(0, 0, 255, 0.1)'
      })
    })
  ]
});


var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    layer
  ],
  view: new ol.View({
    center: ol.proj.fromLonLat([-1.733014, 51.982989]),
    zoom: 14
  })
});
html,
body {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
}

.map {
  height: 100%;
  width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map" class="map"></div>

【问题讨论】:

    标签: openlayers openlayers-6


    【解决方案1】:

    感谢 Mike 和 cabesuon,我有一个解决方案,在这里发布给未来的读者。

    var map = new ol.Map({
      target: 'map',
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        })
      ],
      view: new ol.View({
        center: ol.proj.fromLonLat([-1.733014, 51.982989]),
        zoom: 14
      })
    });
    
    var centerLongitudeLatitude = ol.proj.fromLonLat([-1.733014, 51.982989]);
    var viewProjection = map.getView().getProjection();
    var pointResolution = ol.proj.getPointResolution(viewProjection , 1, centerLongitudeLatitude );
    var radius = 1600 / pointResolution;
    var layer = new ol.layer.Vector({
      source: new ol.source.Vector({
        projection: 'EPSG:4326',
        features: [new ol.Feature(new ol.geom.Circle(centerLongitudeLatitude, radius))]
      }),
      style: [
        new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: 'blue',
            width: 3
          }),
          fill: new ol.style.Fill({
            color: 'rgba(0, 0, 255, 0.1)'
          })
        })
      ]
    });
    
    map.addLayer(layer);
    html,
    body {
      height: 100%;
      width: 100%;
      padding: 0px;
      margin: 0px;
    }
    
    .map {
      height: 100%;
      width: 100%;
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/css/ol.css">
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/build/ol.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="map" class="map"></div>

    【讨论】:

      【解决方案2】:

      矢量图层的 SRS (EPSG:4326) 与圆的中心和圆 (EPSG:3857) 之间存在不一致。您需要以上其中一项,而不是两者兼而有之。

      尝试在不指定projection 的情况下创建图层,它将使用默认视图投影,在本例中为EPSG:3857(因为OSM)。

      更新:

      在构建下面的sn-p之后,我意识到建议的更改不影响结果,不知道刚才为什么,所以我建议使用Polygon.circular作为替代。

      <!doctype html>
      <html lang="en">
        <head>
          <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
          <style>
            .map {
              height: 400px;
              width: 100%;
            }
          </style>
          <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
          <title>Circle features</title>
        </head>
        <body>
          <div id="map" class="map"></div>
      		<script type="text/javascript">
      		// features
          var radius = 1600;
          var center = [-1.733014, 51.982989]
          var fcircle = new ol.Feature({
            geometry: new ol.geom.Circle(
              ol.proj.fromLonLat(center),
              radius
            )
          });
          fcircle.setStyle(new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'blue',
              width: 2
            })
          }));
          var fcircular = new ol.Feature({
            geometry: ol.geom.Polygon.circular(center, radius, 64).transform('EPSG:4326', 'EPSG:3857')
          });
          fcircular.setStyle(new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'red',
              width: 1
            })
          }));
          // map
          var view = new ol.View({
            center: ol.proj.fromLonLat(center),
            zoom: 14
          });
          var map = new ol.Map({
      			target: 'map',
      			layers: [
      				new ol.layer.Tile({
      					source: new ol.source.OSM()
      				}),
              new ol.layer.Vector({
                source: new ol.source.Vector({
                  features: [fcircle, fcircular]
                })
              })
      			],
      			view
      		});
          </script>
        </body>
      </html>

      【讨论】:

      • 非常感谢卡贝索恩。不幸的是,我正处于破解 openlayers 的阶段,并且对 js 知之甚少。您是否有足够的时间发布 sn-p 来展示解决方案?非常感谢,如果没有完全理解。
      • 我已经更新了答案..我很确定在 SO 中看到了一些关于此的内容,但我现在找不到..作为替代方案,您可以使用 Polygon.circular ..我会尝试再看看这个,或者其他人解释背后的原因
      • 谢谢,我现在已经破解了一个临时解决方法 - 在我在英国的纬度上,我可以将 1.62 的恒定乘法因子应用于半径,使其足够接近我的目的。显然,我想以正确的方式做到这一点!我对使用多边形有点犹豫,因为我知道我的一些客户会注意到缺乏平滑曲线并且会不喜欢它(就像我一样)。这是我需要避免的。谢谢!
      • 虽然公平地说,您的多边形实际上看起来很漂亮,当我将分段数增加到 256 时,它与圆形无法区分。所以在这一点上,如果有可能摆脱多边形,那将是一个很好的干净解决方案,否则效果很好。非常感谢。
      • ol.geom.Polygon.circular 仅适用于在投影中看起来不是圆形的大半径圆。对于小半径圆,只需将半径除以圆心的点分辨率ol.proj.getPointResolution(viewProjection, 1, center)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多