【问题标题】:GeoServer - DWITHIN not filtering points correctlyGeoServer - DWITHIN 未正确过滤点
【发布时间】:2017-07-26 17:22:09
【问题描述】:

我正在寻找的解决方案是一种将公里转换为 DWITHIN 请求的度数的准确方法,或者让 GeoServer 识别请求中指定的单位以便能够直接以公里为单位传递。

我正在向 GeoServer 发出 WFS 请求以返回一定距离内的点(例如,在点的 3 公里内),但我的结果不准确。我目前正在使用 OpenLayers 版本 3.11.2 并运行 GeoServer 版本 2.6.2,并且还使用 2.7.1 进行了测试。

这是我用于 DWITHIN 的 CQL 过滤器,其中第三个参数是返回结果的半径的度数。我使用“%29”做了一个右括号,因为我在发出请求时遇到了被丢弃的问题。

CQL_FILTER=dwithin(the_geom,point(46.1379%20-60.1957),0.05577532499489729,meters%29

问题是 GeoServer 中存在一个错误,即使我将单位声明为米,它也只支持度数。更多信息请点击此处https://gis.stackexchange.com/questions/132251/dwithin-wfs-filter-is-not-working

我之前尝试过解决这个问题并达到了当时足够准确的规模,可以在这里阅读Geoserver - filtering points using DWITHIN

这些计算是在 JavaScript 中完成的。最初我使用半径/111.325 将公里转换为度数,而这并未返回搜索中的某些点。例如,半径设置为 2.7 公里,有时 2 公里以外的结果不会返回。

我现在更改了计算,使用来自此问题https://gis.stackexchange.com/questions/142326/calculating-longitude-length-in-miles的信息根据纬度调整经度之间的距离

//get value of a degree in radians at current Latitude
var latRadians = lat * Math.PI / 180;

//get the value in kilometers for the current latitude based off radian value 
var degreeKM = latRadians * 111.325

var converteddistance = radius / degreeKM;

然后我在 CQL Fitler 中传递转换后的距离作为返回结果的半径。这个问题是一些结果现在返回半径之外。这个圆是以5km为半径绘制的,你可以看到返回5.79km的结果。

我还将纬度/经度放入此 url 的计算器中,用于圆心和出现在圆心之外的点。计算器给了我相同的距离和图像中使用的测量工具,所以 我相信圆圈和测量工具工作正常。 http://www.movable-type.co.uk/scripts/latlong.html

【问题讨论】:

  • 你在degreeKM = latRadians * 111.325中缺少一个余弦
  • 我应该在哪里使用余弦?
  • 从您发布的链接来看,应该是degreeKM = cos(latRadians) * 111.325 (at lat 0, 1degreee = 111.325km)
  • 这会导致更多结果返回到距离圆心 7 公里以外的圆外。
  • 根据您使用的数据存储,geoserver 有时可以使用提供的单元,我们欢迎拉取请求以添加功能或赞助新功能。

标签: javascript openlayers openlayers-3 geoserver


【解决方案1】:

计算一级长度的方式存在几个问题。

首先,纬度的长度与经度的长度不同。这样做会产生一个椭圆,而不是一个圆。如果你使用最小的长度(经度),你会省略点,如果你使用最长的(纬度),你会得到太多的点。

要获得给定纬度的经度长度,您必须使用余弦并以度为单位进行计算。

degreeKM = cos(latDegree) * 111.325

在 60 度时,大约为 cos(60)*111.325 = 55.66 公里,对应于找到的值 here,几乎是您当前长度的一半。

话虽如此,这整个方法对于诸如基本任务之类的来说是相当麻烦的。您是否可以访问像 PostGIS 这样可以进行过滤的数据库?

【讨论】:

  • 是的,这很痛苦。如果 GeoServer 能够识别单位,则可以避免整个问题。在 javascript Math.cos() 中执行此操作时,接受一个弧度值。如果我这样做 var degreeKM = Math.cos(60 * Math.PI / 180) * 111.325 我会得到 degreeKM 的值 55.6625 所以它似乎计算正确但仍然返回圆外的值。截至目前,GeoServer 正在从形状文件中加载图层数据。试图避免进行重大更改,但如果 DWITHIN 单位问题没有修复,这可能是唯一的方法
【解决方案2】:

在我的回答中,DWITHIN 基本上是坏的。它不能正确地接受单位,也没有为我画出正确的圆圈,即使在赤道附近的小范围内,它也是长方形的,具有正确的投影输入。

我的解决方法/解决方案:使用客户端上的空间库将圆计算为多边形,生成众所周知的文本 (WKT) 并使用 WITHIN 而不是 DWITHIN

在阅读了一些关于 GeoServer 上 DWITHIN 的投诉并且没有看到任何修复它的尝试后,我决定我现在不应该使用它。也许你或我可以贡献一些时间来修复它:)

客户端代码会更复杂,我不会在这里演示,但是 CQL 代码会更简单,没有半径或单位,看起来像这样:

WITHIN(the_geom,POLYGON((<circle-path-here>)))

【讨论】:

    猜你喜欢
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    相关资源
    最近更新 更多