Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Ultra lightweight, ultra fast calculation of geo distances

License

NotificationsYou must be signed in to change notification settings

hypertidy/geodist

Repository files navigation

R build statuspkgcheckProject Status: Active – The project has reached a stable, usable state and is being actively developed.codecovCRAN_Status_Badgedownloads

geodist

An ultra-lightweight, zero-dependency package for very fast calculationof geodesic distances. Main eponymous function,geodist(), acceptsonly one or two primary arguments, which must be rectangular objectswith unambiguously labelled longitude and latitude columns (that is,some variant oflon/lat, orx/y).

n<-50x<- cbind (-10+20* runif (n),-10+20* runif (n))y<- cbind (-10+20* runif (2*n),-10+20* runif (2*n))colnames (x)<- colnames (y)<- c ("x","y")d0<- geodist (x)# A 50-by-50 matrixd1<- geodist (x,y)# A 50-by-100 matrixd2<- geodist (x,sequential=TRUE)# Vector of length 49d2<- geodist (x,sequential=TRUE,pad=TRUE)# Vector of length 50

Installation

You can install latest stable version ofgeodist from CRAN with:

install.packages("geodist")# current CRAN version

Alternatively, current development versions can be installed using anyof the following options:

# install.packages("remotes")remotes::install_git("https://git.sr.ht/~mpadge/geodist")remotes::install_git("https://codeberg.org/hypertidy/geodist")remotes::install_bitbucket("hypertidy/geodist")remotes::install_gitlab("hypertidy/geodist")remotes::install_github("hypertidy/geodist")

Then load with

library (geodist)packageVersion ("geodist")#> [1] '0.0.7.30'

Detailed Usage

Input(s) to thegeodist() function can be in arbitrary rectangularformat.

n<-1e1x<-tibble::tibble (x=-180+360* runif (n),y=-90+180* runif (n))dim (geodist (x))#> Maximum distance is > 100km. The 'cheap' measure is inaccurate over such#> large distances, you'd likely be better using a different 'measure'.#> [1] 10 10y<-tibble::tibble (x=-180+360* runif (2*n),y=-90+180* runif (2*n))dim (geodist (x,y))#> Maximum distance is > 100km. The 'cheap' measure is inaccurate over such#> large distances, you'd likely be better using a different 'measure'.#> [1] 10 20x<- cbind (-180+360* runif (n),-90+100* runif (n),             seq (n), runif (n))colnames (x)<- c ("lon","lat","a","b")dim (geodist (x))#> Maximum distance is > 100km. The 'cheap' measure is inaccurate over such#> large distances, you'd likely be better using a different 'measure'.#> [1] 10 10

All outputs are distances in metres, calculated with a variety ofspherical and elliptical distance measures. Distance measures currentlyimplemented are Haversine, Vincenty (spherical and elliptical)), thevery fastmapbox cheapruler(see theirblogpost),and the “reference” implementation ofKarney(2013),as implemented in the packagesf. (Note thatgeodist doesnot acceptsf-format objects;thesf package itself shouldbe used for that.) Themapbox cheap ruleralgorithm is intended toprovide approximate yet very fast distance calculations within smallareas (tens to a few hundred kilometres across).

Benchmarks of geodesic accuracy

Thegeodist_benchmark() function - the only other function provided bythegeodist package - compares the accuracy of the different metricsto the nanometre-accuracy standard ofKarney(2013).

geodist_benchmark (lat=30,d=1000)#>            haversine    vincenty       cheap#> absolute 0.748852400 0.748852400 0.576849087#> relative 0.002042704 0.002042704 0.001598258

All distances (d) are in metres, and all measures are accurate towithin 1m over distances out to several km (at the chosen latitude of 30degrees). The following plots compare the absolute and relativeaccuracies of the different distance measures implemented here. Themapbox cheap ruler algorithm is the most accurate for distances out toaround 100km, beyond which it becomes extremely inaccurate. Averagerelative errors of Vincenty distances remain generally constant ataround 0.2%, while relative errors of cheap-ruler distances out to 100kmare around 0.16%.

