--- title: "Map Projections" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Map Projections} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(geographiclib) ``` This vignette covers the map projections available in geographiclib. Each projection has different properties making it suitable for different purposes. ## Contents - [Example Locations](#example-locations) - [UTM/UPS - Universal Transverse Mercator](#utmups---universal-transverse-mercator) - [Transverse Mercator (Custom)](#transverse-mercator-custom) - [Lambert Conformal Conic (LCC)](#lambert-conformal-conic-lcc) - [Albers Equal Area](#albers-equal-area) - [Polar Stereographic](#polar-stereographic) - [Azimuthal Equidistant](#azimuthal-equidistant) - [Cassini-Soldner Projection](#cassini-soldner-projection) - [Gnomonic Projection](#gnomonic-projection) - [OSGB - Ordnance Survey National Grid](#osgb---ordnance-survey-national-grid) - [Projection Comparison](#projection-comparison) - [See Also](#see-also) ## Example Locations We'll use a mix of Northern and Southern Hemisphere locations: ```{r locations} # Australian cities australia <- cbind( lon = c(151.21, 144.96, 153.02, 115.86, 138.60), lat = c(-33.87, -37.81, -27.47, -31.95, -34.93) ) rownames(australia) <- c("Sydney", "Melbourne", "Brisbane", "Perth", "Adelaide") # Antarctic stations antarctic <- cbind( lon = c(166.67, 77.97, 39.58, -64.05, 0), lat = c(-77.85, -68.58, -67.60, -64.25, -90) ) rownames(antarctic) <- c("McMurdo", "Davis", "Mawson", "Palmer", "South Pole") # World cities world_pts <- cbind( lon = c(-0.13, -74.01, 139.69, 151.21, -43.17), lat = c(51.51, 40.71, 35.69, -33.87, -22.91) ) rownames(world_pts) <- c("London", "New York", "Tokyo", "Sydney", "Rio") ``` ## UTM/UPS - Universal Transverse Mercator UTM divides the Earth into 60 zones, each 6 degrees wide. For polar regions (>84N or <80S), UPS (Universal Polar Stereographic) is used instead. ### Basic Conversion ```{r utm-basic} # Convert Australian cities utmups_fwd(australia) ``` ### Understanding UTM Zones ```{r utm-zones} # Points at different longitudes show different zones lon_transect <- cbind( lon = seq(-180, 180, by = 30), lat = -45 ) result <- utmups_fwd(lon_transect) data.frame( lon = result$lon, zone = result$zone, northp = result$northp, crs = result$crs ) ``` ### Polar Regions (UPS) When zone = 0, the projection is UPS rather than UTM: ```{r utm-polar} # Antarctic stations utmups_fwd(antarctic) ``` ### Round-trip Conversion ```{r utm-roundtrip} fwd <- utmups_fwd(australia) rev <- utmups_rev(fwd$x, fwd$y, fwd$zone, fwd$northp) # Verify accuracy max(abs(rev$lon - australia[,1])) max(abs(rev$lat - australia[,2])) ``` ## Transverse Mercator (Custom) For custom Transverse Mercator projections with user-defined central meridian and scale factor (unlike UTM which auto-selects zones): ```{r tm-custom} # Custom TM centered on Tasmania tm_fwd(australia, lon0 = 147, k0 = 1.0) # Compare series approximation vs exact pts <- cbind(lon = c(147, 148, 149), lat = c(-42, -43, -44)) tm_fwd(pts, lon0 = 147) # Fast (~5nm accuracy) tm_exact_fwd(pts, lon0 = 147) # Exact (slower) ``` ## Lambert Conformal Conic (LCC) LCC is ideal for mid-latitude regions with greater east-west extent. It can use one standard parallel (tangent cone) or two (secant cone). ### Single Standard Parallel ```{r lcc-single} # Project Australia using a single standard parallel at -35 lcc_fwd(australia, lon0 = 135, stdlat = -35) ``` ### Two Standard Parallels Two standard parallels give better scale distribution across the region: ```{r lcc-two} # Project Australia using two standard parallels result <- lcc_fwd(australia, lon0 = 135, stdlat1 = -18, stdlat2 = -36) result ``` ### LCC for Antarctica ```{r lcc-antarctic} # Antarctic projection centered on the pole lcc_fwd(antarctic, lon0 = 0, stdlat1 = -71, stdlat2 = -89) ``` ## Albers Equal Area Albers is an equal-area conic projection, ideal for thematic maps where accurate area representation is important. ### Two Standard Parallels (Most Common) ```{r albers-two} # Albers Equal Area for Australia albers_fwd(australia, lon0 = 132, stdlat1 = -18, stdlat2 = -36) ``` ### CONUS Albers (US Standard) ```{r albers-conus} # Continental US configuration conus <- cbind( lon = c(-122.42, -74.01, -87.63, -104.99, -118.24), lat = c(37.77, 40.71, 41.88, 39.74, 34.05) ) rownames(conus) <- c("San Francisco", "New York", "Chicago", "Denver", "Los Angeles") albers_fwd(conus, lon0 = -96, stdlat1 = 29.5, stdlat2 = 45.5) ``` ### Antarctic Albers ```{r albers-antarctic} # Antarctic equal-area projection albers_fwd(antarctic, lon0 = 0, stdlat1 = -72, stdlat2 = -60) ``` ### Why Equal-Area Matters Albers preserves area, making it suitable for: - Choropleth maps (population density, land use) - Statistical analysis where area matters - Environmental mapping ```{r albers-vs-lcc} # Compare Albers (equal-area) vs LCC (conformal) albers_result <- albers_fwd(australia, lon0 = 132, stdlat1 = -18, stdlat2 = -36) lcc_result <- lcc_fwd(australia, lon0 = 132, stdlat1 = -18, stdlat2 = -36) data.frame( city = rownames(australia), albers_scale = round(albers_result$scale, 4), lcc_scale = round(lcc_result$scale, 4) ) ``` ## Polar Stereographic Conformal projection for polar regions. The default scale factor (k0 = 0.994) corresponds to UPS. Use k0 = 1.0 for true stereographic. ### Antarctic Stations ```{r polarstereo-antarctic} # Antarctic stations with UPS-standard scale polarstereo_fwd(antarctic, northp = FALSE, k0 = 0.994) ``` ### Arctic Points ```{r polarstereo-arctic} # Arctic circle of points arctic <- cbind(lon = seq(0, 315, by = 45), lat = 85) polarstereo_fwd(arctic, northp = TRUE) # All points at same latitude have same distance from pole result <- polarstereo_fwd(arctic, northp = TRUE) sqrt(result$x^2 + result$y^2) # All equal ``` ### Pole at Origin The pole is always at the origin: ```{r polarstereo-pole} # South pole polarstereo_fwd(c(0, -90), northp = FALSE) # North pole polarstereo_fwd(c(0, 90), northp = TRUE) ``` ## Azimuthal Equidistant This projection preserves distances from the center point. Useful for showing distances from a specific location. ### Distances from Sydney ```{r azeq-sydney} # Project world cities relative to Sydney sydney <- c(151.21, -33.87) result <- azeq_fwd(world_pts, lon0 = sydney[1], lat0 = sydney[2]) result # Distance from Sydney (in km) = sqrt(x^2 + y^2) / 1000 distances <- sqrt(result$x^2 + result$y^2) / 1000 data.frame( city = rownames(world_pts), distance_km = round(distances) ) ``` ### Distances from South Pole ```{r azeq-pole} # Distance from South Pole to Antarctic stations result <- azeq_fwd(antarctic, lon0 = 0, lat0 = -90) distances <- sqrt(result$x^2 + result$y^2) / 1000 data.frame( station = rownames(antarctic), lat = antarctic[,2], distance_from_pole_km = round(distances) ) ``` ## Cassini-Soldner Projection A historical projection used for large-scale topographic mapping. It's a transverse cylindrical projection that preserves scale along the central meridian. ### Regional Mapping ```{r cassini-basic} # Tasmania centered on Hobart tasmania <- cbind( lon = c(147.32, 145.49, 146.82, 148.29, 147.13), lat = c(-42.88, -40.83, -41.44, -42.15, -43.21) ) rownames(tasmania) <- c("Hobart", "Launceston", "Devonport", "St Helens", "Dover") cassini_fwd(tasmania, lon0 = 147, lat0 = -42) ``` ### Cassini for Antarctic Survey ```{r cassini-antarctic} # McMurdo area survey mcmurdo_area <- cbind( lon = c(166.67, 166.40, 167.00, 166.87, 168.40), lat = c(-77.85, -77.55, -78.15, -78.65, -77.18) ) rownames(mcmurdo_area) <- c("McMurdo", "Marble Point", "Black Island", "Minna Bluff", "Cape Adare") cassini_fwd(mcmurdo_area, lon0 = 166.67, lat0 = -77.85) ``` ## Gnomonic Projection The gnomonic projection has a unique property: geodesics (great circles) appear as straight lines. This makes it invaluable for route planning. ### Great Circle Routes Appear Straight ```{r gnomonic-routes} # Project Sydney-London great circle path sydney_london <- geodesic_path(c(151.21, -33.87), c(-0.13, 51.51), n = 10) # Project onto gnomonic centered between them gnomonic_fwd(cbind(sydney_london$lon, sydney_london$lat), lon0 = 75, lat0 = 10) ``` ### Route Planning ```{r gnomonic-planning} # Flights from Sydney - project candidate destinations destinations <- cbind( lon = c(-0.13, -74.01, 139.69, 77.22, -43.17), lat = c(51.51, 40.71, 35.69, 28.61, -22.91) ) rownames(destinations) <- c("London", "New York", "Tokyo", "Delhi", "Rio") # Gnomonic from Sydney shows great circle routes as straight lines gnomonic_fwd(destinations, lon0 = 151.21, lat0 = -33.87) ``` ## OSGB - Ordnance Survey National Grid OSGB is specific to Great Britain. Note: It uses the OSGB36 datum, not WGS84. ```{r osgb} # British locations (using approximate OSGB36 coordinates) britain <- cbind( lon = c(-0.127, -3.188, -4.251, -1.890, -2.587), lat = c(51.507, 55.953, 55.864, 52.486, 51.454) ) rownames(britain) <- c("London", "Edinburgh", "Glasgow", "Birmingham", "Cardiff") # Convert to OSGB grid osgb_fwd(britain) ``` ### Grid References ```{r osgb-gridref} # Get alphanumeric grid references osgb_gridref(britain, precision = 3) # 100m precision # Parse a grid reference osgb_gridref_rev("TQ308080") ``` ## Projection Comparison Different projections preserve different properties: | Projection | Preserves | Best For | |------------|-----------|----------| | UTM/UPS | Shape (conformal) | Global standard, topographic maps | | Transverse Mercator | Shape (conformal) | Custom zone definitions | | LCC | Shape (conformal) | Mid-latitude regional maps | | Albers Equal Area | Area | Thematic/statistical maps | | Polar Stereographic | Shape (conformal) | Polar regions | | Azimuthal Equidistant | Distance from center | Showing distances from a point | | Cassini-Soldner | Scale on central meridian | Large-scale surveys | | Gnomonic | Great circles as straight lines | Route planning | | OSGB | Shape (conformal) | British mapping | ## See Also - `vignette("geodesics")` for distance and bearing calculations - `vignette("grid-reference-systems")` for MGRS, Geohash, etc. - `vignette("local-coordinates")` for Local Cartesian (ENU) and Geocentric