-
Couldn't load subscription status.
- Fork 2.1k
Implement geom_sf_label() and geom_sf_text() #2761
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
Conversation
|
This PR is ready to review now. But, I don't see why Travis fails. especially, on R 3.1; it fails on |
|
The sf package is missing for 3.1. For the more recent releases, I have noticed that Travis seems to have network issues today. If you restart a failed build it may pass the next time. |
|
Thanks. Hmm, does absense of sf affects the function args? If so, I think I'm missing something. Anyway, will give it a try later. |
When sf package is not installed, test-function-args fails.
2228250 to
7111bf7
Compare
|
OK, I think I found the cause. I've made two mistakes below, both of which are not appropriate when sf package is not installed.
|
7111bf7 to
b444c24
Compare
b444c24 to
bfe7f3a
Compare
|
Confirmed the build on 3.1 passed! Thank you for your advice, Claus. (devel still fails due to the curl's "Connection timed out" error; I think I'm not lucky enough to let all 5 builds pass at the same time...) |
|
You can restart just one particular failed build by clicking on the reload icon to the right of it. In this way, you won't mess up the builds that already succeeded. I have a few comments/questions:
|
The icon doesn't show; it seems I don't have the permission, unfortunately. |
|
(Disclaimer: I'm not a GIS expert but a guy who just wants to add labels on
In sf package (and probably in simple feature access), they are always written as capital. So, I felt it's more natural to use capital letters for computed variables so that we can distinguish them from ggplot's coordinates. That said, I'm still wondering whether they are essentially the same thing,
Thanks, this sounds nice.
Different. As described above,
Your suggestion is about when the first step succeeds but doesn't return For example, consider we have a library(ggplot2)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, proj.4 4.9.3
mat_poly_xy <- rbind(
c(1, 1), c(-1, 1), c(-1, -1), c(1, -1), c(1, 1)
)
poly_xy <- st_polygon(list(mat_poly_xy))
poly_xy
#> POLYGON ((1 1, -1 1, -1 -1, 1 -1, 1 1))In this case, we can choose a point on the polygon by d_poly_xy <- st_sf(geometry = st_sfc(poly_xy))
d_pt_xy <- st_point_on_surface(d_poly_xy)
xy <- st_coordinates(d_pt_xy)So we can combine the coordinates with the original data cbind(d_pt_xy, xy)
#> Simple feature collection with 1 feature and 2 fields
#> geometry type: POINT
#> dimension: XY
#> bbox: xmin: 0 ymin: 0 xmax: 0 ymax: 0
#> epsg (SRID): NA
#> proj4string: NA
#> X Y geometry
#> 1 0 0 POINT (0 0)But, if the polygon has mat_poly_xym <- cbind(mat_poly_xy, 1)
poly_xym <- st_polygon(list(mat_poly_xym), dim = "XYM")
poly_xym
#> POLYGON M ((1 1 1, -1 1 1, -1 -1 1, 1 -1 1, 1 1 1))
d_poly_xym <- st_sf(geometry = st_sfc(poly_xym))
st_point_on_surface(d_poly_xym)
#> Error in CPL_geos_op("point_on_surface", x, numeric(0), integer(0), numeric(0), : GEOS does not support XYM or XYZM geometries; use st_zm() to drop M |
Ah, in short, I commented about errors when Z and/or M are available, which is not always happy. Does my answer make sense? |
|
The Z and M issue still isn't entirely clear to me. Do I understand correctly that the default setup fails if the geometries contain Z or M coordinates? In this case, wouldn't it be better for the default to remove Z and M and then run #' @param fun.geometry
#' A function that takes a `sfc` object and returns a `sfc_POINT` with the
#' same length as the input. If `NULL`, `function(x) sf::st_point_on_surface(sf::st_zm(x))` will be
#' used. |
Generally, yes. (It may not fail depending on what Thanks,
Does this look better to you? |
|
I have no idea why the Travis build still fails, but it seems unrelated to this PR. |
|
Ah, do I have to wait for #2838 to be solved? |
|
I assume it's because of #2824. That needs to be resolved first. |
|
I got it, Sorry that I don't keep up the discussion... |
|
#2824 is now resolved. |
|
Yay, all checks passed! |
|
Looks good to me. @hadley, any concerns from your side? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of documentation style issues, and needs a news bullet; otherwise looks good!
R/sf.R
Outdated
| #' an unusual geom because it will draw different geometric objects depending | ||
| #' on what simple features are present in the data: you can get points, lines, | ||
| #' or polygons. | ||
| #' For texts and labels, you can use `geom_sf_text` and `geom_sf_label`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
text -> text; functions should have () after them
R/sf.R
Outdated
| #' @rdname ggsf | ||
| #' @inheritParams geom_label | ||
| #' @inheritParams stat_sf_coordinates | ||
| #' @seealso [stat_sf_coordinates()] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this seealso belongs in the documentation block above.
R/stat-sf-coordinates.R
Outdated
| #' | ||
| #' `stat_sf_coordinates()` extracts the coordinates from 'sf' objects and | ||
| #' summarises them to one pair of coordinates (x and y) per geometry. This is | ||
| #' convenient when you draw an sf object as geoms like texts and labels (so |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
texts -> text (English is weird)
|
Thanks! I was very anxious if my English is strange, so the comments are very helpful... For a news bullet, should I wait for the release of v3.0.1? |
|
No, please add the news bullet now. Thanks! |
|
Sure! |
|
Added a bullet. |
|
@clauswilke Could you merge this if this is OK? Then I can create another PR to improve the error message you commented :) |
|
Thanks! |
|
This is an extremely useful feature. Thanks!!! |
|
The merge broke the build. Could you look into what's going wrong? I'm in meetings all day. |
|
Hmm, sorry if this is my fault. I will investigate. |
|
Now it's all green. I definitely saw "error" status, but I can't find the errored build in the history. What happened...? |
|
Did I deleted my branch too early? |
|
Anyway, it seems alright now. |
|
This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/ |
This PR closes #2742.
Background
It's very convenient that
geom_sf()automatically chooses the proper geometries (point, line or polygon) based on the type of the simple feature in the data. But, we sometimes want to choose different type of geoms, for example, texts and labels.However, adding flexibility to
geom_sf()(or underlyingsf::st_as_grob()) leads to unmaintainable complexity as discussed in #2111. So, we need to implement it as separate geoms/stats for code simplicity. Here, I proposegeom_sf_label()andgeom_sf_text(), and their corresponding statstat_sf_coordinates().Design
StatSfCoordinatesTexts and labels need pairs of
xandy.StatSfCoordinatesis a stat to provide these via computed variablexandy(lower letters).stat_sf_coordinates()is thestat_function corresponding to this.XandYdimensions of asfobject can be retrieved bysf::st_coordinates(). But, we cannot simply usesf::st_coordinates()texts and labels require exactly one coordinate per geometry whereas it returns multiple locations for a polygon or a line. Instead, these two steps are needed:sf::st_centroid()andsf::st_point_on_surface().sf::st_coordinates().For the first step, users can pass arbitrary function via parameter
fun.geometry. By default,function(x) sf::st_point_on_surface(sf::st_zm(x))is used; I thinksf::st_point_on_surface()is more appropriate thansf::st_centroid()since labels and texts usually are intended to be put within the polygon or the line.geom_sf_label()andgeom_sf_text()geom_sf_label()andgeom_sf_text()are basically same withgeom_label()andgeom_text()for each, except that:StatSfCoordinatesforstatgeometryaesthetic automatically just asgeom_sf()doesfun.geometryargumentConsiderations
ZandMdimensionSimple feature objects may have
Zand/orMdimension in addition toXandY. These dimensions may be useful, but sometimes they are problematic:Mdimension makes functions likesf::st_point_on_surface()andsf::st_centroid()fail.Zdimension may do no harm, butZdimension is not always available in the results.For simplicity, we simply drop
ZandMand use onlyXandY.Warning for longitude/latitude data
Functions that does calculation based on the distances may warn if the on data is in unprojected coordinate system. Though the warnings should not be suppressed, we need to be careful to use
geom_sf_label()in examples. Otherwise, the tests fail.TODOs
stat_sf_coordinates()fun.geometryZandMdimension? (no)Usages
Created on 2018-08-19 by the reprex package (v0.2.0).