├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ ├── pkgdown.yaml │ └── test-coverage.yaml ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── NEWS.md ├── R ├── annotation-map-tile.R ├── annotation-north-arrow.R ├── annotation-scale.R ├── df-spatial-raster.R ├── df-spatial-sf.R ├── df-spatial-sp.R ├── df-spatial-stars.R ├── df-spatial-terra.R ├── df-spatial.R ├── fixed-aspect.R ├── geom-polypath.R ├── geom-spatial-rect.R ├── geom-spatial-segment.R ├── geom-spatial-xline.R ├── geom-spatial.R ├── ggspatial-package.R ├── layer-spatial-bbox.R ├── layer-spatial-raster.R ├── layer-spatial-stars.R ├── layer-spatial-terra.R ├── layer-spatial.R ├── longlake-data.R └── utils.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── cran-comments.md ├── data-raw └── longlake_interp.R ├── ggspatial.Rproj ├── inst ├── longlake │ ├── LongLakeDepthSurvey.dbf │ ├── LongLakeDepthSurvey.prj │ ├── LongLakeDepthSurvey.qpj │ ├── LongLakeDepthSurvey.shp │ ├── LongLakeDepthSurvey.shx │ ├── LongLakeMarshBuildings.dbf │ ├── LongLakeMarshBuildings.prj │ ├── LongLakeMarshBuildings.qpj │ ├── LongLakeMarshBuildings.shp │ ├── LongLakeMarshBuildings.shx │ ├── LongLakeMarshRoads.dbf │ ├── LongLakeMarshRoads.prj │ ├── LongLakeMarshRoads.qpj │ ├── LongLakeMarshRoads.shp │ ├── LongLakeMarshRoads.shx │ ├── LongLakeMarshStreams.dbf │ ├── LongLakeMarshStreams.prj │ ├── LongLakeMarshStreams.qpj │ ├── LongLakeMarshStreams.shp │ ├── LongLakeMarshStreams.shx │ ├── LongLakeMarshWaterPoly.dbf │ ├── LongLakeMarshWaterPoly.prj │ ├── LongLakeMarshWaterPoly.qpj │ ├── LongLakeMarshWaterPoly.shp │ ├── LongLakeMarshWaterPoly.shx │ ├── LongLakeMarshWetlands.dbf │ ├── LongLakeMarshWetlands.gpkg │ ├── LongLakeMarshWetlands.prj │ ├── LongLakeMarshWetlands.qpj │ ├── LongLakeMarshWetlands.shp │ ├── LongLakeMarshWetlands.shx │ ├── longlake.tif │ └── longlake_depth.tif └── rosm.cache │ ├── cartodark │ ├── 13_2635_2916.png │ ├── 13_2635_2917.png │ ├── 13_2636_2916.png │ └── 13_2636_2917.png │ ├── cartolight │ ├── 13_2635_2916.png │ ├── 13_2635_2917.png │ ├── 13_2636_2916.png │ └── 13_2636_2917.png │ ├── osm │ ├── 13_2635_2916.png │ ├── 13_2635_2917.png │ ├── 13_2635_2918.png │ ├── 13_2636_2916.png │ ├── 13_2636_2917.png │ ├── 13_2636_2918.png │ ├── 13_2637_2916.png │ ├── 13_2637_2917.png │ ├── 13_2637_2918.png │ ├── 14_5270_5832.png │ ├── 14_5270_5833.png │ ├── 14_5270_5834.png │ ├── 14_5270_5835.png │ ├── 14_5270_5836.png │ ├── 14_5270_5837.png │ ├── 14_5271_5832.png │ ├── 14_5271_5833.png │ ├── 14_5271_5834.png │ ├── 14_5271_5835.png │ ├── 14_5271_5836.png │ ├── 14_5271_5837.png │ ├── 14_5272_5832.png │ ├── 14_5272_5833.png │ ├── 14_5272_5834.png │ ├── 14_5272_5835.png │ ├── 14_5272_5836.png │ ├── 14_5272_5837.png │ ├── 14_5273_5832.png │ ├── 14_5273_5833.png │ ├── 14_5273_5834.png │ ├── 14_5273_5835.png │ ├── 14_5273_5836.png │ ├── 14_5273_5837.png │ ├── 14_5274_5832.png │ ├── 14_5274_5833.png │ ├── 14_5274_5834.png │ ├── 14_5274_5835.png │ ├── 14_5274_5836.png │ ├── 14_5274_5837.png │ ├── 15_10540_11665.png │ ├── 15_10540_11666.png │ ├── 15_10540_11667.png │ ├── 15_10540_11668.png │ ├── 15_10540_11669.png │ ├── 15_10540_11670.png │ ├── 15_10540_11671.png │ ├── 15_10540_11672.png │ ├── 15_10540_11673.png │ ├── 15_10540_11674.png │ ├── 15_10541_11665.png │ ├── 15_10541_11666.png │ ├── 15_10541_11667.png │ ├── 15_10541_11668.png │ ├── 15_10541_11669.png │ ├── 15_10541_11670.png │ ├── 15_10541_11671.png │ ├── 15_10541_11672.png │ ├── 15_10541_11673.png │ ├── 15_10541_11674.png │ ├── 15_10542_11665.png │ ├── 15_10542_11666.png │ ├── 15_10542_11667.png │ ├── 15_10542_11668.png │ ├── 15_10542_11669.png │ ├── 15_10542_11670.png │ ├── 15_10542_11671.png │ ├── 15_10542_11672.png │ ├── 15_10542_11673.png │ ├── 15_10542_11674.png │ ├── 15_10543_11665.png │ ├── 15_10543_11666.png │ ├── 15_10543_11667.png │ ├── 15_10543_11668.png │ ├── 15_10543_11669.png │ ├── 15_10543_11670.png │ ├── 15_10543_11671.png │ ├── 15_10543_11672.png │ ├── 15_10543_11673.png │ ├── 15_10543_11674.png │ ├── 15_10544_11665.png │ ├── 15_10544_11666.png │ ├── 15_10544_11667.png │ ├── 15_10544_11668.png │ ├── 15_10544_11669.png │ ├── 15_10544_11670.png │ ├── 15_10544_11671.png │ ├── 15_10544_11672.png │ ├── 15_10544_11673.png │ ├── 15_10544_11674.png │ ├── 15_10545_11665.png │ ├── 15_10545_11666.png │ ├── 15_10545_11667.png │ ├── 15_10545_11668.png │ ├── 15_10545_11669.png │ ├── 15_10545_11670.png │ ├── 15_10545_11671.png │ ├── 15_10545_11672.png │ ├── 15_10545_11673.png │ ├── 15_10545_11674.png │ ├── 15_10546_11665.png │ ├── 15_10546_11666.png │ ├── 15_10546_11667.png │ ├── 15_10546_11668.png │ ├── 15_10546_11669.png │ ├── 15_10546_11670.png │ ├── 15_10546_11671.png │ ├── 15_10546_11672.png │ ├── 15_10546_11673.png │ ├── 15_10546_11674.png │ ├── 15_10547_11665.png │ ├── 15_10547_11666.png │ ├── 15_10547_11667.png │ ├── 15_10547_11668.png │ ├── 15_10547_11669.png │ ├── 15_10547_11670.png │ ├── 15_10547_11671.png │ ├── 15_10547_11672.png │ ├── 15_10547_11673.png │ ├── 15_10547_11674.png │ ├── 15_10548_11665.png │ ├── 15_10548_11666.png │ ├── 15_10548_11667.png │ ├── 15_10548_11668.png │ ├── 15_10548_11669.png │ ├── 15_10548_11670.png │ ├── 15_10548_11671.png │ ├── 15_10548_11672.png │ ├── 15_10548_11673.png │ └── 15_10548_11674.png │ ├── stamenbw │ ├── 13_2635_2916.png │ ├── 13_2635_2917.png │ ├── 13_2636_2916.png │ └── 13_2636_2917.png │ └── stamenwatercolor │ ├── 1_0_0.jpg │ ├── 1_1_0.jpg │ ├── 2_0_0.jpg │ ├── 2_0_1.jpg │ ├── 2_1_0.jpg │ ├── 2_1_1.jpg │ ├── 2_2_0.jpg │ ├── 2_2_1.jpg │ ├── 2_3_0.jpg │ └── 2_3_1.jpg ├── man ├── annotation_map_tile.Rd ├── annotation_north_arrow.Rd ├── annotation_scale.Rd ├── annotation_spatial_hline.Rd ├── df_spatial.Rd ├── figures │ └── README-fig-layer-spatial-sf-1.png ├── fixed_plot_aspect.Rd ├── geom_polypath.Rd ├── geom_spatial_rect.Rd ├── geom_spatial_segment.Rd ├── ggspatial-package.Rd ├── layer_spatial.Raster.Rd ├── layer_spatial.Rd ├── layer_spatial.SpatRaster.Rd ├── layer_spatial.bbox.Rd ├── layer_spatial.stars.Rd ├── load_longlake_data.Rd ├── north_arrow_orienteering.Rd ├── reexports.Rd ├── stat_spatial_identity.Rd └── xy_transform.Rd ├── tests ├── testthat.R └── testthat │ ├── .gitignore │ ├── _snaps │ ├── annotation-map-tile │ │ ├── default-epsg.svg │ │ ├── extreme-rotated-epsg.svg │ │ ├── faceted-type.svg │ │ ├── non-default-epsg.svg │ │ ├── rgb-tile-projected-with-alpha.svg │ │ ├── rgb-tile-projected.svg │ │ ├── rgb-tile-with-alpha.svg │ │ ├── rgb-tile.svg │ │ └── specified-default-epsg.svg │ ├── annotation-north-arrow │ │ ├── north-arrow-default-cartesian.svg │ │ ├── north-arrow-default-sf.svg │ │ ├── north-arrows-grid-north.svg │ │ ├── north-arrows-styles-as-calls.svg │ │ ├── north-arrows-styles-as-functions.svg │ │ ├── north-arrows-styles-grid-north.svg │ │ ├── north-arrows-text-colours.svg │ │ ├── north-arrows-true-north-global.svg │ │ ├── north-arrows-true-north.svg │ │ └── north-arrows-use-of-aesthetics.svg │ ├── annotation-scale │ │ ├── scale-bar-defaults-bottom-left.svg │ │ ├── scale-bar-defaults-bottom-right.svg │ │ ├── scale-bar-defaults-cartesian.svg │ │ ├── scale-bar-defaults-coord-sf.svg │ │ ├── scale-bar-defaults-top-left.svg │ │ ├── scale-bar-defaults-top-right.svg │ │ ├── scale-bar-fonts.svg │ │ ├── scale-bar-imperial-plotunit.svg │ │ ├── scale-bar-imperial-unit.svg │ │ ├── scale-bar-metric-plotunit-cartesian.svg │ │ ├── scale-bar-parameters-as-aesthetics.svg │ │ └── scale-bar-ticks.svg │ ├── df-spatial-raster │ │ ├── df-spatial-nband-raster.svg │ │ └── df-spatial-raster.svg │ ├── df-spatial-sf │ │ ├── df-spatial-linestring.svg │ │ ├── df-spatial-multilinestring.svg │ │ ├── df-spatial-multipoint.svg │ │ ├── df-spatial-multipolygon.svg │ │ ├── df-spatial-point.svg │ │ └── df-spatial-polygon.svg │ ├── df-spatial-stars │ │ ├── df-spatial-nband-stars.svg │ │ └── df-spatial-stars.svg │ ├── df-spatial-terra │ │ ├── df-spatial-nband-terra.svg │ │ └── df-spatial-terra.svg │ ├── fixed-aspect │ │ └── stat-aspect-square.svg │ ├── geom-polypath │ │ ├── polygon-with-the-proper-holes.svg │ │ └── polygon-without-the-proper-holes.svg │ ├── geom-spatial-rect │ │ ├── geom-spatial-rect-mapped-aes.svg │ │ ├── geom-spatial-rect.svg │ │ ├── geom-spatial-tile-auto-dims.svg │ │ └── geom-spatial-tile-mapped-dims.svg │ ├── geom-spatial-segment │ │ ├── geom-spatial-segment-great-circle-merc.svg │ │ ├── geom-spatial-segment-great-circle-no-wrap.svg │ │ ├── geom-spatial-segment-great-circle-wrap.svg │ │ ├── geom-spatial-segment-no-great-circle-detail.svg │ │ ├── geom-spatial-segment-no-great-circle-merc.svg │ │ └── geom-spatial-segment-no-great-circle.svg │ ├── geom-spatial-xline │ │ ├── annotation-spatial-hline.svg │ │ ├── annotation-spatial-vline.svg │ │ ├── hline-vline-guessed-limits.svg │ │ ├── spatial-hline-coord-sf-4326.svg │ │ ├── spatial-hline-null-crs.svg │ │ ├── spatial-vline-coord-sf-4326.svg │ │ ├── spatial-vline-null-crs.svg │ │ └── spatial-xline-mapped-aes.svg │ ├── geom-spatial │ │ ├── geom-spatial-label-repel.svg │ │ ├── geom-spatial-label.svg │ │ ├── geom-spatial-path.svg │ │ ├── geom-spatial-point.svg │ │ ├── geom-spatial-polygon.svg │ │ ├── geom-spatial-text-repel.svg │ │ ├── geom-spatial-text.svg │ │ ├── stat-spatial-identity-crs-4326.svg │ │ └── stat-spatial-identity-crs-null.svg │ ├── layer-spatial-bbox │ │ ├── annotation-spatial-bbox.svg │ │ └── layer-spatial-bbox.svg │ ├── layer-spatial-raster │ │ ├── annotation-spatial-raster-alpha.svg │ │ ├── annotation-spatial-raster-project.svg │ │ ├── annotation-spatial-raster.svg │ │ ├── layer-spatial-raster-aes-band1.svg │ │ ├── layer-spatial-raster-aes.svg │ │ ├── layer-spatial-raster-dpi.svg │ │ ├── layer-spatial-raster-lazy.svg │ │ ├── layer-spatial-raster-no-interpolation.svg │ │ ├── layer-spatial-raster-project.svg │ │ └── layer-spatial-raster.svg │ ├── layer-spatial-stars │ │ ├── annotation-spatial-stars-alpha-0-3.svg │ │ ├── annotation-spatial-stars-project.svg │ │ ├── annotation-spatial-stars.svg │ │ ├── layer-spatial-stars-aes-band1.svg │ │ ├── layer-spatial-stars-aes.svg │ │ ├── layer-spatial-stars-dpi.svg │ │ ├── layer-spatial-stars-example-1.svg │ │ ├── layer-spatial-stars-example-2.svg │ │ ├── layer-spatial-stars-lazy.svg │ │ ├── layer-spatial-stars-no-interpolation.svg │ │ ├── layer-spatial-stars-project.svg │ │ └── layer-spatial-stars.svg │ ├── layer-spatial-terra │ │ ├── annotation-spatial-spatraster-alpha-0-3.svg │ │ ├── annotation-spatial-spatraster-project.svg │ │ ├── annotation-spatial-spatraster.svg │ │ ├── layer-spatial-spatraster-aes-band1.svg │ │ ├── layer-spatial-spatraster-aes.svg │ │ ├── layer-spatial-spatraster-dpi.svg │ │ ├── layer-spatial-spatraster-example-1.svg │ │ ├── layer-spatial-spatraster-example-2.svg │ │ ├── layer-spatial-spatraster-lazy.svg │ │ ├── layer-spatial-spatraster-no-interpolation.svg │ │ ├── layer-spatial-spatraster-project.svg │ │ └── layer-spatial-spatraster.svg │ └── layer-spatial │ │ ├── annotation-spatial.svg │ │ ├── layer-spatial.svg │ │ └── shadow-spatial.svg │ ├── test-annotation-map-tile.R │ ├── test-annotation-north-arrow.R │ ├── test-annotation-scale.R │ ├── test-df-spatial-raster.R │ ├── test-df-spatial-sf.R │ ├── test-df-spatial-sp.R │ ├── test-df-spatial-stars.R │ ├── test-df-spatial-terra.R │ ├── test-df-spatial.R │ ├── test-fixed-aspect.R │ ├── test-geom-polypath.R │ ├── test-geom-spatial-rect.R │ ├── test-geom-spatial-segment.R │ ├── test-geom-spatial-xline.R │ ├── test-geom-spatial.R │ ├── test-layer-spatial-bbox.R │ ├── test-layer-spatial-raster.R │ ├── test-layer-spatial-stars.R │ ├── test-layer-spatial-terra.R │ ├── test-layer-spatial.R │ └── test-longlake-data.R └── vignettes ├── .gitignore └── ggspatial.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^data-raw$ 4 | ^rosm\.cache$ 5 | ^README\.md$ 6 | ^\.travis\.yml$ 7 | ^codecov\.yml$ 8 | ^tests/testthat/Rplots\.pdf$ 9 | ^README\.Rmd$ 10 | ^_pkgdown\.yml$ 11 | ^docs$ 12 | ^pkgdown$ 13 | ^vignettes/articles$ 14 | ^\.github$ 15 | ^vignettes$ 16 | ^tests/figs$ 17 | ^cran-comments\.md$ 18 | ^CRAN-RELEASE$ 19 | ^CRAN-SUBMISSION$ 20 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | R_KEEP_PKG_SOURCE: yes 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: rcmdcheck 27 | 28 | - name: Check 29 | env: 30 | VDIFFR_RUN_TESTS: false 31 | run: | 32 | options(crayon.enabled = TRUE) 33 | rcmdcheck::rcmdcheck(args = "--no-manual", error_on = "warning") 34 | shell: Rscript {0} 35 | 36 | - name: Show testthat output 37 | if: always() 38 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true 39 | shell: bash 40 | 41 | - name: Upload check results 42 | if: failure() 43 | uses: actions/upload-artifact@main 44 | with: 45 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 46 | path: check 47 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | permissions: 23 | contents: write 24 | steps: 25 | - uses: actions/checkout@v3 26 | 27 | - uses: r-lib/actions/setup-pandoc@v2 28 | 29 | - uses: r-lib/actions/setup-r@v2 30 | with: 31 | use-public-rspm: true 32 | 33 | - uses: r-lib/actions/setup-r-dependencies@v2 34 | with: 35 | extra-packages: any::pkgdown, local::. 36 | needs: website 37 | 38 | - name: Build site 39 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 40 | shell: Rscript {0} 41 | 42 | - name: Deploy to GitHub pages 🚀 43 | if: github.event_name != 'pull_request' 44 | uses: JamesIves/github-pages-deploy-action@v4.4.1 45 | with: 46 | clean: false 47 | branch: gh-pages 48 | folder: docs 49 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: covr 27 | 28 | - name: Test coverage 29 | run: covr::codecov() 30 | shell: Rscript {0} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .DS_Store 5 | inst/doc 6 | rosm.cache 7 | docs/ 8 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ggspatial 2 | Type: Package 3 | Title: Spatial Data Framework for ggplot2 4 | Version: 1.1.9.9000 5 | Authors@R: c( 6 | person("Dewey", "Dunnington", 7 | email = "dewey@fishandwhistle.net", 8 | role = c("aut", "cre"), 9 | comment = c(ORCID = "0000-0002-9415-4582") 10 | ), 11 | person("Brent", "Thorne", role = "ctb", comment = c(ORCID = "0000-0002-1099-3857")), 12 | person("Diego", "Hernangómez", role = "ctb", comment = c(ORCID = "0000-0001-8457-4658")) 13 | ) 14 | Maintainer: Dewey Dunnington 15 | Description: Spatial data plus the power of the ggplot2 framework means easier mapping when input 16 | data are already in the form of spatial objects. 17 | License: GPL-3 18 | Depends: 19 | R (>= 2.10) 20 | Imports: 21 | sf, 22 | ggplot2 (>= 3.0.0), 23 | rosm (>= 0.2), 24 | abind, 25 | methods, 26 | tibble, 27 | scales, 28 | tidyr, 29 | rlang, 30 | grid, 31 | glue 32 | Suggests: 33 | prettymapr, 34 | knitr, 35 | rmarkdown, 36 | sp, 37 | raster, 38 | terra, 39 | testthat (>= 3.0.0), 40 | dplyr, 41 | withr, 42 | ggrepel, 43 | stars, 44 | covr, 45 | vdiffr, 46 | lwgeom 47 | URL: https://paleolimbot.github.io/ggspatial/, https://github.com/paleolimbot/ggspatial 48 | BugReports: https://github.com/paleolimbot/ggspatial/issues 49 | LazyData: TRUE 50 | RoxygenNote: 7.2.3 51 | Encoding: UTF-8 52 | Roxygen: list(markdown = TRUE) 53 | Config/testthat/edition: 3 54 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(annotation_spatial,Raster) 4 | S3method(annotation_spatial,SpatRaster) 5 | S3method(annotation_spatial,bbox) 6 | S3method(annotation_spatial,default) 7 | S3method(annotation_spatial,stars) 8 | S3method(df_spatial,Raster) 9 | S3method(df_spatial,SpatRaster) 10 | S3method(df_spatial,Spatial) 11 | S3method(df_spatial,sf) 12 | S3method(df_spatial,sfc) 13 | S3method(df_spatial,sfc_GEOMETRY) 14 | S3method(df_spatial,sfc_LINESTRING) 15 | S3method(df_spatial,sfc_MULTILINESTRING) 16 | S3method(df_spatial,sfc_MULTIPOINT) 17 | S3method(df_spatial,sfc_MULTIPOLYGON) 18 | S3method(df_spatial,sfc_POINT) 19 | S3method(df_spatial,sfc_POLYGON) 20 | S3method(df_spatial,stars) 21 | S3method(ggplot_add,fixed_plot_aspect) 22 | S3method(ggplot_build,gg_fixed_plot_aspect) 23 | S3method(layer_spatial,Raster) 24 | S3method(layer_spatial,SpatRaster) 25 | S3method(layer_spatial,bbox) 26 | S3method(layer_spatial,default) 27 | S3method(layer_spatial,stars) 28 | S3method(makeContent,geom_spatial_raster_lazy) 29 | S3method(makeContent,geom_spatial_stars_lazy) 30 | S3method(makeContent,geom_spatial_terra_lazy) 31 | S3method(shadow_spatial,bbox) 32 | S3method(shadow_spatial,default) 33 | export(GeomMapTile) 34 | export(GeomNorthArrow) 35 | export(GeomScaleBar) 36 | export(GeomSpatRaster) 37 | export(GeomSpatialRaster) 38 | export(GeomSpatialStars) 39 | export(GeomSpatialXline) 40 | export(StatSpatRaster) 41 | export(StatSpatRasterAnnotation) 42 | export(StatSpatRasterDf) 43 | export(StatSpatialRaster) 44 | export(StatSpatialRasterAnnotation) 45 | export(StatSpatialRasterDf) 46 | export(StatSpatialRect) 47 | export(StatSpatialSegment) 48 | export(StatSpatialStars) 49 | export(StatSpatialStarsAnnotation) 50 | export(StatSpatialStarsDf) 51 | export(StatSpatialTile) 52 | export(aes) 53 | export(annotation_map_tile) 54 | export(annotation_north_arrow) 55 | export(annotation_scale) 56 | export(annotation_spatial) 57 | export(annotation_spatial_hline) 58 | export(annotation_spatial_vline) 59 | export(coord_sf) 60 | export(df_spatial) 61 | export(fixed_plot_aspect) 62 | export(geom_polypath) 63 | export(geom_sf) 64 | export(geom_spatial_label) 65 | export(geom_spatial_label_repel) 66 | export(geom_spatial_path) 67 | export(geom_spatial_point) 68 | export(geom_spatial_polygon) 69 | export(geom_spatial_rect) 70 | export(geom_spatial_segment) 71 | export(geom_spatial_text) 72 | export(geom_spatial_text_repel) 73 | export(geom_spatial_tile) 74 | export(ggplot) 75 | export(layer_spatial) 76 | export(load_longlake_data) 77 | export(north_arrow_fancy_orienteering) 78 | export(north_arrow_minimal) 79 | export(north_arrow_nautical) 80 | export(north_arrow_orienteering) 81 | export(shadow_spatial) 82 | export(stat_spatial_identity) 83 | export(waiver) 84 | export(xy_transform) 85 | importFrom(ggplot2,aes) 86 | importFrom(ggplot2,after_stat) 87 | importFrom(ggplot2,coord_sf) 88 | importFrom(ggplot2,geom_sf) 89 | importFrom(ggplot2,ggplot) 90 | importFrom(ggplot2,ggplot_add) 91 | importFrom(ggplot2,ggplot_build) 92 | importFrom(ggplot2,waiver) 93 | importFrom(grid,makeContent) 94 | importFrom(grid,unit) 95 | importFrom(rlang,"!!") 96 | importFrom(rlang,.data) 97 | importFrom(sf,st_zm) 98 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # ggspatial (development version) 2 | 3 | * Updated `load_longlake_data()` to use terra package by default instead of the deprecated raster package 4 | * Updated example for `layer_spatial()` to avoid error when plotting raster layer 5 | 6 | # ggspatial 1.1.9 7 | 8 | * Fix donttest examples for updated raster/terra stack. 9 | 10 | # ggspatial 1.1.8 11 | 12 | * Fix `annotation_spatial()` for the latest ggplot2 release (#114, #115). 13 | 14 | # ggspatial 1.1.7 15 | 16 | * Fixed deprecated behaviour advanced in the latest ggplot2 17 | release (#106). 18 | 19 | # ggspatial 1.1.6 20 | 21 | * Added terra package support (@dieghernan, #92, #94) 22 | * Fix north arrow rotation (@potash, #82) 23 | * Add support for factor/categorical rasters (@JoshOBrien, #78) 24 | * Better raster support for stars (@dieghernan, #95) 25 | * Fix example data for updated sf/GDAL (@rsbivand, #101) 26 | 27 | # ggspatial 1.1.5 28 | 29 | * Added a `NEWS.md` file to track changes to the package. 30 | * Suppressed discarded datum warnings that resulted from loading 31 | of test data. 32 | * Suppressed discarded datum warnings that resulted from 33 | 'rosm' package operations. 34 | * Fixed an error that caused RStudio to crash from excessive 35 | memory allocation resulting when trying to plot a single point 36 | with `annotation_map_tile()` (#74). 37 | * Ensured that packages in 'Suggests' are used conditionally in 38 | tests and examples. 39 | -------------------------------------------------------------------------------- /R/df-spatial-raster.R: -------------------------------------------------------------------------------- 1 | 2 | #' @export 3 | df_spatial.Raster <- function(x, ..., hjust = 0.5, vjust = 0.5, na.rm = FALSE) { 4 | # get values in a data frame 5 | nrows <- x@nrows 6 | ncols <- x@ncols 7 | bbox <- raster::as.matrix(x@extent) 8 | 9 | fused <- cbind( 10 | expand.grid(x = seq_len(ncols), y = seq_len(nrows)), 11 | raster::values(x) 12 | ) 13 | 14 | # set names to be x, y, band1, band2, ... 15 | nbands <- ncol(fused) - 2 16 | names(fused) <- c("x", "y", paste0("band", seq_len(nbands))) 17 | 18 | # Ensure that a factor raster's values stay factors in `fused` 19 | # data.frame, taking levels from second column of RAT 20 | if (any(raster::is.factor(x))) { 21 | band_names <- names(fused)[-1:-2] 22 | for (i in seq_along(band_names)) { 23 | if (raster::is.factor(x[[i]])) { 24 | rat <- raster::levels(x[[i]])[[1]] 25 | fused[[band_names[i]]] <- 26 | factor(fused[[band_names[i]]], levels = rat[, 1], labels = rat[, 2]) 27 | } 28 | } 29 | } 30 | 31 | if (na.rm) { 32 | for (i in seq_len(nbands)) { 33 | fused <- fused[!is.na(fused[[paste0("band", i)]]), ] 34 | } 35 | } 36 | 37 | # fix x and y to be physical coordinates using the bbox 38 | bbox_width <- bbox[1, 2] - bbox[1, 1] 39 | bbox_height <- bbox[2, 1] - bbox[2, 2] 40 | res <- raster::res(x) 41 | 42 | fused$x <- bbox[1, 1] + res[1] * hjust + (fused$x - 1) / ncols * bbox_width 43 | fused$y <- bbox[2, 1] + res[2] * vjust + (fused$y - nrows) / nrows * bbox_height 44 | 45 | tibble::as_tibble(fused) 46 | } 47 | -------------------------------------------------------------------------------- /R/df-spatial-sf.R: -------------------------------------------------------------------------------- 1 | 2 | #' @export 3 | df_spatial.sfc_POINT <- function(x, ...) { 4 | df <- tibble::as_tibble(sf::st_coordinates(x)) 5 | names(df) <- tolower(names(df)) 6 | df$feature_id <- seq_len(nrow(df)) 7 | df$part_id <- rep_len(1L, nrow(df)) 8 | df 9 | } 10 | 11 | #' @export 12 | df_spatial.sfc_MULTIPOINT <- function(x, ...) { 13 | df <- tibble::as_tibble(sf::st_coordinates(x)) 14 | names(df) <- gsub("^l1$", "feature_id", tolower(names(df))) 15 | df$feature_id <- as.integer(df$feature_id) 16 | lengths <- rle(df$feature_id)$lengths 17 | df$part_id <- unlist(lapply(lengths, seq_len)) 18 | df 19 | } 20 | 21 | #' @export 22 | df_spatial.sfc_LINESTRING <- function(x, ...) { 23 | df <- tibble::as_tibble(sf::st_coordinates(x)) 24 | names(df) <- gsub("^l1$", "feature_id", tolower(names(df))) 25 | df$feature_id <- as.integer(df$feature_id) 26 | df$part_id <- rep_len(1L, nrow(df)) 27 | df 28 | } 29 | 30 | #' @export 31 | df_spatial.sfc_MULTILINESTRING <- function(x, ...) { 32 | df <- tibble::as_tibble(sf::st_coordinates(x)) 33 | names(df) <- gsub("^l2$", "feature_id", gsub("^l1$", "part_id", tolower(names(df)))) 34 | df$feature_id <- as.integer(df$feature_id) 35 | df$part_id <- as.integer(df$part_id) 36 | df 37 | } 38 | 39 | #' @export 40 | df_spatial.sfc_POLYGON <- function(x, ...) { 41 | df <- tibble::as_tibble(sf::st_coordinates(x)) 42 | names(df) <- gsub( 43 | "^l2$", "feature_id", 44 | gsub( 45 | "^l1$", "piece_id", 46 | tolower(names(df)) 47 | ) 48 | ) 49 | 50 | df$feature_id <- as.integer(df$feature_id) 51 | df$piece_id <- as.integer(df$piece_id) 52 | df$part_id <- 1L 53 | 54 | col_order <- c("x", "y", "z", "m", "feature_id", "part_id", "piece_id") 55 | df[intersect(col_order, names(df))] 56 | } 57 | 58 | #' @export 59 | df_spatial.sfc_MULTIPOLYGON <- function(x, ...) { 60 | df <- tibble::as_tibble(sf::st_coordinates(x)) 61 | names(df) <- gsub( 62 | "^l3$", "feature_id", 63 | gsub( 64 | "^l2$", "part_id", 65 | gsub( 66 | "^l1$", "piece_id", 67 | tolower(names(df)) 68 | ) 69 | ) 70 | ) 71 | 72 | df$feature_id <- as.integer(df$feature_id) 73 | df$piece_id <- as.integer(df$piece_id) 74 | df$part_id <- as.integer(df$part_id) 75 | 76 | col_order <- c("x", "y", "z", "m", "feature_id", "part_id", "piece_id") 77 | df[intersect(col_order, names(df))] 78 | } 79 | 80 | #' @export 81 | df_spatial.sfc_GEOMETRY <- function(x, ...) { 82 | df_spatial(sfc_cast_common(x)) 83 | } 84 | 85 | #' @export 86 | #' @importFrom sf st_zm 87 | df_spatial.sfc <- function(x, ...) { 88 | cls <- paste0("'", class(x), "'", collapse = " / ") 89 | stop("Don't know how to convert object of class ", cls, " to a df") 90 | } 91 | 92 | #' @export 93 | #' @importFrom sf st_zm 94 | df_spatial.sf <- function(x, ...) { 95 | df_geom <- df_spatial(sf::st_geometry(x)) 96 | x_without_geom <- tibble::as_tibble(sf::st_set_geometry(x, NULL)) 97 | fix_duplicate_cols( 98 | df_geom, 99 | x_without_geom[df_geom$feature_id, ] 100 | ) 101 | } 102 | 103 | sfc_cast_common <- function(x) { 104 | types <- unlist(lapply(x, sf::st_geometry_type)) 105 | common_class <- sfg_type_common(types) 106 | sf::st_cast(x, common_class) 107 | } 108 | 109 | sfg_type_common <- function(types) { 110 | if ((length(unique(types)) == 1) && types != "GEOMETRY") { 111 | types 112 | } else if (all(types %in% c("POINT", "MULTIPOINT"))) { 113 | "MULTIPOINT" 114 | } else if(all(types %in% c("LINESTRING", "MULTILINESTRING"))) { 115 | "MULTILINESTRING" 116 | } else if (all(types %in% c("POLYGON", "MULTIPOLYGON"))) { 117 | "MULTIPOLYGON" 118 | } else { 119 | types <- paste0('"', unique(types), "'", collapse = ", ") 120 | stop(glue::glue("Can't find common type for geometry types {types}")) 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /R/df-spatial-sp.R: -------------------------------------------------------------------------------- 1 | 2 | #' @export 3 | df_spatial.Spatial <- function(x, ...) { 4 | if ("data" %in% methods::slotNames(x)) { 5 | # a Spatial*DataFrame 6 | df_spatial(sf::st_as_sf(x)) 7 | } else { 8 | # a Spatial* 9 | df_spatial(sf::st_as_sfc(x)) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /R/df-spatial-stars.R: -------------------------------------------------------------------------------- 1 | 2 | #' @export 3 | #' @importFrom rlang !! 4 | df_spatial.stars <- function(x, ..., na.rm = FALSE) { 5 | 6 | # Get n bands first 7 | nband <- dim(x)[3] 8 | 9 | # On single band we get NA 10 | if (is.na(nband)) nband <- 1 11 | 12 | # To tibble 13 | df <- tibble::as_tibble(as.data.frame(x, ...)) 14 | 15 | 16 | # Handle multi-layer stars objects 17 | if (nband > 1) { 18 | names(df) <- c("x", "y", "band", "values") 19 | 20 | # gather is superseeded, use pivot wider 21 | df <- tidyr::pivot_wider(df, 22 | id_cols = c("x", "y"), 23 | values_from = "values", 24 | names_from = "band", 25 | names_prefix = "band" 26 | ) 27 | } 28 | 29 | # Now rename 30 | names(df) <- c("x", "y", paste0("band", seq_len(nband))) 31 | 32 | # Drop NA 33 | if (na.rm) { 34 | df <- tidyr::drop_na(df) 35 | } 36 | 37 | df 38 | } 39 | -------------------------------------------------------------------------------- /R/df-spatial-terra.R: -------------------------------------------------------------------------------- 1 | 2 | #' @export 3 | df_spatial.SpatRaster <- function(x, ..., na.rm = FALSE) { 4 | # get values in a data frame 5 | df <- tibble::as_tibble( 6 | terra::as.data.frame(x, 7 | xy = TRUE, 8 | na.rm = na.rm 9 | ) 10 | ) 11 | nbands <- terra::nlyr(x) 12 | names(df) <- c("x", "y", paste0("band", seq_len(nbands))) 13 | 14 | tibble::as_tibble(df) 15 | } 16 | -------------------------------------------------------------------------------- /R/df-spatial.R: -------------------------------------------------------------------------------- 1 | 2 | #' Create a ggplot-friendly data frame from a spatial object 3 | #' 4 | #' @param x A spatial object 5 | #' @param ... Passed to specific methods 6 | #' 7 | #' @return A tibble with coordinates as `x` and `y`, 8 | #' features as `feature_id`, and parts as `part_id`. 9 | #' @export 10 | #' 11 | #' @examples 12 | #' \donttest{ 13 | #' load_longlake_data(which = c("longlake_osm", "longlake_depthdf")) 14 | #' df_spatial(longlake_osm) 15 | #' df_spatial(longlake_depthdf) 16 | #' df_spatial(as(longlake_depthdf, "Spatial")) 17 | #' } 18 | #' 19 | df_spatial <- function(x, ...) { 20 | UseMethod("df_spatial") 21 | } 22 | 23 | #' Fix duplicate column names 24 | #' 25 | #' This fixes possible masking of column names within df_spatial without mangling 26 | #' the required column names. 27 | #' 28 | #' @param df A data.frame 29 | #' 30 | #' @return modified df 31 | #' @noRd 32 | #' 33 | fix_duplicate_cols <- function(...) { 34 | df <- cbind(...) 35 | cols <- colnames(df) 36 | dup_cols <- duplicated(cols) 37 | cols[dup_cols] <- paste(cols[dup_cols], seq_along(cols)[dup_cols], sep = "..") 38 | renamed <- colnames(df) != cols 39 | 40 | if(any(renamed)) { 41 | message( 42 | "Renamed columns ", 43 | paste0("`", colnames(df)[renamed], "` => `", cols[renamed], "`", collapse = ", "), 44 | " in df_spatial()" 45 | ) 46 | } 47 | 48 | colnames(df) <- cols 49 | tibble::as_tibble(df) 50 | } 51 | 52 | expect_df_spatial <- function(expr, cols = character(0)) { 53 | expr_quo <- rlang::enquo(expr) 54 | testthat::expect_true( 55 | all(c("x", "y", cols) %in% colnames(df_spatial(expr))) 56 | ) 57 | testthat::expect_s3_class(df_spatial(expr), "data.frame") 58 | testthat::expect_s3_class(df_spatial(expr), "tbl_df") 59 | 60 | invisible(df_spatial(expr)) 61 | } 62 | -------------------------------------------------------------------------------- /R/fixed-aspect.R: -------------------------------------------------------------------------------- 1 | 2 | #' Enforce a plot aspect ratio 3 | #' 4 | #' When using a fixed-aspect coordinate system, [fixed_plot_aspect()] expands 5 | #' either the width or height of the plot to ensure that the output 6 | #' has dimensions that make sense. This is a useful workaround for 7 | #' getting reasonable-shaped plots when using [ggplot2::coord_sf()] 8 | #' or [ggplot2::coord_fixed()] when the data happen to be 9 | #' aligned vertically or horizontally. 10 | #' 11 | #' @param ratio The desired aspect ratio (width / height) 12 | #' 13 | #' @return A [ggplot2::layer()] that can be added to a [ggplot2::ggplot()]. 14 | #' @export 15 | #' 16 | #' @examples 17 | #' library(ggplot2) 18 | #' df <- data.frame(x = 0:5, y = seq(0, 10, length.out = 6)) 19 | #' ggplot(df, aes(x, y)) + 20 | #' geom_point() + 21 | #' fixed_plot_aspect(ratio = 1) + 22 | #' coord_fixed() 23 | #' 24 | fixed_plot_aspect <- function(ratio = 1) { 25 | structure( 26 | list(ratio = ratio), 27 | class = "fixed_plot_aspect" 28 | ) 29 | } 30 | 31 | #' @export 32 | #' @importFrom ggplot2 ggplot_add 33 | ggplot_add.fixed_plot_aspect <- function(object, plot, object_name) { 34 | plot$fixed_aspect_ratio <- object$ratio 35 | class(plot) <- unique(c("gg_fixed_plot_aspect", class(plot))) 36 | plot 37 | } 38 | 39 | #' @export 40 | #' @importFrom ggplot2 ggplot_build 41 | ggplot_build.gg_fixed_plot_aspect <- function(plot) { 42 | # dynamically subclass the coordinate system to modify the scales prior to panel 43 | # params (the last possible moment) 44 | # you'd think this was possible some other way, but until layers have access to 45 | # all the scales, it isn't! 46 | coord_super <- plot$coordinates 47 | desired_aspect <- plot$fixed_aspect_ratio 48 | 49 | plot$coordinates <- ggplot2::ggproto( 50 | NULL, coord_super, 51 | setup_panel_params = function(self, scale_x, scale_y, params = list()) { 52 | new_bounds <- adjust_aspect( 53 | scale_x$get_limits(), 54 | scale_y$get_limits(), 55 | desired_aspect = desired_aspect 56 | ) 57 | 58 | if (!is.null(new_bounds$xlim)) scale_x$train(new_bounds$xlim) 59 | if (!is.null(new_bounds$ylim)) scale_y$train(new_bounds$ylim) 60 | 61 | ggplot2::ggproto_parent(coord_super, self)$setup_panel_params(scale_x, scale_y, params) 62 | } 63 | ) 64 | 65 | class(plot) <- setdiff(class(plot), "gg_fixed_plot_aspect") 66 | ggplot_build(plot) 67 | } 68 | 69 | 70 | adjust_aspect <- function(xlim, ylim, desired_aspect = 1) { 71 | # detect case for all non-finite data 72 | if (!all(is.finite(c(xlim, ylim)))) { 73 | return(list(xlim = NULL, ylim = NULL)) 74 | } 75 | 76 | width <- diff(xlim) 77 | height <- diff(ylim) 78 | current_aspect <- width / height 79 | 80 | if (current_aspect > desired_aspect) { 81 | ymid <- ylim[1] + height / 2 82 | new_height <- height * current_aspect / desired_aspect 83 | plot_bounds <- list( 84 | xlim = xlim, 85 | ylim = c( 86 | ymid - new_height / 2, 87 | ymid + new_height / 2 88 | ) 89 | ) 90 | } else { 91 | xmid <- xlim[1] + width / 2 92 | new_width <- width * desired_aspect / current_aspect 93 | plot_bounds <- list( 94 | xlim = c( 95 | xmid - new_width / 2, 96 | xmid + new_width / 2 97 | ), 98 | ylim = ylim 99 | ) 100 | } 101 | 102 | plot_bounds 103 | } 104 | -------------------------------------------------------------------------------- /R/geom-polypath.R: -------------------------------------------------------------------------------- 1 | 2 | # this is a revised version of GeomPolypath from the ggpolypath package 3 | # see https://github.com/mdsumner/ggpolypath/issues/3 4 | 5 | 6 | 7 | #' Polygons with holes in ggplot2 8 | #' 9 | #' This geometry used to plot polygons with holes in ggplot2 at the 10 | #' more correctly than [geom_polygon][ggplot2::geom_polygon]; however, 11 | #' in recent R and ggplot2 versions this is no longer needed. 12 | #' 13 | #' @param mapping An aesthetic mapping, created with [aes][ggplot2::aes]. The aesthetic 14 | #' will mostly likely need to contain a `group` mapping. 15 | #' @param data A data.frame containing the coordinates to plot. 16 | #' @param stat A statistic to apply (most likely "identity") 17 | #' @param position A position to apply (most likely "identity") 18 | #' @param na.rm Should missing coordinate be removed? 19 | #' @param show.legend Should a legend be shown for mapped aesthetics? 20 | #' @param inherit.aes Should aesthetics be inherited? 21 | #' @param rule A fill rule to apply. One of "winding" or "evenodd". 22 | #' @param ... Passed to the geom and/or stat. 23 | #' 24 | #' @return A ggplot2 layer 25 | #' @export 26 | #' 27 | #' @examples 28 | #' \donttest{ 29 | #' library(ggplot2) 30 | #' load_longlake_data(which = "longlake_waterdf") 31 | #' ggplot(df_spatial(longlake_waterdf), aes(x, y, group = piece_id)) + 32 | #' geom_polypath() 33 | #' } 34 | #' 35 | geom_polypath <- function (mapping = NULL, data = NULL, stat = "identity", position = "identity", 36 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, rule = "winding", 37 | ...) { 38 | if(!(rule %in% c("winding", "evenodd"))) { 39 | stop("geom_polypath: 'rule' must be 'evenodd', or 'winding'") 40 | } 41 | 42 | # No longer needed in recent R + ggplot2 43 | message("`geom_polypath()` is deprecated: use `ggplot2::geom_polygon()` with the `subgroup` aesthetic") 44 | 45 | ggplot2::layer(data = data, mapping = mapping, stat = stat, geom = GeomPolypath, 46 | position = position, show.legend = show.legend, inherit.aes = inherit.aes, 47 | params = list(na.rm = na.rm , rule = rule, ...)) 48 | } 49 | 50 | 51 | GeomPolypath <- ggplot2::ggproto( 52 | "GeomPolypath", 53 | ggplot2::GeomPolygon, 54 | extra_params = c("na.rm", "rule"), 55 | draw_panel = function(self, data, scales, coordinates, rule = "winding") { 56 | n <- nrow(data) 57 | if (n == 1) return(ggplot2::zeroGrob()) 58 | 59 | data$subgroup <- data$group 60 | 61 | # "size" became "linewidth" in ggplot 3.4.0 62 | if (packageVersion("ggplot2") >= "3.4.0") { 63 | data$group <- unclass(factor(with(data, paste(fill, colour, alpha, linewidth, linetype)))) 64 | } else { 65 | data$group <- unclass(factor(with(data, paste(fill, colour, alpha, size, linetype)))) 66 | } 67 | 68 | ggplot2::ggproto_parent(ggplot2::GeomPolygon, self)$draw_panel(data, scales, coordinates, rule = rule) 69 | } 70 | ) 71 | -------------------------------------------------------------------------------- /R/geom-spatial-rect.R: -------------------------------------------------------------------------------- 1 | 2 | #' Projected rectangular regions 3 | #' 4 | #' If you need to plot a [sf::st_bbox()], use [layer_spatial()] instead. 5 | #' While the implementation is slightly differrent, these functions are 6 | #' intended to behave identically to [ggplot2::geom_rect()] and 7 | #' [ggplot2::geom_tile()]. 8 | #' 9 | #' @inheritParams stat_spatial_identity 10 | #' @inheritParams layer_spatial.bbox 11 | #' @inheritParams annotation_spatial_hline 12 | #' @param linejoin How corners should be joined 13 | #' 14 | #' @export 15 | #' 16 | #' @examples 17 | #' library(ggplot2) 18 | #' tile_df <- expand.grid( 19 | #' x = seq(-140, -52, by = 20), 20 | #' y = seq(40, 70, by = 10) 21 | #' ) 22 | #' 23 | #' ggplot(tile_df, aes(x, y)) + 24 | #' geom_spatial_tile(crs = 4326) + 25 | #' coord_sf(crs = 3979) 26 | #' 27 | #' # the same plot using geom_spatial_rect() 28 | #' ggplot( 29 | #' tile_df, 30 | #' aes(xmin = x - 10, xmax = x + 10, ymin = y - 5, ymax = y + 5) 31 | #' ) + 32 | #' geom_spatial_rect(crs = 4326) + 33 | #' coord_sf(crs = 3979) 34 | #' 35 | geom_spatial_rect <- function(mapping = NULL, data = NULL, 36 | ..., 37 | crs = NULL, 38 | detail = 30, 39 | linejoin = "mitre", 40 | na.rm = FALSE, 41 | show.legend = NA, 42 | inherit.aes = TRUE) { 43 | ggplot2::layer( 44 | data = data, 45 | mapping = mapping, 46 | stat = StatSpatialRect, 47 | geom = ggplot2::GeomSf, 48 | position = "identity", 49 | show.legend = show.legend, 50 | inherit.aes = inherit.aes, 51 | params = list( 52 | crs = crs, 53 | detail = detail, 54 | linejoin = linejoin, 55 | legend = "polygon", 56 | na.rm = na.rm, 57 | ... 58 | ) 59 | ) 60 | } 61 | 62 | #' @rdname geom_spatial_rect 63 | #' @export 64 | geom_spatial_tile <- function(mapping = NULL, data = NULL, 65 | ..., 66 | crs = NULL, 67 | detail = 30, 68 | linejoin = "mitre", 69 | na.rm = FALSE, 70 | show.legend = NA, 71 | inherit.aes = TRUE) { 72 | ggplot2::layer( 73 | data = data, 74 | mapping = mapping, 75 | stat = StatSpatialTile, 76 | geom = ggplot2::GeomSf, 77 | position = "identity", 78 | show.legend = show.legend, 79 | inherit.aes = inherit.aes, 80 | params = list( 81 | crs = crs, 82 | detail = detail, 83 | linejoin = linejoin, 84 | legend = "polygon", 85 | na.rm = na.rm, 86 | ... 87 | ) 88 | ) 89 | } 90 | 91 | #' @rdname geom_spatial_rect 92 | #' @export 93 | StatSpatialRect <- ggplot2::ggproto( 94 | "StatSpatialRect", ggplot2::Stat, 95 | 96 | required_aes = c("xmin", "xmax", "ymin", "ymax"), 97 | 98 | compute_layer = function(self, data, params, layout) { 99 | # add dest CRS to parameters 100 | params$crs_dest <- sf::st_crs(layout$coord_params$crs) 101 | ggplot2::ggproto_parent(ggplot2::Stat, self)$compute_layer(data, params, layout) 102 | }, 103 | 104 | compute_panel = function(self, data, scales, crs, crs_dest, detail = 30) { 105 | # source CRS 106 | if(is.null(crs)) { 107 | message("Assuming `crs = 4326` in stat_spatial_rect()") 108 | crs <- sf::st_crs(4326) 109 | } else { 110 | crs <- sf::st_crs(crs) 111 | } 112 | 113 | bboxes <- lapply(seq_len(nrow(data)), function(i) { 114 | sf::st_bbox( 115 | c( 116 | xmin = data$xmin[i], 117 | ymin = data$ymin[i], 118 | xmax = data$xmax[i], 119 | ymax = data$ymax[i] 120 | ), 121 | crs = crs 122 | ) 123 | }) 124 | 125 | geometry <- lapply(bboxes, function(x) sf_bbox_to_sf(x, detail = detail)$geometry[[1]]) 126 | data$geometry <- do.call(sf::st_sfc, c(geometry, list(crs = crs))) 127 | data$geometry <- sf::st_transform(data$geometry, crs = crs_dest) 128 | 129 | # update xmin/xmax/ymin/ymax for proper scale training 130 | projected_bbox <- sf::st_bbox(data$geometry) 131 | data$xmin <- projected_bbox["xmin"] 132 | data$ymin <- projected_bbox["ymin"] 133 | data$xmax <- projected_bbox["xmax"] 134 | data$ymax <- projected_bbox["ymax"] 135 | 136 | data 137 | } 138 | ) 139 | 140 | #' @rdname geom_spatial_rect 141 | #' @export 142 | StatSpatialTile <- ggplot2::ggproto( 143 | "StatSpatialTile", StatSpatialRect, 144 | 145 | setup_data = function(data, params) { 146 | if (all(is.na(data$width))) { 147 | data$width <- ggplot2::resolution(data$x, FALSE) 148 | } 149 | 150 | if (all(is.na(data$height))) { 151 | data$height <- ggplot2::resolution(data$y, FALSE) 152 | } 153 | 154 | x <- NULL; rm(x) 155 | height <- NULL; rm(height) 156 | width <- NULL; rm(width) 157 | 158 | transform( 159 | data, 160 | xmin = x - width / 2, 161 | xmax = x + width / 2, 162 | width = NULL, 163 | ymin = y - height / 2, 164 | ymax = y + height / 2, 165 | height = NULL 166 | ) 167 | }, 168 | 169 | required_aes = c("x", "y"), 170 | default_aes = aes(height = NA_real_, width = NA_real_) 171 | ) 172 | -------------------------------------------------------------------------------- /R/ggspatial-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | # The following block is used by usethis to automatically manage 5 | # roxygen namespace tags. Modify with care! 6 | ## usethis namespace: start 7 | #' @importFrom ggplot2 after_stat 8 | #' @importFrom rlang .data 9 | ## usethis namespace: end 10 | NULL 11 | 12 | #' @importFrom ggplot2 ggplot 13 | #' @export 14 | ggplot2::ggplot 15 | 16 | #' @importFrom ggplot2 aes 17 | #' @export 18 | ggplot2::aes 19 | 20 | #' @importFrom ggplot2 coord_sf 21 | #' @export 22 | ggplot2::coord_sf 23 | 24 | #' @importFrom ggplot2 geom_sf 25 | #' @export 26 | ggplot2::geom_sf 27 | 28 | #' @importFrom ggplot2 waiver 29 | #' @export 30 | ggplot2::waiver 31 | -------------------------------------------------------------------------------- /R/layer-spatial-bbox.R: -------------------------------------------------------------------------------- 1 | 2 | #' Add a bounding box to a map 3 | #' 4 | #' To include a bounding box without drawing it, use [shadow_spatial()] on the 5 | #' original object. 6 | #' 7 | #' @param data A bounding box generated by [sf::st_bbox()] 8 | #' @param detail Passed to [sf::st_segmentize()]: the number of line segments 9 | #' per quadrant of the bounding box. Increase this number for a smoother 10 | #' projected bounding box. 11 | #' @inheritParams layer_spatial 12 | #' 13 | #' @export 14 | #' 15 | #' @examples 16 | #' \donttest{ 17 | #' library(ggplot2) 18 | #' load_longlake_data(which = c("longlake_waterdf", "longlake_depthdf")) 19 | #' ggplot() + 20 | #' layer_spatial(sf::st_bbox(longlake_waterdf)) + 21 | #' layer_spatial(longlake_depthdf) 22 | #' 23 | #' # use shadow_spatial() to include the geographic area of an object 24 | #' # without drawing it 25 | #' ggplot() + 26 | #' shadow_spatial(longlake_waterdf) + 27 | #' layer_spatial(longlake_depthdf) 28 | #' } 29 | #' 30 | layer_spatial.bbox <- function(data, mapping = aes(), ..., detail = 30) { 31 | layer_spatial(sf_bbox_to_sf(data, detail = detail), mapping = mapping, ...) 32 | } 33 | 34 | #' @rdname layer_spatial.bbox 35 | #' @export 36 | annotation_spatial.bbox <- function(data, mapping = aes(), ..., detail = 30) { 37 | annotation_spatial(sf_bbox_to_sf(data, detail = detail), mapping = mapping, ...) 38 | } 39 | 40 | #' @rdname layer_spatial.bbox 41 | #' @export 42 | shadow_spatial.bbox <- function(data, ..., detail = 30) { 43 | shadow_spatial(sf_bbox_to_sf(data, detail = detail)) 44 | } 45 | 46 | sf_bbox_to_sf <- function(data, detail = NULL) { 47 | xs <- data[c("xmin", "xmin", "xmax", "xmax", "xmin")] 48 | ys <- data[c("ymin", "ymax", "ymax", "ymin", "ymin")] 49 | poly <- sf::st_polygon(list(cbind(xs, ys))) 50 | 51 | height <- data["ymax"] - data["ymin"] 52 | width <- data["xmax"] - data["xmin"] 53 | if (!is.null(detail) && any(c(height, width) > 0)) { 54 | dfMaxLength <- min( 55 | c( 56 | height[height > 0] / detail, 57 | width[width > 0] / detail 58 | ) 59 | ) 60 | poly <- sf::st_segmentize(poly, dfMaxLength = dfMaxLength) 61 | } 62 | 63 | geometry <- sf::st_sfc(poly, crs = sf::st_crs(data)) 64 | tbl <- tibble::tibble(geometry = geometry) 65 | sf::st_sf(tbl) 66 | } 67 | -------------------------------------------------------------------------------- /R/layer-spatial.R: -------------------------------------------------------------------------------- 1 | 2 | #' Turn a spatial object into a ggplot2 layer 3 | #' 4 | #' See also [layer_spatial.Raster()], [layer_spatial.stars()], 5 | #' [layer_spatial.SpatRaster()] and [layer_spatial.bbox()] for implementations 6 | #' for other types of spatial objects. 7 | #' 8 | #' @param data An object that can be coerced to an sf object using [st_as_sf][sf::st_as_sf]. 9 | #' @param mapping A mapping, created using [aes][ggplot2::aes]. 10 | #' @param sf_params Passed to [st_as_sf][sf::st_as_sf]. 11 | #' @param inherit.aes Inherit aesthetics from ggplot()? 12 | #' @param ... Passed to [geom_sf][ggplot2::geom_sf] 13 | #' 14 | #' @return A ggplot2 [layer][ggplot2::layer]. 15 | #' @export 16 | #' @importFrom ggplot2 aes 17 | #' 18 | #' @examples 19 | #' \donttest{ 20 | #' library(ggplot2) 21 | #' load_longlake_data( 22 | #' which = c( 23 | #' "longlake_roadsdf", 24 | #' "longlake_depthdf", 25 | #' "longlake_depth_raster" 26 | #' ), 27 | #' raster_format = "terra" 28 | #' ) 29 | #' 30 | #' ggplot() + 31 | #' 32 | #' # annotation_spatial() layers don't train the scales, so data stays central 33 | #' annotation_spatial(longlake_roadsdf, size = 2, col = "black") + 34 | #' annotation_spatial(longlake_roadsdf, size = 1.6, col = "white") + 35 | #' 36 | #' # raster layers train scales and get projected automatically 37 | #' layer_spatial(longlake_depth_raster, aes(alpha = after_stat(band1)), fill = "darkblue") + 38 | #' scale_alpha_continuous(na.value = 0) + 39 | #' 40 | #' # layer_spatial() layers train the scales 41 | #' layer_spatial(longlake_depthdf, aes(col = DEPTH_M)) + 42 | #' 43 | #' # spatial-aware automagic scale bar 44 | #' annotation_scale(location = "tl") + 45 | #' 46 | #' # spatial-aware automagic north arrow 47 | #' annotation_north_arrow(location = "br", which_north = "true") 48 | #' } 49 | #' 50 | layer_spatial <- function(data, mapping, ...) { 51 | UseMethod("layer_spatial") 52 | } 53 | 54 | #' @export 55 | #' @rdname layer_spatial 56 | annotation_spatial <- function(data, mapping, ...) { 57 | UseMethod("annotation_spatial") 58 | } 59 | 60 | #' @rdname layer_spatial 61 | #' @export 62 | layer_spatial.default <- function(data, mapping = aes(), inherit.aes = FALSE, sf_params = list(), ...) { 63 | ggplot2::geom_sf( 64 | mapping = mapping, 65 | data = do.call(sf::st_as_sf, c(list(data), sf_params)), 66 | inherit.aes = inherit.aes, 67 | ... 68 | ) 69 | } 70 | 71 | #' @rdname layer_spatial 72 | #' @export 73 | annotation_spatial.default <- function(data, mapping = aes(), inherit.aes = FALSE, sf_params = list(), ...) { 74 | ggplot2::geom_sf( 75 | mapping = mapping, 76 | data = do.call(sf::st_as_sf, c(list(data), sf_params)), 77 | inherit.aes = inherit.aes, 78 | na.rm = TRUE, 79 | stat = StatSfAnnotation, 80 | ... 81 | ) 82 | } 83 | 84 | #' @export 85 | #' @rdname layer_spatial 86 | shadow_spatial <- function(data, ...) { 87 | UseMethod("shadow_spatial") 88 | } 89 | 90 | #' @rdname layer_spatial 91 | #' @export 92 | shadow_spatial.default <- function(data, ...) { 93 | ggplot2::stat_sf( 94 | mapping = aes(), 95 | data = sf::st_as_sf(data), 96 | inherit.aes = FALSE, 97 | na.rm = FALSE, 98 | geom = GeomBlankSf 99 | ) 100 | } 101 | 102 | StatSfAnnotation <- ggplot2::ggproto( 103 | "StatSfAnnotation", 104 | ggplot2::StatSf, 105 | compute_panel = function(data, scales, coord) { 106 | data$xmin <- NA_real_ 107 | data$xmax <- NA_real_ 108 | data$ymin <- NA_real_ 109 | data$ymax <- NA_real_ 110 | 111 | data 112 | } 113 | ) 114 | 115 | GeomBlankSf <- ggplot2::ggproto( 116 | "GeomBlankSf", 117 | ggplot2::GeomBlank, 118 | extra_params = c(ggplot2::GeomBlank$extra_params, "legend") 119 | ) 120 | -------------------------------------------------------------------------------- /R/longlake-data.R: -------------------------------------------------------------------------------- 1 | 2 | #' Load longlake test data 3 | #' 4 | #' @param env The environment in which to assign the objects 5 | #' @param vector_format,raster_format The format in which objects should be loaded 6 | #' @param which An optional subset of objects to be loaded 7 | #' 8 | #' @export 9 | #' 10 | #' @source The Nova Scotia Topographic Database 11 | #' () and 12 | #' Open Street Map (). 13 | #' 14 | #' @examples 15 | #' load_longlake_data(which = "longlake_waterdf") 16 | #' 17 | load_longlake_data <- function(env = parent.frame(), vector_format = c("sf", "sp"), 18 | raster_format = c("terra", "stars", "stars_proxy", "raster"), 19 | which = NULL) { 20 | raster_format <- match.arg(raster_format) 21 | vector_format <- match.arg(vector_format) 22 | 23 | longlake_folder <- system.file("longlake", package = "ggspatial") 24 | 25 | vector_layers <- c( 26 | "LongLakeDepthSurvey.shp" = "longlake_depthdf", 27 | "LongLakeMarshWaterPoly.shp" = "longlake_waterdf", 28 | "LongLakeMarshRoads.shp" = "longlake_roadsdf", 29 | "LongLakeMarshWetlands.gpkg" = " longlake_marshdf", 30 | "LongLakeMarshStreams.shp" = "longlake_streamsdf", 31 | "LongLakeMarshBuildings.shp" = "longlake_buildingsdf" 32 | ) 33 | 34 | raster_layers <- c( 35 | "longlake_depth.tif" = "longlake_depth_raster", 36 | "longlake.tif" = "longlake_osm" 37 | ) 38 | 39 | if(!is.null(which)) { 40 | vector_layers <- vector_layers[vector_layers %in% which] 41 | raster_layers <- raster_layers[raster_layers %in% which] 42 | } 43 | 44 | if(vector_format == "sf") { 45 | for(i in seq_along(vector_layers)) { 46 | env[[vector_layers[i]]] <- sf::read_sf(file.path(longlake_folder, names(vector_layers)[i])) 47 | } 48 | } else if(vector_format == "sp") { 49 | loadNamespace("sp") 50 | for(i in seq_along(vector_layers)) { 51 | env[[vector_layers[i]]] <- suppressWarnings( 52 | methods::as( 53 | sf::st_zm(sf::read_sf(file.path(longlake_folder, names(vector_layers)[i]))), 54 | "Spatial" 55 | ) 56 | ) 57 | } 58 | } 59 | 60 | if(raster_format == "raster") { 61 | if("longlake_osm" %in% raster_layers) { 62 | env$longlake_osm <- raster::brick(file.path(longlake_folder, "longlake.tif")) 63 | } 64 | 65 | if("longlake_depth_raster" %in% raster_layers) { 66 | env$longlake_depth_raster <- raster::raster(file.path(longlake_folder, "longlake_depth.tif")) 67 | } 68 | } else if(raster_format == "stars") { 69 | for(i in seq_along(raster_layers)) { 70 | env[[raster_layers[i]]] <- stars::read_stars(file.path(longlake_folder, names(raster_layers)[i])) 71 | } 72 | } else if(raster_format == "stars_proxy") { 73 | for(i in seq_along(raster_layers)) { 74 | env[[raster_layers[i]]] <- stars::read_stars(file.path(longlake_folder, names(raster_layers)[i]), proxy = TRUE) 75 | } 76 | } else if (raster_format == "terra"){ 77 | for(i in seq_along(raster_layers)) { 78 | env[[raster_layers[i]]] <- terra::rast(file.path(longlake_folder, names(raster_layers)[i])) 79 | } 80 | 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | 2 | expect_doppelganger_extra <- function(what, x) { 3 | if (identical(Sys.getenv("GGSPATIAL_RUN_EXTRA_VDIFFR"), "true")) { 4 | vdiffr::expect_doppelganger(what, {{ x }}) 5 | } else { 6 | ggplot2::ggplot_gtable(ggplot2::ggplot_build(x)) 7 | testthat::expect_true(TRUE) 8 | x 9 | } 10 | } 11 | 12 | expect_doppelganger <- function(what, x) { 13 | vdiffr::expect_doppelganger(what, {{ x }}) 14 | } 15 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | rosm::set_default_cachedir(system.file("rosm.cache", package = "ggspatial")) 9 | knitr::opts_chunk$set( 10 | collapse = TRUE, 11 | dpi = 150, 12 | comment = "#>", 13 | fig.path = "man/figures/README-", 14 | out.width = "100%" 15 | ) 16 | ``` 17 | 18 | # ggspatial 19 | 20 | 21 | [![ggspatial on CRAN](https://cranlogs.r-pkg.org/badges/ggspatial)](https://cran.r-project.org/package=ggspatial) 22 | [![Coverage Status](https://img.shields.io/codecov/c/github/paleolimbot/ggspatial/master.svg)](https://app.codecov.io/github/paleolimbot/ggspatial?branch=master) 23 | [![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) 24 | [![R-CMD-check](https://github.com/paleolimbot/ggspatial/workflows/R-CMD-check/badge.svg)](https://github.com/paleolimbot/ggspatial/actions) 25 | 26 | 27 | Spatial data plus the power of the `ggplot2` framework means easier mapping. 28 | 29 | ## Installation 30 | 31 | The package is available on CRAN, and can be installed using `install.packages("ggspatial")`. The development version can be installed via **remotes**. 32 | 33 | ```{r, eval=FALSE} 34 | install.packages("ggspatial") 35 | ``` 36 | 37 | Or for the development version: 38 | 39 | ```{r, eval=FALSE} 40 | install.packages("remotes") # if remotes isn't installed 41 | remotes::install_github("paleolimbot/ggspatial") 42 | ``` 43 | 44 | ## Introduction 45 | 46 | This package is a framework for interacting with spatial data using **ggplot2** as a plotting backend. The package supports **sf** package objects, **sp** package objects, and **raster** package objects, and uses `geom_sf()` and `coord_sf()` to do most of the heavy lifting with respect to coordinate transformation. 47 | 48 | ```{r fig-layer-spatial-sf, warning=FALSE, message=FALSE} 49 | library(ggplot2) 50 | library(ggspatial) 51 | load_longlake_data() 52 | 53 | ggplot() + 54 | # loads background map tiles from a tile source 55 | annotation_map_tile(zoomin = -1) + 56 | 57 | # annotation_spatial() layers don't train the scales, so data stays central 58 | annotation_spatial(longlake_roadsdf, size = 2, col = "black") + 59 | annotation_spatial(longlake_roadsdf, size = 1.6, col = "white") + 60 | 61 | # raster layers train scales and get projected automatically 62 | layer_spatial(longlake_depth_raster, aes(colour = after_stat(band1))) + 63 | # make no data values transparent 64 | scale_fill_viridis_c(na.value = NA) + 65 | 66 | # layer_spatial trains the scales 67 | layer_spatial(longlake_depthdf, aes(fill = DEPTH_M)) + 68 | 69 | # spatial-aware automagic scale bar 70 | annotation_scale(location = "tl") + 71 | 72 | # spatial-aware automagic north arrow 73 | annotation_north_arrow(location = "br", which_north = "true") 74 | ``` 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # ggspatial 5 | 6 | 7 | 8 | [![ggspatial on 9 | CRAN](https://cranlogs.r-pkg.org/badges/ggspatial)](https://cran.r-project.org/package=ggspatial) 10 | [![Coverage 11 | Status](https://img.shields.io/codecov/c/github/paleolimbot/ggspatial/master.svg)](https://app.codecov.io/github/paleolimbot/ggspatial?branch=master) 12 | [![Lifecycle: 13 | stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) 14 | [![R-CMD-check](https://github.com/paleolimbot/ggspatial/workflows/R-CMD-check/badge.svg)](https://github.com/paleolimbot/ggspatial/actions) 15 | 16 | 17 | Spatial data plus the power of the `ggplot2` framework means easier 18 | mapping. 19 | 20 | ## Installation 21 | 22 | The package is available on CRAN, and can be installed using 23 | `install.packages("ggspatial")`. The development version can be 24 | installed via **remotes**. 25 | 26 | ``` r 27 | install.packages("ggspatial") 28 | ``` 29 | 30 | Or for the development version: 31 | 32 | ``` r 33 | install.packages("remotes") # if remotes isn't installed 34 | remotes::install_github("paleolimbot/ggspatial") 35 | ``` 36 | 37 | ## Introduction 38 | 39 | This package is a framework for interacting with spatial data using 40 | **ggplot2** as a plotting backend. The package supports **sf** package 41 | objects, **sp** package objects, and **raster** package objects, and 42 | uses `geom_sf()` and `coord_sf()` to do most of the heavy lifting with 43 | respect to coordinate transformation. 44 | 45 | ``` r 46 | library(ggplot2) 47 | library(ggspatial) 48 | load_longlake_data() 49 | 50 | ggplot() + 51 | # loads background map tiles from a tile source 52 | annotation_map_tile(zoomin = -1) + 53 | 54 | # annotation_spatial() layers don't train the scales, so data stays central 55 | annotation_spatial(longlake_roadsdf, size = 2, col = "black") + 56 | annotation_spatial(longlake_roadsdf, size = 1.6, col = "white") + 57 | 58 | # raster layers train scales and get projected automatically 59 | layer_spatial(longlake_depth_raster, aes(colour = after_stat(band1))) + 60 | # make no data values transparent 61 | scale_fill_viridis_c(na.value = NA) + 62 | 63 | # layer_spatial trains the scales 64 | layer_spatial(longlake_depthdf, aes(fill = DEPTH_M)) + 65 | 66 | # spatial-aware automagic scale bar 67 | annotation_scale(location = "tl") + 68 | 69 | # spatial-aware automagic north arrow 70 | annotation_north_arrow(location = "br", which_north = "true") 71 | ``` 72 | 73 | 74 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | development: 2 | mode: auto 3 | 4 | reference: 5 | - title: Spatial annotations 6 | desc: Useful annotations that are frequently found on maps 7 | contents: 8 | - annotation_north_arrow 9 | - starts_with("north_arrow") 10 | - fixed_plot_aspect 11 | - annotation_scale 12 | - title: Spatial-enabled ggplot2 geometries 13 | desc: Use coordinate data with `coord_sf()` 14 | contents: 15 | - starts_with("geom_spatial") 16 | - starts_with("stat_spatial") 17 | - geom_polypath 18 | - title: Layer functions 19 | desc: Convert spatial objects to ggplo2 layers 20 | contents: 21 | - annotation_map_tile 22 | - starts_with("layer_spatial") 23 | - starts_with("annotation_spatial") 24 | - starts_with("shadow_spatial") 25 | - title: Coordinate utilities 26 | desc: Extract and project coordinates from spatial objects 27 | contents: 28 | - starts_with("df_spatial") 29 | - xy_transform 30 | - title: Example data 31 | desc: Data used to demonstrate and test this package 32 | contents: 33 | - contains("longlake") 34 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | 2 | Fixes an issue related to updated terra/raster. 3 | 4 | ## Test environments 5 | 6 | * local R installation 7 | * MacOS (on Github Actions), R-release 8 | * win-builder (devel) 9 | 10 | ## R CMD check results 11 | 12 | 0 errors | 0 warnings | 0 notes 13 | -------------------------------------------------------------------------------- /data-raw/longlake_interp.R: -------------------------------------------------------------------------------- 1 | 2 | library(tidyverse) 3 | library(sf) 4 | 5 | # create a depth raster of longlake using depth_df and outline 6 | ggspatial::load_longlake_data() 7 | 8 | # helper functions from the lake mophometry paper 9 | 10 | # this gets used to create a regular grid for GAM interpolation 11 | create_grid <- function(xy, ...) { 12 | expand.grid( 13 | X = seq(floor(min(xy$X)), ceiling(max(xy$X)), ...), 14 | Y = seq(floor(min(xy$Y)), ceiling(max(xy$Y)), ...) 15 | ) %>% as_tibble() 16 | } 17 | 18 | interpolate_raster <- function(sp, values, boundary = NULL, boundary_values = 0, 19 | method = gam_repl, ...) { 20 | 21 | # create nodes object for processing 22 | points <- sp %>% 23 | st_zm() %>% 24 | transmute(z = !!enquo(values), point_type = "input") %>% 25 | st_cast("POINT", warn = FALSE) 26 | 27 | if(!is.null(boundary)) { 28 | boundary <- boundary %>% 29 | st_transform(st_crs(points)) %>% 30 | st_zm() 31 | points <- points %>% 32 | rbind( 33 | boundary %>% 34 | transmute(z = !!enquo(boundary_values), point_type = "boundary") %>% 35 | st_cast("POINT", warn = FALSE) 36 | ) 37 | } 38 | 39 | rast <- method(points, ...) 40 | 41 | if(!is.null(boundary)) { 42 | rast <- raster::mask(rast, as(boundary, "Spatial")) 43 | } 44 | 45 | rast 46 | } 47 | 48 | gam_repl <- function(points, k = 60, quiet = TRUE, by = NULL, length.out = 100) { 49 | # significant inspiration from here: 50 | # https://www.fromthebottomoftheheap.net/2016/03/27/soap-film-smoothers/ 51 | 52 | if(is.null(by)) { 53 | grid_gen <- function(xy) { 54 | create_grid(xy, length.out = length.out) 55 | } 56 | } else { 57 | grid_gen <- function(xy) { 58 | create_grid(xy, by = by) 59 | } 60 | } 61 | 62 | if(!quiet) message("Creating grid...") 63 | 64 | # get z points, z as a data frame 65 | z_values <- bind_cols( 66 | points %>% unclass() %>% as_tibble() %>% select(-geometry), 67 | points %>% st_coordinates() %>% as_tibble() 68 | ) 69 | 70 | if(!quiet) message("Fitting GAM...") 71 | s <- mgcv::s 72 | tprs <- mgcv::gam(z ~ s(X, Y, k = k), data = z_values, method = "REML") 73 | 74 | if(!quiet) message("Interpolating...") 75 | 76 | # create grid, predict values at regularly-spaced grid locations 77 | grid <- grid_gen(z_values) 78 | grid$z <- predict(tprs, grid, type = "response") 79 | 80 | # return raster with correct points 81 | raster::rasterFromXYZ(grid, crs = st_crs(points)$proj4string) 82 | } 83 | 84 | longlake_depth_raster <- interpolate_raster( 85 | longlake_depthdf, 86 | values = DEPTH_M, 87 | boundary = longlake_waterdf %>% slice(2) 88 | ) 89 | 90 | raster::plot(longlake_depth_raster) 91 | 92 | raster_fname <- "inst/longlake/longlake_depth.tif" 93 | unlink(raster_fname) 94 | raster::writeRaster(longlake_depth_raster, raster_fname) 95 | 96 | -------------------------------------------------------------------------------- /ggspatial.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /inst/longlake/LongLakeDepthSurvey.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeDepthSurvey.dbf -------------------------------------------------------------------------------- /inst/longlake/LongLakeDepthSurvey.prj: -------------------------------------------------------------------------------- 1 | PROJCS["UTM_Zone_20_Northern_Hemisphere",GEOGCS["GCS_GRS 1980(IUGG, 1980)",DATUM["D_unknown",SPHEROID["GRS80",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /inst/longlake/LongLakeDepthSurvey.qpj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD83 / UTM zone 20N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26920"]] 2 | -------------------------------------------------------------------------------- /inst/longlake/LongLakeDepthSurvey.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeDepthSurvey.shp -------------------------------------------------------------------------------- /inst/longlake/LongLakeDepthSurvey.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeDepthSurvey.shx -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshBuildings.dbf: -------------------------------------------------------------------------------- 1 | _!hOBJECTIDN 2 | FEAT_CODEC ZVALUEN STARTDATEDENDDATEDPRODUCTCSCALECCOLLECTORCCAPTURECPRODYEARCPRODMONTHCX_Y_ACCCZ_ACCCPROVKEYC FILENAMEC ANGLEN 665582BLDG60 132004100100000000PAMGGNK07EEEBL0000124966b3ksmk 89 665585BLDG60 02008100700000000PAMGGNK07EEE b3ksmk 5 665584BLDG60 02008100700000000PAMGGNK07EEE b3ksmk 45 665589BLDG60 02008100700000000PAMGGNK07EEE b3ksmk 20 665587BLDG60 02008100700000000PAMGGNK07EEE b3ksmk 40 665590BLDG60 02008100700000000PAMGGNK07EEE b3ksmk 35 665586BLDG60 02008100700000000PAMGGNK07EEE b3ksmk 40 647456BLDG60 152004100100000000PAMGGNK07EEEBL0000124647b3knmk 179 647436BLDG60 152004100100000000PAMGGNK07EEEBL0000124648b3knmk 178 647328BLDG60 142004100100000000PAMGGNK07EEEBL0000124649b3knmk 41 647556BLDG60 02008100700000000PAMGGNK07EEE b3knmk 45 647474BLDG60 132004100100000000PAMGGNK07EEEBL0000124646b3knmk 198 0 01899123018991230 0 0 01899123018991230 0 -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshBuildings.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_UTM_Zone_20N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshBuildings.qpj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD83 / UTM zone 20N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26920"]] 2 | -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshBuildings.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshBuildings.shp -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshBuildings.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshBuildings.shx -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshRoads.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshRoads.dbf -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshRoads.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_UTM_Zone_20N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshRoads.qpj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD83 / UTM zone 20N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26920"]] 2 | -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshRoads.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshRoads.shp -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshRoads.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshRoads.shx -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshStreams.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshStreams.dbf -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshStreams.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_UTM_Zone_20N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshStreams.qpj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD83 / UTM zone 20N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26920"]] 2 | -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshStreams.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshStreams.shp -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshStreams.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshStreams.shx -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWaterPoly.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshWaterPoly.dbf -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWaterPoly.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_UTM_Zone_20N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWaterPoly.qpj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD83 / UTM zone 20N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26920"]] 2 | -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWaterPoly.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshWaterPoly.shp -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWaterPoly.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshWaterPoly.shx -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWetlands.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshWetlands.dbf -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWetlands.gpkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshWetlands.gpkg -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWetlands.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_UTM_Zone_20N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWetlands.qpj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD83 / UTM zone 20N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26920"]] 2 | -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWetlands.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshWetlands.shp -------------------------------------------------------------------------------- /inst/longlake/LongLakeMarshWetlands.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/LongLakeMarshWetlands.shx -------------------------------------------------------------------------------- /inst/longlake/longlake.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/longlake.tif -------------------------------------------------------------------------------- /inst/longlake/longlake_depth.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/longlake/longlake_depth.tif -------------------------------------------------------------------------------- /inst/rosm.cache/cartodark/13_2635_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartodark/13_2635_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/cartodark/13_2635_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartodark/13_2635_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/cartodark/13_2636_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartodark/13_2636_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/cartodark/13_2636_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartodark/13_2636_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/cartolight/13_2635_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartolight/13_2635_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/cartolight/13_2635_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartolight/13_2635_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/cartolight/13_2636_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartolight/13_2636_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/cartolight/13_2636_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/cartolight/13_2636_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2635_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2635_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2635_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2635_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2635_2918.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2635_2918.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2636_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2636_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2636_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2636_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2636_2918.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2636_2918.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2637_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2637_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2637_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2637_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/13_2637_2918.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/13_2637_2918.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5270_5832.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5270_5832.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5270_5833.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5270_5833.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5270_5834.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5270_5834.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5270_5835.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5270_5835.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5270_5836.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5270_5836.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5270_5837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5270_5837.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5271_5832.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5271_5832.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5271_5833.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5271_5833.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5271_5834.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5271_5834.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5271_5835.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5271_5835.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5271_5836.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5271_5836.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5271_5837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5271_5837.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5272_5832.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5272_5832.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5272_5833.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5272_5833.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5272_5834.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5272_5834.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5272_5835.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5272_5835.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5272_5836.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5272_5836.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5272_5837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5272_5837.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5273_5832.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5273_5832.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5273_5833.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5273_5833.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5273_5834.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5273_5834.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5273_5835.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5273_5835.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5273_5836.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5273_5836.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5273_5837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5273_5837.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5274_5832.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5274_5832.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5274_5833.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5274_5833.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5274_5834.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5274_5834.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5274_5835.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5274_5835.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5274_5836.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5274_5836.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/14_5274_5837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/14_5274_5837.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10540_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10540_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10541_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10541_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10542_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10542_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10543_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10543_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10544_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10544_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10545_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10545_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10546_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10546_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10547_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10547_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11665.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11665.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11666.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11667.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11668.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11669.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11670.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11671.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11671.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11672.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11673.png -------------------------------------------------------------------------------- /inst/rosm.cache/osm/15_10548_11674.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/osm/15_10548_11674.png -------------------------------------------------------------------------------- /inst/rosm.cache/stamenbw/13_2635_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenbw/13_2635_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/stamenbw/13_2635_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenbw/13_2635_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/stamenbw/13_2636_2916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenbw/13_2636_2916.png -------------------------------------------------------------------------------- /inst/rosm.cache/stamenbw/13_2636_2917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenbw/13_2636_2917.png -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/1_0_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/1_0_0.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/1_1_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/1_1_0.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_0_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_0_0.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_0_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_0_1.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_1_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_1_0.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_1_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_1_1.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_2_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_2_0.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_2_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_2_1.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_3_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_3_0.jpg -------------------------------------------------------------------------------- /inst/rosm.cache/stamenwatercolor/2_3_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/inst/rosm.cache/stamenwatercolor/2_3_1.jpg -------------------------------------------------------------------------------- /man/annotation_map_tile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation-map-tile.R 3 | \docType{data} 4 | \name{annotation_map_tile} 5 | \alias{annotation_map_tile} 6 | \alias{GeomMapTile} 7 | \title{Add background OSM tiles} 8 | \format{ 9 | An object of class \code{GeomMapTile} (inherits from \code{Geom}, \code{ggproto}, \code{gg}) of length 5. 10 | } 11 | \usage{ 12 | annotation_map_tile( 13 | type = "osm", 14 | zoom = NULL, 15 | zoomin = -2, 16 | forcedownload = FALSE, 17 | cachedir = NULL, 18 | progress = c("text", "none"), 19 | quiet = TRUE, 20 | interpolate = TRUE, 21 | data = NULL, 22 | mapping = NULL, 23 | alpha = 1 24 | ) 25 | 26 | GeomMapTile 27 | } 28 | \arguments{ 29 | \item{type}{The map type (one of that returned by \link[rosm:osm.types]{rosm::osm.types})} 30 | 31 | \item{zoom}{The zoom level (overrides zoomin)} 32 | 33 | \item{zoomin}{Delta on default zoom. The default value is designed 34 | to download fewer tiles than you probably want. Use \code{-1} or \code{0} to 35 | increase the resolution.} 36 | 37 | \item{forcedownload}{Re-download cached tiles?} 38 | 39 | \item{cachedir}{Specify cache directory} 40 | 41 | \item{progress}{Use \code{progress = "none"} to suppress progress and zoom output} 42 | 43 | \item{quiet}{Use \code{quiet = FALSE} to see which URLs are downloaded} 44 | 45 | \item{interpolate}{Passed to \code{\link[grid:grid.raster]{grid::rasterGrob()}}} 46 | 47 | \item{data, mapping}{Specify data and mapping to use this geom with facets} 48 | 49 | \item{alpha}{Use to make this layer semi-transparent} 50 | } 51 | \value{ 52 | A ggplot2 layer 53 | } 54 | \description{ 55 | Uses \code{\link[rosm:osm.image]{rosm::osm.image()}} to add background tiles. If you are publishing 56 | a map using these tiles, make sure to use the proper attribution 57 | (e.g., "Copyright OpenStreetMap contributors" when using an 58 | OpenStreetMap-based tile set). 59 | } 60 | \examples{ 61 | \donttest{ 62 | library(ggplot2) 63 | load_longlake_data(which = "longlake_waterdf") 64 | 65 | ggplot() + 66 | annotation_map_tile(zoom = 13, cachedir = system.file("rosm.cache", package = "ggspatial")) + 67 | geom_sf(data = longlake_waterdf, fill = NA, col = "grey50") 68 | } 69 | 70 | } 71 | \keyword{datasets} 72 | -------------------------------------------------------------------------------- /man/annotation_north_arrow.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation-north-arrow.R 3 | \docType{data} 4 | \name{annotation_north_arrow} 5 | \alias{annotation_north_arrow} 6 | \alias{GeomNorthArrow} 7 | \title{Spatial-aware north arrow} 8 | \format{ 9 | An object of class \code{GeomNorthArrow} (inherits from \code{Geom}, \code{ggproto}, \code{gg}) of length 5. 10 | } 11 | \usage{ 12 | annotation_north_arrow( 13 | mapping = NULL, 14 | data = NULL, 15 | ..., 16 | height = unit(1.5, "cm"), 17 | width = unit(1.5, "cm"), 18 | pad_x = unit(0.25, "cm"), 19 | pad_y = unit(0.25, "cm"), 20 | rotation = NULL, 21 | style = north_arrow_orienteering 22 | ) 23 | 24 | GeomNorthArrow 25 | } 26 | \arguments{ 27 | \item{mapping, data, ...}{See Aesthetics} 28 | 29 | \item{height, width}{Height and width of north arrow} 30 | 31 | \item{pad_x, pad_y}{Padding between north arrow and edge of frame} 32 | 33 | \item{rotation}{Override the rotation of the north arrow (degrees conterclockwise)} 34 | 35 | \item{style}{A grob or callable that produces a grob that will be drawn as the north arrow. 36 | See \link{north_arrow_orienteering} for options.} 37 | } 38 | \value{ 39 | A ggplot2 layer 40 | } 41 | \description{ 42 | Spatial-aware north arrow 43 | } 44 | \section{Aesthetics}{ 45 | 46 | The following can be used as parameters or aesthetics. Using them as 47 | aesthetics is useful when facets are used to display multiple panels, 48 | and a different (or missing) scale bar is required in different panels. 49 | Otherwise, just pass them as arguments to \code{annotation_north_arrow()}. 50 | \itemize{ 51 | \item which_north: "grid" results in a north arrow always pointing up; "true" always points to the 52 | north pole from whichever corner of the map the north arrow is in. 53 | \item location: Where to put the scale bar ("tl" for top left, etc.) 54 | } 55 | } 56 | 57 | \examples{ 58 | 59 | cities <- data.frame( 60 | x = c(-63.58595, 116.41214), 61 | y = c(44.64862, 40.19063), 62 | city = c("Halifax", "Beijing") 63 | ) 64 | 65 | ggplot(cities) + 66 | geom_spatial_point(aes(x, y), crs = 4326) + 67 | annotation_north_arrow(which_north = "true") + 68 | coord_sf(crs = 3995) 69 | 70 | ggplot(cities) + 71 | geom_spatial_point(aes(x, y), crs = 4326) + 72 | annotation_north_arrow(which_north = "grid") + 73 | coord_sf(crs = 3995) 74 | 75 | } 76 | \keyword{datasets} 77 | -------------------------------------------------------------------------------- /man/annotation_scale.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation-scale.R 3 | \docType{data} 4 | \name{annotation_scale} 5 | \alias{annotation_scale} 6 | \alias{GeomScaleBar} 7 | \title{Spatial-aware scalebar annotation} 8 | \format{ 9 | An object of class \code{GeomScaleBar} (inherits from \code{Geom}, \code{ggproto}, \code{gg}) of length 5. 10 | } 11 | \usage{ 12 | annotation_scale( 13 | mapping = NULL, 14 | data = NULL, 15 | ..., 16 | plot_unit = NULL, 17 | bar_cols = c("black", "white"), 18 | line_width = 1, 19 | height = unit(0.25, "cm"), 20 | pad_x = unit(0.25, "cm"), 21 | pad_y = unit(0.25, "cm"), 22 | text_pad = unit(0.15, "cm"), 23 | text_cex = 0.7, 24 | text_face = NULL, 25 | text_family = "", 26 | tick_height = 0.6 27 | ) 28 | 29 | GeomScaleBar 30 | } 31 | \arguments{ 32 | \item{mapping, data, ...}{See Aesthetics} 33 | 34 | \item{plot_unit}{For non-coord_sf applications, specify the unit for x and y coordinates. 35 | Must be one of km, m, cm, mi, ft, or in.} 36 | 37 | \item{bar_cols}{Colours to use for the bars} 38 | 39 | \item{line_width}{Line width for scale bar} 40 | 41 | \item{height}{Height of scale bar} 42 | 43 | \item{pad_x, pad_y}{Distance between scale bar and edge of panel} 44 | 45 | \item{text_pad, text_cex, text_face, text_family}{Parameters for label} 46 | 47 | \item{tick_height}{Height of ticks relative to height of scale bar} 48 | } 49 | \value{ 50 | A ggplot2 layer. 51 | } 52 | \description{ 53 | Spatial-aware scalebar annotation 54 | } 55 | \section{Aesthetics}{ 56 | 57 | The following can be used as parameters or aesthetics. Using them as 58 | aesthetics is useful when facets are used to display multiple panels, 59 | and a different (or missing) scale bar is required in different panels. 60 | Otherwise, just pass them as arguments to \code{annotation_scale}. 61 | \itemize{ 62 | \item width_hint: The (suggested) proportion of the plot area which the scalebar should occupy. 63 | \item unit_category: Use "metric" or "imperial" units. 64 | \item style: One of "bar" or "ticks" 65 | \item location: Where to put the scale bar ("tl" for top left, etc.) 66 | \item line_col and text_col: Line and text colour, respectively 67 | } 68 | } 69 | 70 | \examples{ 71 | cities <- data.frame( 72 | x = c(-63.58595, 116.41214), 73 | y = c(44.64862, 40.19063), 74 | city = c("Halifax", "Beijing") 75 | ) 76 | 77 | ggplot(cities) + 78 | geom_spatial_point(aes(x, y), crs = 4326) + 79 | annotation_scale() + 80 | coord_sf(crs = 3995) 81 | 82 | } 83 | \keyword{datasets} 84 | -------------------------------------------------------------------------------- /man/annotation_spatial_hline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-spatial-xline.R 3 | \docType{data} 4 | \name{annotation_spatial_hline} 5 | \alias{annotation_spatial_hline} 6 | \alias{annotation_spatial_vline} 7 | \alias{GeomSpatialXline} 8 | \title{Projected horizontal and vertical lines} 9 | \format{ 10 | An object of class \code{GeomSpatialXline} (inherits from \code{GeomHline}, \code{Geom}, \code{ggproto}, \code{gg}) of length 4. 11 | } 12 | \usage{ 13 | annotation_spatial_hline( 14 | mapping = NULL, 15 | data = NULL, 16 | stat = "identity", 17 | ..., 18 | intercept = waiver(), 19 | limits = NULL, 20 | detail = 100, 21 | crs = NULL, 22 | na.rm = FALSE, 23 | show.legend = NA 24 | ) 25 | 26 | annotation_spatial_vline( 27 | mapping = NULL, 28 | data = NULL, 29 | stat = "identity", 30 | ..., 31 | intercept = waiver(), 32 | limits = NULL, 33 | detail = 100, 34 | crs = NULL, 35 | na.rm = FALSE, 36 | show.legend = NA 37 | ) 38 | 39 | GeomSpatialXline 40 | } 41 | \arguments{ 42 | \item{mapping}{An aesthetic mapping created with \code{\link[ggplot2:aes]{ggplot2::aes()}}.} 43 | 44 | \item{data}{A data frame or other object, coerced to a data.frame by \code{\link[ggplot2:fortify]{ggplot2::fortify()}}.} 45 | 46 | \item{stat}{Statistical transformation to use on this layer. See \code{\link[ggplot2:layer]{ggplot2::layer()}}.} 47 | 48 | \item{...}{Passed to the combined stat/geom as parameters or fixed aesthetics.} 49 | 50 | \item{intercept}{The x or y value that should be constant in the given 51 | \code{crs}. Can also be passed as an aesthetic through \code{data} and \code{mapping}.} 52 | 53 | \item{limits}{Use \code{NULL} to guess the minimum and maximum x or y value in 54 | the non-constant dimension, or specify a vector of length 2 to specify 55 | manually.} 56 | 57 | \item{detail}{The number of points that should be used when converting the 58 | line into segments.} 59 | 60 | \item{crs}{The crs of the x and y aesthetics, or NULL to use default lon/lat 61 | crs (with a message).} 62 | 63 | \item{na.rm}{Should missing aesthetic values be removed?} 64 | 65 | \item{show.legend}{Should the legend be shown?} 66 | } 67 | \description{ 68 | Projected horizontal and vertical lines 69 | } 70 | \examples{ 71 | cities <- data.frame( 72 | x = c(-63.58595, 116.41214, 0), 73 | y = c(44.64862, 40.19063, 89.9), 74 | city = c("Halifax", "Beijing", "North Pole") 75 | ) 76 | 77 | p <- ggplot(cities, aes(x, y, label = city)) + 78 | geom_spatial_point(crs = 4326) + 79 | # view of the north pole 80 | coord_sf(crs = 3995) 81 | 82 | p + 83 | # longitude lines 84 | annotation_spatial_vline( 85 | intercept = seq(-180, 180, by = 10), 86 | crs = 4326 87 | ) + 88 | # latitude lines 89 | annotation_spatial_hline( 90 | intercept = seq(0, 90, by = 10), 91 | crs = 4326 92 | ) 93 | 94 | } 95 | \keyword{datasets} 96 | -------------------------------------------------------------------------------- /man/df_spatial.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/df-spatial.R 3 | \name{df_spatial} 4 | \alias{df_spatial} 5 | \title{Create a ggplot-friendly data frame from a spatial object} 6 | \usage{ 7 | df_spatial(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A spatial object} 11 | 12 | \item{...}{Passed to specific methods} 13 | } 14 | \value{ 15 | A tibble with coordinates as \code{x} and \code{y}, 16 | features as \code{feature_id}, and parts as \code{part_id}. 17 | } 18 | \description{ 19 | Create a ggplot-friendly data frame from a spatial object 20 | } 21 | \examples{ 22 | \donttest{ 23 | load_longlake_data(which = c("longlake_osm", "longlake_depthdf")) 24 | df_spatial(longlake_osm) 25 | df_spatial(longlake_depthdf) 26 | df_spatial(as(longlake_depthdf, "Spatial")) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /man/figures/README-fig-layer-spatial-sf-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paleolimbot/ggspatial/5c4c903a0785702d83acfe6d9753294882ed676c/man/figures/README-fig-layer-spatial-sf-1.png -------------------------------------------------------------------------------- /man/fixed_plot_aspect.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fixed-aspect.R 3 | \name{fixed_plot_aspect} 4 | \alias{fixed_plot_aspect} 5 | \title{Enforce a plot aspect ratio} 6 | \usage{ 7 | fixed_plot_aspect(ratio = 1) 8 | } 9 | \arguments{ 10 | \item{ratio}{The desired aspect ratio (width / height)} 11 | } 12 | \value{ 13 | A \code{\link[ggplot2:layer]{ggplot2::layer()}} that can be added to a \code{\link[ggplot2:ggplot]{ggplot2::ggplot()}}. 14 | } 15 | \description{ 16 | When using a fixed-aspect coordinate system, \code{\link[=fixed_plot_aspect]{fixed_plot_aspect()}} expands 17 | either the width or height of the plot to ensure that the output 18 | has dimensions that make sense. This is a useful workaround for 19 | getting reasonable-shaped plots when using \code{\link[ggplot2:ggsf]{ggplot2::coord_sf()}} 20 | or \code{\link[ggplot2:coord_fixed]{ggplot2::coord_fixed()}} when the data happen to be 21 | aligned vertically or horizontally. 22 | } 23 | \examples{ 24 | library(ggplot2) 25 | df <- data.frame(x = 0:5, y = seq(0, 10, length.out = 6)) 26 | ggplot(df, aes(x, y)) + 27 | geom_point() + 28 | fixed_plot_aspect(ratio = 1) + 29 | coord_fixed() 30 | 31 | } 32 | -------------------------------------------------------------------------------- /man/geom_polypath.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-polypath.R 3 | \name{geom_polypath} 4 | \alias{geom_polypath} 5 | \title{Polygons with holes in ggplot2} 6 | \usage{ 7 | geom_polypath( 8 | mapping = NULL, 9 | data = NULL, 10 | stat = "identity", 11 | position = "identity", 12 | na.rm = FALSE, 13 | show.legend = NA, 14 | inherit.aes = TRUE, 15 | rule = "winding", 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{mapping}{An aesthetic mapping, created with \link[ggplot2:aes]{aes}. The aesthetic 21 | will mostly likely need to contain a \code{group} mapping.} 22 | 23 | \item{data}{A data.frame containing the coordinates to plot.} 24 | 25 | \item{stat}{A statistic to apply (most likely "identity")} 26 | 27 | \item{position}{A position to apply (most likely "identity")} 28 | 29 | \item{na.rm}{Should missing coordinate be removed?} 30 | 31 | \item{show.legend}{Should a legend be shown for mapped aesthetics?} 32 | 33 | \item{inherit.aes}{Should aesthetics be inherited?} 34 | 35 | \item{rule}{A fill rule to apply. One of "winding" or "evenodd".} 36 | 37 | \item{...}{Passed to the geom and/or stat.} 38 | } 39 | \value{ 40 | A ggplot2 layer 41 | } 42 | \description{ 43 | This geometry used to plot polygons with holes in ggplot2 at the 44 | more correctly than \link[ggplot2:geom_polygon]{geom_polygon}; however, 45 | in recent R and ggplot2 versions this is no longer needed. 46 | } 47 | \examples{ 48 | \donttest{ 49 | library(ggplot2) 50 | load_longlake_data(which = "longlake_waterdf") 51 | ggplot(df_spatial(longlake_waterdf), aes(x, y, group = piece_id)) + 52 | geom_polypath() 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /man/geom_spatial_rect.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-spatial-rect.R 3 | \docType{data} 4 | \name{geom_spatial_rect} 5 | \alias{geom_spatial_rect} 6 | \alias{geom_spatial_tile} 7 | \alias{StatSpatialRect} 8 | \alias{StatSpatialTile} 9 | \title{Projected rectangular regions} 10 | \format{ 11 | An object of class \code{StatSpatialRect} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 4. 12 | 13 | An object of class \code{StatSpatialTile} (inherits from \code{StatSpatialRect}, \code{Stat}, \code{ggproto}, \code{gg}) of length 4. 14 | } 15 | \usage{ 16 | geom_spatial_rect( 17 | mapping = NULL, 18 | data = NULL, 19 | ..., 20 | crs = NULL, 21 | detail = 30, 22 | linejoin = "mitre", 23 | na.rm = FALSE, 24 | show.legend = NA, 25 | inherit.aes = TRUE 26 | ) 27 | 28 | geom_spatial_tile( 29 | mapping = NULL, 30 | data = NULL, 31 | ..., 32 | crs = NULL, 33 | detail = 30, 34 | linejoin = "mitre", 35 | na.rm = FALSE, 36 | show.legend = NA, 37 | inherit.aes = TRUE 38 | ) 39 | 40 | StatSpatialRect 41 | 42 | StatSpatialTile 43 | } 44 | \arguments{ 45 | \item{mapping}{An aesthetic mapping created with \code{\link[ggplot2:aes]{ggplot2::aes()}}.} 46 | 47 | \item{data}{A data frame or other object, coerced to a data.frame by \code{\link[ggplot2:fortify]{ggplot2::fortify()}}.} 48 | 49 | \item{...}{Passed to the combined stat/geom as parameters or fixed aesthetics.} 50 | 51 | \item{crs}{The crs of the x and y aesthetics, or NULL to use default lon/lat 52 | crs (with a message).} 53 | 54 | \item{detail}{Passed to \code{\link[sf:geos_unary]{sf::st_segmentize()}}: the number of line segments 55 | per quadrant of the bounding box. Increase this number for a smoother 56 | projected bounding box.} 57 | 58 | \item{linejoin}{How corners should be joined} 59 | 60 | \item{na.rm}{Should missing aesthetic values be removed?} 61 | 62 | \item{show.legend, inherit.aes}{See \code{\link[ggplot2:layer]{ggplot2::layer()}}.} 63 | } 64 | \description{ 65 | If you need to plot a \code{\link[sf:st_bbox]{sf::st_bbox()}}, use \code{\link[=layer_spatial]{layer_spatial()}} instead. 66 | While the implementation is slightly differrent, these functions are 67 | intended to behave identically to \code{\link[ggplot2:geom_tile]{ggplot2::geom_rect()}} and 68 | \code{\link[ggplot2:geom_tile]{ggplot2::geom_tile()}}. 69 | } 70 | \examples{ 71 | library(ggplot2) 72 | tile_df <- expand.grid( 73 | x = seq(-140, -52, by = 20), 74 | y = seq(40, 70, by = 10) 75 | ) 76 | 77 | ggplot(tile_df, aes(x, y)) + 78 | geom_spatial_tile(crs = 4326) + 79 | coord_sf(crs = 3979) 80 | 81 | # the same plot using geom_spatial_rect() 82 | ggplot( 83 | tile_df, 84 | aes(xmin = x - 10, xmax = x + 10, ymin = y - 5, ymax = y + 5) 85 | ) + 86 | geom_spatial_rect(crs = 4326) + 87 | coord_sf(crs = 3979) 88 | 89 | } 90 | \keyword{datasets} 91 | -------------------------------------------------------------------------------- /man/geom_spatial_segment.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-spatial-segment.R 3 | \docType{data} 4 | \name{geom_spatial_segment} 5 | \alias{geom_spatial_segment} 6 | \alias{StatSpatialSegment} 7 | \title{Spatial line segments} 8 | \format{ 9 | An object of class \code{StatSpatialSegment} (inherits from \code{StatSpatialRect}, \code{Stat}, \code{ggproto}, \code{gg}) of length 3. 10 | } 11 | \usage{ 12 | geom_spatial_segment( 13 | mapping = NULL, 14 | data = NULL, 15 | ..., 16 | crs = NULL, 17 | detail = waiver(), 18 | great_circle = TRUE, 19 | wrap_dateline = TRUE, 20 | arrow = NULL, 21 | lineend = "butt", 22 | linejoin = "round", 23 | na.rm = FALSE, 24 | show.legend = NA, 25 | inherit.aes = TRUE 26 | ) 27 | 28 | StatSpatialSegment 29 | } 30 | \arguments{ 31 | \item{mapping}{An aesthetic mapping created with \code{\link[ggplot2:aes]{ggplot2::aes()}}.} 32 | 33 | \item{data}{A data frame or other object, coerced to a data.frame by \code{\link[ggplot2:fortify]{ggplot2::fortify()}}.} 34 | 35 | \item{...}{Passed to the combined stat/geom as parameters or fixed aesthetics.} 36 | 37 | \item{crs}{The crs of the x and y aesthetics, or NULL to use default lon/lat 38 | crs (with a message).} 39 | 40 | \item{detail}{Passed to \code{\link[sf:geos_unary]{sf::st_segmentize()}}: the number of line segments 41 | per quadrant of the bounding box. Increase this number for a smoother 42 | projected bounding box.} 43 | 44 | \item{great_circle}{If \code{TRUE}, use \code{\link[lwgeom:geod]{lwgeom::st_geod_segmentize()}} 45 | to connect the (x, y) and (xend, yend) with the shortest possible 46 | great circle along the earth.} 47 | 48 | \item{wrap_dateline}{When using \code{great_circle = TRUE}, using 49 | \code{wrap_dateline = TRUE} splits the great circle along the dateline. 50 | You may want to pass \code{FALSE} here if using \code{arrow} and a projection 51 | that wraps the dateline.} 52 | 53 | \item{arrow}{An arrow specification as a call to \code{\link[grid:arrow]{grid::arrow()}}.} 54 | 55 | \item{lineend}{See \code{\link[ggplot2:geom_segment]{ggplot2::geom_segment()}}.} 56 | 57 | \item{linejoin}{How corners should be joined} 58 | 59 | \item{na.rm}{Should missing aesthetic values be removed?} 60 | 61 | \item{show.legend, inherit.aes}{See \code{\link[ggplot2:layer]{ggplot2::layer()}}.} 62 | } 63 | \description{ 64 | While the implementation is slightly differrent, this function is 65 | intended to behave identically to \code{\link[ggplot2:geom_segment]{ggplot2::geom_segment()}}. Use 66 | \code{great_circle = FALSE} and \code{detail = NULL} if you wish ignore the fact 67 | that the earth is round. 68 | } 69 | \examples{ 70 | library(ggplot2) 71 | 72 | # visualize flights from 73 | # Halifax -> Anchorage -> Berlin -> Halifax 74 | cities <- data.frame( 75 | lon = c(-63.58595, 116.41214, 13.50, -149.75), 76 | lat = c(44.64862, 40.19063, 52.51, 61.20), 77 | city = c("Halifax", "Beijing", "Berlin", "Anchorage"), 78 | city_to = c("Anchorage", "Beijing", "Berlin", "Halifax") 79 | ) 80 | 81 | cities$lon_end <- cities$lon[c(4, 3, 1, 2)] 82 | cities$lat_end <- cities$lat[c(4, 3, 1, 2)] 83 | 84 | p <- ggplot(cities, aes(lon, lat, xend = lon_end, yend = lat_end)) + 85 | geom_spatial_point(crs = 4326) 86 | 87 | # by default, geom_spatial_segment() connects points 88 | # using the shortest distance along the face of the earth 89 | # wrapping at the date line 90 | p + 91 | geom_spatial_segment(crs = 4326) + 92 | coord_sf(crs = 3857) 93 | 94 | # to let the projection handle the dateline, 95 | # use `wrap_dateline = FALSE` (most useful for 96 | # when using `arrow`) 97 | p + 98 | geom_spatial_segment( 99 | wrap_dateline = FALSE, 100 | arrow = grid::arrow(), 101 | crs = 4326 102 | ) + 103 | coord_sf(crs = 3995) 104 | 105 | # to ignore the roundness of the earth, use 106 | # `great_circle = FALSE` 107 | p + 108 | geom_spatial_segment( 109 | great_circle = FALSE, 110 | arrow = grid::arrow(), 111 | crs = 4326 112 | ) + 113 | coord_sf(crs = 3995) 114 | 115 | } 116 | \keyword{datasets} 117 | -------------------------------------------------------------------------------- /man/ggspatial-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggspatial-package.R 3 | \docType{package} 4 | \name{ggspatial-package} 5 | \alias{ggspatial} 6 | \alias{ggspatial-package} 7 | \title{ggspatial: Spatial Data Framework for ggplot2} 8 | \description{ 9 | Spatial data plus the power of the ggplot2 framework means easier mapping when input data are already in the form of spatial objects. 10 | } 11 | \seealso{ 12 | Useful links: 13 | \itemize{ 14 | \item \url{https://paleolimbot.github.io/ggspatial/} 15 | \item \url{https://github.com/paleolimbot/ggspatial} 16 | \item Report bugs at \url{https://github.com/paleolimbot/ggspatial/issues} 17 | } 18 | 19 | } 20 | \author{ 21 | \strong{Maintainer}: Dewey Dunnington \email{dewey@fishandwhistle.net} (\href{https://orcid.org/0000-0002-9415-4582}{ORCID}) 22 | 23 | Other contributors: 24 | \itemize{ 25 | \item Brent Thorne (\href{https://orcid.org/0000-0002-1099-3857}{ORCID}) [contributor] 26 | \item Diego Hernangómez (\href{https://orcid.org/0000-0001-8457-4658}{ORCID}) [contributor] 27 | } 28 | 29 | } 30 | \keyword{internal} 31 | -------------------------------------------------------------------------------- /man/layer_spatial.Raster.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer-spatial-raster.R 3 | \docType{data} 4 | \name{layer_spatial.Raster} 5 | \alias{layer_spatial.Raster} 6 | \alias{annotation_spatial.Raster} 7 | \alias{StatSpatialRaster} 8 | \alias{StatSpatialRasterAnnotation} 9 | \alias{StatSpatialRasterDf} 10 | \alias{GeomSpatialRaster} 11 | \title{Spatial ggplot2 layer for raster objects} 12 | \format{ 13 | An object of class \code{StatSpatialRaster} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 3. 14 | 15 | An object of class \code{StatSpatialRaster} (inherits from \code{StatSpatialRaster}, \code{Stat}, \code{ggproto}, \code{gg}) of length 3. 16 | 17 | An object of class \code{StatSpatialRasterDf} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 5. 18 | 19 | An object of class \code{GeomSpatialRaster} (inherits from \code{Geom}, \code{ggproto}, \code{gg}) of length 5. 20 | } 21 | \usage{ 22 | \method{layer_spatial}{Raster}( 23 | data, 24 | mapping = NULL, 25 | interpolate = NULL, 26 | is_annotation = FALSE, 27 | lazy = FALSE, 28 | dpi = 150, 29 | ... 30 | ) 31 | 32 | \method{annotation_spatial}{Raster}(data, mapping = NULL, interpolate = NULL, ...) 33 | 34 | StatSpatialRaster 35 | 36 | StatSpatialRasterAnnotation 37 | 38 | StatSpatialRasterDf 39 | 40 | GeomSpatialRaster 41 | } 42 | \arguments{ 43 | \item{data}{A Raster object} 44 | 45 | \item{mapping}{Currently, only RGB or RGBA rasters are supported. In the future, one may be able to 46 | map specific bands to the fill and alpha aesthetics.} 47 | 48 | \item{interpolate}{Interpolate resampling for rendered raster image} 49 | 50 | \item{is_annotation}{Lets raster exist without modifying scales} 51 | 52 | \item{lazy}{Delay projection and resample of raster until the plot is being rendered} 53 | 54 | \item{dpi}{if lazy = TRUE, the dpi to which the raster should be resampled} 55 | 56 | \item{...}{Passed to other methods} 57 | } 58 | \value{ 59 | A ggplot2 layer 60 | } 61 | \description{ 62 | This is intended for use with RGB(A) rasters (e.g., georeferenced imagery or photos). To work with 63 | bands as if they were columns, use \link{df_spatial} and \link{geom_raster}. 64 | } 65 | \examples{ 66 | \donttest{ 67 | library(ggplot2) 68 | load_longlake_data(which = c("longlake_osm", "longlake_depth_raster")) 69 | ggplot() + layer_spatial(longlake_osm) 70 | ggplot() + layer_spatial(longlake_depth_raster) + scale_fill_continuous(na.value = NA) 71 | } 72 | 73 | } 74 | \keyword{datasets} 75 | -------------------------------------------------------------------------------- /man/layer_spatial.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer-spatial.R 3 | \name{layer_spatial} 4 | \alias{layer_spatial} 5 | \alias{annotation_spatial} 6 | \alias{layer_spatial.default} 7 | \alias{annotation_spatial.default} 8 | \alias{shadow_spatial} 9 | \alias{shadow_spatial.default} 10 | \title{Turn a spatial object into a ggplot2 layer} 11 | \usage{ 12 | layer_spatial(data, mapping, ...) 13 | 14 | annotation_spatial(data, mapping, ...) 15 | 16 | \method{layer_spatial}{default}( 17 | data, 18 | mapping = aes(), 19 | inherit.aes = FALSE, 20 | sf_params = list(), 21 | ... 22 | ) 23 | 24 | \method{annotation_spatial}{default}( 25 | data, 26 | mapping = aes(), 27 | inherit.aes = FALSE, 28 | sf_params = list(), 29 | ... 30 | ) 31 | 32 | shadow_spatial(data, ...) 33 | 34 | \method{shadow_spatial}{default}(data, ...) 35 | } 36 | \arguments{ 37 | \item{data}{An object that can be coerced to an sf object using \link[sf:st_as_sf]{st_as_sf}.} 38 | 39 | \item{mapping}{A mapping, created using \link[ggplot2:aes]{aes}.} 40 | 41 | \item{...}{Passed to \link[ggplot2:ggsf]{geom_sf}} 42 | 43 | \item{inherit.aes}{Inherit aesthetics from ggplot()?} 44 | 45 | \item{sf_params}{Passed to \link[sf:st_as_sf]{st_as_sf}.} 46 | } 47 | \value{ 48 | A ggplot2 \link[ggplot2:layer]{layer}. 49 | } 50 | \description{ 51 | See also \code{\link[=layer_spatial.Raster]{layer_spatial.Raster()}}, \code{\link[=layer_spatial.stars]{layer_spatial.stars()}}, 52 | \code{\link[=layer_spatial.SpatRaster]{layer_spatial.SpatRaster()}} and \code{\link[=layer_spatial.bbox]{layer_spatial.bbox()}} for implementations 53 | for other types of spatial objects. 54 | } 55 | \examples{ 56 | \donttest{ 57 | library(ggplot2) 58 | load_longlake_data( 59 | which = c( 60 | "longlake_roadsdf", 61 | "longlake_depthdf", 62 | "longlake_depth_raster" 63 | ), 64 | raster_format = "terra" 65 | ) 66 | 67 | ggplot() + 68 | 69 | # annotation_spatial() layers don't train the scales, so data stays central 70 | annotation_spatial(longlake_roadsdf, size = 2, col = "black") + 71 | annotation_spatial(longlake_roadsdf, size = 1.6, col = "white") + 72 | 73 | # raster layers train scales and get projected automatically 74 | layer_spatial(longlake_depth_raster, aes(alpha = after_stat(band1)), fill = "darkblue") + 75 | scale_alpha_continuous(na.value = 0) + 76 | 77 | # layer_spatial() layers train the scales 78 | layer_spatial(longlake_depthdf, aes(col = DEPTH_M)) + 79 | 80 | # spatial-aware automagic scale bar 81 | annotation_scale(location = "tl") + 82 | 83 | # spatial-aware automagic north arrow 84 | annotation_north_arrow(location = "br", which_north = "true") 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /man/layer_spatial.SpatRaster.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer-spatial-terra.R 3 | \docType{data} 4 | \name{layer_spatial.SpatRaster} 5 | \alias{layer_spatial.SpatRaster} 6 | \alias{annotation_spatial.SpatRaster} 7 | \alias{StatSpatRaster} 8 | \alias{StatSpatRasterAnnotation} 9 | \alias{StatSpatRasterDf} 10 | \alias{GeomSpatRaster} 11 | \title{Spatial ggplot2 layer for SpatRaster objects} 12 | \format{ 13 | An object of class \code{StatSpatialRaster} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 3. 14 | 15 | An object of class \code{StatSpatRaster} (inherits from \code{StatSpatialRaster}, \code{Stat}, \code{ggproto}, \code{gg}) of length 3. 16 | 17 | An object of class \code{StatSpatRasterDf} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 5. 18 | 19 | An object of class \code{GeomSpatRaster} (inherits from \code{Geom}, \code{ggproto}, \code{gg}) of length 5. 20 | } 21 | \usage{ 22 | \method{layer_spatial}{SpatRaster}( 23 | data, 24 | mapping = NULL, 25 | interpolate = NULL, 26 | is_annotation = FALSE, 27 | lazy = FALSE, 28 | dpi = 150, 29 | ... 30 | ) 31 | 32 | \method{annotation_spatial}{SpatRaster}(data, mapping = NULL, interpolate = NULL, ...) 33 | 34 | StatSpatRaster 35 | 36 | StatSpatRasterAnnotation 37 | 38 | StatSpatRasterDf 39 | 40 | GeomSpatRaster 41 | } 42 | \arguments{ 43 | \item{data}{A SpatRaster object created with \code{\link[terra:rast]{terra::rast()}}.} 44 | 45 | \item{mapping}{Currently, only RGB or RGBA rasters are supported. In the future, one may be able to 46 | map specific bands to the fill and alpha aesthetics.} 47 | 48 | \item{interpolate}{Interpolate resampling for rendered raster image} 49 | 50 | \item{is_annotation}{Lets raster exist without modifying scales} 51 | 52 | \item{lazy}{Delay projection and resample of raster until the plot is being rendered} 53 | 54 | \item{dpi}{if lazy = TRUE, the dpi to which the raster should be resampled} 55 | 56 | \item{...}{Passed to other methods} 57 | } 58 | \value{ 59 | A ggplot2 layer 60 | } 61 | \description{ 62 | This is intended for use with RGB(A) rasters (e.g., georeferenced imagery 63 | or photos). To work with bands as if they were columns, use \link{df_spatial} 64 | and \link{geom_raster}. 65 | } 66 | \examples{ 67 | \donttest{ 68 | 69 | library(ggplot2) 70 | load_longlake_data( 71 | which = c( 72 | "longlake_osm", 73 | "longlake_depth_raster" 74 | ), 75 | raster_format = "terra" 76 | ) 77 | ggplot() + 78 | layer_spatial(longlake_osm) 79 | 80 | ggplot() + 81 | layer_spatial(longlake_depth_raster) + 82 | scale_fill_continuous( 83 | na.value = NA, 84 | type = "viridis" 85 | ) 86 | } 87 | } 88 | \keyword{datasets} 89 | -------------------------------------------------------------------------------- /man/layer_spatial.bbox.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer-spatial-bbox.R 3 | \name{layer_spatial.bbox} 4 | \alias{layer_spatial.bbox} 5 | \alias{annotation_spatial.bbox} 6 | \alias{shadow_spatial.bbox} 7 | \title{Add a bounding box to a map} 8 | \usage{ 9 | \method{layer_spatial}{bbox}(data, mapping = aes(), ..., detail = 30) 10 | 11 | \method{annotation_spatial}{bbox}(data, mapping = aes(), ..., detail = 30) 12 | 13 | \method{shadow_spatial}{bbox}(data, ..., detail = 30) 14 | } 15 | \arguments{ 16 | \item{data}{A bounding box generated by \code{\link[sf:st_bbox]{sf::st_bbox()}}} 17 | 18 | \item{mapping}{A mapping, created using \link[ggplot2:aes]{aes}.} 19 | 20 | \item{...}{Passed to \link[ggplot2:ggsf]{geom_sf}} 21 | 22 | \item{detail}{Passed to \code{\link[sf:geos_unary]{sf::st_segmentize()}}: the number of line segments 23 | per quadrant of the bounding box. Increase this number for a smoother 24 | projected bounding box.} 25 | } 26 | \description{ 27 | To include a bounding box without drawing it, use \code{\link[=shadow_spatial]{shadow_spatial()}} on the 28 | original object. 29 | } 30 | \examples{ 31 | \donttest{ 32 | library(ggplot2) 33 | load_longlake_data(which = c("longlake_waterdf", "longlake_depthdf")) 34 | ggplot() + 35 | layer_spatial(sf::st_bbox(longlake_waterdf)) + 36 | layer_spatial(longlake_depthdf) 37 | 38 | # use shadow_spatial() to include the geographic area of an object 39 | # without drawing it 40 | ggplot() + 41 | shadow_spatial(longlake_waterdf) + 42 | layer_spatial(longlake_depthdf) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /man/layer_spatial.stars.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layer-spatial-stars.R 3 | \docType{data} 4 | \name{layer_spatial.stars} 5 | \alias{layer_spatial.stars} 6 | \alias{annotation_spatial.stars} 7 | \alias{StatSpatialStars} 8 | \alias{StatSpatialStarsAnnotation} 9 | \alias{StatSpatialStarsDf} 10 | \alias{GeomSpatialStars} 11 | \title{Spatial ggplot2 layer for stars objects} 12 | \format{ 13 | An object of class \code{StatSpatialStars} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 3. 14 | 15 | An object of class \code{StatSpatialStars} (inherits from \code{StatSpatialStars}, \code{Stat}, \code{ggproto}, \code{gg}) of length 3. 16 | 17 | An object of class \code{StatSpatialStarsDf} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 5. 18 | 19 | An object of class \code{GeomSpatialStars} (inherits from \code{Geom}, \code{ggproto}, \code{gg}) of length 5. 20 | } 21 | \usage{ 22 | \method{layer_spatial}{stars}( 23 | data, 24 | mapping = NULL, 25 | interpolate = NULL, 26 | is_annotation = FALSE, 27 | lazy = FALSE, 28 | dpi = 150, 29 | options = character(0), 30 | ... 31 | ) 32 | 33 | \method{annotation_spatial}{stars}(data, mapping = NULL, interpolate = NULL, ...) 34 | 35 | StatSpatialStars 36 | 37 | StatSpatialStarsAnnotation 38 | 39 | StatSpatialStarsDf 40 | 41 | GeomSpatialStars 42 | } 43 | \arguments{ 44 | \item{data}{A stars object} 45 | 46 | \item{mapping}{Currently, only RGB or RGBA rasters are supported. In the future, one may be able to 47 | map specific bands to the fill and alpha aesthetics.} 48 | 49 | \item{interpolate}{Interpolate resampling for rendered raster image} 50 | 51 | \item{is_annotation}{Lets raster exist without modifying scales} 52 | 53 | \item{lazy}{Delay projection and resample of raster until the plot is being rendered} 54 | 55 | \item{dpi}{if lazy = TRUE, the dpi to which the raster should be resampled} 56 | 57 | \item{options}{GDAL options for warping/resampling (see \link[stars:st_warp]{st_warp})} 58 | 59 | \item{...}{Passed to other methods} 60 | } 61 | \value{ 62 | A ggplot2 layer 63 | } 64 | \description{ 65 | This is intended for use with RGB(A) rasters (e.g., georeferenced imagery or photos). To work with 66 | bands as if they were columns, use \link{df_spatial} and \link{geom_raster}. 67 | } 68 | \examples{ 69 | \donttest{ 70 | 71 | library(ggplot2) 72 | load_longlake_data( 73 | which = c( 74 | "longlake_osm", 75 | "longlake_depth_raster" 76 | ), 77 | raster_format = "stars" 78 | ) 79 | ggplot() + 80 | layer_spatial(longlake_osm) 81 | 82 | ggplot() + 83 | layer_spatial(longlake_depth_raster) + 84 | scale_fill_continuous( 85 | na.value = NA, 86 | type = "viridis" 87 | ) 88 | } 89 | } 90 | \keyword{datasets} 91 | -------------------------------------------------------------------------------- /man/load_longlake_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/longlake-data.R 3 | \name{load_longlake_data} 4 | \alias{load_longlake_data} 5 | \title{Load longlake test data} 6 | \source{ 7 | The Nova Scotia Topographic Database 8 | (\url{https://geonova.novascotia.ca/}) and 9 | Open Street Map (\url{https://www.openstreetmap.org/}). 10 | } 11 | \usage{ 12 | load_longlake_data( 13 | env = parent.frame(), 14 | vector_format = c("sf", "sp"), 15 | raster_format = c("terra", "stars", "stars_proxy", "raster"), 16 | which = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{env}{The environment in which to assign the objects} 21 | 22 | \item{vector_format, raster_format}{The format in which objects should be loaded} 23 | 24 | \item{which}{An optional subset of objects to be loaded} 25 | } 26 | \description{ 27 | Load longlake test data 28 | } 29 | \examples{ 30 | load_longlake_data(which = "longlake_waterdf") 31 | 32 | } 33 | -------------------------------------------------------------------------------- /man/north_arrow_orienteering.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation-north-arrow.R 3 | \name{north_arrow_orienteering} 4 | \alias{north_arrow_orienteering} 5 | \alias{north_arrow_fancy_orienteering} 6 | \alias{north_arrow_minimal} 7 | \alias{north_arrow_nautical} 8 | \title{North arrow styles} 9 | \usage{ 10 | north_arrow_orienteering( 11 | line_width = 1, 12 | line_col = "black", 13 | fill = c("white", "black"), 14 | text_col = "black", 15 | text_family = "", 16 | text_face = NULL, 17 | text_size = 10, 18 | text_angle = 0 19 | ) 20 | 21 | north_arrow_fancy_orienteering( 22 | line_width = 1, 23 | line_col = "black", 24 | fill = c("white", "black"), 25 | text_col = "black", 26 | text_family = "", 27 | text_face = NULL, 28 | text_size = 10, 29 | text_angle = 0 30 | ) 31 | 32 | north_arrow_minimal( 33 | line_width = 1, 34 | line_col = "black", 35 | fill = "black", 36 | text_col = "black", 37 | text_family = "", 38 | text_face = NULL, 39 | text_size = 10 40 | ) 41 | 42 | north_arrow_nautical( 43 | line_width = 1, 44 | line_col = "black", 45 | fill = c("black", "white"), 46 | text_size = 10, 47 | text_face = NULL, 48 | text_family = "", 49 | text_col = "black", 50 | text_angle = 0 51 | ) 52 | } 53 | \arguments{ 54 | \item{line_width, line_col, fill}{Parameters customizing the appearance of the north arrow} 55 | 56 | \item{text_col, text_family, text_face, text_size, text_angle}{Parameters customizing the 57 | text of the north arrow} 58 | } 59 | \value{ 60 | A Grob with npc coordinates (more or less) 0 to 1 61 | } 62 | \description{ 63 | North arrow styles 64 | } 65 | \examples{ 66 | grid::grid.newpage() 67 | grid::grid.draw(north_arrow_orienteering()) 68 | 69 | grid::grid.newpage() 70 | grid::grid.draw(north_arrow_fancy_orienteering()) 71 | 72 | grid::grid.newpage() 73 | grid::grid.draw(north_arrow_minimal()) 74 | 75 | grid::grid.newpage() 76 | grid::grid.draw(north_arrow_nautical()) 77 | 78 | } 79 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggspatial-package.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{ggplot} 7 | \alias{aes} 8 | \alias{coord_sf} 9 | \alias{geom_sf} 10 | \alias{waiver} 11 | \title{Objects exported from other packages} 12 | \keyword{internal} 13 | \description{ 14 | These objects are imported from other packages. Follow the links 15 | below to see their documentation. 16 | 17 | \describe{ 18 | \item{ggplot2}{\code{\link[ggplot2]{aes}}, \code{\link[ggplot2:ggsf]{coord_sf}}, \code{\link[ggplot2:ggsf]{geom_sf}}, \code{\link[ggplot2]{ggplot}}, \code{\link[ggplot2]{waiver}}} 19 | }} 20 | 21 | -------------------------------------------------------------------------------- /man/stat_spatial_identity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-spatial.R 3 | \name{stat_spatial_identity} 4 | \alias{stat_spatial_identity} 5 | \alias{geom_spatial_point} 6 | \alias{geom_spatial_path} 7 | \alias{geom_spatial_polygon} 8 | \alias{geom_spatial_text} 9 | \alias{geom_spatial_label} 10 | \alias{geom_spatial_text_repel} 11 | \alias{geom_spatial_label_repel} 12 | \title{Spatial-aware ggplot2 layers} 13 | \usage{ 14 | stat_spatial_identity( 15 | mapping = NULL, 16 | data = NULL, 17 | crs = NULL, 18 | geom = "point", 19 | position = "identity", 20 | ..., 21 | show.legend = NA, 22 | inherit.aes = TRUE 23 | ) 24 | 25 | geom_spatial_point(mapping = NULL, data = NULL, crs = NULL, ...) 26 | 27 | geom_spatial_path(mapping = NULL, data = NULL, crs = NULL, ...) 28 | 29 | geom_spatial_polygon(mapping = NULL, data = NULL, crs = NULL, ...) 30 | 31 | geom_spatial_text(mapping = NULL, data = NULL, crs = NULL, ...) 32 | 33 | geom_spatial_label(mapping = NULL, data = NULL, crs = NULL, ...) 34 | 35 | geom_spatial_text_repel(mapping = NULL, data = NULL, crs = NULL, ...) 36 | 37 | geom_spatial_label_repel(mapping = NULL, data = NULL, crs = NULL, ...) 38 | } 39 | \arguments{ 40 | \item{mapping}{An aesthetic mapping created with \code{\link[ggplot2:aes]{ggplot2::aes()}}.} 41 | 42 | \item{data}{A data frame or other object, coerced to a data.frame by \code{\link[ggplot2:fortify]{ggplot2::fortify()}}.} 43 | 44 | \item{crs}{The crs of the x and y aesthetics, or NULL to use default lon/lat 45 | crs (with a message).} 46 | 47 | \item{geom}{The geometry to use.} 48 | 49 | \item{position}{The position to use.} 50 | 51 | \item{...}{Passed to the combined stat/geom as parameters or fixed aesthetics.} 52 | 53 | \item{show.legend, inherit.aes}{See \code{\link[ggplot2:layer]{ggplot2::layer()}}.} 54 | } 55 | \value{ 56 | A \code{\link[ggplot2:layer]{ggplot2::layer()}}. 57 | } 58 | \description{ 59 | These layers are much like their counterparts, \link[ggplot2:stat_identity]{stat_identity}, 60 | \link[ggplot2:geom_point]{geom_point}, \link[ggplot2:geom_path]{geom_path}, 61 | and \link[ggplot2:geom_polygon]{geom_polygon}, except they have a \code{crs} argument that 62 | ensures they are projected when using \link[ggplot2:ggsf]{coord_sf}. Stats are applied to the x and y coordinates 63 | that have been transformed. 64 | } 65 | \examples{ 66 | cities <- data.frame( 67 | x = c(-63.58595, 116.41214, 0), 68 | y = c(44.64862, 40.19063, 89.9), 69 | city = c("Halifax", "Beijing", "North Pole") 70 | ) 71 | 72 | library(ggrepel) 73 | ggplot(cities, aes(x, y)) + 74 | geom_spatial_point(crs = 4326) + 75 | stat_spatial_identity(aes(label = city), geom = "label_repel") + 76 | coord_sf(crs = 3857) 77 | 78 | } 79 | -------------------------------------------------------------------------------- /man/xy_transform.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-spatial.R 3 | \name{xy_transform} 4 | \alias{xy_transform} 5 | \title{Coordinate transform} 6 | \usage{ 7 | xy_transform(x, y, from = 4326, to = 4326, na.rm = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{The x coordinate} 11 | 12 | \item{y}{The y coordinate} 13 | 14 | \item{from}{From CRS} 15 | 16 | \item{to}{To CRS} 17 | 18 | \item{na.rm}{Warn for non-finite cases?} 19 | } 20 | \value{ 21 | A data.frame with x and y components. 22 | } 23 | \description{ 24 | Coordinate transform, propotating non-finite cases. 25 | } 26 | \examples{ 27 | xy_transform(c(1, 2, 3), c(1, 2, 3), to = 3857) 28 | xy_transform(c(1, 2, 3), c(NA, NA, NA), to = 3857) 29 | xy_transform(c(1, 2, 3), c(NA, 2, 3), to = 3857) 30 | xy_transform(c(1, 2, 3), c(1, 2, NA), to = 3857) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(ggspatial) 3 | 4 | test_check("ggspatial") 5 | -------------------------------------------------------------------------------- /tests/testthat/.gitignore: -------------------------------------------------------------------------------- 1 | Rplots.pdf 2 | rosm.cache 3 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geom-spatial-segment/geom-spatial-segment-no-great-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 40 51 | ° 52 | N 53 | 40 54 | ° 55 | N 56 | 57 | 58 | 59 | 0 60 | ° 61 | x 62 | y 63 | geom_spatial_segment(), no great circle 64 | 65 | 66 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geom-spatial-xline/annotation-spatial-hline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 38 | 50 39 | 60 40 | 70 41 | 80 42 | 90 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -50 54 | 0 55 | 50 56 | 100 57 | x 58 | y 59 | annotation_spatial_hline() 60 | 61 | 62 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geom-spatial-xline/annotation-spatial-vline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 38 | 50 39 | 60 40 | 70 41 | 80 42 | 90 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -50 54 | 0 55 | 50 56 | 100 57 | x 58 | y 59 | annotation_spatial_vline() 60 | 61 | 62 | -------------------------------------------------------------------------------- /tests/testthat/test-annotation-map-tile.R: -------------------------------------------------------------------------------- 1 | 2 | # max test length was exceeded on CRAN, so these tests are skipped 3 | if (identical(Sys.getenv("NOT_CRAN"), "true")) { 4 | 5 | test_that("annotation_map_tile() works as intended", { 6 | skip_if_not_installed("vdiffr") 7 | 8 | load_longlake_data(which = "longlake_waterdf") 9 | 10 | expect_message( 11 | expect_doppelganger_extra( 12 | "default EPSG", 13 | ggplot() + 14 | annotation_map_tile(zoom = 13, cachedir = system.file("rosm.cache", package = "ggspatial")) + 15 | geom_sf(data = longlake_waterdf, fill = NA, col = "grey50") 16 | ), 17 | "Zoom: 13" 18 | ) 19 | 20 | expect_message( 21 | expect_doppelganger_extra( 22 | "non-default EPSG", 23 | ggplot() + 24 | annotation_map_tile(zoom = 13, cachedir = system.file("rosm.cache", package = "ggspatial")) + 25 | geom_sf(data = longlake_waterdf, fill = NA, col = "grey50") + 26 | coord_sf(crs = 26920) 27 | ), 28 | "Zoom: 13" 29 | ) 30 | 31 | expect_message( 32 | expect_doppelganger_extra( 33 | "specified default EPSG", 34 | ggplot() + 35 | annotation_map_tile(zoom = 13, cachedir = system.file("rosm.cache", package = "ggspatial")) + 36 | geom_sf(data = longlake_waterdf, fill = NA, col = "grey50") + 37 | coord_sf(crs = 3857) 38 | ), 39 | "Zoom: 13" 40 | ) 41 | 42 | expect_message( 43 | expect_doppelganger_extra( 44 | "extreme rotated EPSG", 45 | ggplot() + 46 | annotation_map_tile(zoom = 13, cachedir = system.file("rosm.cache", package = "ggspatial")) + 47 | geom_sf(data = longlake_waterdf, fill = NA, col = "grey50") + 48 | coord_sf(crs = 3978) 49 | ), 50 | "Zoom: 13" 51 | ) 52 | 53 | expect_message( 54 | expect_doppelganger_extra( 55 | "faceted type", 56 | ggplot() + 57 | annotation_map_tile( 58 | data = tibble::tibble( 59 | type = c("osm", "stamenbw", "cartolight", "cartodark"), 60 | zoom = 13 61 | ), 62 | cachedir = system.file("rosm.cache", package = "ggspatial"), 63 | mapping = aes(type = type, zoom = zoom) 64 | ) + 65 | geom_sf(data = longlake_waterdf, fill = NA, col = "grey50") + 66 | coord_sf(crs = 3857) + 67 | ggplot2::facet_wrap(~type) 68 | ), 69 | "Zoom: 13" 70 | ) 71 | 72 | df_alta <- data.frame(lon = c(-122.974, -123.0042), lat = c(50.1232, 50.1035)) 73 | p <- ggplot(df_alta, aes(lon, lat)) + geom_spatial_point(crs = 4326) 74 | 75 | expect_doppelganger_extra( 76 | "rgb tile", 77 | p + 78 | annotation_map_tile(alpha = 1) 79 | ) 80 | 81 | expect_doppelganger_extra( 82 | "rgb tile with alpha", 83 | p + 84 | annotation_map_tile(alpha = 0.5) 85 | ) 86 | expect_doppelganger_extra( 87 | "rgb tile projected", 88 | p + 89 | annotation_map_tile(alpha = 1) + 90 | coord_sf(crs = 26910) 91 | ) 92 | expect_doppelganger_extra( 93 | "rgb tile projected with alpha", 94 | p + 95 | annotation_map_tile(alpha = 0.5) + 96 | coord_sf(crs = 26910) 97 | ) 98 | 99 | }) 100 | 101 | test_that("annotation_map_tile() does not fail when handed a single point", { 102 | p <- sf::st_sf(sf::st_sfc(sf::st_point(c(219200, 629650)), crs = 2039)) %>% 103 | ggplot() + 104 | annotation_map_tile() + 105 | geom_sf() 106 | 107 | expect_warning(ggplot2::ggplotGrob(p), "bounding box is too small") 108 | }) 109 | } 110 | -------------------------------------------------------------------------------- /tests/testthat/test-df-spatial-raster.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("Raster* objects are converted properly by df_spatial", { 3 | skip_if_not_installed("raster") 4 | 5 | load_longlake_data(which = c("longlake_depth_raster", "longlake_osm"), raster_format = "raster") 6 | expect_df_spatial(longlake_depth_raster, "band1") 7 | expect_df_spatial(longlake_osm, c("band1", "band2", "band3")) 8 | expect_equal( 9 | nrow(df_spatial(longlake_depth_raster)), 10 | longlake_depth_raster@nrows * longlake_depth_raster@ncols 11 | ) 12 | expect_equal( 13 | nrow(df_spatial(longlake_osm)), 14 | longlake_osm@nrows * longlake_osm@ncols 15 | ) 16 | 17 | skip_if_not_installed("vdiffr") 18 | 19 | expect_doppelganger_extra( 20 | "df_spatial(), raster", 21 | ggplot(df_spatial(longlake_depth_raster)) + ggplot2::geom_raster(aes(x, y, fill = band1)) 22 | ) 23 | 24 | expect_doppelganger_extra( 25 | "df_spatial(), nband raster", 26 | ggplot(df_spatial(longlake_osm)) + ggplot2::geom_raster(aes(x, y, fill = band1)) 27 | ) 28 | }) 29 | 30 | test_that("x and y coordinates are exactly right for raster df", { 31 | rst <- raster::raster( 32 | matrix( 33 | rep_len(c(0, 1), 9), 34 | ncol = 3 35 | ), 36 | xmn = 0, xmx = 3, 37 | ymn = 0, ymx = 6 38 | ) 39 | 40 | df <- df_spatial(rst) 41 | 42 | expect_setequal(df$x, c(0.5, 1.5, 2.5)) 43 | expect_setequal(df$y, c(1, 3, 5)) 44 | 45 | df2 <- df_spatial(rst, hjust = 0, vjust = 0) 46 | expect_setequal(df2$x, c(0, 1, 2)) 47 | expect_setequal(df2$y, c(0, 2, 4)) 48 | 49 | df3 <- df_spatial(rst, hjust = 1, vjust = 1) 50 | expect_setequal(df3$x, c(1, 2, 3)) 51 | expect_setequal(df3$y, c(2, 4, 6)) 52 | }) 53 | 54 | test_that("na.rm works on df_spatial.Raster()", { 55 | load_longlake_data(which = "longlake_osm", raster_format = "raster") 56 | df <- df_spatial(longlake_osm) 57 | expect_true(any(is.na(df$band1))) 58 | expect_true(any(is.na(df$band2))) 59 | expect_true(any(is.na(df$band3))) 60 | 61 | df_finite <- df_spatial(longlake_osm, na.rm = TRUE) 62 | expect_false(any(is.na(df_finite$band1))) 63 | expect_false(any(is.na(df_finite$band2))) 64 | expect_false(any(is.na(df_finite$band3))) 65 | }) 66 | 67 | test_that("Factor Raster* objects are properly converted", { 68 | # Test factor RasterLayer 69 | r_num <- raster::raster(nrows = 3, ncols = 3, crs = raster::crs(4326), xmn = 0, xmx = 3, 70 | ymn = 0, ymx = 3, vals = c(1,2,3,3,1,2,2,3,1)) 71 | r_fac <- raster::as.factor(r_num) 72 | levels(r_fac) <- 73 | data.frame(ID = 1:3, landcover = c("grassland", "savannah", "forest")) 74 | expect_true(inherits(df_spatial(r_num)[["band1"]], "numeric")) 75 | expect_true(inherits(df_spatial(r_fac)[["band1"]], "factor")) 76 | expect_identical(levels(df_spatial(r_fac)[["band1"]]), 77 | c("grassland", "savannah", "forest")) 78 | 79 | # Test RasterStack with mixed factor and numeric layers 80 | s <- raster::stack(r_fac, r_num, r_fac) 81 | expect_identical(unname(sapply(df_spatial(s)[-1:-2], class)), 82 | c("factor", "numeric", "factor")) 83 | 84 | # Test factor RasterBrick 85 | b <- raster::brick(r_fac, r_fac, r_fac) 86 | expect_identical(unname(sapply(df_spatial(b)[-1:-2], class)), 87 | c("factor", "factor", "factor")) 88 | }) 89 | -------------------------------------------------------------------------------- /tests/testthat/test-df-spatial-sf.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("duplicate cols are warned for in sf objects", { 3 | load_longlake_data(which = "longlake_depthdf") 4 | longlake_depthdf$x <- "x value" 5 | expect_message(df_spatial(longlake_depthdf), "Renamed columns") 6 | }) 7 | 8 | test_that("df_spatial() works with sf objects", { 9 | skip_if_not_installed("vdiffr") 10 | 11 | # load the long lake test data 12 | load_longlake_data() 13 | 14 | # point / sf 15 | df_points <- expect_df_spatial(longlake_depthdf, c("NOTES", "DEPTH_M")) 16 | expect_true(inherits(df_points$feature_id, "integer")) 17 | expect_true(inherits(df_points$part_id, "integer")) 18 | expect_equal(nrow(df_points), nrow(longlake_depthdf)) 19 | 20 | df_points_sfc <- expect_df_spatial(longlake_depthdf$geometry) 21 | expect_identical(df_points_sfc, df_points[c("x", "y", "feature_id", "part_id")]) 22 | 23 | expect_doppelganger( 24 | "df_spatial(), point", 25 | ggplot(df_points, aes(x, y, colour = DEPTH_M)) + ggplot2::geom_point() 26 | ) 27 | 28 | 29 | # multipoint / sf 30 | multipoints_sf <- dplyr::summarise(dplyr::group_by(longlake_depthdf, NOTES), one = 1) 31 | df_multipoints <- expect_df_spatial(multipoints_sf, c("NOTES", "one")) 32 | expect_true(inherits(df_multipoints$feature_id, "integer")) 33 | expect_true(inherits(df_multipoints$part_id, "integer")) 34 | expect_setequal(df_multipoints$NOTES, c("mouth of inlet", "reeds", NA)) 35 | expect_setequal(df_multipoints$feature_id, 1:3) 36 | expect_equal(nrow(df_multipoints), nrow(df_points)) 37 | 38 | df_multipoints_sfc <- expect_df_spatial(multipoints_sf$geometry) 39 | expect_identical(df_multipoints_sfc, df_multipoints[c("x", "y", "feature_id", "part_id")]) 40 | 41 | expect_doppelganger( 42 | "df_spatial(), multipoint", 43 | ggplot(df_multipoints, aes(x, y, colour = one)) + ggplot2::geom_point() 44 | ) 45 | 46 | # linestring 47 | df_lines <- expect_df_spatial(longlake_roadsdf, c("z", "OBJECTID")) 48 | expect_true(inherits(df_lines$feature_id, "integer")) 49 | expect_true(inherits(df_lines$part_id, "integer")) 50 | expect_setequal(df_lines$feature_id, seq_len(nrow(longlake_roadsdf))) 51 | 52 | df_lines_sfc <- expect_df_spatial(longlake_roadsdf$geometry) 53 | expect_identical(df_lines_sfc, df_lines[c("x", "y", "z", "feature_id", "part_id")]) 54 | 55 | expect_doppelganger( 56 | "df_spatial(), linestring", 57 | ggplot(df_lines, aes(x, y, group = interaction(feature_id, part_id))) + ggplot2::geom_path() 58 | ) 59 | 60 | # multilinestring 61 | multilines_sf <- dplyr::summarise(longlake_roadsdf, one = 1) 62 | df_multilines <- expect_df_spatial(multilines_sf, c("z", "part_id", "one")) 63 | expect_true(inherits(df_multilines$feature_id, "integer")) 64 | expect_true(inherits(df_multilines$part_id, "integer")) 65 | 66 | df_multilines_sfc <- expect_df_spatial(multilines_sf$geometry, c("z", "part_id")) 67 | expect_identical(df_multilines_sfc, df_multilines[c("x", "y", "z", "part_id", "feature_id")]) 68 | 69 | expect_doppelganger( 70 | "df_spatial(), multilinestring", 71 | ggplot(df_multilines, aes(x, y, group = interaction(feature_id, part_id))) + ggplot2::geom_path() 72 | ) 73 | 74 | # polygon 75 | df_polygons <- expect_df_spatial(longlake_waterdf, c("part_id", "piece_id")) 76 | expect_true(inherits(df_polygons$feature_id, "integer")) 77 | expect_true(inherits(df_polygons$part_id, "integer")) 78 | expect_true(inherits(df_polygons$piece_id, "integer")) 79 | expect_length(unique(df_polygons$feature_id), nrow(longlake_waterdf)) 80 | expect_length(unique(df_polygons$part_id), 1) 81 | expect_length(unique(df_polygons$piece_id), 7) 82 | 83 | df_polygons_sfc <- expect_df_spatial(longlake_waterdf$geometry, c("part_id", "piece_id")) 84 | expect_identical( 85 | df_polygons_sfc, 86 | df_polygons[c("x", "y", "z", "feature_id", "part_id", "piece_id")] 87 | ) 88 | 89 | expect_doppelganger( 90 | "df_spatial(), polygon", 91 | ggplot( 92 | df_polygons, 93 | aes(x, y, group = interaction(feature_id, part_id), subgroup = piece_id, fill = label) 94 | ) + 95 | ggplot2::geom_polygon() 96 | ) 97 | 98 | # multipolygon 99 | multipolygons_sf <- dplyr::summarise(longlake_waterdf, one = 1) 100 | df_multipolygons <- expect_df_spatial(multipolygons_sf, c("part_id", "piece_id")) 101 | expect_true(inherits(df_multipolygons$feature_id, "integer")) 102 | expect_true(inherits(df_multipolygons$part_id, "integer")) 103 | expect_true(inherits(df_multipolygons$piece_id, "integer")) 104 | expect_length(unique(df_multipolygons$feature_id), nrow(multipolygons_sf)) 105 | expect_length(unique(df_multipolygons$part_id), nrow(longlake_waterdf)) 106 | expect_length(unique(df_multipolygons$piece_id), 7) 107 | 108 | df_multipolygons_sfc <- expect_df_spatial(multipolygons_sf$geometry, c("part_id", "piece_id")) 109 | 110 | expect_identical( 111 | df_multipolygons_sfc, 112 | df_multipolygons[c("x", "y", "z", "feature_id", "part_id", "piece_id")] 113 | ) 114 | 115 | expect_doppelganger_extra( 116 | "df_spatial(), multipolygon", 117 | ggplot( 118 | df_multipolygons, 119 | aes(x, y, group = interaction(feature_id, part_id), subgroup = piece_id) 120 | ) + 121 | ggplot2::geom_polygon() 122 | ) 123 | }) 124 | -------------------------------------------------------------------------------- /tests/testthat/test-df-spatial-sp.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("df_spatial() works with sp objects", { 3 | skip_if_not_installed("sp") 4 | 5 | # load the long lake test data 6 | load_longlake_data(vector_format = "sp") 7 | 8 | # point / sp 9 | df_points <- expect_df_spatial(longlake_depthdf, c("NOTES", "DEPTH_M")) 10 | expect_true(inherits(df_points$part_id, "integer")) 11 | expect_equal(nrow(df_points), nrow(longlake_depthdf)) 12 | 13 | df_points_sfc <- expect_df_spatial(as(longlake_depthdf, "SpatialPoints")) 14 | expect_identical(df_points_sfc, df_points[c("x", "y", "feature_id", "part_id")]) 15 | 16 | # linestring 17 | df_lines <- expect_df_spatial(longlake_roadsdf, "OBJECTID") 18 | expect_true(inherits(df_lines$part_id, "integer")) 19 | expect_setequal(df_lines$feature_id, seq_len(nrow(longlake_roadsdf))) 20 | 21 | df_lines_sfc <- expect_df_spatial(as(longlake_roadsdf, "SpatialLines")) 22 | expect_identical(df_lines_sfc, df_lines[c("x", "y", "feature_id", "part_id")]) 23 | 24 | # polygon 25 | df_polygons <- expect_df_spatial(longlake_waterdf, c("part_id", "piece_id")) 26 | expect_true(inherits(df_polygons$part_id, "integer")) 27 | expect_true(inherits(df_polygons$piece_id, "integer")) 28 | expect_length(unique(df_polygons$feature_id), nrow(longlake_waterdf)) 29 | expect_length(unique(df_polygons$part_id), 1) 30 | expect_length(unique(df_polygons$piece_id), 7) 31 | 32 | df_polygons_sfc <- expect_df_spatial( 33 | as(longlake_waterdf, "SpatialPolygons"), 34 | c("part_id", "piece_id") 35 | ) 36 | expect_identical( 37 | df_polygons_sfc, 38 | df_polygons[c("x", "y", "feature_id", "part_id", "piece_id")] 39 | ) 40 | }) 41 | 42 | test_that("df_spatial() works with sp objects where column names are duplicated", { 43 | skip_if_not_installed("sp") 44 | 45 | spdf <- sp::SpatialPointsDataFrame( 46 | expand.grid(x = c(30, 60), y = c(40, 70)), data = data.frame(feat_name = 1:4) 47 | ) 48 | 49 | expect_identical( 50 | df_spatial(spdf), 51 | tibble::tibble( 52 | !!!expand.grid(x = c(30, 60), y = c(40, 70)), 53 | feature_id = 1:4, 54 | part_id = 1L, 55 | feat_name = 1:4 56 | ) 57 | ) 58 | }) 59 | -------------------------------------------------------------------------------- /tests/testthat/test-df-spatial-stars.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("stars objects are converted properly by df_spatial", { 3 | skip_if_not_installed("stars") 4 | 5 | load_longlake_data( 6 | which = c( 7 | "longlake_depth_raster", 8 | "longlake_osm" 9 | ), 10 | raster_format = "stars" 11 | ) 12 | 13 | expect_s3_class(longlake_depth_raster, "stars") 14 | expect_s3_class(longlake_osm, "stars") 15 | 16 | expect_df_spatial(longlake_depth_raster, "band1") 17 | expect_df_spatial(longlake_osm, c("band1", "band2", "band3")) 18 | expect_equal( 19 | nrow(df_spatial(longlake_depth_raster)), 20 | prod(dim(longlake_depth_raster)) 21 | ) 22 | 23 | df_stars <- df_spatial(longlake_osm) 24 | 25 | skip_if_not_installed("terra") 26 | # Get the same result than I would get with terra 27 | test_env <- new.env(parent = emptyenv()) 28 | load_longlake_data( 29 | env = test_env, 30 | raster_format = "terra" 31 | ) 32 | 33 | expect_s4_class(test_env$longlake_osm, "SpatRaster") 34 | df_terra <- df_spatial(test_env$longlake_osm) 35 | 36 | 37 | expect_equal(df_stars, df_terra) 38 | 39 | 40 | skip_if_not_installed("vdiffr") 41 | 42 | # Recheck 43 | expect_s3_class(longlake_depth_raster, "stars") 44 | expect_s3_class(longlake_osm, "stars") 45 | 46 | expect_doppelganger_extra( 47 | "df_spatial(), stars", 48 | ggplot(df_spatial(longlake_depth_raster)) + 49 | ggplot2::geom_raster(aes(x, y, fill = band1)) 50 | ) 51 | 52 | expect_doppelganger_extra( 53 | "df_spatial(), nband stars", 54 | ggplot(df_spatial(longlake_osm)) + 55 | ggplot2::geom_raster(aes(x, y, fill = band1)) 56 | ) 57 | }) 58 | 59 | test_that("x and y coordinates are exactly right for stars df", { 60 | skip_if_not_installed("stars") 61 | 62 | # Create stars object from df 63 | df <- data.frame( 64 | x = rep(seq(0.5, 2.5, 1), 3), 65 | y = rep(seq(5, 1, -2), 3) 66 | ) 67 | 68 | rst <- stars::st_as_stars(df) 69 | rst$band <- matrix( 70 | rep_len(c(0, 1), 9), 71 | ncol = 3 72 | ) 73 | 74 | df <- df_spatial(rst) 75 | 76 | expect_setequal(df$x, c(0.5, 1.5, 2.5)) 77 | expect_setequal(df$y, c(1, 3, 5)) 78 | }) 79 | 80 | test_that("na.rm works on df_spatial.stars()", { 81 | skip_if_not_installed("stars") 82 | 83 | load_longlake_data(which = "longlake_osm", raster_format = "stars") 84 | expect_s3_class(longlake_osm, "stars") 85 | df <- df_spatial(longlake_osm) 86 | expect_true(any(is.na(df$band1))) 87 | expect_true(any(is.na(df$band2))) 88 | expect_true(any(is.na(df$band3))) 89 | 90 | df_finite <- df_spatial(longlake_osm, na.rm = TRUE) 91 | expect_false(any(is.na(df_finite$band1))) 92 | expect_false(any(is.na(df_finite$band2))) 93 | expect_false(any(is.na(df_finite$band3))) 94 | }) 95 | 96 | 97 | test_that("Factor stars objects are properly converted", { 98 | skip_if_not_installed("stars") 99 | # Test factor 100 | 101 | # Create stars object from df 102 | df <- data.frame( 103 | x = rep(seq(0.5, 2.5, 1), 3), 104 | y = rep(seq(5, 1, -2), 3) 105 | ) 106 | 107 | r_num <- stars::st_as_stars(df) 108 | # Test here also a change of name: band_with_another_name 109 | r_num$band_with_another_name <- matrix( 110 | rep_len(c(0, 1), 9), 111 | ncol = 3 112 | ) 113 | 114 | # Assess factors 115 | 116 | r_fac <- r_num 117 | factrs <- c("grassland", "savannah", "forest") 118 | landcover <- factor(factrs, levels = factrs) 119 | r_fac$band_with_another_name <- landcover 120 | 121 | 122 | expect_true(inherits(df_spatial(r_num)[["band1"]], "numeric")) 123 | expect_true(inherits(df_spatial(r_fac)[["band1"]], "factor")) 124 | expect_identical( 125 | levels(df_spatial(r_fac)[["band1"]]), 126 | c("grassland", "savannah", "forest") 127 | ) 128 | }) 129 | 130 | test_that("Handle multi-layer objects stars", { 131 | skip_if_not_installed("stars") 132 | 133 | 134 | df <- data.frame( 135 | x = rep(seq(0.5, 2.5, 1), 6), 136 | y = rep(seq(5, 1, -2), 6), 137 | band = rep(seq(1,6,1), 6), 138 | value = c(0,1) 139 | ) 140 | 141 | r_six_layers <- stars::st_as_stars(df, dims = c("x", "y", "band")) 142 | 143 | expect_equal(as.integer(dim(r_six_layers))[3], 6) 144 | expect_df_spatial( 145 | r_six_layers, 146 | paste0( 147 | "band", 148 | seq_len(dim(r_six_layers)[3]) 149 | ) 150 | ) 151 | }) 152 | -------------------------------------------------------------------------------- /tests/testthat/test-df-spatial-terra.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("SpatRaster objects are converted properly by df_spatial", { 3 | skip_if_not_installed("terra") 4 | 5 | load_longlake_data( 6 | which = c( 7 | "longlake_depth_raster", 8 | "longlake_osm" 9 | ), 10 | raster_format = "terra" 11 | ) 12 | 13 | expect_s4_class(longlake_depth_raster, "SpatRaster") 14 | expect_s4_class(longlake_osm, "SpatRaster") 15 | 16 | expect_df_spatial(longlake_depth_raster, "band1") 17 | expect_df_spatial(longlake_osm, c("band1", "band2", "band3")) 18 | expect_equal( 19 | nrow(df_spatial(longlake_depth_raster)), 20 | terra::nrow(longlake_depth_raster) * terra::ncol(longlake_depth_raster) 21 | ) 22 | 23 | expect_s4_class(longlake_osm, "SpatRaster") 24 | df_terra <- df_spatial(longlake_osm) 25 | 26 | skip_if_not_installed("raster") 27 | # Get the same result than I would get with raster 28 | test_env <- new.env(parent = emptyenv()) 29 | load_longlake_data( 30 | env = test_env, 31 | raster_format = "raster" 32 | ) 33 | 34 | expect_s4_class(test_env$longlake_osm, "Raster") 35 | df_rast <- df_spatial(test_env$longlake_osm) 36 | 37 | 38 | expect_equal(df_terra, df_rast) 39 | 40 | 41 | skip_if_not_installed("vdiffr") 42 | 43 | # Recheck 44 | expect_s4_class(longlake_depth_raster, "SpatRaster") 45 | expect_s4_class(longlake_osm, "SpatRaster") 46 | 47 | expect_doppelganger_extra( 48 | "df_spatial(), terra", 49 | ggplot(df_spatial(longlake_depth_raster)) + 50 | ggplot2::geom_raster(aes(x, y, fill = band1)) 51 | ) 52 | 53 | expect_doppelganger_extra( 54 | "df_spatial(), nband terra", 55 | ggplot(df_spatial(longlake_osm)) + 56 | ggplot2::geom_raster(aes(x, y, fill = band1)) 57 | ) 58 | }) 59 | 60 | test_that("x and y coordinates are exactly right for terra df", { 61 | 62 | skip_if_not_installed("terra") 63 | 64 | rst <- terra::rast( 65 | matrix( 66 | rep_len(c(0, 1), 9), 67 | ncol = 3 68 | ) 69 | ) 70 | 71 | terra::ext(rst) <- c(0, 3, 0, 6) 72 | 73 | df <- df_spatial(rst) 74 | 75 | expect_setequal(df$x, c(0.5, 1.5, 2.5)) 76 | expect_setequal(df$y, c(1, 3, 5)) 77 | }) 78 | 79 | test_that("na.rm works on df_spatial.SpatRaster()", { 80 | 81 | skip_if_not_installed("terra") 82 | 83 | load_longlake_data(which = "longlake_osm", raster_format = "terra") 84 | expect_s4_class(longlake_osm, "SpatRaster") 85 | df <- df_spatial(longlake_osm) 86 | expect_true(any(is.na(df$band1))) 87 | expect_true(any(is.na(df$band2))) 88 | expect_true(any(is.na(df$band3))) 89 | 90 | df_finite <- df_spatial(longlake_osm, na.rm = TRUE) 91 | expect_false(any(is.na(df_finite$band1))) 92 | expect_false(any(is.na(df_finite$band2))) 93 | expect_false(any(is.na(df_finite$band3))) 94 | }) 95 | 96 | test_that("Factor SpatRast objects are properly converted", { 97 | 98 | skip_if_not_installed("terra") 99 | 100 | # Test factor SpatRast 101 | r_num <- terra::rast( 102 | nrows = 3, ncols = 3, 103 | crs = sf::st_crs(4326)$proj4string, 104 | xmin = 0, xmax = 3, 105 | ymin = 0, ymax = 3, 106 | vals = c(1, 2, 3, 3, 1, 2, 2, 3, 1) 107 | ) 108 | 109 | r_fac <- terra::merge(r_num, r_num) 110 | 111 | levels(r_fac) <- 112 | data.frame(ID = 1:3, landcover = c("grassland", "savannah", "forest")) 113 | 114 | expect_true(inherits(df_spatial(r_num)[["band1"]], "numeric")) 115 | expect_true(inherits(df_spatial(r_fac)[["band1"]], "factor")) 116 | expect_identical( 117 | levels(df_spatial(r_fac)[["band1"]]), 118 | c("grassland", "savannah", "forest") 119 | ) 120 | }) 121 | 122 | test_that("Handle multi-layer objects", { 123 | skip_if_not_installed("terra") 124 | 125 | r_six_layers <- terra::rast( 126 | nrows = 3, ncols = 3, 127 | nlyrs = 6, 128 | crs = sf::st_crs(4326)$wkt, 129 | vals = c(1, 2, 3, 3, 1, 2, 2, 3, 1) 130 | ) 131 | 132 | 133 | expect_equal(terra::nlyr(r_six_layers), 6) 134 | expect_df_spatial( 135 | r_six_layers, 136 | paste0( 137 | "band", 138 | seq_len(terra::nlyr(r_six_layers)) 139 | ) 140 | ) 141 | }) 142 | -------------------------------------------------------------------------------- /tests/testthat/test-df-spatial.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("duplicate column name fixing works", { 3 | tbl <- tibble::as_tibble(list(x = 1:5, y = 1:5, x = letters[1:5]), .name_repair = identity) 4 | expect_message( 5 | expect_identical( 6 | fix_duplicate_cols(tbl), 7 | tibble::tibble(x = 1:5, y = 1:5, x..3 = letters[1:5]) 8 | ), 9 | "Renamed columns" 10 | ) 11 | 12 | tbl2 <- tibble::as_tibble(list(x = 1:5, y = 1:5, z = letters[1:5])) 13 | expect_identical( 14 | expect_silent(fix_duplicate_cols(tbl2)), 15 | tbl2 16 | ) 17 | }) 18 | -------------------------------------------------------------------------------- /tests/testthat/test-fixed-aspect.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("aspect adjuster works", { 3 | 4 | equal <- adjust_aspect(c(0, 10), c(0, 10), desired_aspect = 1) 5 | expect_equal(equal$xlim, c(0, 10)) 6 | expect_equal(equal$ylim, c(0, 10)) 7 | 8 | wider <- adjust_aspect(c(0, 10), c(0, 10), desired_aspect = 2) 9 | expect_equal(wider$xlim, c(-5, 15)) 10 | expect_equal(wider$ylim, c(0, 10)) 11 | 12 | taller <- adjust_aspect(c(0, 10), c(0, 10), desired_aspect = 0.5) 13 | expect_equal(taller$xlim, c(0, 10)) 14 | expect_equal(taller$ylim, c(-5, 15)) 15 | 16 | non_finite <- adjust_aspect(c(NA, 10), c(0, 10), desired_aspect = 1) 17 | expect_null(non_finite$xlim) 18 | expect_null(non_finite$ylim) 19 | }) 20 | 21 | test_that("fixed aspect works", { 22 | df <- tibble::tibble(x = 0:5, y = seq(0, 10, length.out = 6)) 23 | p <- ggplot(df, aes(x, y)) + 24 | ggplot2::geom_point() + 25 | fixed_plot_aspect(ratio = 1) + 26 | ggplot2::coord_fixed() 27 | 28 | expect_s3_class(p, "gg_fixed_plot_aspect") 29 | 30 | built <- ggplot2::ggplot_build(p) 31 | xlim <- built$layout$panel_scales_x[[1]]$get_limits() 32 | ylim <- built$layout$panel_scales_y[[1]]$get_limits() 33 | 34 | expect_equal(xlim, c(-2.5, 7.5)) 35 | expect_equal(ylim, c(0, 10)) 36 | 37 | skip_if_not_installed("vdiffr") 38 | expect_doppelganger("stat_aspect() square", p) 39 | }) 40 | 41 | test_that("fixed aspect does not fail with zero layers", { 42 | p <- ggplot() + fixed_plot_aspect() 43 | expect_s3_class(p, "gg_fixed_plot_aspect") 44 | expect_s3_class(ggplot2::ggplot_build(p), "ggplot_built") 45 | }) 46 | 47 | test_that("fixed aspect works with spatial data", { 48 | cities <- data.frame( 49 | x = c(-63.58595, 116.41214), 50 | y = c(44.64862, 40.19063), 51 | city = c("Halifax", "Beijing") 52 | ) 53 | 54 | cities_sf <- sf::st_as_sf(cities, coords = c("x", "y"), crs = 4326) 55 | 56 | p <- ggplot() + 57 | layer_spatial(cities_sf) + 58 | coord_sf(crs = 3857) + 59 | fixed_plot_aspect(0.5) 60 | 61 | expect_s3_class(p, "gg_fixed_plot_aspect") 62 | built <- ggplot2::ggplot_build(p) 63 | xlim <- built$layout$panel_scales_x[[1]]$get_limits() 64 | ylim <- built$layout$panel_scales_y[[1]]$get_limits() 65 | expect_equal(diff(xlim) / diff(ylim), 0.5) 66 | }) 67 | 68 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-polypath.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("polypath works as intended", { 3 | skip_if_not_installed("vdiffr") 4 | 5 | load_longlake_data(which = "longlake_waterdf") 6 | df <- df_spatial(longlake_waterdf[3,]) 7 | expect_doppelganger( 8 | "polygon without the proper holes", 9 | ggplot() + 10 | ggplot2::geom_polygon(aes(x, y, group = piece_id), data = df) 11 | ) 12 | 13 | expect_doppelganger( 14 | "polygon with the proper holes", 15 | ggplot() + 16 | geom_polypath(aes(x, y, group = piece_id), data = df) 17 | ) 18 | 19 | expect_error( 20 | ggplot() + geom_polypath(aes(x, y, group = piece_id), data = df, rule = "fish"), 21 | "must be 'evenodd'" 22 | ) 23 | }) 24 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-spatial-rect.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("geom_spatial_rect() works", { 3 | # Canada! 4 | tile_df <- expand.grid( 5 | xmin = seq(-140, -52, by = 20), 6 | ymin = seq(40, 70, by = 10) 7 | ) 8 | 9 | tile_df$xmax <- tile_df$xmin + 20 10 | tile_df$ymax <- tile_df$ymin + 10 11 | tile_df$x <- (tile_df$xmin + tile_df$xmax) / 2 12 | tile_df$y <- (tile_df$ymin + tile_df$ymax) / 2 13 | tile_df$width <- 20 14 | tile_df$height <- 10 15 | 16 | 17 | p <- ggplot( 18 | tile_df, 19 | aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, x = x, y = y) 20 | ) + 21 | # use something with WGS84 ellipsoid so there's no datum transform 22 | # this is EPSG:3979 with WGS84 ellipsoid 23 | coord_sf( 24 | crs = "+proj=lcc +lat_1=49 +lat_2=77 +lat_0=49 +lon_0=-95 +x_0=0 +y_0=0 +type=crs" 25 | ) 26 | 27 | expect_message( 28 | ggplot2::ggplot_build(p + geom_spatial_rect()), 29 | "Assuming `crs = 4326`" 30 | ) 31 | 32 | expect_silent( 33 | ggplot2::ggplot_build(p + geom_spatial_rect(crs = 4326)) 34 | ) 35 | 36 | skip_if_not_installed("vdiffr") 37 | 38 | expect_doppelganger( 39 | "geom_spatial_rect()", 40 | p + geom_spatial_rect(crs = 4326) 41 | ) 42 | 43 | expect_doppelganger( 44 | "geom_spatial_rect(), mapped aes", 45 | p + geom_spatial_rect(aes(fill = factor(xmin)), crs = 4326) 46 | ) 47 | 48 | expect_doppelganger( 49 | "geom_spatial_tile(), mapped dims", 50 | p + geom_spatial_tile(aes(height = 7.5, width = 5), crs = 4326) 51 | ) 52 | 53 | expect_doppelganger( 54 | "geom_spatial_tile(), auto dims", 55 | p + geom_spatial_tile(crs = 4326) 56 | ) 57 | }) 58 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-spatial-segment.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("geom_spatial_segment() works", { 3 | skip_if_not_installed("vdiffr") 4 | skip_if_not_installed("lwgeom") 5 | 6 | cities <- data.frame( 7 | x = c(-63.58595, 116.41214, 13.50, -149.75), 8 | y = c(44.64862, 40.19063, 52.51, 61.20), 9 | city = c("Halifax", "Beijing", "Berlin", "Anchorage") 10 | ) 11 | 12 | cities$xend <- cities$x[c(2, 4, 1, 3)] 13 | cities$yend <- cities$y[c(2, 4, 1, 3)] 14 | 15 | p <- ggplot(cities, aes(x, y, xend = xend, yend = yend)) + 16 | geom_spatial_point(crs = 4326) + 17 | # view of the north pole 18 | coord_sf(crs = 3995) 19 | 20 | expect_message( 21 | ggplot2::ggplot_build(p + geom_spatial_segment()), 22 | "Assuming `crs = 4326`" 23 | ) 24 | 25 | expect_silent( 26 | ggplot2::ggplot_build(p + geom_spatial_segment(crs = 4326)) 27 | ) 28 | 29 | expect_doppelganger( 30 | "geom_spatial_segment(), great circle wrap", 31 | p + geom_spatial_segment( 32 | crs = 4326, 33 | great_circle = TRUE, 34 | wrap_dateline = TRUE, 35 | arrow = grid::arrow() 36 | ) 37 | ) 38 | 39 | expect_doppelganger( 40 | "geom_spatial_segment(), great circle no wrap", 41 | p + geom_spatial_segment( 42 | crs = 4326, 43 | great_circle = TRUE, 44 | wrap_dateline = FALSE, 45 | arrow = grid::arrow() 46 | ) 47 | ) 48 | 49 | expect_doppelganger( 50 | "geom_spatial_segment(), no great circle", 51 | p + geom_spatial_segment(crs = 4326, great_circle = FALSE) 52 | ) 53 | 54 | expect_doppelganger( 55 | "geom_spatial_segment(), no great circle + detail", 56 | p + geom_spatial_segment(detail = 100, great_circle = FALSE, crs = 4326) 57 | ) 58 | 59 | expect_doppelganger( 60 | "geom_spatial_segment(), great circle merc", 61 | # don't use halifax -> beijing for this one 62 | ggplot( 63 | cities[cities$city != "Halifax", ], 64 | aes(x, y, xend = xend, yend = yend) 65 | ) + 66 | geom_spatial_point(crs = 4326) + 67 | coord_sf(crs = 3857) + 68 | geom_spatial_segment(crs = 4326, great_circle = TRUE) 69 | ) 70 | 71 | expect_doppelganger( 72 | "geom_spatial_segment(), no great circle merc", 73 | ggplot(cities, aes(x, y, xend = xend, yend = yend)) + 74 | geom_spatial_point(crs = 4326) + 75 | coord_sf(crs = 3857) + 76 | geom_spatial_segment(crs = 4326, great_circle = FALSE) 77 | ) 78 | }) 79 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-spatial-xline.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("annotation_spatial_(h|v)line work with coord_sf()", { 3 | skip_if_not_installed("vdiffr") 4 | 5 | cities <- data.frame( 6 | x = c(-63.58595, 116.41214, 0), 7 | y = c(44.64862, 40.19063, 89.9), 8 | city = c("Halifax", "Beijing", "North Pole") 9 | ) 10 | 11 | p <- ggplot(cities, aes(x, y, label = city)) + 12 | geom_spatial_point(crs = 4326) + 13 | # view of the north pole 14 | coord_sf(crs = 3995) 15 | 16 | expect_doppelganger( 17 | "spatial_xline/mapped aes", 18 | p + 19 | annotation_spatial_hline( 20 | aes(intercept = y, col = city), 21 | crs = 4326 22 | ) + 23 | annotation_spatial_vline( 24 | aes(intercept = x, lty = city), 25 | crs = 4326 26 | ) 27 | ) 28 | 29 | expect_message( 30 | expect_doppelganger( 31 | "spatial_hline() NULL crs", 32 | p + 33 | annotation_spatial_hline(intercept = seq(0, 80, by = 10), limits = c(-180, 180)) 34 | ), 35 | "Assuming `crs = 4326`" 36 | ) 37 | 38 | expect_message( 39 | expect_doppelganger( 40 | "spatial_vline() NULL crs", 41 | p + 42 | annotation_spatial_vline(intercept = seq(-180, 180, by = 10), limits = c(0, 90)) 43 | ), 44 | "Assuming `crs = 4326`" 45 | ) 46 | 47 | expect_silent( 48 | ggplot2::ggplot_gtable( 49 | ggplot2::ggplot_build( 50 | p + 51 | annotation_spatial_vline( 52 | intercept = seq(-180, 180, by = 10), limits = c(0, 90), 53 | crs = 4326 54 | ) 55 | ) 56 | ) 57 | ) 58 | 59 | expect_silent( 60 | ggplot2::ggplot_gtable( 61 | ggplot2::ggplot_build( 62 | p + 63 | annotation_spatial_hline( 64 | intercept = seq(0, 80, by = 10), 65 | limits = c(-180, 180), 66 | crs = 4326 67 | ) 68 | ) 69 | ) 70 | ) 71 | 72 | expect_doppelganger( 73 | "hline/vline + guessed limits", 74 | p + 75 | annotation_spatial_hline( 76 | intercept = seq(0, 80, by = 10), 77 | crs = 4326 78 | ) + 79 | annotation_spatial_vline( 80 | intercept = seq(-180, 180, by = 10), 81 | crs = 4326 82 | ) 83 | ) 84 | }) 85 | 86 | 87 | test_that("annotation_spatial_xline() works with a warning in cartesian coords", { 88 | skip_if_not_installed("vdiffr") 89 | 90 | cities <- data.frame( 91 | x = c(-63.58595, 116.41214, 0), 92 | y = c(44.64862, 40.19063, 89.9), 93 | city = c("Halifax", "Beijing", "North Pole") 94 | ) 95 | 96 | p <- ggplot(cities, aes(x, y, label = city)) + 97 | ggplot2::geom_point() 98 | 99 | expect_warning( 100 | expect_doppelganger( 101 | "annotation_spatial_hline()", 102 | p + annotation_spatial_hline(intercept = 60, crs = 4326) 103 | ), 104 | "Ignoring transformation" 105 | ) 106 | 107 | expect_warning( 108 | expect_doppelganger( 109 | "annotation_spatial_vline()", 110 | p + annotation_spatial_vline(intercept = 15, crs = 4326) 111 | ), 112 | "Ignoring transformation" 113 | ) 114 | 115 | p2 <- ggplot(cities, aes(x, y)) + 116 | geom_spatial_point(crs = 4326) + 117 | coord_sf(crs = 4326) 118 | 119 | expect_doppelganger( 120 | "spatial_hline, coord_sf/4326", 121 | p2 + annotation_spatial_hline(intercept = 60) 122 | ) 123 | 124 | expect_doppelganger( 125 | "spatial_vline, coord_sf/4326", 126 | p2 + annotation_spatial_vline(intercept = 15, crs = 4326) 127 | ) 128 | 129 | }) 130 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-spatial.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("xy_transform works as intended", { 3 | # regular case 4 | expect_s3_class(xy_transform(c(1, 2, 3), c(1, 2, 3), to = 3857), "data.frame") 5 | expect_equal(nrow(xy_transform(c(1, 2, 3), c(1, 2, 3), to = 3857)), 3) 6 | expect_equal(colnames(xy_transform(c(1, 2, 3), c(1, 2, 3), to = 3857)), c("x", "y")) 7 | 8 | # NA cases, observations have to stay in order 9 | expect_identical(xy_transform(c(NA, 2, 3), c(1, 2, 3), to = 3857, na.rm = TRUE)$y[1], NA_real_) 10 | expect_identical(xy_transform(c(1, NA, 3), c(1, 2, 3), to = 3857, na.rm = TRUE)$y[2], NA_real_) 11 | expect_identical(xy_transform(c(1, 2, NA), c(1, 2, 3), to = 3857, na.rm = TRUE)$y[3], NA_real_) 12 | 13 | # messaging 14 | expect_warning( 15 | xy_transform(c(NA, 2, 3), c(1, 2, 3), to = 3857, na.rm = FALSE), 16 | "non-finite points removed" 17 | ) 18 | expect_silent(xy_transform(c(NA, 2, 3), c(1, 2, 3), to = 3857, na.rm = TRUE)) 19 | 20 | # zero-length cases 21 | expect_equal(nrow(xy_transform(numeric(0), numeric(0), to = 3857)), 0) 22 | expect_equal(colnames(xy_transform(numeric(0), numeric(0), to = 3857)), c("x", "y")) 23 | }) 24 | 25 | test_that("geom_spatial_* geoms work properly", { 26 | skip_if_not_installed("vdiffr") 27 | 28 | load_longlake_data(which = c("longlake_depthdf", "longlake_waterdf")) 29 | 30 | point_df <- df_spatial(longlake_depthdf) 31 | 32 | point <- ggplot(point_df, aes(x, y)) + 33 | geom_spatial_point(aes(col = DEPTH_M), crs = 26920) + 34 | coord_sf(crs = 3857) 35 | 36 | expect_doppelganger( 37 | "geom_spatial_point()", 38 | point 39 | ) 40 | 41 | path <- ggplot(point_df[order(point_df$WAYPOINT_I),], aes(x, y)) + 42 | geom_spatial_path(aes(col = DEPTH_M), crs = 26920) + 43 | coord_sf(crs = 3857) 44 | 45 | expect_doppelganger( 46 | "geom_spatial_path()", 47 | path 48 | ) 49 | 50 | poly_df <- df_spatial(longlake_waterdf[2,]) 51 | poly <- ggplot(poly_df, aes(x, y)) + 52 | geom_spatial_polygon(crs = 26920) + 53 | coord_sf(crs = 3857) 54 | 55 | expect_doppelganger( 56 | "geom_spatial_polygon()", 57 | poly 58 | ) 59 | 60 | }) 61 | 62 | test_that("spatial labellers work properly", { 63 | skip_if_not_installed("vdiffr") 64 | 65 | cities <- data.frame( 66 | x = c(-63.58595, 116.41214, 0), 67 | y = c(44.64862, 40.19063, 89.9), 68 | city = c("Halifax", "Beijing", "North Pole") 69 | ) 70 | 71 | p <- ggplot(cities, aes(x, y, label = city)) + 72 | geom_spatial_point(crs = 4326) + 73 | coord_sf(crs = 3857) 74 | 75 | expect_doppelganger( 76 | "geom_spatial_text()", 77 | p + 78 | geom_spatial_text(crs = 4326) 79 | ) 80 | 81 | expect_doppelganger( 82 | "geom_spatial_label()", 83 | p + 84 | geom_spatial_label(crs = 4326) 85 | ) 86 | 87 | expect_doppelganger( 88 | "geom_spatial_text_repel()", 89 | p + 90 | geom_spatial_text_repel(crs = 4326, seed = 12) 91 | ) 92 | 93 | expect_doppelganger( 94 | "geom_spatial_label_repel()", 95 | p + 96 | geom_spatial_label_repel(crs = 4326, seed = 12) 97 | ) 98 | 99 | 100 | }) 101 | 102 | test_that("stat_spatial_identity function", { 103 | skip_if_not_installed("vdiffr") 104 | 105 | load_longlake_data(which = c("longlake_depthdf", "longlake_waterdf")) 106 | df <- df_spatial(longlake_depthdf) 107 | 108 | expect_message( 109 | expect_doppelganger( 110 | "stat_spatial_identity(crs = NULL)", 111 | ggplot() + 112 | annotation_spatial(longlake_waterdf, fill = "lightblue") + 113 | stat_spatial_identity(aes(LON, LAT, col = DEPTH_M), data = df) 114 | ), 115 | "Assuming `crs = 4326`" 116 | ) 117 | 118 | expect_doppelganger( 119 | "stat_spatial_identity(crs = 4326)", 120 | ggplot() + 121 | annotation_spatial(longlake_waterdf, fill = "lightblue") + 122 | stat_spatial_identity(aes(LON, LAT, col = DEPTH_M), data = df, crs = 4326) 123 | ) 124 | }) 125 | 126 | test_that("create spatial stat class gets tested", { 127 | expect_s3_class( 128 | create_spatial_stat_class(ggplot2::StatIdentity, "stat_spatial_identity"), 129 | "StatIdentity" 130 | ) 131 | }) 132 | -------------------------------------------------------------------------------- /tests/testthat/test-layer-spatial-bbox.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("bbox functions work", { 3 | load_longlake_data(which = "longlake_waterdf") 4 | box <- sf::st_bbox(longlake_waterdf) 5 | expect_s3_class(sf_bbox_to_sf(box), "sf") 6 | expect_s3_class(sf_bbox_to_sf(box)$geometry, "sfc_POLYGON") 7 | expect_identical(sf::st_crs(sf_bbox_to_sf(box)), sf::st_crs(longlake_waterdf)) 8 | expect_identical(sf::st_bbox(sf_bbox_to_sf(box)), box) 9 | }) 10 | 11 | test_that("bbox functions work with detail arg", { 12 | load_longlake_data(which = "longlake_waterdf") 13 | box <- sf::st_bbox(longlake_waterdf) 14 | expect_s3_class(sf_bbox_to_sf(box, detail = 30), "sf") 15 | expect_s3_class(sf_bbox_to_sf(box, detail = 30)$geometry, "sfc_POLYGON") 16 | expect_identical( 17 | sf::st_crs(sf_bbox_to_sf(box, detail = 30)), 18 | sf::st_crs(longlake_waterdf) 19 | ) 20 | expect_identical(sf::st_bbox(sf_bbox_to_sf(box, detail= 30)), box) 21 | 22 | poly_detail <- sf_bbox_to_sf(box, detail = 2) 23 | poly_no_detail <- sf_bbox_to_sf(box, detail = NULL) 24 | expect_equal(nrow(poly_no_detail$geometry[[1]][[1]]), 5) 25 | expect_true(nrow(poly_detail$geometry[[1]][[1]]) > 5) 26 | }) 27 | 28 | test_that("bbox plotting works", { 29 | skip_if_not_installed("vdiffr") 30 | 31 | load_longlake_data(which = c("longlake_waterdf", "longlake_depthdf")) 32 | 33 | expect_doppelganger( 34 | "layer_spatial.bbox()", 35 | ggplot() + 36 | layer_spatial(sf::st_bbox(longlake_waterdf)) + 37 | layer_spatial(longlake_depthdf) 38 | ) 39 | 40 | expect_doppelganger( 41 | "annotation_spatial.bbox()", 42 | ggplot() + 43 | annotation_spatial(sf::st_bbox(longlake_waterdf)) + 44 | layer_spatial(longlake_depthdf) 45 | ) 46 | }) 47 | -------------------------------------------------------------------------------- /tests/testthat/test-layer-spatial-raster.R: -------------------------------------------------------------------------------- 1 | 2 | # max test length was exceeded on CRAN, so these tests are skipped 3 | if (identical(Sys.getenv("NOT_CRAN"), "true")) { 4 | 5 | test_that("layer-spatial works for raster objects", { 6 | skip_if_not_installed("vdiffr") 7 | skip_if_not_installed("raster") 8 | 9 | load_longlake_data(which = c("longlake_osm", "longlake_depthdf", "longlake_depth_raster"), raster_format = "raster") 10 | 11 | # should have little grey thing around it 12 | expect_doppelganger_extra( 13 | "layer_spatial.Raster()", 14 | ggplot() + 15 | layer_spatial(longlake_osm) + 16 | layer_spatial(longlake_depthdf) 17 | ) 18 | 19 | # should not have little grey thing around it 20 | expect_doppelganger_extra( 21 | "annotation_spatial.Raster()", 22 | ggplot() + 23 | annotation_spatial(longlake_osm) + 24 | layer_spatial(longlake_depthdf) 25 | ) 26 | 27 | # grey thing 28 | expect_doppelganger_extra( 29 | "layer_spatial.Raster() project", 30 | ggplot() + 31 | layer_spatial(longlake_osm) + 32 | layer_spatial(longlake_depthdf) + 33 | coord_sf(crs = 3978) 34 | ) 35 | 36 | # no grey thing 37 | expect_doppelganger_extra( 38 | "annotation_spatial.Raster() project", 39 | ggplot() + 40 | annotation_spatial(longlake_osm) + 41 | layer_spatial(longlake_depthdf) + 42 | coord_sf(crs = 3978) 43 | ) 44 | 45 | # with alpha 46 | expect_doppelganger_extra( 47 | "annotation_spatial.Raster() alpha", 48 | ggplot() + 49 | annotation_spatial(longlake_osm, alpha = 0.7) + 50 | layer_spatial(longlake_depthdf) + 51 | coord_sf(crs = 3978) 52 | ) 53 | 54 | # with aesthetics 55 | expect_doppelganger_extra( 56 | "layer_spatial.Raster() aes()", 57 | ggplot() + 58 | layer_spatial(longlake_osm, aes()) + 59 | layer_spatial(longlake_depthdf) 60 | ) 61 | 62 | expect_doppelganger_extra( 63 | "layer_spatial.Raster() aes(band1)", 64 | ggplot() + 65 | layer_spatial(longlake_osm, aes(alpha = after_stat(band1), fill = NULL)) + 66 | layer_spatial(longlake_depthdf) 67 | ) 68 | 69 | # dpi works 70 | vdiffr::expect_doppelganger( 71 | "layer_spatial.Raster() dpi", 72 | ggplot() + 73 | layer_spatial(longlake_osm, lazy = TRUE, dpi = 2) 74 | ) 75 | 76 | # lazy works 77 | vdiffr::expect_doppelganger( 78 | "layer_spatial.Raster() lazy", 79 | ggplot() + 80 | layer_spatial(longlake_osm, lazy = TRUE) 81 | ) 82 | 83 | # interpolation works 84 | vdiffr::expect_doppelganger( 85 | "layer_spatial.Raster() no interpolation", 86 | ggplot() + 87 | layer_spatial(longlake_osm, 88 | lazy = TRUE, 89 | interpolate = FALSE, 90 | dpi = 5 91 | ) 92 | ) 93 | }) 94 | 95 | } 96 | -------------------------------------------------------------------------------- /tests/testthat/test-layer-spatial-terra.R: -------------------------------------------------------------------------------- 1 | 2 | # max test length was exceeded on CRAN, so these tests are skipped 3 | if (identical(Sys.getenv("NOT_CRAN"), "true")) { 4 | test_that("layer-spatial works for terra objects", { 5 | skip_if_not_installed("vdiffr") 6 | skip_if_not_installed("terra") 7 | 8 | load_longlake_data( 9 | which = c( 10 | "longlake_osm", "longlake_depthdf", 11 | "longlake_depth_raster" 12 | ), 13 | raster_format = "terra" 14 | ) 15 | 16 | expect_s4_class(longlake_osm, "SpatRaster") 17 | expect_s4_class(longlake_depth_raster, "SpatRaster") 18 | 19 | 20 | # should have little grey thing around it 21 | expect_doppelganger_extra( 22 | "layer_spatial.SpatRaster()", 23 | ggplot() + 24 | layer_spatial(longlake_osm) + 25 | layer_spatial(longlake_depthdf) 26 | ) 27 | 28 | # should not have little grey thing around it 29 | expect_doppelganger_extra( 30 | "annotation_spatial.SpatRaster()", 31 | ggplot() + 32 | annotation_spatial(longlake_osm) + 33 | layer_spatial(longlake_depthdf) 34 | ) 35 | 36 | # grey thing 37 | expect_doppelganger_extra( 38 | "layer_spatial.SpatRaster() project", 39 | ggplot() + 40 | layer_spatial(longlake_osm) + 41 | layer_spatial(longlake_depthdf) + 42 | coord_sf(crs = 3978) 43 | ) 44 | 45 | # no grey thing 46 | expect_doppelganger_extra( 47 | "annotation_spatial.SpatRaster() project", 48 | ggplot() + 49 | annotation_spatial(longlake_osm) + 50 | layer_spatial(longlake_depthdf) + 51 | coord_sf(crs = 3978) 52 | ) 53 | 54 | # with alpha 55 | expect_doppelganger_extra( 56 | "annotation_spatial.SpatRaster() alpha 0.3", 57 | ggplot() + 58 | annotation_spatial(longlake_osm, alpha = 0.3) + 59 | layer_spatial(longlake_depthdf) + 60 | coord_sf(crs = 3978) 61 | ) 62 | 63 | # with aesthetics 64 | expect_doppelganger_extra( 65 | "layer_spatial.SpatRaster() aes()", 66 | ggplot() + 67 | layer_spatial(longlake_osm, aes()) + 68 | layer_spatial(longlake_depthdf) 69 | ) 70 | 71 | expect_doppelganger_extra( 72 | "layer_spatial.SpatRaster() aes(band1)", 73 | ggplot() + 74 | layer_spatial( 75 | longlake_osm, 76 | aes(alpha = after_stat(band1), fill = NULL) 77 | ) + 78 | layer_spatial(longlake_depthdf) 79 | ) 80 | 81 | # dpi works 82 | expect_doppelganger_extra( 83 | "layer_spatial.SpatRaster() dpi", 84 | ggplot() + 85 | layer_spatial(longlake_osm, lazy = TRUE, dpi = 2) 86 | ) 87 | 88 | # lazy works 89 | expect_doppelganger_extra( 90 | "layer_spatial.SpatRaster() lazy", 91 | ggplot() + 92 | layer_spatial(longlake_osm, lazy = TRUE) 93 | ) 94 | 95 | # interpolation works 96 | expect_doppelganger_extra( 97 | "layer_spatial.SpatRaster() no interpolation", 98 | ggplot() + 99 | layer_spatial(longlake_osm, 100 | lazy = TRUE, 101 | interpolate = FALSE, 102 | dpi = 5 103 | ) 104 | ) 105 | 106 | # Test examples 107 | expect_doppelganger_extra( 108 | "layer_spatial.SpatRaster() example 1", 109 | ggplot() + 110 | layer_spatial(longlake_osm) 111 | ) 112 | expect_doppelganger_extra( 113 | "layer_spatial.SpatRaster() example 2", 114 | # Not removing NAs to avoid warning 115 | ggplot() + 116 | layer_spatial(longlake_depth_raster) + 117 | ggplot2::scale_fill_continuous(type = "viridis") 118 | ) 119 | }) 120 | } 121 | 122 | test_that("Full lifecycle", { 123 | skip_if_not_installed("terra") 124 | skip_on_cran() 125 | # Read 126 | terra <- terra::rast( 127 | system.file("longlake/longlake.tif", package = "ggspatial") 128 | ) 129 | expect_s4_class(terra, "SpatRaster") 130 | 131 | plot <- ggplot() + 132 | layer_spatial(terra) 133 | expect_s3_class(plot, "ggplot") 134 | 135 | # Write to tempfile without warning 136 | tmp <- tempfile(fileext = ".png") 137 | 138 | expect_silent(ggplot2::ggsave(tmp, plot, width = 4, height = 4)) 139 | 140 | unlink(tmp) 141 | }) 142 | -------------------------------------------------------------------------------- /tests/testthat/test-layer-spatial.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("layer_spatial() works as intended", { 3 | skip_if_not_installed("vdiffr") 4 | 5 | load_longlake_data(which = c("longlake_roadsdf", "longlake_waterdf", "longlake_depthdf")) 6 | 7 | expect_doppelganger( 8 | "layer_spatial()", 9 | ggplot() + 10 | layer_spatial(longlake_roadsdf, size = 1, col = "black") + 11 | layer_spatial(longlake_roadsdf, size = 0.8, col = "white") + 12 | layer_spatial(longlake_waterdf, fill = "lightblue", col = NA) + 13 | layer_spatial(longlake_depthdf, aes(col = DEPTH_M)) 14 | ) 15 | 16 | expect_doppelganger( 17 | "shadow_spatial()", 18 | ggplot() + 19 | shadow_spatial(longlake_roadsdf) + 20 | shadow_spatial(longlake_waterdf) + 21 | layer_spatial(longlake_depthdf, aes(col = DEPTH_M)) 22 | ) 23 | 24 | expect_doppelganger( 25 | "annotation_spatial()", 26 | ggplot() + 27 | annotation_spatial(longlake_roadsdf, size = 1, col = "black") + 28 | annotation_spatial(longlake_roadsdf, size = 0.8, col = "white") + 29 | annotation_spatial(longlake_waterdf, fill = "lightblue", col = NA) + 30 | layer_spatial(longlake_depthdf, aes(col = DEPTH_M)) 31 | ) 32 | 33 | # sp objects converted to sf 34 | expect_true(inherits(layer_spatial(suppressWarnings(as(longlake_depthdf, "Spatial")), aes(col = DEPTH_M)), "list")) 35 | expect_true(inherits(layer_spatial(longlake_depthdf, aes(col = DEPTH_M)), "list")) 36 | }) 37 | 38 | test_that("3D sp data can be used with layer_spatial()", { 39 | spoints <- sp::SpatialPoints( 40 | matrix(c(0, 0, 1, 1, 1, 0), nrow = 2, byrow = TRUE), 41 | proj4string = sp::CRS("+proj=longlat +datum=WGS84 +no_defs +type=crs") 42 | ) 43 | expect_silent(ggplot() + layer_spatial(spoints)) 44 | }) 45 | -------------------------------------------------------------------------------- /tests/testthat/test-longlake-data.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("longlake data loader works as expected", { 3 | 4 | test_env <- new.env(parent = emptyenv()) 5 | load_longlake_data(env = test_env, vector_format = "sf", raster_format = "raster") 6 | expect_length(test_env, 8) 7 | expect_s3_class(test_env$longlake_depthdf, "sf") 8 | expect_s4_class(test_env$longlake_osm, "RasterBrick") 9 | 10 | test_env2 <- new.env(parent = emptyenv()) 11 | load_longlake_data( 12 | env = test_env2, 13 | vector_format = "sp", raster_format = "stars", 14 | which = c("longlake_depthdf", "longlake_osm") 15 | ) 16 | expect_setequal(names(test_env2), c("longlake_depthdf", "longlake_osm")) 17 | expect_s4_class(test_env2$longlake_depthdf, "SpatialPointsDataFrame") 18 | expect_s3_class(test_env2$longlake_osm, "stars") 19 | 20 | test_env3 <- new.env(parent = emptyenv()) 21 | load_longlake_data(env = test_env3, raster_format = "stars_proxy", which = c("longlake_depth_raster", "longlake_osm")) 22 | expect_s3_class(test_env3$longlake_osm, "stars_proxy") 23 | expect_s3_class(test_env3$longlake_depth_raster, "stars_proxy") 24 | 25 | test_env4 <- new.env(parent = emptyenv()) 26 | load_longlake_data( 27 | env = test_env4, raster_format = "terra", 28 | which = c("longlake_depth_raster", "longlake_osm") 29 | ) 30 | 31 | expect_length(test_env4, 2) 32 | expect_s4_class(test_env4$longlake_depth_raster, "SpatRaster") 33 | expect_s4_class(test_env4$longlake_osm, "SpatRaster") 34 | 35 | }) 36 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | --------------------------------------------------------------------------------