0

sf function st_cast() doesn't work on SpatVectors, and I've tried to look for a way to convert all geometries to single polygons, but to no success.

Is there a way to do that in R ?

I guess something similar to "Multipart to siglepart" from QGIS but in R.

Here's a sample of the SpatVector that I'm trying to convert :

{
"type": "FeatureCollection",
"name": "ouep",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "lat": 0.0094476802225528719, "lon": -7.4798193078730311, "area_m2": 0.0053714972533285736, "perimeter": 0.55000130419074167, "type": "Moving clip", "area_change": 2.8756180885289577 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -7.479819246345164, 0.009447066030968 ], [ -7.479819145284656, 0.009447108424846 ], [ -7.479819052647101, 0.009447244082252 ], [ -7.47981895158866, 0.009447447567867 ], [ -7.47981892632492, 0.009447566267372 ], [ -7.479818934750374, 0.00944785453669 ], [ -7.479818976861431, 0.009448032584906 ], [ -7.479819103189485, 0.009448168239464 ], [ -7.479819187407355, 0.009448193673906 ], [ -7.479819431637903, 0.009448168235192 ], [ -7.479819557963348, 0.009448100405448 ], [ -7.479819734817685, 0.009447905397359 ], [ -7.479819776925042, 0.009447795176148 ], [ -7.479819785345598, 0.0094477019124 ], [ -7.479819785343749, 0.009447557777687 ], [ -7.479819751656188, 0.009447515385562 ], [ -7.479819734811918, 0.009447456036193 ], [ -7.479819701124574, 0.009447430601094 ], [ -7.479819616907032, 0.009447430602189 ], [ -7.479819591642204, 0.009447464516568 ], [ -7.479819583221212, 0.009447523866265 ], [ -7.479819591644271, 0.009447625608307 ], [ -7.479819591645795, 0.009447744307482 ], [ -7.479819549538218, 0.009447837571668 ], [ -7.479819448478582, 0.009447947793646 ], [ -7.47981933899643, 0.009447998666145 ], [ -7.479819212670114, 0.009447998667788 ], [ -7.479819162139155, 0.009447964754395 ], [ -7.479819136873131, 0.009447905405136 ], [ -7.479819103183067, 0.009447668007222 ], [ -7.479819120024289, 0.00944748995824 ], [ -7.4798192463481, 0.009447294950808 ], [ -7.479819280035664, 0.009447337342932 ], [ -7.479819288458179, 0.009447396692411 ], [ -7.479819305302012, 0.009447422127729 ], [ -7.479819423206574, 0.009447422126196 ], [ -7.479819456893156, 0.009447388211707 ], [ -7.479819456891525, 0.009447261034019 ], [ -7.479819423203309, 0.009447167770819 ], [ -7.47981933898479, 0.009447091465301 ], [ -7.479819246345164, 0.009447066030968 ] ] ] ] } },
{ "type": "Feature", "properties": { "lat": 0.0094408986852160467, "lon": -7.479818762002111, "area_m2": 0.0057125168264737453, "perimeter": 0.57850928640435806, "type": "Moving clip", "area_change": 2.6806622600462524 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -7.479818673578972, 0.009440291706874 ], [ -7.479818572518358, 0.009440325622238 ], [ -7.479818471458828, 0.009440444322727 ], [ -7.479818404086967, 0.009440613893854 ], [ -7.479818378823443, 0.009440749550384 ], [ -7.479818378824422, 0.009440825856997 ], [ -7.479818395669235, 0.009440927598929 ], [ -7.479818395670651, 0.009441037819592 ], [ -7.479818437782574, 0.00944128369591 ], [ -7.479818580954029, 0.009441410871737 ], [ -7.479818682015514, 0.009441444784474 ], [ -7.479818740967795, 0.009441444783708 ], [ -7.479818926245738, 0.009441393910224 ], [ -7.479819086257329, 0.009441258251943 ], [ -7.479819204160149, 0.00944112259421 ], [ -7.479819221002352, 0.00944102085184 ], [ -7.479819246267072, 0.009440978458949 ], [ -7.479819263109386, 0.009440885195092 ], [ -7.479819237843252, 0.00944081736732 ], [ -7.479819229419868, 0.009440690189741 ], [ -7.479819162045507, 0.009440664755079 ], [ -7.47981909467169, 0.00944068171298 ], [ -7.479819035720173, 0.009440741063334 ], [ -7.479819052565637, 0.009440893676341 ], [ -7.479819018880796, 0.00944106324703 ], [ -7.479818850447558, 0.009441207383933 ], [ -7.479818707278277, 0.009441249778357 ], [ -7.479818639903916, 0.009441224343695 ], [ -7.479818589372195, 0.009441131080713 ], [ -7.479818555681589, 0.009440851290236 ], [ -7.479818555680393, 0.009440758026598 ], [ -7.47981860620918, 0.00944062236974 ], [ -7.479818648316972, 0.00944054606258 ], [ -7.4798186904252, 0.00944050366947 ], [ -7.479818707268708, 0.009440503669251 ], [ -7.479818724112869, 0.009440554540107 ], [ -7.479818732536364, 0.009440690196199 ], [ -7.47981874938009, 0.009440707153005 ], [ -7.479818791489078, 0.009440724109483 ], [ -7.479818867284868, 0.009440724108498 ], [ -7.47981891781485, 0.009440681715278 ], [ -7.479818900968623, 0.009440469752683 ], [ -7.479818850436793, 0.009440368011189 ], [ -7.479818799905614, 0.00944031714077 ], [ -7.479818673578972, 0.009440291706874 ] ] ] ] } },
{ "type": "Feature", "properties": { "lat": 0.0094344091100990318, "lon": -7.4798182693341619, "area_m2": 0.0057555837422150194, "perimeter": 0.56625903964917079, "type": "Moving clip", "area_change": 10.779772909142428 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -7.479818176612329, 0.009433805651213 ], [ -7.47981807555182, 0.009433848045088 ], [ -7.479817966070644, 0.009433975224198 ], [ -7.479817932384386, 0.009434034574224 ], [ -7.479817873434605, 0.009434229580779 ], [ -7.479817873437865, 0.009434483936156 ], [ -7.479817932393731, 0.009434763726306 ], [ -7.479818050299812, 0.00943488242395 ], [ -7.479818134517898, 0.009434924815419 ], [ -7.479818336639893, 0.009434916334281 ], [ -7.479818505074219, 0.009434856982506 ], [ -7.479818631399121, 0.009434746760201 ], [ -7.479818698772178, 0.009434670452713 ], [ -7.479818749299986, 0.009434458489243 ], [ -7.479818740874973, 0.009434204133975 ], [ -7.479818698765549, 0.009434153263446 ], [ -7.479818606126362, 0.009434161743162 ], [ -7.47981857243956, 0.009434178700625 ], [ -7.479818530331441, 0.009434229572247 ], [ -7.479818538757107, 0.00943453479859 ], [ -7.479818521914141, 0.009434577191372 ], [ -7.479818479806022, 0.009434628062994 ], [ -7.479818302950376, 0.00943472132893 ], [ -7.479818176624062, 0.009434721330571 ], [ -7.47981812609321, 0.009434695895689 ], [ -7.47981807556073, 0.009434543283119 ], [ -7.479818058714939, 0.009434365234574 ], [ -7.47981804187078, 0.009434314363717 ], [ -7.479818041870235, 0.009434271971154 ], [ -7.479818075556166, 0.009434187185591 ], [ -7.479818159771971, 0.009434051528296 ], [ -7.479818201880417, 0.009434026092211 ], [ -7.479818227145895, 0.009434043048908 ], [ -7.479818252412571, 0.009434153269244 ], [ -7.479818277678159, 0.009434178704453 ], [ -7.479818387161075, 0.009434187181544 ], [ -7.479818437691166, 0.009434153266837 ], [ -7.479818412423839, 0.009433992175427 ], [ -7.47981837031398, 0.009433907390848 ], [ -7.479818277673597, 0.009433822606925 ], [ -7.479818176612329, 0.009433805651213 ] ] ] ] } }
]
}

importing it with terra: vector = vect(file.path("input.geojson"))

The goal would be for it to have geometry type "Polygon"

3
  • 1
    Your sample doesn't seem to be MULTIPOLYGON - it looks like three features, all single ring POLYGON objects.
    – Spacedman
    Mar 24 at 16:44
  • Hi @Spacedman, yes those are polygons and the problem is that they're marked as Multi when they're not. The platform I'm working with doesn't accept multipolygons, and that's why I'm trying to change the type actually Mar 27 at 9:22
  • I would honestly stay in a sf class and coerce to terra Vect when necessary. You can always just do it on the fly eg., extract(y, vect(x)) Apr 6 at 21:06

1 Answer 1

2

The equivalent in terra is terra::disagg()

As @Spacedman pointed out, your geojson (although named MULTIPOLYGON) are in reality POLYGON, so I used dummy data to demonstrate how to do this on terra:

library(sf)
#> Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE



in_sf <- giscoR::gisco_get_countries(country = c("DNK"))
in_sf
#> Simple feature collection with 1 feature and 5 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: 8.10064 ymin: 54.60267 xmax: 15.15353 ymax: 57.67627
#> Geodetic CRS:  WGS 84
#>    CNTR_ID NAME_ENGL ISO3_CODE CNTR_NAME FID                       geometry
#> 98      DK   Denmark       DNK   Danmark  DK MULTIPOLYGON (((9.42015 54....
plot(in_sf$geometry, col=c("red", "blue", "green"))

