Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ms_simplify produces clockwise instead of counterclockwise coordinates #167

Closed
gittybobomber opened this issue Oct 14, 2023 · 8 comments · Fixed by #168
Closed

ms_simplify produces clockwise instead of counterclockwise coordinates #167

gittybobomber opened this issue Oct 14, 2023 · 8 comments · Fixed by #168

Comments

@gittybobomber
Copy link

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
Copy link
Owner

ateucher commented Oct 18, 2023

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
Copy link
Owner

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

@ateucher
Copy link
Owner

ateucher commented Oct 18, 2023

@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

ateucher added a commit that referenced this issue Oct 18, 2023
ateucher added a commit that referenced this issue Oct 18, 2023
@gittybobomber
Copy link
Author

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
Copy link
Owner

ateucher commented Oct 19, 2023

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
Copy link
Owner

ateucher commented Oct 19, 2023

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
Copy link
Author

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
Copy link
Owner

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

ateucher added a commit that referenced this issue Oct 23, 2023
* Add gj2008 flag to allow reverse winding order

* Expose gj2008 flag in dots arguments

* Ensure all -o flags are passed together

* Add test for #167

* Update NEWS for #167, #168

* Add gj2008 to sf and sp methods

* Remove spurious argument to fc_command()

* Add gj2008 to clip and erase

* Ensure quiet flag is passed through appropriately

* Update documenation for gj2008 flag

* Update snapshot

* quiet flag only apply when sys = TRUE

* Test gj2008 with sf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants