翻转LatLong与LongLat的字符串

时间:2014-06-03 09:50:20

标签: marklogic

以下查询没问题。但在新的情况下,我在变量$ point中得到Lat / Long而不是Long / Lat。有没有办法翻转这个字符串中的两个部分?

let $point  := fn:flip((52.2264, 6.8804) ... $point = (6.8804, 52.2264)

查询

let $polypoints  := $doc/k:coordinates/text()
let $poly        := cts:polygon($polypoints)
let $point       := cts:point(6.8804, 52.2264)

return (cts:polygon-contains($poly,$point, "coordinate-system=wgs84"))

协调数据:

<coordinates>6.8804,52.2264 6.8793,52.2257 6.8791,52.2256 6.879,52.2254 6.8788,52.2247 6.8787,52.2239 6.8786,52.2232 6.8786,52.2224 6.8786,52.2219 6.8786,52.2216 6.8786,52.2214 6.8787,52.2214 6.8803,52.2216 6.887,52.2223 6.8872,52.2223 6.8873,52.2223 6.8882,52.2224 6.8907,52.2226 6.8915,52.2227 6.8927,52.2229 6.8947,52.223 6.8957,52.2231 6.8993,52.2235 6.9003,52.2236 6.9045,52.224 6.9095,52.2245 6.9093,52.2246 6.9094,52.2247 6.9094,52.2248 6.9094,52.2253 6.9095,52.2255 6.9095,52.2263 6.9094,52.2268 6.9093,52.2271 6.9092,52.2274 6.9088,52.2278 6.9086,52.228 6.9083,52.2281 6.9079,52.2282 6.9076,52.2284 6.9073,52.2284 6.906,52.2286 6.905,52.2287 6.9044,52.2288 6.9041,52.2288 6.9039,52.2287 6.9037,52.2287 6.9035,52.2286 6.903,52.2284 6.9022,52.2281 6.9023,52.228 6.9014,52.2278 6.9004,52.2277 6.9003,52.2279 6.8982,52.2276 6.8978,52.2276 6.8963,52.2275 6.8948,52.2278 6.8946,52.2278 6.8924,52.2281 6.892,52.2282 6.8919,52.2282 6.8917,52.2283 6.8911,52.2284 6.8902,52.2285 6.8899,52.2286 6.8883,52.2281 6.8868,52.2276 6.8855,52.2274 6.8838,52.227 6.8829,52.2269 6.8825,52.2269 6.8819,52.2268 6.8815,52.2268 6.8812,52.2267 6.881,52.2266 6.8804,52.2264 </coordinates>

3 个答案:

答案 0 :(得分:2)

首先,您是打算反转坐标文本还是反转您的观点? 如果您试图反转单点的坐标 - 你没有告诉你如何得到cts:点,你的例子显示了一个构造 按数字。在这种情况下,只需反转数字即可

let $point       := cts:point(6.8804, 52.2264)

变为

let $point       := cts:point(52.2264,6.8804)

但是你的第二点意味着该点来自一个字符串某处 ... 你有控制权吗?坐标或点不正确? 或者重要吗?

您的解决方案将起作用,假设您的观点以文字开头并转换文字 在创建cts之前:point() - 这是假设你的观点是错误的。

类似的另一种解决方案可能会或可能不会更有效

let $pointtext := "6.8804, 52.2264"    --- Assuming your point starts as text ...
let $point := cts:point($pointtext) ,
    $point := cts:point(  cts:point-longitude($point) , cts:point-longitude) )

另一种解决方案是将字符串标记为:

let $pointtext := "6.8804,52.2264"      (: Assuming your point comes from text beyond your control :)
let $latlong := fn:tokenize($pointtext,","),
    $point := cts:point($latlong[2]  cast as xs:double ,$latlong[1]  cast as xs:double ) 

现在你原来的问题似乎意味着你得到一个点作为一个序列: 如果你的点已经是2的序列但是反转了,那么一个简单的方法就是反转它们 或者按照相反的顺序使用它们:(不知道你从哪里得到fn:flip()但假设你要求它...它的fn:反向)

所以这回答了你提出的原始问题:

let $pointrev := (52.2264, 6.8804)  , 
$point  := fn:reverse( $pointseq )

但当然,这并没有使cts:point ...所以如果你开始使用序列中的一对数字,你不需要反转它们只需要调用cts:point with reversed args喜欢

let $point := cts:point( $pointrev[2] , $pointrev[1] )

现在,如果您的问题是源数据被反转,那么解决方案类似但反过来 这将翻转多边形的长/纬度坐标(假设为v7 ..否则使用for循环)

let $polypoints := $doc/coordinates/string()  (: USE string() NOT text() !!! trust me :)
let $poly := cts:polygon($polypoints)
let $newpoly := cts:polygon( 
  cts:polygon-vertices( $poly ) ! 
     cts:point( cts:point-longitude(.) , cts:point-latitude(.) ))

总的来说,我建议 1)首先尝试使输入数据正确 2)尽可能避免在XQuery中进行字符串解析,它更快,更精确   让底层代码做到这一点 3)如果你使用wgs84那么重要的是数据是按顺序的,因为   世界不是一个完美的领域,所以你可以通过使用逆转得到不同的结果   某些功能的坐标......(或者可能不取决于你做的......) 4)尽可能少地改变数据。如果你有一张巨大的地图(比如一百万分)    并且仅测试1点,只需更改该点(除非违反#3)    但是,如果您测试很多点或者您的多边形被翻转,则需要更正...    这让我们回到了#1 ......错误数据的来源是什么?    到目前为止,最好的解决方案是修复源..因为否则你    可能发现其他东西也被打破了,你需要在神秘的地方破解数据,

答案 1 :(得分:2)

您还可以使用cts:long-lat-point构造函数:

cts:long-lat-point("12,40") => 40,12

答案 2 :(得分:0)

我现在使用的是:

  let $pa := fn:substring-after(fn:string($point), ",")
  let $pb := fn:substring-before(fn:string($point), ",")
  let $point := fn:concat($pa, ',', $pb)