【问题标题】:How to retrieve latitude and longitude from geosparql's wktLiteral?如何从 geosparql 的 wktLiteral 中检索经纬度?
【发布时间】:2015-04-24 00:02:36
【问题描述】:

我正在处理包含地理参考资料的 RDF 数据,例如具有指定位置的 POI:

@prefix ogc:   <http://www.opengis.net/ont/geosparql#> .

:poi  ogc:hasGeometry  :geo
:geo  ogc:asWKT        "POINT(48.5 11.7)"^^ogc:wktLiteral .

所以有某种 POI 位于 (48.5, 11.7)。 我可以使用GeoSPARQL-queries 来处理这些位置,但现在我想分别提取纬度和经度,这样我就可以将其输入到不支持WKT 的不同应用程序中。

SELECT ?lat ?lon
WHERE {
    # how do I get lat and lon from "POINT(48.5 11.7)"^^ogc:wktLiteral?
}

我在OGC's GeoSPARQL specification 中没有发现任何有用的信息,所以我想知道在 SPARQL 查询中手动提取此类数据的最佳方法是什么。

【问题讨论】:

    标签: rdf geospatial sparql


    【解决方案1】:

    用正则表达式做这类事情总是有点棘手,尤其是当我们看起来没有精确的语法可以使用时,但我认为以下方法可行:

    prefix ogc: <urn:ex:>
    
    select ?lat ?long where {
      values ?point { "POINT(48.5 11.7)"^^ogc:wktLiteral }
      bind( replace( str(?point), "^[^0-9\\.]*([0-9\\.]+) .*$", "$1" ) as ?long )
      bind( replace( str(?point), "^.* ([0-9\\.]+)[^0-9\\.]*$", "$1" ) as ?lat )
    }
    
    -------------------
    | lat    | long   |
    ===================
    | "11.7" | "48.5" |
    -------------------
    

    这里的关键在于正则表达式

    "^[^0-9\\.]*([0-9\\.]+) .*$" === <non-number>(number) <anything>
    "^.* ([0-9\\.]+)[^0-9\\.]*$" === <anything> (number)<non-number>
    

    当然,这实际上是number 的近似值,因为它会匹配具有多个点的事物,但如果数据良好,您应该没有问题。如果您需要将这些值转换为数字类型,您也可以进行这种类型的转换:

    prefix ogc: <urn:ex:>
    prefix xsd: <http://www.w3.org/2001/XMLSchema#>
    
    select ?lat ?long where {
      values ?point { "POINT(48.5 11.7)"^^ogc:wktLiteral }
      bind( xsd:decimal( replace( str(?point), "^[^0-9\\.]*([0-9\\.]+) .*$", "$1" )) as ?long )
      bind( xsd:decimal( replace( str(?point), "^.* ([0-9\\.]+)[^0-9\\.]*$", "$1" )) as ?lat )
    }
    
    ---------------
    | lat  | long |
    ===============
    | 11.7 | 48.5 |  # note: no quotation marks; these are numbers
    ---------------
    

    请注意,还有其他类型的 WKT 点,此代码无法正确处理它们。例如,来自 Wikipedia 的 Well-known text 文章的一些示例:

    POINT ZM (1 1 5 60)
    POINT M (1 1 80)
    POINT EMPTY
    

    【讨论】:

    • POINT 的 WKT 定义是 POINT(XY),因此,POINT(LNG LAT)。你的经纬度在这里颠倒了。
    • @lreeder 好的,这很容易解决。但是,那个逗号是怎么回事? Wikipedia 的示例使用 POINT (30 10),没有逗号,与 OP 相同。
    • 对不起,习惯。我在评论中删除了 X,Y 之间的逗号。
    • @lreeder 好的,我会解决纬度/经度问题。好收获
    • 感谢您的回答!我一直在用正则表达式匹配和替换自己的东西,但是您的代码更短(并且可能更有效)。
    【解决方案2】:

    Joshua 的回复没有考虑纬度或经度的负值。对此的更正是:

    prefix ogc: <urn:ex:>
    select ?lat ?long where {
       values ?point { "POINT(48.5 -11.7)"^^ogc:wktLiteral }
       bind( replace( str(?point), "^[^0-9\\.-]*([-]?[0-9\\.]+) .*$", "$1" ) as ?long )
       bind( replace( str(?point), "^.* ([-]?[0-9\\.]+)[^0-9\\.]*$", "$1" ) as ?lat )
    }
    

    结果

    --------------------
    | lat     | long   |
    ===================
    | "-11.7" | "48.5" |
    --------------------
    

    我已经用 Rubular 测试了正则表达式,用议会 SPARQL 端点测试了 GeoSPARQL 查询,看起来还可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 2016-12-10
      相关资源
      最近更新 更多