Recology

R/etc.

 

openadds - open addresses client

openadds talks to Openaddresses.io. a run down of its things:

Install

devtools::install_github("sckott/openadds")
library("openadds")

List datasets

Scrapes links to datasets from the openaddresses site

dat <- oa_list()
dat[2:6]
#> [1] "http://data.openaddresses.io.s3.amazonaws.com/20150511/au-tas-launceston.csv"   
#> [2] "http://s3.amazonaws.com/data.openaddresses.io/20141127/au-victoria.zip"         
#> [3] "http://data.openaddresses.io.s3.amazonaws.com/20150511/be-flanders.zip"         
#> [4] "http://data.openaddresses.io.s3.amazonaws.com/20150417/ca-ab-calgary.zip"       
#> [5] "http://data.openaddresses.io.s3.amazonaws.com/20150511/ca-ab-grande_prairie.zip"

Search for datasets

Uses oa_list() internally, then searches through columns requested.

oa_search(country = "us", state = "ca")
#> Source: local data frame [68 x 5]
#> 
#>    country state             city  ext
#> 1       us    ca san_mateo_county .zip
#> 2       us    ca   alameda_county .zip
#> 3       us    ca   alameda_county .zip
#> 4       us    ca           amador .zip
#> 5       us    ca           amador .zip
#> 6       us    ca      bakersfield .zip
#> 7       us    ca      bakersfield .zip
#> 8       us    ca         berkeley .zip
#> 9       us    ca         berkeley .zip
#> 10      us    ca     butte_county .zip
#> ..     ...   ...              ...  ...
#> Variables not shown: url (chr)

Get data

Passing in a URL

(out1 <- oa_get(dat[5]))
#> <Openaddresses data> ~/.openadds/ca-ab-calgary.zip
#> Dimensions [350962, 13]
#> 
#>    OBJECTID ADDRESS_TY                 ADDRESS    STREET_NAM STREET_TYP
#> 0    757023     Parcel  249 SAGE MEADOWS CI NW  SAGE MEADOWS         CI
#> 1    757022     Parcel           2506 17 ST SE            17         ST
#> 2    757021     Parcel     305 EVANSPARK GD NW     EVANSPARK         GD
#> 3    757020     Parcel     321 EVANSPARK GD NW     EVANSPARK         GD
#> 4    757019     Parcel   204 EVANSBROOKE LD NW   EVANSBROOKE         LD
#> 5    757018     Parcel   200 EVANSBROOKE LD NW   EVANSBROOKE         LD
#> 6    757017     Parcel 219 HIDDEN VALLEY LD NW HIDDEN VALLEY         LD
#> 7    757016     Parcel 211 HIDDEN VALLEY LD NW HIDDEN VALLEY         LD
#> 8    757015     Parcel 364 HIDDEN VALLEY LD NW HIDDEN VALLEY         LD
#> 9    757014     Parcel 348 HIDDEN VALLEY LD NW HIDDEN VALLEY         LD
#> ..      ...        ...                     ...           ...        ...
#> Variables not shown: STREET_QUA (fctr), HOUSE_NUMB (int), HOUSE_ALPH
#>      (fctr), SUITE_NUMB (int), SUITE_ALPH (fctr), LONGITUDE (dbl),
#>      LATITUDE (dbl), COMM_NAME (fctr)

First getting URL for dataset through as_openadd(), then passing to oa_get()

