Skip to content

Commit 7637548

Browse files
committed
Quick approximation for map projections
Instead of reprojecting everything, we just set the aspect ratio of the plot to the ratio between the length of one degree of lat over one degree of lon.
1 parent ae175ae commit 7637548

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Collate:
7171
'coord-map.r'
7272
'coord-munch.r'
7373
'coord-polar.r'
74+
'coord-quickmap.R'
7475
'coord-transform.r'
7576
'facet-.r'
7677
'facet-grid-.r'

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,14 @@ export(borders)
191191
export(calc_element)
192192
export(continuous_scale)
193193
export(coord)
194+
export(coord_aspect)
194195
export(coord_cartesian)
195196
export(coord_equal)
196197
export(coord_fixed)
197198
export(coord_flip)
198199
export(coord_map)
199200
export(coord_polar)
201+
export(coord_quickmap)
200202
export(coord_trans)
201203
export(cut_interval)
202204
export(cut_number)
@@ -289,6 +291,7 @@ export(position_identity)
289291
export(position_jitter)
290292
export(position_stack)
291293
export(qplot)
294+
export(quickmap)
292295
export(quickplot)
293296
export(rel)
294297
export(resolution)

R/coord-quickmap.R

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#' Cartesian coordinates with an aspect ratio approximating mercator projection.
2+
#'
3+
#' The represenation of a portion of the earth, wich is approximately spherical,
4+
#' onto a flat 2D plane requires a projection. This is what
5+
#' \code{\link{coord_map}} does. These projections account for the fact that the
6+
#' actual length (in km) of one degree of longitude varies between the equator
7+
#' and the pole. Near the equator, the ratio between the lengths of one degree
8+
#' of latitude and one degree of longitude is approximately 1. Near the pole, it
9+
#' is tends towards infinity because the length of one degree of longitude tends
10+
#' towards 0. For regions that span only a few degrees and are not too close to
11+
#' the poles, setting the aspect ratio of the plot to the appropriate lat/lon
12+
#' ratio approximates the usual mercator projection. This is what
13+
#' \code{coord_quickmap} does. With \code{\link{coord_map}} all elements of the
14+
#' graphic have to be projected which is not the case here. So
15+
#' \code{\link{coord_quickmap}} has the advantage of being much faster, in
16+
#' particular for complex plots such as those using with
17+
#' \code{\link{geom_tile}}, at the expense of correctedness in the projection.
18+
#'
19+
#' @export
20+
#' @inheritParams coord_cartesian
21+
#' @examples
22+
#' # ensures that the ranges of axes are equal to the specified ratio by
23+
#' # adjusting the plot aspect ratio
24+
#'
25+
#' if (require("maps")) {
26+
#' # Create a lat-long dataframe from the maps package
27+
#' nz <- map_data("nz")
28+
#' # Prepare a plot of the map
29+
#' nzmap <- ggplot(nz, aes(x=long, y=lat, group=group)) +
30+
#' geom_polygon(fill="white", colour="black")
31+
#'
32+
#' # Plot it in cartesian coordinates
33+
#' nzmap
34+
#' # With correct mercator projection
35+
#' nzmap + coord_map()
36+
#' # With the aspect ratio approximation
37+
#' nzmap + coord_quickmap()
38+
#' }
39+
#'
40+
#' # Resize the plot to see that the specified aspect ratio is maintained
41+
coord_quickmap <- function(xlim = NULL, ylim = NULL) {
42+
coord(limits = list(x = xlim, y = ylim),
43+
subclass = c("quickmap", "cartesian"))
44+
}
45+
46+
#' @export coord_aspect quickmap
47+
coord_aspect.quickmap <- function(coord, ranges) {
48+
# compute coordinates of center point of map
49+
x.center <- sum(ranges$x.range) / 2
50+
y.center <- sum(ranges$y.range) / 2
51+
52+
# compute distance corresponding to 1 degree in either direction
53+
# from the center
54+
x.dist <- dist_central_angle(x.center+c(-0.5,0.5), rep(y.center,2))
55+
y.dist <- dist_central_angle(rep(x.center,2), y.center+c(-0.5,0.5))
56+
# NB: this makes the projection correct in the center of the plot and
57+
# increasingly less correct towards the edges. For regions of reasonnable
58+
# size, this seems to give better results than computing this ratio from
59+
# the total lat and lon span.
60+
61+
# scale the plot with this aspect ratio
62+
ratio <- y.dist / x.dist
63+
64+
diff(ranges$y.range) / diff(ranges$x.range) * ratio
65+
}

man/coord_quickmap.Rd

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
% Generated by roxygen2 (4.0.0): do not edit by hand
2+
\name{coord_quickmap}
3+
\alias{coord_quickmap}
4+
\title{Cartesian coordinates with an aspect ratio approximating mercator projection.}
5+
\usage{
6+
coord_quickmap(xlim = NULL, ylim = NULL)
7+
}
8+
\arguments{
9+
\item{xlim}{limits for the x axis}
10+
11+
\item{ylim}{limits for the y axis}
12+
}
13+
\description{
14+
The represenation of a portion of the earth, wich is approximately spherical,
15+
onto a flat 2D plane requires a projection. This is what
16+
\code{\link{coord_map}} does. These projections account for the fact that the
17+
actual length (in km) of one degree of longitude varies between the equator
18+
and the pole. Near the equator, the ratio between the lengths of one degree
19+
of latitude and one degree of longitude is approximately 1. Near the pole, it
20+
is tends towards infinity because the length of one degree of longitude tends
21+
towards 0. For regions that span only a few degrees and are not too close to
22+
the poles, setting the aspect ratio of the plot to the appropriate lat/lon
23+
ratio approximates the usual mercator projection. This is what
24+
\code{coord_quickmap} does. With \code{\link{coord_map}} all elements of the
25+
graphic have to be projected which is not the case here. So
26+
\code{\link{coord_quickmap}} has the advantage of being much faster, in
27+
particular for complex plots such as those using with
28+
\code{\link{geom_tile}}, at the expense of correctedness in the projection.
29+
}
30+
\examples{
31+
# ensures that the ranges of axes are equal to the specified ratio by
32+
# adjusting the plot aspect ratio
33+
34+
if (require("maps")) {
35+
# Create a lat-long dataframe from the maps package
36+
nz <- map_data("nz")
37+
# Prepare a plot of the map
38+
nzmap <- ggplot(nz, aes(x=long, y=lat, group=group)) +
39+
geom_polygon(fill="white", colour="black")
40+
41+
# Plot it in cartesian coordinates
42+
nzmap
43+
# With correct mercator projection
44+
nzmap + coord_map()
45+
# With the aspect ratio approximation
46+
nzmap + coord_quickmap()
47+
}
48+
49+
# Resize the plot to see that the specified aspect ratio is maintained
50+
}
51+

0 commit comments

Comments
 (0)