将 json 对象转换为空间线数据框
Convert json object to spatial lines data frame
我从 EnergyData 下载了伊拉克电网的 geojson 文件。可以自己下载文件here and visit the webpage here
我尝试使用 geojsonio::geojson_read
将文件读入 R,但它抛出了错误。另一位用户热心指出,能源数据网站提供的文件格式不正确,不符合 geojson 格式,因此文件名具有误导性。所以他们建议我使用 jsonlite::read_json
。虽然该函数确实将文件读入 R,但它不是空间对象。这是一个多级列表。我也试过 sf::st_read
但对象是一个混乱的数据框。我需要我的最终对象是一个空间线数据框,这样我就可以将它与另一个空间线对象合并和裁剪,并写出生成的 shapefile。但是当我尝试 sp::SpatialLinesDataFrame
时,我无法正确索引到对象以按正确的顺序连接线。我需要 R 中的对象看起来像网页上的图片,而不是它只是一团糟。
这是我的代码:
library(geojsonio)
library(jsonlite)
library(sf)
library(sp)
Iraq_electric_json <- jsonlite::read_json("Filepath/electric-network-iraq.geojson")
Iraq_electric_df <- sf::st_read("Filepath/electric-network-iraq.geojson")
# ERRORS HERE
Sldf <- SpatialLinesDataFrame(data = Iraq_electric_df$geometry)
我在此处 post 编辑了我的问题的第一部分(如何读取 geojson 文件):
geojsonio::geojson_read error for a geojson file "conversion from feature type sfc_GEOMETRY to sp is not supported"
但是由于问题的第 2 部分(更改对象格式)与第 1 部分大不相同,我决定 post 一个全新的问题。
这很长,因为解决方案主要是四处挖掘并弄清楚您希望如何使用此文件。这里有一些潜在的问题:
- 就像我在您的第一个 post 中提到的那样,就 GeoJSON 文件的结构而言,该文件可能存在格式错误。一些阅读它的方法会发出最后一行不完整的警告;尾随空行是 json 文件中预期结构的一部分。
nodes
和 interconnection
属性是数组,我认为 R 函数不知道如何处理这些; sf
函数知道将这些读取为列表列,但这可能不适用于 geojsonio
个。
- 存在多种几何类型。
最后一点很重要,因为它会阻止您使用 sp::Spatial*
类——它们仅适用于单一几何类型(SpatialGrid
、SpatialPolygons
、 ETC。)。该文件将点和线混合在一起,因此您需要 sf
之类的东西来容纳混合的几何类型。
我尝试了几种阅读方式,其中一些 return 列出了您可以进一步挖掘的内容,一些 return sf
个对象:
library(dplyr)
library(sf)
path <- "https://development-data-hub-s3-public.s3.amazonaws.com/ddhfiles/145188/electric-network-iraq.geojson"
# sf
iraq1 <- st_read(path, drivers = "GeoJSON")
#> options: GeoJSON
#> Reading layer `electric-network-iraq' from data source
#> `https://development-data-hub-s3-public.s3.amazonaws.com/ddhfiles/145188/electric-network-iraq.geojson'
#> using driver `GeoJSON'
#> Simple feature collection with 48 features and 6 fields
#> Geometry type: GEOMETRY
#> Dimension: XY
#> Bounding box: xmin: 40.99849 ymin: 30.50785 xmax: 47.85893 ymax: 37.88342
#> Geodetic CRS: WGS 84
# list
iraq2 <- jsonlite::read_json(path)
str(iraq2, max.level = 1)
#> List of 2
#> $ type : chr "FeatureCollection"
#> $ features:List of 48
# list
iraq3 <- readLines(path) %>%
geojson::to_geojson() %>%
jsonlite::fromJSON()
#> Warning in readLines(path): incomplete final line found on 'https://development-
#> data-hub-s3-public.s3.amazonaws.com/ddhfiles/145188/electric-network-
#> iraq.geojson'
#> Registered S3 method overwritten by 'geojsonlint':
#> method from
#> print.location dplyr
# sf, same warning about incomplete final line
iraq4 <- suppressWarnings(geojsonsf::geojson_sf(path))
#> Registered S3 method overwritten by 'geojsonsf':
#> method from
#> print.geojson geojson
我将继续处理第一个,一个具有混合几何类型(只是通用 GEOMETRY
)的 sf
对象。注意这里有些是线,有些是点,还有两列是字符串列表。
head(iraq1)
#> Simple feature collection with 6 features and 6 fields
#> Geometry type: GEOMETRY
#> Dimension: XY
#> Bounding box: xmin: 41.12771 ymin: 36.34583 xmax: 43.12683 ymax: 37.88342
#> Geodetic CRS: WGS 84
#> transmissionPower lineType name nodeType nodes
#> 1 400 single <NA> <NA> Batman, Zakho
#> 2 NA <NA> Zakho city
#> 3 400 single <NA> <NA> Mosul Dam, Zakho
#> 4 NA <NA> Mosul Dam dam
#> 5 400 double <NA> <NA> Mosul, Mosul Dam
#> 6 NA <NA> Mosul city
#> interconnection geometry
#> 1 Syria, Turkey LINESTRING (41.12771 37.883...
#> 2 POINT (42.68304 37.14215)
#> 3 LINESTRING (42.68304 37.142...
#> 4 POINT (42.83355 36.62586)
#> 5 LINESTRING (42.83355 36.625...
#> 6 POINT (43.12683 36.34583)
plot(iraq1["geometry"])
如果你真的需要一个sp::Spatial
对象,你必须把点和线分开。我根据维数(点为 0,线为 1)拆分它们并写出现在可读的 GeoJSON 文件,然后将它们读回。最后你得到一个 SpatialPointsDataFrame
和一个 SpatialLinesDataFrame
。您不必将它们写入文件;您可以将每个数据帧传递给 sf::as_Spatial
并获得相同的 sp
类.
iraq1 %>%
mutate(dimension = st_dimension(geometry)) %>%
split(.$dimension) %>%
purrr::iwalk(~geojsonio::geojson_write(.x, file = sprintf("iraq_repaired_dim%s.geojson", .y)))
iraq_pts <- geojsonio::geojson_read("iraq_repaired_dim0.geojson", what = "sp")
iraq_lines <- geojsonio::geojson_read("iraq_repaired_dim1.geojson", what = "sp")
class(iraq_pts)
#> [1] "SpatialPointsDataFrame"
#> attr(,"package")
#> [1] "sp"
class(iraq_lines)
#> [1] "SpatialLinesDataFrame"
#> attr(,"package")
#> [1] "sp"
我从 EnergyData 下载了伊拉克电网的 geojson 文件。可以自己下载文件here and visit the webpage here
我尝试使用 geojsonio::geojson_read
将文件读入 R,但它抛出了错误。另一位用户热心指出,能源数据网站提供的文件格式不正确,不符合 geojson 格式,因此文件名具有误导性。所以他们建议我使用 jsonlite::read_json
。虽然该函数确实将文件读入 R,但它不是空间对象。这是一个多级列表。我也试过 sf::st_read
但对象是一个混乱的数据框。我需要我的最终对象是一个空间线数据框,这样我就可以将它与另一个空间线对象合并和裁剪,并写出生成的 shapefile。但是当我尝试 sp::SpatialLinesDataFrame
时,我无法正确索引到对象以按正确的顺序连接线。我需要 R 中的对象看起来像网页上的图片,而不是它只是一团糟。
这是我的代码:
library(geojsonio)
library(jsonlite)
library(sf)
library(sp)
Iraq_electric_json <- jsonlite::read_json("Filepath/electric-network-iraq.geojson")
Iraq_electric_df <- sf::st_read("Filepath/electric-network-iraq.geojson")
# ERRORS HERE
Sldf <- SpatialLinesDataFrame(data = Iraq_electric_df$geometry)
我在此处 post 编辑了我的问题的第一部分(如何读取 geojson 文件):
geojsonio::geojson_read error for a geojson file "conversion from feature type sfc_GEOMETRY to sp is not supported"
但是由于问题的第 2 部分(更改对象格式)与第 1 部分大不相同,我决定 post 一个全新的问题。
这很长,因为解决方案主要是四处挖掘并弄清楚您希望如何使用此文件。这里有一些潜在的问题:
- 就像我在您的第一个 post 中提到的那样,就 GeoJSON 文件的结构而言,该文件可能存在格式错误。一些阅读它的方法会发出最后一行不完整的警告;尾随空行是 json 文件中预期结构的一部分。
nodes
和interconnection
属性是数组,我认为 R 函数不知道如何处理这些;sf
函数知道将这些读取为列表列,但这可能不适用于geojsonio
个。- 存在多种几何类型。
最后一点很重要,因为它会阻止您使用 sp::Spatial*
类——它们仅适用于单一几何类型(SpatialGrid
、SpatialPolygons
、 ETC。)。该文件将点和线混合在一起,因此您需要 sf
之类的东西来容纳混合的几何类型。
我尝试了几种阅读方式,其中一些 return 列出了您可以进一步挖掘的内容,一些 return sf
个对象:
library(dplyr)
library(sf)
path <- "https://development-data-hub-s3-public.s3.amazonaws.com/ddhfiles/145188/electric-network-iraq.geojson"
# sf
iraq1 <- st_read(path, drivers = "GeoJSON")
#> options: GeoJSON
#> Reading layer `electric-network-iraq' from data source
#> `https://development-data-hub-s3-public.s3.amazonaws.com/ddhfiles/145188/electric-network-iraq.geojson'
#> using driver `GeoJSON'
#> Simple feature collection with 48 features and 6 fields
#> Geometry type: GEOMETRY
#> Dimension: XY
#> Bounding box: xmin: 40.99849 ymin: 30.50785 xmax: 47.85893 ymax: 37.88342
#> Geodetic CRS: WGS 84
# list
iraq2 <- jsonlite::read_json(path)
str(iraq2, max.level = 1)
#> List of 2
#> $ type : chr "FeatureCollection"
#> $ features:List of 48
# list
iraq3 <- readLines(path) %>%
geojson::to_geojson() %>%
jsonlite::fromJSON()
#> Warning in readLines(path): incomplete final line found on 'https://development-
#> data-hub-s3-public.s3.amazonaws.com/ddhfiles/145188/electric-network-
#> iraq.geojson'
#> Registered S3 method overwritten by 'geojsonlint':
#> method from
#> print.location dplyr
# sf, same warning about incomplete final line
iraq4 <- suppressWarnings(geojsonsf::geojson_sf(path))
#> Registered S3 method overwritten by 'geojsonsf':
#> method from
#> print.geojson geojson
我将继续处理第一个,一个具有混合几何类型(只是通用 GEOMETRY
)的 sf
对象。注意这里有些是线,有些是点,还有两列是字符串列表。
head(iraq1)
#> Simple feature collection with 6 features and 6 fields
#> Geometry type: GEOMETRY
#> Dimension: XY
#> Bounding box: xmin: 41.12771 ymin: 36.34583 xmax: 43.12683 ymax: 37.88342
#> Geodetic CRS: WGS 84
#> transmissionPower lineType name nodeType nodes
#> 1 400 single <NA> <NA> Batman, Zakho
#> 2 NA <NA> Zakho city
#> 3 400 single <NA> <NA> Mosul Dam, Zakho
#> 4 NA <NA> Mosul Dam dam
#> 5 400 double <NA> <NA> Mosul, Mosul Dam
#> 6 NA <NA> Mosul city
#> interconnection geometry
#> 1 Syria, Turkey LINESTRING (41.12771 37.883...
#> 2 POINT (42.68304 37.14215)
#> 3 LINESTRING (42.68304 37.142...
#> 4 POINT (42.83355 36.62586)
#> 5 LINESTRING (42.83355 36.625...
#> 6 POINT (43.12683 36.34583)
plot(iraq1["geometry"])
如果你真的需要一个sp::Spatial
对象,你必须把点和线分开。我根据维数(点为 0,线为 1)拆分它们并写出现在可读的 GeoJSON 文件,然后将它们读回。最后你得到一个 SpatialPointsDataFrame
和一个 SpatialLinesDataFrame
。您不必将它们写入文件;您可以将每个数据帧传递给 sf::as_Spatial
并获得相同的 sp
类.
iraq1 %>%
mutate(dimension = st_dimension(geometry)) %>%
split(.$dimension) %>%
purrr::iwalk(~geojsonio::geojson_write(.x, file = sprintf("iraq_repaired_dim%s.geojson", .y)))
iraq_pts <- geojsonio::geojson_read("iraq_repaired_dim0.geojson", what = "sp")
iraq_lines <- geojsonio::geojson_read("iraq_repaired_dim1.geojson", what = "sp")
class(iraq_pts)
#> [1] "SpatialPointsDataFrame"
#> attr(,"package")
#> [1] "sp"
class(iraq_lines)
#> [1] "SpatialLinesDataFrame"
#> attr(,"package")
#> [1] "sp"