Performance comparison

The following code demonstrates the relative speed advantages of thedifferent distance measures implemented in thegeodist package.

n<-1e3dx<-dy<-0.01x<- cbind (-100+dx* runif (n),20+dy* runif (n))y<- cbind (-100+dx* runif (2*n),20+dy* runif (2*n))colnames (x)<- colnames (y)<- c ("x","y")rbenchmark::benchmark (replications=10,order="test",d1<- geodist (x,measure="cheap"),d2<- geodist (x,measure="haversine"),d3<- geodist (x,measure="vincenty"),d4<- geodist (x,measure="geodesic")) [,1:4]#>                                      test replications elapsed relative#> 1     d1 <- geodist(x, measure = "cheap")           10   0.068    1.000#> 2 d2 <- geodist(x, measure = "haversine")           10   0.137    2.015#> 3  d3 <- geodist(x, measure = "vincenty")           10   0.223    3.279#> 4  d4 <- geodist(x, measure = "geodesic")           10   3.038   44.676

Geodesic distance calculation is available in thesfpackage. Comparing computationspeeds requires conversion of sets of numeric lon-lat points tosfform with the following code:

require (magrittr)x_to_sf<-function (x){    sapply (seq (nrow (x)),function (i)sf::st_point (x [i, ]) %>%sf::st_sfc ()) %>%sf::st_sfc (crs=4326)}
n<-1e2x<- cbind (-180+360* runif (n),-90+180* runif (n))colnames (x)<- c ("x","y")xsf<- x_to_sf (x)sf_dist<-function (xsf)sf::st_distance (xsf,xsf)geo_dist<-function (x) geodist (x,measure="geodesic")rbenchmark::benchmark (replications=10,order="test",                      sf_dist (xsf),                      geo_dist (x)) [,1:4]#>           test replications elapsed relative#> 2  geo_dist(x)           10   0.061    1.000#> 1 sf_dist(xsf)           10   0.146    2.393

Confirm that the two give almost identical results:

ds<-matrix (as.numeric (sf_dist (xsf)),nrow= length (xsf))dg<- geodist (x,measure="geodesic")formatC (max (abs (ds-dg)),format="e")#> [1] "3.7708e+04"

All results are in metres, so the two differ by only around 10nanometres.

Thegeosphere packagealso offers sequential calculation which is benchmarked with thefollowing code:

fgeodist<-function () geodist (x,measure="vincenty",sequential=TRUE)fgeosph<-function ()geosphere::distVincentySphere (x)rbenchmark::benchmark (replications=10,order="test",                       fgeodist (),                       fgeosph ()) [,1:4]#>         test replications elapsed relative#> 1 fgeodist()           10   0.016     1.00#> 2  fgeosph()           10   0.036     2.25

geodist is thus around 3 times faster thansf for highly accurategeodesic distance calculations, and around twice as fast asgeospherefor calculation of sequential distances.

Test Results

require (devtools)require (testthat)
date()#> [1] "Wed Oct 19 12:10:55 2022"devtools::test("tests/")#> ℹ Testing geodist#> ══ Results ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════#> Duration: 1.3 s#>#> [ FAIL 0 | WARN 0 | SKIP 0 | PASS 125 ]

Contributors

All contributions to this project are gratefully acknowledged using theallcontributorspackage following theall-contributors specification.Contributions of any kind are welcome!

Code


mpadge

daniellemccool

Issues


mdsumner

edzer

njtierney

mkuehn10

asardaes

marcosci

mem48

dcooley

Robinlovelace

espinielli

Maschette

About

Ultra lightweight, ultra fast calculation of geo distances

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors6


[8]ページ先頭

©2009-2025 Movatter.jp