(x <- as_openadd("us", "nm", "hidalgo"))
#> <<OpenAddreses>> 
#>   <<country>> us
#>   <<state>> nm
#>   <<city>> hidalgo
#>   <<extension>> .csv
oa_get(x)
#> <Openaddresses data> ~/.openadds/us-nm-hidalgo.csv
#> Dimensions [170659, 37]
#> 
#>    OBJECTID Shape ADD_NUM ADD_SUF PRE_MOD PRE_DIR PRE_TYPE         ST_NAME
#> 1         1    NA     422                       S                      2ND
#> 2         2    NA    1413                       S                      4TH
#> 3         3    NA     412                       E                 CHAMPION
#> 4         4    NA     110                       E                   SAMANO
#> 5         5    NA    2608                       W          FREDDY GONZALEZ
#> 6         6    NA    2604                       W          FREDDY GONZALEZ
#> 7         7    NA    1123                       W                      FAY
#> 8         8    NA     417                       S                      2ND
#> 9         9    NA    4551                       E                    TEXAS
#> 10       10    NA     810                                        DRIFTWOOD
#> ..      ...   ...     ...     ...     ...     ...      ...             ...
#> Variables not shown: ST_TYPE (chr), POS_DIR (chr), POS_MOD (chr), ESN
#>      (int), MSAG_COMM (chr), PARCEL_ID (chr), PLACE_TYPE (chr), LANDMARK
#>      (chr), BUILDING (chr), UNIT (chr), ROOM (chr), FLOOR (int), LOC_NOTES
#>      (chr), ST_ALIAS (chr), FULL_ADDR (chr), ZIP (chr), POSTAL_COM (chr),
#>      MUNICIPAL (chr), COUNTY (chr), STATE (chr), SOURCE (chr), REGION
#>      (chr), EXCH (chr), LAT (dbl), LONG (dbl), PICTURE (chr), OA:x (dbl),
#>      OA:y (dbl), OA:geom (chr)

Combine multiple datasets

combine attemps to guess lat/long and address columns, but definitely more work to do to make this work for most cases. Lat/long and address columns vary among every dataset - some datasets have no lat/long data, some have no address data.

out2 <- oa_get(dat[32])
(alldat <- oa_combine(out1, out2))
#> Source: local data frame [418,623 x 4]
#> 
#>          lon      lat                 address           dataset
#> 1  -114.1303 51.17188  249 SAGE MEADOWS CI NW ca-ab-calgary.zip
#> 2  -114.0190 51.03168           2506 17 ST SE ca-ab-calgary.zip
#> 3  -114.1175 51.17497     305 EVANSPARK GD NW ca-ab-calgary.zip
#> 4  -114.1175 51.17461     321 EVANSPARK GD NW ca-ab-calgary.zip
#> 5  -114.1212 51.16268   204 EVANSBROOKE LD NW ca-ab-calgary.zip
#> 6  -114.1213 51.16264   200 EVANSBROOKE LD NW ca-ab-calgary.zip
#> 7  -114.1107 51.14784 219 HIDDEN VALLEY LD NW ca-ab-calgary.zip
#> 8  -114.1108 51.14768 211 HIDDEN VALLEY LD NW ca-ab-calgary.zip
#> 9  -114.1121 51.14780 364 HIDDEN VALLEY LD NW ca-ab-calgary.zip
#> 10 -114.1117 51.14800 348 HIDDEN VALLEY LD NW ca-ab-calgary.zip
#> ..       ...      ...                     ...               ...

Map data

Get some data

(out <- oa_get(dat[400]))
#> <Openaddresses data> ~/.openadds/us-ca-sonoma_county.zip
#> Dimensions [217243, 5]
#> 
#>          LON      LAT  NUMBER          STREET POSTCODE
#> 1  -122.5327 38.29779 3771  A       Cory Lane       NA
#> 2  -122.5422 38.30354   18752 White Oak Drive       NA
#> 3  -122.5412 38.30327   18749 White Oak Drive       NA
#> 4  -122.3997 38.26122    3552       Napa Road       NA
#> 5  -122.5425 38.30404    3998 White Oak Court       NA
#> 6  -122.5429 38.30434    4026 White Oak Court       NA
#> 7  -122.5430 38.30505    4039 White Oak Court       NA
#> 8  -122.5417 38.30504    4017 White Oak Court       NA
#> 9  -122.5409 38.30436   18702 White Oak Drive       NA
#> 10 -122.5403 38.30392   18684 White Oak Drive       NA
#> ..       ...      ...     ...             ...      ...

Make an interactive map (not all data)

library("leaflet")

x <- oa_get(oa_search(country = "us", city = "boulder")[1,]$url)
y <- oa_get(oa_search(country = "us", city = "gunnison")[1,]$url)
oa_combine(x, y) %>% 
  leaflet() %>%
  addTiles() %>%
  addCircles(lat = ~lat, lng = ~lon, popup = ~address)

image

To do

  • Surely there are many datasets that won't work in oa_combine() - gotta go through many more.
  • An easy viz function wrapping leaflet
  • Since you can get a lot of spatial data quickly, easy way to visualize big data, maybe marker clusters?

lawn - a new package to do geospatial analysis

