1

I am working with the Native Land data accessible via API:


library(httr)
library(jsonlite)
library(raster)
library(sf)
library(tmap)

res = GET("https://native-land.ca/api/index.php?maps=languages,territories")
data = fromJSON(rawToChar(res$content))

The resulting dataframe contains a geometry variable that appears like so:

enter image description here

I tried creating an sf object

dataSf = st_as_sf(data, coords = "geometry$coordinates",
 crs = "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")

But I receive an error message, "Error: undefined columns selected". I also substituted wkt for coords in the code above and receive an error message: "replacement has 0 rows, data has 3424".

How can I convert this dataframe into an SF object?

4
  • The JSON returned is almost a geoJSON file. It's mentioned in the docs: "The data comes down from these as a list of features, though not a full geoJSON. This should still be useful in any web application. " with a template of how to make a full geoJSON from it. That would be the best way to do this. Download the API response and make a correct geoJSON file, then read that with st_read.
    – Spacedman
    Commented Sep 4, 2022 at 21:08
  • The data appears to be a mix of 2-d "POLYGON" objects and 3-d "POLYGON Z" objects, which sf doesn't like and throws an error. This is also a problem with the downloaded geoJSON objects of the whole data set, like: 149613070.v2.pressablecdn.com/coordinates/…
    – Spacedman
    Commented Sep 4, 2022 at 21:16
  • Thank you. I want to make sure I understand your suggestion fully. You are recommending that I download the dataframe that I obtain through the API, then do something to it to make it more readable in, say, Excel, then try reading it again in R? If that's the case, do you have any sources on how to make a "full geo JSON"?
    – user157564
    Commented Sep 4, 2022 at 21:22
  • I tried to download the geoJSON and convert it to an ESRI shapefile online. This yields an object that looks a lot more like what I have in mind. But I cannot implement any sf commands over it. I can plot it using plot( ) but I need to be able to do more with it than that. Any suggestions?
    – user157564
    Commented Sep 4, 2022 at 22:32

1 Answer 1

1

There are two problems here. First, the API returns a fragment of a GeoJSON file, which would be a valid file for st_read to consume if it wasn't a fragment. One fix to this would be to use paste functions (or other text manipulation) to build a complete GeoJSON file and then read that.

The downloadable "territories" JSON file given here https://native-land.ca/resources/api-docs/ is a valid geoJSON file, so you could use that if you want to get all the data and aren't doing anything more complex with their API calls.

But then you hit the second problem.

The second problem is that the data has a mixture of 2-D polygons and 3-D polygons. While I think this is valid under the OGC Simple Features data model (QGIS and other GDAL/OGR tools read it in okay) it seems the R sf package isn't happy with it:

> terr = st_read("./indigenousTerritories.json")
Reading layer `indigenousTerritories' from data source 
  `/path/indigenousTerritories.json' 
  using driver `GeoJSON'
Error in CPL_get_z_range(obj, 3) : z error - expecting three columns;

I can't see any option to handle this except maybe the "type" parameter, which still gives the same error even when trying to read as a "GEOMETRYCOLLECTION" which I thought might treat each geometry separately, so that the varying dimensions would be allowed for, but no:

> terr = st_read("./indigenousTerritories.json", type=7)
Reading layer `indigenousTerritories' from data source 
  `/path/indigenousTerritories.json' 
  using driver `GeoJSON'
converted into: GEOMETRYCOLLECTION
Error in CPL_get_z_range(obj, 1) : z error - expecting three columns;

Fix I have now is to use the ogr2ogr command-line tool with its -dim option to convert to something with consistent dimension:

$ ogr2ogr indigenousTerritories.gpkg indigenousTerritories.json -dim XY
Warning 1: Field 'ID' already exists. Renaming it as 'ID2'

Then you can read from that GeoPackage:

> library(sf)
Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1; sf_use_s2() is TRUE
> terr = st_read("./indigenousTerritories.gpkg")
Reading layer `indigenousTerritories' from data source 
  `/nobackup/rowlings/Downloads/SO/indigenousTerritories.gpkg' 
  using driver `GPKG'
Simple feature collection with 2024 features and 6 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -189.8148 ymin: -56.02359 xmax: 178.5443 ymax: 83.77334
Geodetic CRS:  WGS 84

If you don't have the command line tools you can get them with the gdalUtils R package and call them from R:

> library(gdalUtils)
> ogr2ogr("./indigenousTerritories.json", "indigenousTerritories.gpkg", dim="XY")
Warning 1: Field 'ID' already exists. Renaming it as 'ID2'
character(0)
> terr = st_read("./indigenousTerritories.gpkg", quiet=TRUE)
> 

This issue with mixed dimensions has come up before and was marked closed: https://github.com/r-spatial/sf/issues/1592 so I'm not sure why its still failing on my sf: 1.0-5 and later, according to reports.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.