Hi Jacob, 

well — the geo distance computes the distance of the direct line between the 
two coordinates:
>        <gml:coordinates>52.519881,13.407338</gml:coordinates>
and
>    <gml:coordinates>51.507351,-0.12766</gml:coordinates>

Which happens to be 13.572817977888896  <=> 
https://en.wikipedia.org/wiki/Euclidean_distance

Yet, the earth is spherical, so you need to take that into account, 
https://en.wikipedia.org/wiki/Geographical_distance 
<https://en.wikipedia.org/wiki/Geographical_distance>

I think what you are actually looking for is the great-circle distance — the 
length of a line traveling along the surface between two points on a circle.

A somehow good approximation for that distance can be computed using the 
haversine formula:
http://www.movable-type.co.uk/scripts/latlong.html 
<http://www.movable-type.co.uk/scripts/latlong.html>

I rewrote the Javascript as XQuery and the result seems to be about right.

> import module namespace geo = "http://expath.org/ns/geo";;
> declare namespace gml='http://www.opengis.net/gml';
> 
> 
> (: formula taken from here: 
>   https://www.movable-type.co.uk/scripts/latlong.html
> :) 
> declare function local:haversine(
>   $point1 as element(gml:Point),
>   $point2 as element(gml:Point)
> ) as xs:double {
>   let $r    := 6371  (: earth radius in KM :)
>   let $lat1 := geo:x($point1)
>   let $lat2 := geo:x($point2)
>   let $lon1 := geo:y($point1)
>   let $lon2 := geo:y($point2)
>   let $φ1   := $lat1 => local:radians()
>   let $φ2   := $lat2 => local:radians()
>   let $Δφ   := ($lat2 - $lat1) => local:radians()
>   let $Δλ   := ($lon2 - $lon1) => local:radians()
> 
>   let $a    := math:pow(math:sin($Δφ div 2), 2) +
>                math:cos($φ1) * math:cos($φ2) *
>                math:pow(math:sin($Δλ div 2), 2)
>   let $c   := 2 * math:asin(math:sqrt($a))
>   
>   return $c * $r
> };
> 
> 
> declare function local:radians(
>   $deg as xs:double
> ) as xs:double {
>   $deg * (math:pi() div 180)
> };
> 
> 
> let $berlin :=
>  <gml:Point>
>        <gml:coordinates>52.519881,13.407338</gml:coordinates>
>  </gml:Point>
> let $london :=
>  <gml:Point>
>    <gml:coordinates>51.507351,-0.12766</gml:coordinates>
>  </gml:Point>
> return local:haversine($berlin, $london)
> (: returns 931.7188794140812 :)



Maybe you should make yourself comfortable with the maths behind that formula 
to better understand its shortcomings, nevertheless, here’s what I came up with 
in a more readable version:

https://gist.github.com/micheee/e47166d0947f925e395504c1e220fbea 
<https://gist.github.com/micheee/e47166d0947f925e395504c1e220fbea>

Best
Michael






> Am 26.02.2019 um 13:19 schrieb Jacob Borisov <jacobbori...@gmail.com>:
> 
> Hi! For example, it's need to get the distance between Berlin and
> London, which is 934 km.
> 
> So I've put the coordinates as they can be found in Google Maps, etc.:
> 
> let $berlin :=
>  <gml:Point>
>        <gml:coordinates>52.519881,13.407338</gml:coordinates>
>  </gml:Point>
> let $london :=
>  <gml:Point>
>    <gml:coordinates>51.507351,-0.12766</gml:coordinates>
>  </gml:Point>
> return geo:distance($berlin, $london)
> 
> And the result is 13.572817977888896
> 
> Also I had trying to change srsName attribute of gml:Point's to
> different values like "3857", "EPSG:3857" (it's uses meter units as
> mentioned here https://epsg.io/3857), but practically this changes
> nothing. Thanks.
> 
> вт, 26 февр. 2019 г. в 19:33, Michael Seiferle <m...@basex.org>:
>> 
>> Hi Jacob,
>> 
>> I’ve never really used the geo:module but according to the documentation:
>>> in the units of the spatial reference system of geometry1
>> If I understand it correctly, you would have to convert your coordinates to 
>> map them to miles or kilometers for example.
>> 
>> Maybe you can provide an example?
>> 
>> Given this very simple query:
>>> import module namespace geo = "http://expath.org/ns/geo";;
>>> declare namespace gml='http://www.opengis.net/gml';
>>> let $point1 :=<gml:Point><gml:coordinates>1,1</gml:coordinates></gml:Point>
>>> let $point2 := <gml:Point><gml:coordinates>2,2</gml:coordinates></gml:Point>
>>> return geo:distance($point1, $point2)
>> 
>> The result is math:sqrt(2),  the length of a straight line from P(1,1) — 
>> P’(2,2) but this length does not contain any unit of measurement.
>> 
>> 
>> 
>> Best
>> Michael
>> 
>> 
>> 
>>> Am 26.02.2019 um 12:12 schrieb Jacob Borisov <jacobbori...@gmail.com>:
>>> 
>>> Hello. Could anybody explain how to get a result from geo:distance()
>>> in kilometers or miles? Thanks.
>> 

Reply via email to