lawn is an R wrapper for the Javascript library turf.js for advanced geospatial analysis. In addition, we have a few functions to interface with the geojson-random Javascript library.

lawn includes traditional spatial operations, helper functions for creating GeoJSON data, and data classification and statistics tools.

There is an additional helper function (see view()) in this package to help visualize data with interactive maps via the leaflet package (https://github.com/rstudio/leaflet). Note that leaflet is not required to install lawn - it's in Suggests, not Imports or Depends.

Use cases for this package include (but not limited to, obs.) the following (all below assumes GeoJSON format):

  • Create random spatial data.
  • Convert among spatial data types (e.g. Polygon to FeatureCollection)
  • Transform objects, including merging many, simplifying, calculating hulls, etc.
  • Measuring objects
  • Performing interpolation of objects
  • Aggregating data (aka properties) associated with objects

Install

Stable lawn version from CRAN - this should fetch leaflet, which is not on CRAN, but in a drat repo (let me know if it doesn't)

install.packages("lawn")

Or, the development version from Github

devtools::install_github("ropensci/lawn")
library("lawn")

view

lawn includes a tiny helper function for visualizing geojson. For examples below, we'll make liberal use of the lawn::view() function to visualize what it is the heck we're doing. mkay, lets roll...

We've tried to make view() work with as many inputs as possible, from class character containing json to the class json from the jsonlite package, to the class list to all of the GeoJSON outputs from functions in lawn.

view(lawn_data$points_average)

map1

Here, we sample at random two points from the same dataset just viewed.

lawn_sample(lawn_data$points_average, 2) %>% view()

map2

Make some geojson data

Point

lawn_point(c(-74.5, 40))
#> $type
#> [1] "Feature"
#> 
#> $geometry
#> $geometry$type
#> [1] "Point"
#> 
#> $geometry$coordinates
#> [1] -74.5  40.0
#> 
#> 
#> $properties
#> named list()
#> 
#> attr(,"class")
#> [1] "point"
lawn_point(c(-74.5, 40)) %>% view

point

Polygon

rings <- list(list(
  c(-2.275543, 53.464547),
  c(-2.275543, 53.489271),
  c(-2.215118, 53.489271),
  c(-2.215118, 53.464547),
  c(-2.275543, 53.464547)
))
lawn_polygon(rings)
#> $type
#> [1] "Feature"
#> 
#> $geometry
#> $geometry$type
#> [1] "Polygon"
#> 
#> $geometry$coordinates
#> , , 1
#> 
#>           [,1]      [,2]      [,3]      [,4]      [,5]
#> [1,] -2.275543 -2.275543 -2.215118 -2.215118 -2.275543
#> 
#> , , 2
#> 
#>          [,1]     [,2]     [,3]     [,4]     [,5]
#> [1,] 53.46455 53.48927 53.48927 53.46455 53.46455
#> 
#> 
#> 
#> $properties
#> named list()
#> 
#> attr(,"class")
#> [1] "polygon"
lawn_polygon(rings) %>% view

polygon

Random set of points

lawn_random(n = 2)
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#>      type geometry.type  geometry.coordinates
#> 1 Feature         Point -137.46327, -63.46154
#> 2 Feature         Point  -110.68426, 83.10533
#> 
#> attr(,"class")
#> [1] "featurecollection"
lawn_random(n = 5) %>% view

rand1

Or, use a different Javascript library (geojson-random) to create random features.

Positions

gr_position()
#> [1] -179.77996   45.99018

Points

gr_point(2)
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#>      type geometry.type geometry.coordinates
#> 1 Feature         Point   5.83895, -27.77218
#> 2 Feature         Point   78.50177, 14.95840
#> 
#> attr(,"class")
#> [1] "featurecollection"
gr_point(2) %>% view

rand2

Polygons

gr_polygon(n = 1, vertices = 5, max_radial_length = 5)
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#>      type geometry.type
#> 1 Feature       Polygon
#>                                                                                                           geometry.coordinates
#> 1 67.58827, 67.68551, 67.00091, 66.70156, 65.72578, 67.58827, -42.11340, -42.69850, -43.54866, -42.42758, -41.76731, -42.11340
#> 
#> attr(,"class")
#> [1] "featurecollection"
gr_polygon(n = 1, vertices = 5, max_radial_length = 5) %>% view

rand3

count

Count number of points within polygons, appends a new field to properties (see the count field)

lawn_count(polygons = lawn_data$polygons_count, points = lawn_data$points_count)
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#>      type pt_count geometry.type
#> 1 Feature        2       Polygon
#> 2 Feature        0       Polygon
#>                                                                                           geometry.coordinates
#> 1 -112.07239, -112.07239, -112.02810, -112.02810, -112.07239, 46.58659, 46.61761, 46.61761, 46.58659, 46.58659
#> 2 -112.02398, -112.02398, -111.96613, -111.96613, -112.02398, 46.57043, 46.61502, 46.61502, 46.57043, 46.57043
#> 
#> attr(,"class")
#> [1] "featurecollection"

distance

Define two points

from <- '{
 "type": "Feature",
 "properties": {},
 "geometry": {
   "type": "Point",
   "coordinates": [-75.343, 39.984]
 }
}'
to <- '{
  "type": "Feature",
  "properties": {},
  "geometry": {
    "type": "Point",
    "coordinates": [-75.534, 39.123]
  }
}'

