将 'multifeature' GeoJSON 的特征转换为 R 空间对象
Convert features of a 'multifeature' GeoJSON into R spatial objects
通常您可以使用 trusty readOGR
将 geojson 文件读入 R,如图所示 here。
但是,对于多功能 geojson,这会失败。
可重现的例子:
downloader::download("https://github.com/Robinlovelace/Creating-maps-in-R/raw/master/data/test-multifeature.geojson", "test.geojson")
test <- rgdal::readOGR("test.geojson", "OGRGeoJSON") # fails with:
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv, :
Multiple incompatible geometries: wkbPoint: 98; wkbLineString: 660; wkbPolygon: 23
错误消息很清楚,并指出了解决方案:拆分功能。
但是,除了使用正则表达式执行此操作外,我不知道该怎么做。
非常欢迎任何想法。
令人惊奇的是:GitHub displays the data natively on the browser,而 R 甚至(似乎)无法读入它!
另一种解决方法:
test <- geojsonio::geojson_read("test.geojson")
您可以在命令行上使用 ogr2ogr 将这个巨大的嵌合体拆分为可感知的东西:
ogr2ogr -where "OGR_GEOMETRY='LINESTRING'" \
-f "GeoJSON" lines.geojson test.geojson
点和多边形也类似。
几年前有一些关于将 OGR_SQL 实现到 readOGR
的讨论,那时您可以从 R 中执行此操作,但 Roger 不想这样做并且没有人愿意帮忙:(
创建拆分的 geojson 文件后,您可以将它们读入单个 rgeos::SpatialCollections
对象:
points=readOGR("points.geojson","OGRGeoJSON")
polys=readOGR("polygons.geojson","OGRGeoJSON")
lines=readOGR("lines.geojson","OGRGeoJSON")
require(rgeos)
g = SpatialCollections(points=points, lines=lines, polygons=polys)
plot(g)
如果您想尝试使用 geojsonio
进行一些尝试,那么您可以使用 Filter
来 select 列出几何集合中给定几何的元素
polygon_features = Filter(
function(f){f$geometry$type=="Polygon"},
test$features)
但是你仍然需要构建一些你可以进入单独的 R 实体的东西....
您可以使用各种 GDAL 函数的 require_geomType
参数来提取您需要的特征:
library(rgdal)
ogrListLayers("test.geojson")
## [1] "OGRGeoJSON"
## attr(,"driver")
## [1] "GeoJSON"
## attr(,"nlayers")
## [1] 1
# This fails but you can at least see the geoms it whines about
ogrInfo("test.geojson", "OGRGeoJSON")
## Error in ogrInfo("test.geojson", "OGRGeoJSON") :
## Multiple incompatible geometries: wkbPoint: 98; wkbLineString: 660; wkbPolygon: 23
ogrInfo("test.geojson", "OGRGeoJSON", require_geomType="wkbPoint")
## NOTE: keeping only 98 wkbPoint of 781 features
## note that extent applies to all features
## Source: "test.geojson", layer: "OGRGeoJSON"
## Driver: GeoJSON number of rows 781
## selected geometry type: wkbPoint with 98 rows
## Feature type: wkbPoint with 2 dimensions
## Extent: (12.48326 41.88355) - (12.5033 41.89629)
## CRS: +proj=longlat +datum=WGS84 +no_defs
## Number of fields: 78
## name type length typeName
## 1 area 4 0 String
## 2 bicycle 4 0 String
## ...
## LONG LIST - 78 total
ogrInfo("test.geojson", "OGRGeoJSON", require_geomType="wkbLineString")
## NOTE: keeping only 660 wkbLineString of 781 features
## note that extent applies to all features
## Source: "test.geojson", layer: "OGRGeoJSON"
## Driver: GeoJSON number of rows 781
## selected geometry type: wkbLineString with 660 rows
## Feature type: wkbLineString with 2 dimensions
## Extent: (12.48326 41.88355) - (12.5033 41.89629)
## CRS: +proj=longlat +datum=WGS84 +no_defs
## Number of fields: 78
## name type length typeName
## 1 area 4 0 String
## 2 bicycle 4 0 String
## ...
## LONG LIST - 78 total (same as above)
ogrInfo("test.geojson", "OGRGeoJSON", require_geomType="wkbPolygon")
## NOTE: keeping only 23 wkbPolygon of 781 features
## note that extent applies to all features
## Source: "test.geojson", layer: "OGRGeoJSON"
## Driver: GeoJSON number of rows 781
## selected geometry type: wkbPolygon with 23 rows
## Feature type: wkbPolygon with 2 dimensions
## Extent: (12.48326 41.88355) - (12.5033 41.89629)
## CRS: +proj=longlat +datum=WGS84 +no_defs
## Number of fields: 78
## name type length typeName
## 1 area 4 0 String
## 2 bicycle 4 0 String
## ...
## LONG LIST - 78 total (same as above)
points <- readOGR("test.geojson", "OGRGeoJSON", require_geomType="wkbPoint")
## OGR data source with driver: GeoJSON
## Source: "test.geojson", layer: "OGRGeoJSON"
## with 781 features;
## Selected wkbPoint feature type, with 98 rows
## It has 78 fields
## NOTE: keeping only 98 wkbPoint of 781 features
lines <- readOGR("test.geojson", "OGRGeoJSON", require_geomType="wkbLineString")
## OGR data source with driver: GeoJSON
## Source: "test.geojson", layer: "OGRGeoJSON"
## with 781 features;
## Selected wkbLineString feature type, with 660 rows
## It has 78 fields
## NOTE: keeping only 660 wkbLineString of 781 features
polygons <- readOGR("test.geojson", "OGRGeoJSON", require_geomType="wkbPolygon")
## OGR data source with driver: GeoJSON
## Source: "test.geojson", layer: "OGRGeoJSON"
## with 781 features;
## Selected wkbPolygon feature type, with 23 rows
## It has 78 fields
## NOTE: keeping only 23 wkbPolygon of 781 features
# prove they red in things
plot(lines, col="#7f7f7f")
plot(polygons, add=TRUE)
plot(points, add=TRUE, col="red")
几年后,一些替代方案 - library(geojsonsf)
和 library(sf)
都将读取 geojson 并转换为 sf
对象
url <- 'https://github.com/Robinlovelace/Creating-maps-in-R/raw/master/data/test-multifeature.geojson'
## these give the same result
sf <- geojsonsf::geojson_sf( url )
sf <- sf::st_read( url )
一起来看看
library(mapdeck)
set_token( "MAPBOX_TOKEN" )
mapdeck( style = mapdeck_style("light") ) %>%
add_sf( sf )
通常您可以使用 trusty readOGR
将 geojson 文件读入 R,如图所示 here。
但是,对于多功能 geojson,这会失败。
可重现的例子:
downloader::download("https://github.com/Robinlovelace/Creating-maps-in-R/raw/master/data/test-multifeature.geojson", "test.geojson")
test <- rgdal::readOGR("test.geojson", "OGRGeoJSON") # fails with:
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv, :
Multiple incompatible geometries: wkbPoint: 98; wkbLineString: 660; wkbPolygon: 23
错误消息很清楚,并指出了解决方案:拆分功能。 但是,除了使用正则表达式执行此操作外,我不知道该怎么做。
非常欢迎任何想法。
令人惊奇的是:GitHub displays the data natively on the browser,而 R 甚至(似乎)无法读入它!
另一种解决方法:
test <- geojsonio::geojson_read("test.geojson")
您可以在命令行上使用 ogr2ogr 将这个巨大的嵌合体拆分为可感知的东西:
ogr2ogr -where "OGR_GEOMETRY='LINESTRING'" \
-f "GeoJSON" lines.geojson test.geojson
点和多边形也类似。
几年前有一些关于将 OGR_SQL 实现到 readOGR
的讨论,那时您可以从 R 中执行此操作,但 Roger 不想这样做并且没有人愿意帮忙:(
创建拆分的 geojson 文件后,您可以将它们读入单个 rgeos::SpatialCollections
对象:
points=readOGR("points.geojson","OGRGeoJSON")
polys=readOGR("polygons.geojson","OGRGeoJSON")
lines=readOGR("lines.geojson","OGRGeoJSON")
require(rgeos)
g = SpatialCollections(points=points, lines=lines, polygons=polys)
plot(g)
如果您想尝试使用 geojsonio
进行一些尝试,那么您可以使用 Filter
来 select 列出几何集合中给定几何的元素
polygon_features = Filter(
function(f){f$geometry$type=="Polygon"},
test$features)
但是你仍然需要构建一些你可以进入单独的 R 实体的东西....
您可以使用各种 GDAL 函数的 require_geomType
参数来提取您需要的特征:
library(rgdal)
ogrListLayers("test.geojson")
## [1] "OGRGeoJSON"
## attr(,"driver")
## [1] "GeoJSON"
## attr(,"nlayers")
## [1] 1
# This fails but you can at least see the geoms it whines about
ogrInfo("test.geojson", "OGRGeoJSON")
## Error in ogrInfo("test.geojson", "OGRGeoJSON") :
## Multiple incompatible geometries: wkbPoint: 98; wkbLineString: 660; wkbPolygon: 23
ogrInfo("test.geojson", "OGRGeoJSON", require_geomType="wkbPoint")
## NOTE: keeping only 98 wkbPoint of 781 features
## note that extent applies to all features
## Source: "test.geojson", layer: "OGRGeoJSON"
## Driver: GeoJSON number of rows 781
## selected geometry type: wkbPoint with 98 rows
## Feature type: wkbPoint with 2 dimensions
## Extent: (12.48326 41.88355) - (12.5033 41.89629)
## CRS: +proj=longlat +datum=WGS84 +no_defs
## Number of fields: 78
## name type length typeName
## 1 area 4 0 String
## 2 bicycle 4 0 String
## ...
## LONG LIST - 78 total
ogrInfo("test.geojson", "OGRGeoJSON", require_geomType="wkbLineString")
## NOTE: keeping only 660 wkbLineString of 781 features
## note that extent applies to all features
## Source: "test.geojson", layer: "OGRGeoJSON"
## Driver: GeoJSON number of rows 781
## selected geometry type: wkbLineString with 660 rows
## Feature type: wkbLineString with 2 dimensions
## Extent: (12.48326 41.88355) - (12.5033 41.89629)
## CRS: +proj=longlat +datum=WGS84 +no_defs
## Number of fields: 78
## name type length typeName
## 1 area 4 0 String
## 2 bicycle 4 0 String
## ...
## LONG LIST - 78 total (same as above)
ogrInfo("test.geojson", "OGRGeoJSON", require_geomType="wkbPolygon")
## NOTE: keeping only 23 wkbPolygon of 781 features
## note that extent applies to all features
## Source: "test.geojson", layer: "OGRGeoJSON"
## Driver: GeoJSON number of rows 781
## selected geometry type: wkbPolygon with 23 rows
## Feature type: wkbPolygon with 2 dimensions
## Extent: (12.48326 41.88355) - (12.5033 41.89629)
## CRS: +proj=longlat +datum=WGS84 +no_defs
## Number of fields: 78
## name type length typeName
## 1 area 4 0 String
## 2 bicycle 4 0 String
## ...
## LONG LIST - 78 total (same as above)
points <- readOGR("test.geojson", "OGRGeoJSON", require_geomType="wkbPoint")
## OGR data source with driver: GeoJSON
## Source: "test.geojson", layer: "OGRGeoJSON"
## with 781 features;
## Selected wkbPoint feature type, with 98 rows
## It has 78 fields
## NOTE: keeping only 98 wkbPoint of 781 features
lines <- readOGR("test.geojson", "OGRGeoJSON", require_geomType="wkbLineString")
## OGR data source with driver: GeoJSON
## Source: "test.geojson", layer: "OGRGeoJSON"
## with 781 features;
## Selected wkbLineString feature type, with 660 rows
## It has 78 fields
## NOTE: keeping only 660 wkbLineString of 781 features
polygons <- readOGR("test.geojson", "OGRGeoJSON", require_geomType="wkbPolygon")
## OGR data source with driver: GeoJSON
## Source: "test.geojson", layer: "OGRGeoJSON"
## with 781 features;
## Selected wkbPolygon feature type, with 23 rows
## It has 78 fields
## NOTE: keeping only 23 wkbPolygon of 781 features
# prove they red in things
plot(lines, col="#7f7f7f")
plot(polygons, add=TRUE)
plot(points, add=TRUE, col="red")
几年后,一些替代方案 - library(geojsonsf)
和 library(sf)
都将读取 geojson 并转换为 sf
对象
url <- 'https://github.com/Robinlovelace/Creating-maps-in-R/raw/master/data/test-multifeature.geojson'
## these give the same result
sf <- geojsonsf::geojson_sf( url )
sf <- sf::st_read( url )
一起来看看
library(mapdeck)
set_token( "MAPBOX_TOKEN" )
mapdeck( style = mapdeck_style("light") ) %>%
add_sf( sf )