Closed SymbolixAU closed 7 years ago
Thanks for this @SymbolixAU
You could do that afterwards with jqr
, e.g.,
library(geojsonio)
library(sf)
library(jqr)
p1 <- rbind(c(0,0), c(1,0), c(3,2), c(2,4), c(1,4), c(0,0))
p2 <- rbind(c(5,5), c(5,6), c(4,5), c(5,5))
poly_sfc <- st_sfc(st_polygon(list(p1)), st_polygon(list(p2)))
poly_sf <- st_sf(foo = c("a", "b"), bar = 1:2, poly_sfc)
(x <- geojson_json(poly_sf))
#> {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"foo":"a","bar":1},"geometry":{"type":"Polygon","coordinates":[[[0,0],[1,0],[3,2],[2,4],[1,4],[0,0]]]}},{"type":"Feature","properties":{"foo":"b","bar":2},"geometry":{"type":"Polygon","coordinates":[[[5,5],[5,6],[4,5],[5,5]]]}}]}
unclass(jq(unclass(x), ".features[]"))
#> [1] "{\"type\":\"Feature\",\"properties\":{\"foo\":\"a\",\"bar\":1},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[0,0],[1,0],[3,2],[2,4],[1,4],[0,0]]]}}"
#> [2] "{\"type\":\"Feature\",\"properties\":{\"foo\":\"b\",\"bar\":2},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[5,5],[5,6],[4,5],[5,5]]]}}"
But, that's of course a solution that doesn't really get at your question within this pkg. We may be able to allow this in geojson_json
/geojson_list
- though need to think about how it would work.
With geojson_list
it's straightforward to index to the array of features output$features
, but not so easy with geojson_json
output
cc @ateucher
@SymbolixAU okay, reinstall devtools::install_github("ropensci/geojsonio@atomize")
see geojson_atomize
and it's examples
i thought it might be easier to make a new fxn rather than change behavior in the two work horse fxns geojson_json
/geojson_list
right now the fxn works with output of those two fxns just listed.
Polygon
) - make it a Featurethoughts?
the fxn name may need to change as atomize only fits the first two egs in the list above
Thanks for looking at this; and for adding it to your next milestone! I think this is a good start.
However, I'm wondering if it's erroneous to class the output as json
, given:
library(sf)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
geo <- geojson_json(nc)
atom <- geojson_atomize(geo)
class(atom)
# "json"
jsonlite::validate(atom)
# [1] FALSE
# error...
Maybe the returned value(s) should be a vector of JSON objects, rather than collapsed down into one long char?
try again
yep - that's got it working
I think it might be worth allowing the user to specify if they want to combine
the tmp
object through an argument in the function - thoughts?
This goes back to my original use-case of storing the data in a database, where you may want to insert geometries/features as separate documents.
good idea. Do you ever want them as separate JSON objects? or always as one JSON object?
I think I would get more use out of separate JSON objects, primarily because I can then work with each geometry/feature independently, both for plotting and storing.
For example, this workflow
x <- geo
stripjqr <- function(x) gsub('\\"', "", unclass(x))
type <- stripjqr(jqr::jq(unclass(x), ".type"))
keys <- stripjqr(jqr::jq(unclass(x), "keys[]"))
if (type %in% c('Point', 'MultiPoint',
'Polygon', 'MultiPolygon',
'LineString', 'MultiLineString')) {
tmp <- jqr::jq(unclass(x), '{ "type": "Feature", "geometry": . }')
} else {
if ("features" %in% keys) {
tmp <- jqr::jq(unclass(x), ".features[]")
}
if ("geometries" %in% keys) {
tmp <- jqr::jq(unclass(x), ".geometries[]")
}
}
library(mongolite)
library(symbolix.utils)
mong <- ConnectToMongo(db = "test", collection = "geotest", usr = "db_user")
# mong$drop()
mong$insert(tmp)
# List of 6
# $ nInserted : int 100
# $ nMatched : int 0
# $ nModified : int 0
# $ nRemoved : int 0
# $ nUpserted : int 0
# $ writeErrors: list()
inserts 100 features into the database. This then allows me to geo-index the geometries and do geometry calculations on-the-fly on the server. (I wrote a recent blog post giving an example of what I'm doing, if you're intersted: https://www.symbolix.com.au/blog-main/2017-3)
thanks. i think it makes sense to provide a parameter to toggle this behavior - i think it makes sense to have default of one single JSON valid output since that's what this pkg does - jqr
doesn't necessarily do that, but i think we should be consistent with behavior that already exists in this pkg
p.s. note that we don't add the properties
element, which is needed often for other downstream things (e.g., the leaflet R package and http://geojson.io)
Yeah happy with that. And thanks for introducing me to jqr
too, it's made my life a whole lot easier https://github.com/SymbolixAU/googleway/blob/master/R/results_access.R#L110 !
p.s. that's Ok, I can live without the properties
element
geojson_txt <- '{
"type" : "Feature",
"geometry" : {
"type" : "Polygon", "coordinates" : [
[
[144.88, -37.85],
[145.02, -37.85],
[145.02, -37.80],
[144.88, -37.80],
[144.88, -37.85]
]
]
}
}'
## geojson is in dev
devtools::install_git("SymbolixAU/googleway")
mapKey <- symbolix.utils::mapKey()
google_map(key = mapKey) %>%
add_geojson(geojson = geojson_txt)
great, glad you like jqr
- glad we were able to wrap it up nicely in R (same person did the heavy lifting that made mongolite
😸 )
yeah, I'm well aware/greatful to Jeroen :) - I use his packages a lot !
This issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with a reprex: https://reprex.tidyverse.org) and link to this issue.
When converting a single row of an
sf
object to geoJSON, is it possible to return a singleFeature
, rather than aFeatureCollection
?Example
Taking the data supplied by
sf
, if you convert a single row it returns aFeatureCollection
Would it be possible to return this just as a
Feature
?The use-case I'm thinking for this is storage in a GeoDatabase (MongoDB), where you want a document per feature, rather than inserting all the objects as an entire
FeatureCollection
.