-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
easy conversion for GeoJSON as R list to sf #185
Comments
If someone can provide me with examples of each of the seven types, as R data, I'll take a look. |
Would it be safe to assume that |
sf assumes that character data is WKT; I may hope the R lists with GeoJSON have a class? |
@edzer, this will provide a pretty thorough start using your examples in library(sf)
# use newest geojsonio from Github
# devtools::install_github("ropensci/geojsonio")
library(geojsonio)
library(magrittr)
# use sf examples
p1 = st_point(c(1,2))
geojsonio::geojson_list(p1)
(p2 = st_point(c(1,2,3)))
geojsonio::geojson_list(p2)
p3 = st_point(c(1,2,3), "XYM")
geojsonio::geojson_list(p3)
pts = matrix(1:10, , 2)
(mp1 = st_multipoint(pts))
geojsonio::geojson_list(mp1)
pts = matrix(1:15, , 3)
(mp2 = st_multipoint(pts))
geojsonio::geojson_list(mp2)
(mp3 = st_multipoint(pts, "XYM"))
geojsonio::geojson_list(mp3)
pts = matrix(1:20, , 4)
(mp4 = st_multipoint(pts))
geojsonio::geojson_list(mp4)
pts = matrix(1:10, , 2)
(ls1 = st_linestring(pts))
geojsonio::geojson_list(ls1)
pts = matrix(1:15, , 3)
(ls2 = st_linestring(pts))
geojsonio::geojson_list(ls2)
(ls3 = st_linestring(pts, "XYM"))
pts = matrix(1:20, , 4)
geojsonio::geojson_list(ls3)
(ls4 = st_linestring(pts))
geojsonio::geojson_list(ls4)
outer = matrix(c(0,0,10,0,10,10,0,10,0,0),ncol=2, byrow=TRUE)
hole1 = matrix(c(1,1,1,2,2,2,2,1,1,1),ncol=2, byrow=TRUE)
hole2 = matrix(c(5,5,5,6,6,6,6,5,5,5),ncol=2, byrow=TRUE)
pts = list(outer, hole1, hole2)
(ml1 = st_multilinestring(pts))
geojsonio::geojson_list(ml1)
pts3 = lapply(pts, function(x) cbind(x, 0))
(ml2 = st_multilinestring(pts3))
geojsonio::geojson_list(ml2)
(ml3 = st_multilinestring(pts3, "XYM"))
geojsonio::geojson_list(ml3)
pts4 = lapply(pts3, function(x) cbind(x, 0))
(ml4 = st_multilinestring(pts4))
geojsonio::geojson_list(ml4)
outer = matrix(c(0,0,10,0,10,10,0,10,0,0),ncol=2, byrow=TRUE)
hole1 = matrix(c(1,1,1,2,2,2,2,1,1,1),ncol=2, byrow=TRUE)
hole2 = matrix(c(5,5,5,6,6,6,6,5,5,5),ncol=2, byrow=TRUE)
pts = list(outer, hole1, hole2)
(pl1 = st_polygon(pts))
geojsonio::geojson_list(pl1)
pts3 = lapply(pts, function(x) cbind(x, 0))
(pl2 = st_polygon(pts3))
geojsonio::geojson_list(pl2)
(pl3 = st_polygon(pts3, "XYM"))
geojsonio::geojson_list(pl3)
pts4 = lapply(pts3, function(x) cbind(x, 0))
(pl4 = st_polygon(pts4))
geojsonio::geojson_list(pl4)
pol1 = list(outer, hole1, hole2)
pol2 = list(outer + 12, hole1 + 12)
pol3 = list(outer + 24)
mp = list(pol1,pol2,pol3)
(mp1 = st_multipolygon(mp))
geojsonio::geojson_list(mp1)
pts3 = lapply(mp, function(x) lapply(x, function(y) cbind(y, 0)))
(mp2 = st_multipolygon(pts3))
geojsonio::geojson_list(mp2)
(mp3 = st_multipolygon(pts3, "XYM"))
geojsonio::geojson_list(mp3)
pts4 = lapply(mp2, function(x) lapply(x, function(y) cbind(y, 0)))
(mp4 = st_multipolygon(pts4))
geojsonio::geojson_list(mp4)
(gc = st_geometrycollection(list(p1, ls1, pl1, mp1)))
geojsonio::geojson_list(gc)
st_geometrycollection() # empty geometry
c(st_point(1:2), st_point(5:6)) %>%
geojsonio::geojson_list(mp4)
c(st_point(1:2), st_multipoint(matrix(5:8,2))) %>%
geojsonio::geojson_list()
c(st_multipoint(matrix(1:4,2)), st_multipoint(matrix(5:8,2))) %>%
geojsonio::geojson_list()
c(st_linestring(matrix(1:6,3)), st_linestring(matrix(11:16,3))) %>%
geojsonio::geojson_list()
c(st_multilinestring(list(matrix(1:6,3))), st_multilinestring(list(matrix(11:16,3)))) %>%
geojsonio::geojson_list()
pl = list(rbind(c(0,0), c(1,0), c(1,1), c(0,1), c(0,0)))
c(st_polygon(pl), st_polygon(pl)) %>%
geojsonio::geojson_list()
c(st_polygon(pl), st_multipolygon(list(pl))) %>%
geojsonio::geojson_list()
c(st_linestring(matrix(1:6,3)), st_point(1:2)) %>%
geojsonio::geojson_list()
c(st_geometrycollection(list(st_point(1:2), st_linestring(matrix(1:6,3)))),
st_geometrycollection(list(st_multilinestring(list(matrix(11:16,3)))))) %>%
geojsonio::geojson_list()
c(st_geometrycollection(list(st_point(1:2), st_linestring(matrix(1:6,3)))),
st_multilinestring(list(matrix(11:16,3))), st_point(5:6),
st_geometrycollection(list(st_point(10:11)))) %>%
geojsonio::geojson_list() |
Here's a a first shot at it. It returns
|
Did this work out, and should we add it to |
Did anyone look at this? |
@edzer I'll have a look at these soon. |
I should be able to test tomorrow. Sorry for the delay. Yes, these will be very important for |
|
I guess a AFAICS, coordinates in geojson should be a vector or array. Who created this |
Thanks @edzer. By no means did I intend to imply that coordinates as a
|
I think this
|
Do the |
pinging @sckott and @ateucher. In the
|
@timelyportfolio i think geojson as a list or string both make sense - i'd like to soon depend on our |
@sckott correct me if I'm wrong, but because |
@ateucher right, we should specify a structure for that type - i thin kit would make most sense to include list support in |
Since your geometries are a constrained subset of simple features, you could as well follow the |
I think that's a great idea @edzer |
This is some ugly code, but I'll post as a starting point to converting
|
I'm not very familiar with json, but it seems that multiple R representations could be valid? Example with OSM data: response = httr::GET("https://nominatim.openstreetmap.org/search?format=json&limit=1&polygon_geojson=1&q=hawai")
js_h <- httr::content(response, "parsed")[[1]]
js_l <- jsonlite::fromJSON(httr::content(response, as="text"))
str(js_h$geojson, 2)
#> List of 2
#> $ type : chr "MultiPolygon"
#> $ coordinates:List of 17
#> ..$ :List of 1
#> ..$ :List of 1
#> ...
str(js_l$geojson, 3)
#> 'data.frame': 1 obs. of 2 variables:
#> $ type : chr "MultiPolygon"
#> $ coordinates:List of 1
#> ..$ :List of 17
#> .. ..$ : num [1, 1:248, 1:2] -157 -157 -157 -157 -157 ...
#> .. ..$ : num [1, 1:235, 1:2] -157 -157 -157 -157 -157 ...
#> .. ..$ : num [1, 1:192, 1:2] -171 -171 -171 -171 -171 ...
#> .. ..$ : num [1, 1:156, 1:2] -166 -166 -166 -166 -166 ...
#> .. ..$ : num [1, 1:134, 1:2] -156 -156 -156 -156 -156 ...
#> ... I couldn't get either to work right of the bat with |
Looks like you found one I have not discovered yet. Here is my first attempt at converting coordinates from |
Any reason to keep this issue open? |
@edzer even though I opened the issue, I am probably the least qualified to answer "open or close?" Whether easy One concern I do have is that |
If geojson comes as a text string, why wouldn't it have a class? for wkt, |
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.1.3, proj.4 4.9.3
geojson_txt <- "{\"type\":\"MultiPoint\",\"coordinates\":[[3.2,4],[3,4.6],[3.8,4.4],[3.5,3.8],[3.4,3.6],[3.9,4.5]]}"
st_read(geojson_txt)
#> Reading layer `OGRGeoJSON' from data source `{"type":"MultiPoint","coordinates":[[3.2,4],[3,4.6],[3.8,4.4],[3.5,3.8],[3.4,3.6],[3.9,4.5]]}' using driver `GeoJSON'
#> converted into: MULTIPOINT
#> Simple feature collection with 1 feature and 0 fields
#> geometry type: MULTIPOINT
#> dimension: XY
#> bbox: xmin: 3 ymin: 3.6 xmax: 3.9 ymax: 4.6
#> epsg (SRID): 4326
#> proj4string: +proj=longlat +datum=WGS84 +no_defs |
Super cool, didn't know that! For this case, it pays off to use > x = read_sf(geojson_txt)
> x
Simple feature collection with 1 feature and 0 fields
geometry type: MULTIPOINT
dimension: XY
bbox: xmin: 3 ymin: 3.6 xmax: 3.9 ymax: 4.6
epsg (SRID): 4326
proj4string: +proj=longlat +datum=WGS84 +no_defs
geometry
1 MULTIPOINT(3.2 4, 3 4.6, 3.... at @timelyportfolio : I guess the |
Guess so :) Thanks @ateucher for answering from Runconf! Now I need to see if I should do this instead of my hacked conversion in |
What if the geoJSON character string is a column in a data.frame? I can read a single cell using Can the mechanics of |
Yes; a reprex would be helpful here! I'd try to |
Okay! We know that library(sf)
#> Linking to GEOS 3.6.2, GDAL 2.2.3, proj.4 4.9.3
geo <- "{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68152563269095,36.43764870908927]}"
read_sf(geo)
#> Simple feature collection with 1 feature and 0 fields
#> geometry type: POINT
#> dimension: XY
#> bbox: xmin: -118.6815 ymin: 36.43765 xmax: -118.6815 ymax: 36.43765
#> epsg (SRID): 4326
#> proj4string: +proj=longlat +datum=WGS84 +no_defs
#> geometry
#> 1 POINT (-118.681525632691 36... But if we have a data.frame with a column that is a character representation of a geoJSON... geo <- c("{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68152563269095,36.43764870908927]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67408758213843,36.43366018922779]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67708346361097,36.44208638659282]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67886661944996,36.44110273135671]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68089232041565,36.44173155205561]}")
test <- data.frame(numbers = 1:5, letters = letters[1:5], geometry = geo)
test
#> numbers letters
#> 1 1 a
#> 2 2 b
#> 3 3 c
#> 4 4 d
#> 5 5 e
#> geometry
#> 1 {"geodesic":true,"type":"Point","coordinates":[-118.68152563269095,36.43764870908927]}
#> 2 {"geodesic":true,"type":"Point","coordinates":[-118.67408758213843,36.43366018922779]}
#> 3 {"geodesic":true,"type":"Point","coordinates":[-118.67708346361097,36.44208638659282]}
#> 4 {"geodesic":true,"type":"Point","coordinates":[-118.67886661944996,36.44110273135671]}
#> 5 {"geodesic":true,"type":"Point","coordinates":[-118.68089232041565,36.44173155205561]} ...we might like to be able to turn that whole data.frame into a simple feature by making the character column the geometry column of the simple feature with library(sf)
#> Linking to GEOS 3.6.2, GDAL 2.2.3, proj.4 4.9.3
geo <- c("{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68152563269095,36.43764870908927]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67408758213843,36.43366018922779]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67708346361097,36.44208638659282]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67886661944996,36.44110273135671]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68089232041565,36.44173155205561]}")
test <- data.frame(numbers = 1:5, letters = letters[1:5], geometry = geo)
test$geometry <- st_as_sfc(test$geometry)
#> OGR: Unsupported geometry type
#> Error in CPL_sfc_from_wkt(x): OGR error
test <- st_as_sf(test)
#> Error in st_sf(x, ..., agr = agr): no simple features geometry column present |
Yeah, right now you have to do sth like > do.call(rbind, lapply(as.character(test$geometry), read_sf))
Simple feature collection with 5 features and 0 fields
geometry type: POINT
dimension: XY
bbox: xmin: -118.6815 ymin: 36.43366 xmax: -118.6741 ymax: 36.44209
epsg (SRID): 4326
proj4string: +proj=longlat +datum=WGS84 +no_defs
geometry
1 POINT (-118.681525632691 36...
2 POINT (-118.674087582138 36...
3 POINT (-118.677083463611 36...
4 POINT (-118.67886661945 36....
5 POINT (-118.680892320416 36... and it would be quite simple to modify the |
We now have > geo <- c("{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68152563269095,36.43764870908927]}",
+ "{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67408758213843,36.43366018922779]}",
+ "{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67708346361097,36.44208638659282]}",
+ "{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67886661944996,36.44110273135671]}",
+ "{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68089232041565,36.44173155205561]}")
> st_as_sfc(geo, GeoJSON=TRUE)
Geometry set for 5 features
geometry type: POINT
dimension: XY
bbox: xmin: -118.6815 ymin: 36.43366 xmax: -118.6741 ymax: 36.44209
epsg (SRID): 4326
proj4string: +proj=longlat +datum=WGS84 +no_defs
POINT (-118.681525632691 36.4376487090893)
POINT (-118.674087582138 36.4336601892278)
POINT (-118.677083463611 36.4420863865928)
POINT (-118.67886661945 36.4411027313567)
POINT (-118.680892320416 36.4417315520556) |
FWIW, you can also use the library(sf)
library(wellknown)
geo <- c("{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68152563269095,36.43764870908927]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67408758213843,36.43366018922779]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67708346361097,36.44208638659282]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.67886661944996,36.44110273135671]}",
"{\"geodesic\":true,\"type\":\"Point\",\"coordinates\":[-118.68089232041565,36.44173155205561]}")
wkt = sapply(geo, wellknown::geojson2wkt, USE.NAMES = FALSE)
test <- data.frame(numbers = 1:5, letters = letters[1:5], geometry = wkt)
st_as_sf(test, wkt = "geometry")
Simple feature collection with 5 features and 2 fields
geometry type: POINT
dimension: XY
bbox: xmin: -118.6815 ymin: 36.43366 xmax: -118.6741 ymax: 36.44209
epsg (SRID): NA
proj4string: NA
numbers letters geometry
1 1 a POINT (-118.681525632691 36...
2 2 b POINT (-118.674087582138 36...
3 3 c POINT (-118.677083463611 36...
4 4 d POINT (-118.67886661945 36....
5 5 e POINT (-118.680892320416 36... Though it doesn't infer crs as @edzer 's new implementation. |
"infer" is too much honour: the json doesn't contain it, but the GeoJSON rfc says it only can be 4326, GDAL adheres to that I suppose. |
Thank you both! These are great and straightforward solutions. |
Hi @edzer , @timelyportfolio, and @tim-salabim. I'm aware this issue has long been closed. I was wondering if I could get some assistance in converting this data to a spatial object. https://gist.github.com/denironyx/9fa87a93c10ffa92608362ae770bd7bc |
@denironyx looks like you are working on a very neat project. Here is one solution, but I am sure there are others.
|
Thanks @timelyportfolio for the assistance. It worked magic! |
As discussed in #39 (comment), easily converting GeoJSON as an R list to
sf
would be really helpful. @ateucher has already done all the hard work for the reversesf
-> GeoJSON ropensci/geojsonio#95.The text was updated successfully, but these errors were encountered: