ateucher / rmapshaper

An R wrapper for the mapshaper javascript library
http://andyteucher.ca/rmapshaper/
Other
200 stars 13 forks source link

ms_simplify produces clockwise instead of counterclockwise coordinates #167

Closed gittybobomber closed 10 months ago

gittybobomber commented 11 months ago

At least for R Plotly choropleth geo plots, the coordinates need to be counterclockwise, otherwise the outside area instead of the inside area gets colored. But ms_simplify produces clockwise instead of counterclockwise coordinates.

I have described the problem and a solution in detail here: https://stackoverflow.com/questions/77289351/choropleth-plot-gets-inverted-after-simplifying-geojson-with-rmapshaper

Could you change it or offer an option to chose between clockwise and counterclockwise?

ateucher commented 11 months ago

Interesting, it seems to be due to the fact the D3 requires rotation different to the simple features specification. Same issue reported here in the mapshaper repo.

I've simplified your example here:

library(plotly)
library(rmapshaper)
library(readr)

geojson <- read_file('https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_DEU_0.json') |> 
  ms_simplify(keep = 0.01)

g <- list(
  fitbounds = "locations",
  projection = list(type = 'mercator'),
  visible = FALSE
)

fig <- plot_ly()
fig <- fig %>% add_trace(
  type="choropleth",
  geojson=jsonlite::fromJSON(geojson, simplifyDataFrame = FALSE),
  locations="Germany",
  text="Germany",
  z=0,
  colors = c('white','#ed6a12'),
  showscale=T,
  marker = list(line=list(color='grey',width=0.25)),
  featureidkey = 'properties.COUNTRY'
)

fig <- fig %>% layout(
  geo = g
)

fig

image

ateucher commented 11 months ago

I'll see about adding the -o gj2008 flag as an argument, stay tuned.

ateucher commented 11 months ago

@gittybobomber this works for me now. Please install from:

remotes::install_github("ateucher/rmapshaper@gj-2008")

and try again, setting gj2008 = TRUE:

# remotes::install_github("ateucher/rmapshaper@gj-2008")

library(plotly)
library(rmapshaper)
library(readr)

geojson <- read_file('https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_DEU_0.json') |> 
  ms_simplify(keep = 0.01, gj2008 = TRUE)

g <- list(
  fitbounds = "locations",
  projection = list(type = 'mercator'),
  visible = FALSE
)

fig <- plot_ly()
fig <- fig %>% add_trace(
  type="choropleth",
  geojson=jsonlite::fromJSON(geojson, simplifyDataFrame = FALSE),
  locations="Germany",
  text="Germany",
  z=0,
  colors = c('white','#ed6a12'),
  showscale=T,
  marker = list(line=list(color='grey',width=0.25)),
  featureidkey = 'properties.COUNTRY'
)

fig <- fig %>% layout(
  geo = g
)

fig

image

gittybobomber commented 11 months ago

Thanks a lot, but unfortunately I have problems installing it.

I uninstall/unload first (otherwise R Warning: Paket rmapshaper wird gerade benutzt und deshab nicht installiert"): detach("package:rmapshaper", unload=TRUE) remove.packages('rmapshaper')

Then I install from your github: remotes::install_github("ateucher/rmapshaper@gj-2008") library(rmapshaper)

Then run geojson <- read_file('https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_DEU_0.json') |> ms_simplify(keep = 0.01, gj2008 = TRUE, sys = TRUE)

I get error: Error: The mapshaper node library must be installed and on your PATH. Install node.js (https://nodejs.org/en/) and then install mapshaper with: npm install -g mapshaper (I installed node.js, still error)

Or if I run geosf <- geojson_sf('https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_DEU_0.json') geosf_simpl <- ms_simplify(geosf, keep = 0.01, gj2008 = TRUE, sys = TRUE)

I get error: Error in ms_sf(input, call, ...) : unused argument (gj2008 = TRUE)

I don't get these errors when I use the "normal" install.packages('rmapshaper'). Can you advise, please?

ateucher commented 11 months ago

Oh, sorry! I think the installation was fine, but I accidentally pasted the wrong ms_simplify() call. You can leave out sys= TRUE and just use:

geosf_simpl <- ms_simplify(geojson, keep = 0.01, gj2008 = TRUE)
ateucher commented 11 months ago

When you tried it on the sf object, that error is expected as it doesn't make sense for sf objects to be wound the wrong way. But I will make that error clearer.

Edit: I did implement the gj2008 argument for sf objects, though it seems unlikely to be helpful here

gittybobomber commented 10 months ago

Thank you very much, it works now!

Just another question: In the webservice https://mapshaper.org/ it is possible to tranform in the console via

$ -proj from=EPSG:25833 crs=EPSG:4326

from the coordinate system used by the official German statistical office https://regionalatlas.statistikportal.de/ UTM, Zone 32N, Datum ETRS89 (EPSG: 25832)

to the GeoJSON standard coordinations World Geodetic System EPSG 4326, WGS84

Is this possible with rmapshaper, too? Could not find it yet.

ateucher commented 10 months ago

Is this possible with rmapshaper, too? Could not find it yet.

Not directly, because I try not to replicate what's already available in existing tools (I.e., sf::st_transform()).

You can perform pretty much any mapshaper command on geojson objects in R with apply_mapshaper_commands(), however it's not working at the moment with -proj... not sure why