首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Openlayers 3以米为单位的圆半径

Openlayers 3以米为单位的圆半径
EN

Stack Overflow用户
提问于 2015-08-25 19:35:23
回答 2查看 13.9K关注 0票数 5

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

为了得到以米为单位的半径,我跟踪了this。运行示例link

代码语言:javascript
复制
var radiusInMeters = circleRadius * ol.proj.METERS_PER_UNIT['m'];

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

代码语言:javascript
复制
select st_astext(st_buffer('POINT(79.25887485937808 17.036647682474722 0)'::geography, 365.70644956827164));

但两者覆盖的区域并不相同。有谁能告诉我我哪里做错了?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-28 04:46:11

ol.geom.Circle可能不代表圆形

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

这可以通过Tissot的indicatrix可视化,该indicatrix显示了当投影到平面上时,地球上的圆形区域是如何变换的。使用投影EPSG:3857,如下所示:

该图像来自OpenLayer 3's Tissot example,显示半径均为80万米的区域。如果将这些圆绘制为半径为800000的ol.geom.Circle (使用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来完成

代码语言:javascript
复制
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实现这一点

代码语言:javascript
复制
var circularPolygon = ol.geom.Polygon.circular(wgs84Sphere, center, radius, 64);

还有ol.geom.Polygon.fromCircle,它获取ol.geom.Circle并将其转换为表示相同区域的多边形。

票数 20
EN

Stack Overflow用户

发布于 2021-05-18 16:20:40

我的答案是对Alvin的伟大答案的补充。

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

如果这个圆的直径很小(<几公里),你可以忽略地球的粗糙度。然后,您可以在点要素的样式函数中使用标记"Circle“。

下面是我的style函数:

代码语言:javascript
复制
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示例中观察到的失真效果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32202944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档