geo:distance() return units

Tuesday, 26 February 2019 · 4 messages
JB
Jacob Borisov26 Feb 2019 12:12 #
Hello. Could anybody explain how to get a result from geo:distance() in kilometers or miles? Thanks.
MS
Michael Seiferle26 Feb 2019 12:33 #
Hi Jacob, I’ve never really used the geo:module but according to the documentation:
Quoted text · Jacob Borisov · 1 line
> 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:
Quoted text · Jacob Borisov · 5 lines
> 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
Quoted text · Jacob Borisov · 4 lines
> Am 26.02.2019 um 12:12 schrieb Jacob Borisov <jacobborisov at gmail.com>: > > Hello. Could anybody explain how to get a result from geo:distance() > in kilometers or miles? Thanks.
JB
Jacob Borisov26 Feb 2019 13:19 #
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 <ms at basex.org>:
Quoted text · Michael Seiferle · 30 lines
> > 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 <jacobborisov at gmail.com>: > > > > Hello. Could anybody explain how to get a result from geo:distance() > > in kilometers or miles? Thanks. >
MS
Michael Seiferle26 Feb 2019 14:40 #
Hi Jacob, well — the geo distance computes the distance of the direct line between the two coordinates:
Quoted text · Jacob Borisov · 1 line
> <gml:coordinates>52.519881,13.407338</gml:coordinates>
and
Quoted text · Jacob Borisov · 1 line
> <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.
Quoted text · Jacob Borisov · 47 lines
> 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
Quoted text · Jacob Borisov · 55 lines
> Am 26.02.2019 um 13:19 schrieb Jacob Borisov <jacobborisov at 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 <ms at 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 <jacobborisov at gmail.com>: >>> >>> Hello. Could anybody explain how to get a result from geo:distance() >>> in kilometers or miles? Thanks. >>

⚡Generated with XQuery