Calculate distance, default units is kilometers (default output: km)

lawn_distance(from, to)
#> [1] 97.15958

sample from a FeatureCollection

dat <- lawn_data$points_average
cat(dat)
#> {
#>   "type": "FeatureCollection",
#>   "features": [
#>     {
#>       "type": "Feature",
#>       "properties": {
#>         "population": 200
#>       },
#>       "geometry": {
#>         "type": "Point",
...

Sample 2 points at random

lawn_sample(dat, 2)
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#>      type population geometry.type geometry.coordinates
#> 1 Feature        200         Point   10.80643, 59.90891
#> 2 Feature        600         Point   10.71579, 59.90478
#> 
#> attr(,"class")
#> [1] "featurecollection"

extent

Calculates the extent of all input features in a FeatureCollection, and returns a bounding box.

lawn_extent(lawn_data$points_average)
#> [1] 10.71579 59.90478 10.80643 59.93162

buffer

Calculates a buffer for input features for a given radius.

dat <- '{
 "type": "Feature",
 "properties": {},
 "geometry": {
     "type": "Polygon",
     "coordinates": [[
       [-112.072391,46.586591],
       [-112.072391,46.61761],
       [-112.028102,46.61761],
       [-112.028102,46.586591],
       [-112.072391,46.586591]
     ]]
   }
}'
view(dat)

buffer1

lawn_buffer(dat, 1, "miles") %>% view

buffer2

Union polygons together

poly1 <- '{
 "type": "Feature",
 "properties": {
   "fill": "#0f0"
 },
 "geometry": {
   "type": "Polygon",
   "coordinates": [[
     [-122.801742, 45.48565],
     [-122.801742, 45.60491],
     [-122.584762, 45.60491],
     [-122.584762, 45.48565],
     [-122.801742, 45.48565]
    ]]
 }
}'

poly2 <- '{
 "type": "Feature",
 "properties": {
   "fill": "#00f"
 },
 "geometry": {
   "type": "Polygon",
   "coordinates": [[
     [-122.520217, 45.535693],
     [-122.64038, 45.553967],
     [-122.720031, 45.526554],
     [-122.669906, 45.507309],
     [-122.723464, 45.446643],
     [-122.532577, 45.408574],
     [-122.487258, 45.477466],
     [-122.520217, 45.535693]
     ]]
 }
}'
view(poly1)

union1

view(poly2)

union2

Visualize union-ed polygons

lawn_union(poly1, poly2) %>% view

union3

See also lawn_merge() and lawn_intersect().

lint input geojson

For most functions, you can lint your input geojson data to make sure it is proper geojson. We use the javascript library geojsonhint. See the lint parameter.

Good GeoJSON

dat <- '{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "population": 200
      },
      "geometry": {
        "type": "Point",
        "coordinates": [10.724029, 59.926807]
      }
    }
  ]
}'
lawn_extent(dat)
#> [1] 10.72403 59.92681 10.72403 59.92681

Bad GeoJSON

dat <- '{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "population": 200
      },
      "geometry": {
        "type": "Point"
      }
    }
  ]
}'
lawn_extent(dat, lint = TRUE)

#> Error: Line 1 - "coordinates" property required