# Cast with sf
in_sf_casted <- st_cast(in_sf, "POLYGON") 
#> Warning in st_cast.sf(in_sf, "POLYGON"): repeating attributes for all
#> sub-geometries for which they may not be constant
in_sf_casted
#> Simple feature collection with 15 features and 5 fields
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: 8.10064 ymin: 54.60267 xmax: 15.15353 ymax: 57.67627
#> Geodetic CRS:  WGS 84
#> First 10 features:
#>      CNTR_ID NAME_ENGL ISO3_CODE CNTR_NAME FID                       geometry
#> 98        DK   Denmark       DNK   Danmark  DK POLYGON ((9.42015 54.83196,...
#> 98.1      DK   Denmark       DNK   Danmark  DK POLYGON ((12.58275 55.80797...
#> 98.2      DK   Denmark       DNK   Danmark  DK POLYGON ((10.40881 55.59131...
#> 98.3      DK   Denmark       DNK   Danmark  DK POLYGON ((15.15353 55.07771...
#> 98.4      DK   Denmark       DNK   Danmark  DK POLYGON ((10.73503 54.74956...
#> 98.5      DK   Denmark       DNK   Danmark  DK POLYGON ((11.09601 57.26031...
#> 98.6      DK   Denmark       DNK   Danmark  DK POLYGON ((10.6356 55.78535,...
#> 98.7      DK   Denmark       DNK   Danmark  DK POLYGON ((8.57284 55.08161,...
#> 98.8      DK   Denmark       DNK   Danmark  DK POLYGON ((8.59464 56.60148,...
#> 98.9      DK   Denmark       DNK   Danmark  DK POLYGON ((10.46664 54.88936...
plot(in_sf_casted$geometry, col=c("red", "blue", "green"))


# With SpatVector
library(terra)
#> terra 1.7.18
spv <- vect(in_sf) 
spv
#>  class       : SpatVector 
#>  geometry    : polygons 
#>  dimensions  : 1, 5  (geometries, attributes)
#>  extent      : 8.10064, 15.15353, 54.60267, 57.67627  (xmin, xmax, ymin, ymax)
#>  coord. ref. : lon/lat WGS 84 (EPSG:4326) 
#>  names       : CNTR_ID NAME_ENGL ISO3_CODE CNTR_NAME   FID
#>  type        :   <chr>     <chr>     <chr>     <chr> <chr>
#>  values      :      DK   Denmark       DNK   Danmark    DK

plot(spv, col=c("red", "blue", "green"))


spv_cast <- disagg(spv)

spv_cast
#>  class       : SpatVector 
#>  geometry    : polygons 
#>  dimensions  : 15, 5  (geometries, attributes)
#>  extent      : 8.10064, 15.15353, 54.60267, 57.67627  (xmin, xmax, ymin, ymax)
#>  coord. ref. : lon/lat WGS 84 (EPSG:4326) 
#>  names       : CNTR_ID NAME_ENGL ISO3_CODE CNTR_NAME   FID
#>  type        :   <chr>     <chr>     <chr>     <chr> <chr>
#>  values      :      DK   Denmark       DNK   Danmark    DK
#>                     DK   Denmark       DNK   Danmark    DK
#>                     DK   Denmark       DNK   Danmark    DK

plot(spv_cast, col=c("red", "blue", "green"))

Created on 2023-03-24 with reprex v2.0.2

3
  • Note that sf provides the MULTIPOLYGON description while terra describes both POLYGON and MULTIPOLYGON as #> geometry : polygons , so there is not an easy way to tell on terra if you have MULTI or not.
    – dieghernan
    Mar 24 at 19:54
  • Thank you so much for your detailed answer ! I appreciate it. But if my multipolygons are already single polygons, it seems that there's no simple way in Terra to just change the type. I should then try to go from SpatVector to feature collection to do it. Mar 27 at 11:28
  • You can still try to do terra::disagg() but you won’t notice any change on your SpatVector
    – dieghernan
    Mar 27 at 14:07

Your Answer

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

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