1

使用 Solr 4.5 和用例是我需要按到给定路线的距离对结果进行排序。使用包含 1 个地理坐标作为 rpt 字段geo(兴趣点的位置)的文档。

这是我的目标的说明:http: //i.imgur.com/lGgMEal.jpg。我想计算从文档到给定路线的最短距离并将其用作提升组件。

当前的尝试是{!score=recipDistance}在模式中使用函数edismax并在 WKT 中将路线描述作为 LineString 发送。这是现在发送的查询:

fl=*,score,distdeg:query({!score=distance filter=false v=$spatialfilter})
defType=edismax
q.alt=*:*
boost=query({!score=distance filter=false v=$spatialfilter})
spatialfilter=geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869))"

并以 URI 形式:

http://sokemotortest:8080/solr/collection1/select?fl=*%2Cscore%2Cdistdeg%3Aquery%28{!score%3Ddistance+filter%3Dfalse+v%3D%24spatialfilter}%29&wt=json&debugQuery=true&defType=edismax&q.alt=*%3A*&boost=query%28{!score=distance%20filter=false%20v=$spatialfilter}%29&spatialfilter=geo:%22Intersects%28LINESTRING%20%2859.79619%2011.38690,%2060.25974%2011.63869%29%29%22

我对这种方法的问题是:

  • 距离似乎是从形状(路线)的中心计算的。这意味着我们获得的距离不是到线路,而是到现场。有了这个查询Pt(x=60.027965,y=11.512795)
  • 距离计算的结果似乎是错误的。索引中有 4 个文档,它们按以下顺序排列:

    • (1) 59.7333、7.61283
    • (2) 59.6236、10.7263
    • (3) 59.6238、10.7385
    • (4) 64.12379、22.14029

    当订单应该是:

    • (3) 59.6238、10.7385
    • (2) 59.6236、10.7263
    • (1) 59.7333、7.61283
    • (4) 64.12379、22.14029

您可以在此处查看带有 boost calc 调试的完整结果:pastebin.com/5tvCb0Cf

另一种可行的解决方案可能是按到路线的距离过滤文档(例如:http: //i.imgur.com/EJu8Kcg.jpg)。这可以通过使用似乎在 jTS 和 spatial4j 中都支持的缓冲线来完成。唯一的问题是我如何发送缓冲行作为Intersect函数的输入(像这样:)geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869) d=1)"

这里的解决方案是创建一个自定义搜索组件,该组件将接受作为 LineString 的路由,并将进一步作为 Polygon 或 MuliPolygon 转发查询,但除非必要,否则我宁愿避免开发自定义组件。

我的问题是:

  • 在 Solr 4.5 中是否有可能获得到 LineString 的距离,而不是到形状的中心?
  • 我们可以发送一个缓冲的行作为Intersect函数的输入吗(像这样:)geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869) d=1)"

PS:索引中的字段说明:

<field name="geo" type="location_rpt" indexed="true" stored="true"/>

字段类型定义:

<fieldType name="location_rpt"
    class="solr.SpatialRecursivePrefixTreeFieldType"
    spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory" 
    geo="true"
    distErrPct="0.025"
    maxDistErr="0.000009"
    units="degrees"
    />
4

1 回答 1

0
  1. 不可能(不自定义 Solr)从每个文档的索引点获取查询 LineString 的距离。您将需要编写一个引用 lineString 的 ValueSourceParser(您可以使用 JTS WKT 解析器对其进行解析)并且还引用您的索引点字段。为了在每个文档的基础上有效地从文档中检索点,请使用 LatLonType,而不是 RPT。JTS 可以计算点和 LineString 之间的距离,但请记住 JTS 在欧几里得空间中运行。为了获得更好的准确性,您需要将数据(索引点和 lineString)“投影”到以 lineString 为中心的投影。Proj4j 可以提供帮助。

  2. RE bufferedLineStrings,您可能有兴趣知道 Spatial4j 的主分支具有“BufferedLineString”形状——它是 Spatial4j 的原生分支。但是,它还没有集成到形状解析中,所以还没有完全准备好。需要明确的是,它经过了很好的测试,我私下将它与非开源的解析器一起使用。它也是欧几里得空间有限的,如 JTS。解决此问题的最佳方法是添加您自己的 Solr 查询解析器(比听起来容易)。这个查询解析器会读取一个缓冲距离,一个 LineString,并从那里使用 JTS 来缓冲它。投影到形状的中心点是不可行的,因为它必须与索引数据对齐,因此您可以通过适当数量的过度缓冲来补偿,从而增加形状大小,但至少确保捕获最小距离。我有计划更好地解决这个问题,但我一直很忙。

于 2013-10-21T19:51:50.207 回答