To do

  • As Turf.js changes, we'll update lawn
  • Performance improvements. We realize that this package is slower than the C based rgdal/rgeos - we are looking into ways to increaes performance to get closer to the performance of those packages.

geojsonio - a new package to do geojson things

geojsonio converts geographic data to GeoJSON and TopoJSON formats - though the focus is mostly on GeoJSON

For those not familiar GeoJSON it is a format for encoding a variety of geographic data structures. GeoJSON supports the following geometry types: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection. These geometry types are also found in well known text (WKT), and have equivalents in R's spatial classes. Read the spec for more detailed information.

Other great geojson resources:

Functions in this package are organized first around what you're working with or want to get, geojson or topojson, then convert to or read from various formats:

  • geojson_list() - convert to GeoJSON as R list format
  • geojson_json() - convert to GeoJSON as json
  • geojson_read()/topojson_read() - read a GeoJSON/TopoJSON file from file path or URL
  • geojson_write() - write a GeoJSON file locally (no write TopoJSON yet)

Each of the above functions have methods for various objects/classes, including numeric, data.frame, list, SpatialPolygons, SpatialLines, SpatialPoints, etc. (including the classes in rgeos)

Use cases for this package include (but not limited to, obs.) the following:

  • Get data in GeoJSON json format, and you want to get it into a list in R.
  • Get data into GeoJSON format to use downstream to make a interactive map
    • in R (e.g., with leaflet)
    • or in another context (e.g., using javascript with mapbox/leaflet)
  • Data is in a data.frame/matrix/list and you want to make GeoJSON format data.
  • Data is in one of the many spatial classes (e.g., SpatialPoints) and you want GeoJSON
  • You need to add styling to your data - can do with this package for certain data types.
  • You want to check that your GeoJSON data is valid - two ways to do it in geojsonio.
  • Combine objects together (e.g., a point and a line), either from two geo_list objects, or two json objects. See ?geojson-add

Install

See the github repo for notes about dependencies https://github.com/ropensci/geojsonio#install.

CRAN version or the dev version from GitHub

install.packages("geojsonio")
devtools::install_github("sckott/geojsonio")
library("geojsonio")

GeoJSON

Convert various formats to geojson

From a numeric vector of length 2

as json

geojson_json(c(32.45, -99.74))
#> {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[32.45,-99.74]},"properties":{}}]}

as a list

geojson_list(c(32.45, -99.74))
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#> 
#> $features[[1]]$geometry
#> $features[[1]]$geometry$type
...

From a data.frame

as json

geojson_json(us_cities[1:2, ], lat = 'lat', lon = 'long')
#> {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-99.74,32.45]},"properties":{"name":"Abilene TX","country.etc":"TX","pop":"113888","capital":"0"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-81.52,41.08]},"properties":{"name":"Akron OH","country.etc":"OH","pop":"206634","capital":"0"}}]}

as a list

geojson_list(us_cities[1:2, ], lat = 'lat', lon = 'long')
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#> 
#> $features[[1]]$geometry
#> $features[[1]]$geometry$type
...

From SpatialPolygons class

library('sp')
poly1 <- Polygons(list(Polygon(cbind(c(-100, -90, -85, -100),
  c(40, 50, 45, 40)))), "1")
poly2 <- Polygons(list(Polygon(cbind(c(-90, -80, -75, -90),
  c(30, 40, 35, 30)))), "2")
(sp_poly <- SpatialPolygons(list(poly1, poly2), 1:2))
#> An object of class "SpatialPolygons"
#> Slot "polygons":
#> [[1]]
#> An object of class "Polygons"
#> Slot "Polygons":
#> [[1]]
#> An object of class "Polygon"
#> Slot "labpt":
#> [1] -91.66667  45.00000
#> 
...

to json

geojson_json(sp_poly)
#> {"type":"FeatureCollection","features":[{"type":"Feature","id":1,"properties":{"dummy":0},"geometry":{"type":"Polygon","coordinates":[[[-100,40],[-90,50],[-85,45],[-100,40]]]}},{"type":"Feature","id":2,"properties":{"dummy":0},"geometry":{"type":"Polygon","coordinates":[[[-90,30],[-80,40],[-75,35],[-90,30]]]}}]}

to a list

geojson_list(sp_poly)
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#> 
#> $features[[1]]$id
#> [1] 1
...

