diff --git a/CITATION.cff b/CITATION.cff index f76f7698..df7f23e0 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -8,7 +8,7 @@ message: 'To cite package "nominatimlite" in publications use:' type: software license: MIT title: 'nominatimlite: Interface with ''Nominatim'' API Service' -version: 0.4.0 +version: 0.4.0.9000 doi: 10.32614/CRAN.package.nominatimlite abstract: Lite interface for getting data from 'OSM' service 'Nominatim' . Extract coordinates from addresses, find places near a set of coordinates and return @@ -28,7 +28,7 @@ preferred-citation: orcid: https://orcid.org/0000-0001-8457-4658 doi: 10.32614/CRAN.package.nominatimlite year: '2024' - version: 0.4.0 + version: 0.4.0.9000 url: https://dieghernan.github.io/nominatimlite/ abstract: Lite interface for getting data from OSM service Nominatim . Extract coordinates from addresses, find places near a set of coordinates and diff --git a/DESCRIPTION b/DESCRIPTION index e41a13a7..cd4db62b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: nominatimlite Title: Interface with 'Nominatim' API Service -Version: 0.4.0 +Version: 0.4.0.9000 Authors@R: c( person("Diego", "Hernangómez", , "diego.hernangomezherrero@gmail.com", role = c("aut", "cre", "cph"), comment = c(ORCID = "0000-0001-8457-4658")), diff --git a/NEWS.md b/NEWS.md index 6b41e26e..c5a50516 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ +# nominatimlite (development version) + +- Fix input validation in `geo_address_lookup()` and `geo_address_lookup_sf()` + that crashes the function if the OSM ID is too long (#47 reported by + \@lshydro). + # nominatimlite 0.4.0 - New functions: diff --git a/R/geo_address_lookup.R b/R/geo_address_lookup.R index f2469648..11a5156f 100644 --- a/R/geo_address_lookup.R +++ b/R/geo_address_lookup.R @@ -59,7 +59,8 @@ geo_address_lookup <- function(osm_ids, api <- prepare_api_url(nominatim_server, "lookup?") # Prepare nodes - osm_ids <- as.integer(osm_ids) + osm_ids <- as.numeric(osm_ids) + osm_ids <- floor(abs(osm_ids)) type <- as.character(type) nodes <- paste0(type, osm_ids, collapse = ",") diff --git a/R/geo_address_lookup_sf.R b/R/geo_address_lookup_sf.R index 6dc4ef68..5ca19701 100644 --- a/R/geo_address_lookup_sf.R +++ b/R/geo_address_lookup_sf.R @@ -74,7 +74,8 @@ geo_address_lookup_sf <- function(osm_ids, api <- prepare_api_url(nominatim_server, "lookup?") # Prepare nodes - osm_ids <- as.integer(osm_ids) + osm_ids <- as.numeric(osm_ids) + osm_ids <- floor(abs(osm_ids)) type <- as.character(type) nodes <- paste0(type, osm_ids, collapse = ",") diff --git a/R/geo_lite_sf.R b/R/geo_lite_sf.R index b95bbf0a..ea80586e 100644 --- a/R/geo_lite_sf.R +++ b/R/geo_lite_sf.R @@ -150,7 +150,7 @@ geo_lite_sf <- function(address, getrows <- dplyr::left_join(init_key, template, by = "query") # Select rows - all_res <- all_res[as.integer(getrows$rindex), ] + all_res <- all_res[as.double(getrows$rindex), ] all_res <- sf_to_tbl(all_res) } diff --git a/R/reverse_geo_lite_sf.R b/R/reverse_geo_lite_sf.R index 02387d4f..bd5b85bc 100644 --- a/R/reverse_geo_lite_sf.R +++ b/R/reverse_geo_lite_sf.R @@ -162,7 +162,7 @@ reverse_geo_lite_sf <- function(lat, )) # Select rows - all_res <- all_res[as.integer(getrows$rindex), ] + all_res <- all_res[as.double(getrows$rindex), ] } # Final cleanup diff --git a/README.md b/README.md index c2aca6ec..a7fb0fa5 100644 --- a/README.md +++ b/README.md @@ -217,15 +217,14 @@ A BibTeX entry for LaTeX users is doi = {10.32614/CRAN.package.nominatimlite}, author = {Diego Hernangómez}, year = {2024}, - version = {0.4.0}, + version = {0.4.0.9000}, url = {https://dieghernan.github.io/nominatimlite/}, abstract = {Lite interface for getting data from OSM service Nominatim . Extract coordinates from addresses, find places near a set of coordinates and return spatial objects on sf format.}, } ## References -
+
diff --git a/codemeta.json b/codemeta.json index 2a7d8c7f..73597fac 100644 --- a/codemeta.json +++ b/codemeta.json @@ -8,13 +8,13 @@ "codeRepository": "https://github.com/dieghernan/nominatimlite", "issueTracker": "https://github.com/dieghernan/nominatimlite/issues", "license": "https://spdx.org/licenses/MIT", - "version": "0.4.0", + "version": "0.4.0.9000", "programmingLanguage": { "@type": "ComputerLanguage", "name": "R", "url": "https://r-project.org" }, - "runtimePlatform": "R version 4.4.0 (2024-04-24 ucrt)", + "runtimePlatform": "R version 4.4.1 (2024-06-14)", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", @@ -220,7 +220,7 @@ }, "applicationCategory": "cartography", "keywords": ["r", "geocoding", "openstreetmap", "address", "nominatim", "reverse-geocoding", "rstats", "shapefile", "r-package", "spatial", "cran", "api-wrapper", "api", "gis"], - "fileSize": "250.978KB", + "fileSize": "245.448KB", "citation": [ { "@type": "SoftwareSourceCode", diff --git a/data/osm_amenities.rda b/data/osm_amenities.rda index eaecd91d..eab45025 100644 Binary files a/data/osm_amenities.rda and b/data/osm_amenities.rda differ diff --git a/inst/schemaorg.json b/inst/schemaorg.json index 43d25a59..9f007b8d 100644 --- a/inst/schemaorg.json +++ b/inst/schemaorg.json @@ -47,8 +47,8 @@ "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "runtimePlatform": "R version 4.4.0 (2024-04-24 ucrt)", - "version": "0.4.0" + "runtimePlatform": "R version 4.4.1 (2024-06-14)", + "version": "0.4.0.9000" }, { "id": "https://doi.org/10.32614/CRAN.package.nominatimlite", diff --git a/man/figures/README-line-object-1.png b/man/figures/README-line-object-1.png index eb1860db..a6f7078e 100644 Binary files a/man/figures/README-line-object-1.png and b/man/figures/README-line-object-1.png differ diff --git a/man/figures/README-pizzahut-1.png b/man/figures/README-pizzahut-1.png index 1e87258f..e3e0b6ba 100644 Binary files a/man/figures/README-pizzahut-1.png and b/man/figures/README-pizzahut-1.png differ diff --git a/man/figures/README-statue_liberty-1.png b/man/figures/README-statue_liberty-1.png index 6dc7fe45..be12c007 100644 Binary files a/man/figures/README-statue_liberty-1.png and b/man/figures/README-statue_liberty-1.png differ diff --git a/tests/testthat/test-geo_address_lookup.R b/tests/testthat/test-geo_address_lookup.R index 4f02d342..da2c887a 100644 --- a/tests/testthat/test-geo_address_lookup.R +++ b/tests/testthat/test-geo_address_lookup.R @@ -142,3 +142,33 @@ test_that("Fail", { expect_true(all(is.na(several[, 2:3]))) }) + + +test_that("Integers #47", { + skip_on_cran() + skip_if_api_server() + skip_if_offline() + + + vector_ids <- "9743343761" + + several <- geo_address_lookup(vector_ids) + + # IDs should have the right string + comp <- unique(gsub("[^0-9]", "", several$query)) + + expect_identical(vector_ids, comp) + + + # With decimals + vector_ids2 <- 9743343761.34 + several <- geo_address_lookup(vector_ids2) + + expect_identical(vector_ids, comp) + + # With negatives + vector_ids3 <- -1 * vector_ids2 + several <- geo_address_lookup(vector_ids3) + + expect_identical(vector_ids, comp) +}) diff --git a/tests/testthat/test-geo_address_lookup_sf.R b/tests/testthat/test-geo_address_lookup_sf.R index d952a341..c7b5d372 100644 --- a/tests/testthat/test-geo_address_lookup_sf.R +++ b/tests/testthat/test-geo_address_lookup_sf.R @@ -127,3 +127,33 @@ test_that("Fail", { expect_true(all(sf::st_is_empty(several))) }) + + +test_that("Integers #47", { + skip_on_cran() + skip_if_api_server() + skip_if_offline() + + + vector_ids <- "9743343761" + + several <- geo_address_lookup_sf(vector_ids) + + # IDs should have the right string + comp <- unique(gsub("[^0-9]", "", several$query)) + + expect_identical(vector_ids, comp) + + + # With decimals + vector_ids2 <- 9743343761.34 + several <- geo_address_lookup_sf(vector_ids2) + + expect_identical(vector_ids, comp) + + # With negatives + vector_ids3 <- -1 * vector_ids2 + several <- geo_address_lookup_sf(vector_ids3) + + expect_identical(vector_ids, comp) +}) diff --git a/vignettes/nominatimlite.Rmd b/vignettes/nominatimlite.Rmd index f02e69df..f5574807 100644 --- a/vignettes/nominatimlite.Rmd +++ b/vignettes/nominatimlite.Rmd @@ -1,164 +1,164 @@ ---- -title: "Get started with nominatimlite" -output: rmarkdown::html_vignette -desc: > - Quick examples showing what **nominatimlite** can do for you. -vignette: > - %\VignetteIndexEntry{Get started with nominatimlite} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} -bibliography: references.bib -link-citations: true ---- - - - - - -The goal of **nominatimlite** is to provide a light interface for geocoding -addresses, based on the [Nominatim -API](https://nominatim.org/release-docs/latest/). It also allows to load spatial -objects using the **sf** package. - -Full site with examples and vignettes on - - -## What is Nominatim? - -**Nominatim** is a tool to search -[OpenStreetMap](https://www.openstreetmap.org/) data by name and address -([geocoding](https://wiki.openstreetmap.org/wiki/Geocoding "Geocoding")) and to -generate synthetic addresses of OSM points (reverse geocoding). - -## Why **nominatimlite**? - -The main goal of **nominatimlite** is to access the Nominatim API avoiding the -dependency on **curl**. In some situations, **curl** may not be available or -accessible, so **nominatimlite** uses base functions to overcome this -limitation. - -## Recommended packages - -There are other packages much more complete and mature than **nominatimlite**, -that presents similar features: - -- [**tidygeocoder**](https://jessecambon.github.io/tidygeocoder/) - [@R-tidygeocoder]: Allows to interface with Nominatim, Google, TomTom, - Mapbox, etc. for geocoding and reverse geocoding. -- [**osmdata**](https://docs.ropensci.org/osmdata/) [@R-osmdata]: Great for - downloading spatial data from OpenStreetMap, via the [Overpass - API](https://wiki.openstreetmap.org/wiki/Overpass_API). -- [**arcgeocoder**](https://dieghernan.github.io/arcgeocoder/) - [@R-arcgeocoder]: Lite interface for geocoding with the ArcGIS REST API - Service. - -## Usage - -### `sf` objects - -With **nominatimlite** you can extract spatial objects easily: - - -``` r -library(nominatimlite) - -# Extract some points - Pizza Hut in California - -CA <- geo_lite_sf("California", points_only = FALSE) - -pizzahut <- geo_lite_sf("Pizza Hut, California", - limit = 50, - custom_query = list(countrycodes = "us") -) - -library(ggplot2) - -ggplot(CA) + - geom_sf() + - geom_sf(data = pizzahut, col = "red") -``` - -![Pizza Hut in California](../man/figures/README-pizzahut-1.png){width="100%"} - -You can also extract polygon and line objects (if available) using the option -`points_only = FALSE`: - - -``` r -sol_poly <- geo_lite_sf("Statue of Liberty, NY, USA", points_only = FALSE) - -ggplot(sol_poly) + - geom_sf() -``` - -![The Statue of -Liberty](../man/figures/README-statue_liberty-1.png){width="100%"} - -### Geocoding and reverse geocoding - -*Note: examples adapted from **tidygeocoder** package* - -In this first example we will geocode a few addresses using the `geo_lite()` -function: - - -``` r -library(tibble) - -# create a dataframe with addresses -some_addresses <- tribble( - ~name, ~addr, - "White House", "1600 Pennsylvania Ave NW, Washington, DC", - "Transamerica Pyramid", "600 Montgomery St, San Francisco, CA 94111", - "Willis Tower", "233 S Wacker Dr, Chicago, IL 60606" -) - -# geocode the addresses -lat_longs <- geo_lite(some_addresses$addr, lat = "latitude", long = "longitude") -#> | | | 0% | |================= | 33% | |================================= | 67% | |==================================================| 100% -``` - -Only latitude and longitude are returned from the geocoder service in this -example, but `full_results = TRUE` can be used to return all of the data from -the geocoder service. - - - -|query | latitude| longitude|address | -|:------------------------------------------|--------:|----------:|:-----------------------------------------------------------------------------------------------------------------| -|1600 Pennsylvania Ave NW, Washington, DC | 38.89770| -77.03655|White House, 1600, Pennsylvania Avenue Northwest, Ward 2, Washington, District of Columbia, 20500, United States | -|600 Montgomery St, San Francisco, CA 94111 | 37.79520| -122.40279|Transamerica Pyramid, 600, Montgomery Street, Financial District, San Francisco, California, 94111, United States | -|233 S Wacker Dr, Chicago, IL 60606 | 41.87874| -87.63596|Willis Tower, 233, South Wacker Drive, Printer's Row, Loop, Chicago, Cook County, Illinois, 60606, United States | - - - -To perform reverse geocoding (obtaining addresses from geographic coordinates), -we can use the `reverse_geo_lite()` function. The arguments are similar to the -`geo_lite()` function, but now we specify the input data columns with the `lat` -and `long` arguments. The dataset used here is from the geocoder query above. -The single line address is returned in a column named by the `address`. - - -``` r -reverse <- reverse_geo_lite( - lat = lat_longs$latitude, long = lat_longs$longitude, - address = "address_found" -) -#> | | | 0% | |================= | 33% | |================================= | 67% | |==================================================| 100% -``` - - - -|address_found | lat| lon| -|:-----------------------------------------------------------------------------------------------------------------------------------|--------:|----------:| -|Zastava Sjedinjenih Američkih Država, Pennsylvania Avenue Northwest, Ward 2, Washington, District of Columbia, 20006, United States | 38.89772| -77.03655| -|Transamerica Pyramid, 600, Montgomery Street, Financial District, San Francisco, California, 94111, United States | 37.79520| -122.40279| -|Willis Tower, 233, South Wacker Drive, Printer's Row, Loop, Chicago, Cook County, Illinois, 60606, United States | 41.87874| -87.63596| - - - -For more advance users, see [Nominatim -docs](https://nominatim.org/release-docs/latest/api/Search/) to check the -parameters available. - -## References +--- +title: "Get started with nominatimlite" +output: rmarkdown::html_vignette +desc: > + Quick examples showing what **nominatimlite** can do for you. +vignette: > + %\VignetteIndexEntry{Get started with nominatimlite} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +bibliography: references.bib +link-citations: true +--- + + + + + +The goal of **nominatimlite** is to provide a light interface for geocoding +addresses, based on the [Nominatim +API](https://nominatim.org/release-docs/latest/). It also allows to load spatial +objects using the **sf** package. + +Full site with examples and vignettes on + + +## What is Nominatim? + +**Nominatim** is a tool to search +[OpenStreetMap](https://www.openstreetmap.org/) data by name and address +([geocoding](https://wiki.openstreetmap.org/wiki/Geocoding "Geocoding")) and to +generate synthetic addresses of OSM points (reverse geocoding). + +## Why **nominatimlite**? + +The main goal of **nominatimlite** is to access the Nominatim API avoiding the +dependency on **curl**. In some situations, **curl** may not be available or +accessible, so **nominatimlite** uses base functions to overcome this +limitation. + +## Recommended packages + +There are other packages much more complete and mature than **nominatimlite**, +that presents similar features: + +- [**tidygeocoder**](https://jessecambon.github.io/tidygeocoder/) + [@R-tidygeocoder]: Allows to interface with Nominatim, Google, TomTom, + Mapbox, etc. for geocoding and reverse geocoding. +- [**osmdata**](https://docs.ropensci.org/osmdata/) [@R-osmdata]: Great for + downloading spatial data from OpenStreetMap, via the [Overpass + API](https://wiki.openstreetmap.org/wiki/Overpass_API). +- [**arcgeocoder**](https://dieghernan.github.io/arcgeocoder/) + [@R-arcgeocoder]: Lite interface for geocoding with the ArcGIS REST API + Service. + +## Usage + +### `sf` objects + +With **nominatimlite** you can extract spatial objects easily: + + +``` r +library(nominatimlite) + +# Extract some points - Pizza Hut in California + +CA <- geo_lite_sf("California", points_only = FALSE) + +pizzahut <- geo_lite_sf("Pizza Hut, California", + limit = 50, + custom_query = list(countrycodes = "us") +) + +library(ggplot2) + +ggplot(CA) + + geom_sf() + + geom_sf(data = pizzahut, col = "red") +``` + +![Pizza Hut in California](../man/figures/README-pizzahut-1.png){width="100%"} + +You can also extract polygon and line objects (if available) using the option +`points_only = FALSE`: + + +``` r +sol_poly <- geo_lite_sf("Statue of Liberty, NY, USA", points_only = FALSE) + +ggplot(sol_poly) + + geom_sf() +``` + +![The Statue of +Liberty](../man/figures/README-statue_liberty-1.png){width="100%"} + +### Geocoding and reverse geocoding + +*Note: examples adapted from **tidygeocoder** package* + +In this first example we will geocode a few addresses using the `geo_lite()` +function: + + +``` r +library(tibble) + +# create a dataframe with addresses +some_addresses <- tribble( + ~name, ~addr, + "White House", "1600 Pennsylvania Ave NW, Washington, DC", + "Transamerica Pyramid", "600 Montgomery St, San Francisco, CA 94111", + "Willis Tower", "233 S Wacker Dr, Chicago, IL 60606" +) + +# geocode the addresses +lat_longs <- geo_lite(some_addresses$addr, lat = "latitude", long = "longitude") +#> | | | 0% | |================= | 33% | |================================= | 67% | |==================================================| 100% +``` + +Only latitude and longitude are returned from the geocoder service in this +example, but `full_results = TRUE` can be used to return all of the data from +the geocoder service. + + + +|query | latitude| longitude|address | +|:------------------------------------------|--------:|----------:|:-----------------------------------------------------------------------------------------------------------------| +|1600 Pennsylvania Ave NW, Washington, DC | 38.89770| -77.03655|White House, 1600, Pennsylvania Avenue Northwest, Ward 2, Washington, District of Columbia, 20500, United States | +|600 Montgomery St, San Francisco, CA 94111 | 37.79520| -122.40279|Transamerica Pyramid, 600, Montgomery Street, Financial District, San Francisco, California, 94111, United States | +|233 S Wacker Dr, Chicago, IL 60606 | 41.87874| -87.63596|Willis Tower, 233, South Wacker Drive, Printer's Row, Loop, Chicago, Cook County, Illinois, 60606, United States | + + + +To perform reverse geocoding (obtaining addresses from geographic coordinates), +we can use the `reverse_geo_lite()` function. The arguments are similar to the +`geo_lite()` function, but now we specify the input data columns with the `lat` +and `long` arguments. The dataset used here is from the geocoder query above. +The single line address is returned in a column named by the `address`. + + +``` r +reverse <- reverse_geo_lite( + lat = lat_longs$latitude, long = lat_longs$longitude, + address = "address_found" +) +#> | | | 0% | |================= | 33% | |================================= | 67% | |==================================================| 100% +``` + + + +|address_found | lat| lon| +|:-----------------------------------------------------------------------------------------------------------------------------------|--------:|----------:| +|Zastava Sjedinjenih Američkih Država, Pennsylvania Avenue Northwest, Ward 2, Washington, District of Columbia, 20006, United States | 38.89772| -77.03655| +|Transamerica Pyramid, 600, Montgomery Street, Financial District, San Francisco, California, 94111, United States | 37.79520| -122.40279| +|Willis Tower, 233, South Wacker Drive, Printer's Row, Loop, Chicago, Cook County, Illinois, 60606, United States | 41.87874| -87.63596| + + + +For more advance users, see [Nominatim +docs](https://nominatim.org/release-docs/latest/api/Search/) to check the +parameters available. + +## References