将“多特征”GeoJSON的特征转换为R空间对象

7

通常,您可以使用可靠的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在浏览器上本地显示数据,而R甚至(看起来)无法读取它!另一种解决方案的替代方法:
test <- geojsonio::geojson_read("test.geojson")
3个回答

10
您可以在各种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")

enter image description here


那是最近发布的rgdal吗?我在0.9-1中没有看到它 - 刚刚升级到0.9-3,现在我有了! - Spacedman
1
我认为它是在0.9-2版本中加入的。它非常有用,特别是对于这些时髦的GeoJSON形状文件,这些酷孩子们现在正在使用的文件;-) - hrbrmstr
3
很酷。我的多功能/GeoJSON探索总结与R/gdal可以在这里找到:http://rpubs.com/RobinLovelace/84577。如果您使用Ubuntu,可以更新gdal:$ sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable && sudo apt-get update $ sudo apt-get install gdal-bin - RobinLovelace

3

您可以在命令行上使用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,则可以使用过滤器从几何集合中选择给定几何形状的列表元素。

polygon_features = Filter(
    function(f){f$geometry$type=="Polygon"},
    test$features)

但是你仍然需要构建一些可以分离成不同 R 实体的东西...


1
几年后,有两个替代方案 - 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 )

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接