From SpatialPoints class

x <- c(1, 2, 3, 4, 5)
y <- c(3, 2, 5, 1, 4)
(s <- SpatialPoints(cbind(x, y)))
#> SpatialPoints:
#>      x y
#> [1,] 1 3
#> [2,] 2 2
#> [3,] 3 5
#> [4,] 4 1
#> [5,] 5 4
#> Coordinate Reference System (CRS) arguments: NA

to json

geojson_json(s)
#> {"type":"FeatureCollection","features":[{"type":"Feature","id":1,"properties":{"dat":1},"geometry":{"type":"Point","coordinates":[1,3]}},{"type":"Feature","id":2,"properties":{"dat":2},"geometry":{"type":"Point","coordinates":[2,2]}},{"type":"Feature","id":3,"properties":{"dat":3},"geometry":{"type":"Point","coordinates":[3,5]}},{"type":"Feature","id":4,"properties":{"dat":4},"geometry":{"type":"Point","coordinates":[4,1]}},{"type":"Feature","id":5,"properties":{"dat":5},"geometry":{"type":"Point","coordinates":[5,4]}}]}

to a list

geojson_list(s)
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#> 
#> $features[[1]]$id
#> [1] 1
...

Combine objects

geo_list + geo_list

Note: geo_list is the output type from geojson_list(), it's just a list with a class attached so we know it's geojson :)

vec <- c(-99.74, 32.45)
a <- geojson_list(vec)
vecs <- list(c(100.0, 0.0), c(101.0, 0.0), c(100.0, 0.0))
b <- geojson_list(vecs, geometry = "polygon")
a + b
#> $type
#> [1] "FeatureCollection"
#> 
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#> 
#> $features[[1]]$geometry
#> $features[[1]]$geometry$type
...

json + json

c <- geojson_json(c(-99.74, 32.45))
vecs <- list(c(100.0, 0.0), c(101.0, 0.0), c(101.0, 1.0), c(100.0, 1.0), c(100.0, 0.0))
d <- geojson_json(vecs, geometry = "polygon")
c + d
#> {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-99.74,32.45]},"properties":{}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[100,0],[101,0],[101,1],[100,1],[100,0]]]},"properties":[]}]}

Write geojson

geojson_write(us_cities[1:2, ], lat = 'lat', lon = 'long')
#> <geojson>
#>   Path:       myfile.geojson
#>   From class: data.frame

Topojson

In the current version of this package you can read topojson. Writing topojson was in this package, but is gone for now - will come back later as in interface to topojson via V8.

Read from a file

file <- system.file("examples", "us_states.topojson", package = "geojsonio")
out <- topojson_read(file)

Read from a URL

url <- "https://raw.githubusercontent.com/shawnbot/d3-cartogram/master/data/us-states.topojson"
out <- topojson_read(url)

Lint geojson

There are two ways to do this in this package.

lint, locally

Uses the javascript library geojsonhint from Mapbox. We're running this locally via the V8 package.

Good

lint('{"type": "Point", "coordinates": [-100, 80]}')
#> [1] "valid"

Bad

lint('{"type": "Rhombus", "coordinates": [[1, 2], [3, 4], [5, 6]]}')
#> $message
#> [1] "The type Rhombus is unknown"
#> 
#> $line
#> [1] 1

validate, with a web service

Uses the web service at http://geojsonlint.com/

Good

validate('{"type": "Point", "coordinates": [-100, 80]}')
#> $status
#> [1] "ok"

Bad

validate('{"type": "Rhombus", "coordinates": [[1, 2], [3, 4], [5, 6]]}')
#> $message
#> [1] "\"Rhombus\" is not a valid GeoJSON type."
#> 
#> $status
#> [1] "error"

To do

  • I'd like to replace rgdal with javascript libraries to read from various file types (kml, shp, etc.) and convert to geojson. This is in development, and will come in the next version of this package most likely. This should make installation a bit easier as we won't have to depend on rgdal and GDAL
  • Performance improvements. Some operations already use the gdal or geos C libraries, so are quite fast, though the round trip to disk and back does take significant time. I'd like to speed this up.
  • More input types. We already have operations (json, list, etc.) for lots of input types (data.frame, list, sp classes), but likely there will be more added.
  • Most likely add functions topojson_list(), topojson_json()