├── .Rbuildignore
├── .github
├── .gitignore
└── workflows
│ ├── R-CMD-check.yaml
│ └── test-coverage.yaml
├── .gitignore
├── CITATION.cff
├── DESCRIPTION
├── NAMESPACE
├── NEWS.md
├── R
├── main.R
└── package.R
├── README.Rmd
├── README.md
├── codemeta.json
├── fisheye.Rproj
├── inst
└── tinytest
│ └── test_fisheye.R
├── man
├── figures
│ ├── README-example-1.png
│ ├── README-example-2.png
│ ├── README-example2-1.png
│ ├── README-example2-2.png
│ ├── README-unnamed-chunk-2-1.png
│ ├── README-unnamed-chunk-2-2.png
│ ├── fig.jpg
│ └── logo.png
├── fisheye-package.Rd
└── fisheye.Rd
└── tests
└── tinytest.R
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^codecov\.yml$
4 | ^\.github$
5 | figures
6 | ^README\.Rmd$
7 | ^CITATION\.cff$
8 | ^codemeta\.json$
9 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/workflows/R-CMD-check.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 |
7 | name: R-CMD-check
8 |
9 | jobs:
10 | R-CMD-check:
11 | runs-on: ${{ matrix.config.os }}
12 |
13 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
14 |
15 | strategy:
16 | fail-fast: false
17 | matrix:
18 | config:
19 | - {os: macos-latest, r: 'release'}
20 | - {os: windows-latest, r: 'release'}
21 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
22 | - {os: ubuntu-latest, r: 'release'}
23 | - {os: ubuntu-latest, r: 'oldrel-1'}
24 |
25 | env:
26 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
27 | R_KEEP_PKG_SOURCE: yes
28 |
29 | steps:
30 | - uses: actions/checkout@v3
31 |
32 | - uses: r-lib/actions/setup-pandoc@v2
33 |
34 | - uses: r-lib/actions/setup-r@v2
35 | with:
36 | r-version: ${{ matrix.config.r }}
37 | http-user-agent: ${{ matrix.config.http-user-agent }}
38 | use-public-rspm: true
39 |
40 | - uses: r-lib/actions/setup-r-dependencies@v2
41 | with:
42 | extra-packages: any::rcmdcheck
43 | needs: check
44 |
45 | - uses: r-lib/actions/check-r-package@v2
46 | with:
47 | upload-snapshots: true
48 |
--------------------------------------------------------------------------------
/.github/workflows/test-coverage.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 |
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@v3
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: any::covr
27 | needs: coverage
28 |
29 | - name: Test coverage
30 | run: |
31 | covr::codecov(
32 | quiet = FALSE,
33 | clean = FALSE,
34 | install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package")
35 | )
36 | shell: Rscript {0}
37 |
38 | - name: Show testthat output
39 | if: always()
40 | run: |
41 | ## --------------------------------------------------------------------
42 | find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true
43 | shell: bash
44 |
45 | - name: Upload test results
46 | if: failure()
47 | uses: actions/upload-artifact@v3
48 | with:
49 | name: coverage-test-failures
50 | path: ${{ runner.temp }}/package
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # History files
2 | .Rhistory
3 | .Rapp.history
4 |
5 | # Session Data files
6 | .RData
7 |
8 | # User-specific files
9 | .Ruserdata
10 |
11 | # Example code in package build process
12 | *-Ex.R
13 |
14 | # Output files from R CMD build
15 | /*.tar.gz
16 |
17 | # Output files from R CMD check
18 | /*.Rcheck/
19 |
20 | # RStudio files
21 | .Rproj.user/
22 |
23 | # produced vignettes
24 | vignettes/*.html
25 | vignettes/*.pdf
26 |
27 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
28 | .httr-oauth
29 |
30 | # knitr and R markdown default cache directories
31 | *_cache/
32 | /cache/
33 |
34 | # Temporary files created by R markdown
35 | *.utf8.md
36 | *.knit.md
37 |
38 | # R Environment Variables
39 | .Renviron
40 |
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------
2 | # CITATION file created with {cffr} R package, v0.5.0
3 | # See also: https://docs.ropensci.org/cffr/
4 | # -----------------------------------------------------------
5 |
6 | cff-version: 1.2.0
7 | message: 'To cite package "fisheye" in publications use:'
8 | type: software
9 | license: GPL-3.0-only
10 | title: 'fisheye: Transform Base Maps Using Log-Azimuthal Projection'
11 | version: 0.2.0
12 | abstract: Base maps are transformed to focus on a specific location using an azimuthal
13 | logarithmic distance transformation.
14 | authors:
15 | - family-names: Giraud
16 | given-names: Timothée
17 | email: timothee.giraud@cnrs.fr
18 | orcid: https://orcid.org/0000-0002-1932-3323
19 | - family-names: Guibard
20 | given-names: Luc
21 | repository: https://CRAN.R-project.org/package=fisheye
22 | repository-code: https://github.com/riatelab/fisheye
23 | url: https://github.com/riatelab/fisheye
24 | contact:
25 | - family-names: Giraud
26 | given-names: Timothée
27 | email: timothee.giraud@cnrs.fr
28 | orcid: https://orcid.org/0000-0002-1932-3323
29 | keywords:
30 | - map
31 | - r
32 | - spatial
33 | references:
34 | - type: software
35 | title: 'R: A Language and Environment for Statistical Computing'
36 | notes: Depends
37 | url: https://www.R-project.org/
38 | authors:
39 | - name: R Core Team
40 | location:
41 | name: Vienna, Austria
42 | year: '2023'
43 | institution:
44 | name: R Foundation for Statistical Computing
45 | version: '>= 3.5.0'
46 | - type: software
47 | title: sf
48 | abstract: 'sf: Simple Features for R'
49 | notes: Imports
50 | url: https://r-spatial.github.io/sf/
51 | repository: https://CRAN.R-project.org/package=sf
52 | authors:
53 | - family-names: Pebesma
54 | given-names: Edzer
55 | email: edzer.pebesma@uni-muenster.de
56 | orcid: https://orcid.org/0000-0001-8049-7069
57 | year: '2023'
58 | - type: software
59 | title: covr
60 | abstract: 'covr: Test Coverage for Packages'
61 | notes: Suggests
62 | url: https://covr.r-lib.org
63 | repository: https://CRAN.R-project.org/package=covr
64 | authors:
65 | - family-names: Hester
66 | given-names: Jim
67 | email: james.f.hester@gmail.com
68 | year: '2023'
69 | - type: software
70 | title: tinytest
71 | abstract: 'tinytest: Lightweight and Feature Complete Unit Testing Framework'
72 | notes: Suggests
73 | url: https://github.com/markvanderloo/tinytest
74 | repository: https://CRAN.R-project.org/package=tinytest
75 | authors:
76 | - family-names: van der Loo
77 | given-names: Mark
78 | email: mark.vanderloo@gmail.com
79 | orcid: https://orcid.org/0000-0002-9807-4686
80 | year: '2023'
81 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: fisheye
2 | Title: Transform Base Maps Using Log-Azimuthal Projection
3 | Version: 0.3.0
4 | Authors@R: c(person("Timothée", "Giraud",
5 | email = "timothee.giraud@cnrs.fr",
6 | role = c("cre","aut"),
7 | comment = c(ORCID = "0000-0002-1932-3323")),
8 | person(given = "Luc",
9 | family = "Guibard",
10 | role = c("aut")))
11 | Description: Base maps are transformed to focus on a specific location using an
12 | azimuthal logarithmic distance transformation.
13 | URL: https://github.com/riatelab/fisheye
14 | BugReports: https://github.com/riatelab/fisheye/issues
15 | License: GPL-3
16 | Depends:
17 | R (>= 3.5.0)
18 | Imports:
19 | sf
20 | Encoding: UTF-8
21 | RoxygenNote: 7.3.1
22 | Suggests:
23 | covr,
24 | tinytest
25 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(fisheye)
4 | importFrom(sf,"st_crs<-")
5 | importFrom(sf,"st_geometry<-")
6 | importFrom(sf,st_centroid)
7 | importFrom(sf,st_coordinates)
8 | importFrom(sf,st_crs)
9 | importFrom(sf,st_geometry)
10 | importFrom(sf,st_geometry_type)
11 | importFrom(sf,st_linestring)
12 | importFrom(sf,st_point)
13 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # fisheye 0.2.0
2 |
3 | - update docs and links
4 |
--------------------------------------------------------------------------------
/R/main.R:
--------------------------------------------------------------------------------
1 | #' @title fisheye
2 | #' @description This function transform an sf layer with a fisheye
3 | #' transformation. Several methods are available. This is a visualisation
4 | #' method that should not be used for geospatial calculation (area,
5 | #' distances...).
6 | #' The output sf object has no CRS as it is not relevant.
7 | #'
8 | #'
9 | #' @param x an sf object (POINT, LINESTRING, MULTILINESTRING, POLYGON,
10 | #' MULTIPOLYGON) to be transformed. This object needs to be projected
11 | #' (no lon/lat).
12 | #' @param centre an sf object, the center of the transformation. This object
13 | #' must use the same projection as x.
14 | #' @param method transfomation method, either 'log' or 'sqrt'. See Details.
15 | #' @param k integer, factor to adjust the log transformation, higher values
16 | #' soften the deformation. See Details.
17 | #'
18 | #' @details
19 | #' The 'log' method transforms distances to \code{center} with:
20 | #' \eqn{{d}' = \log(1 + 10^{-k} * d)}{%
21 | #' d' = log(1 + 10^(-k) * d)}
22 | #' \cr
23 | #' The 'sqrt' method transforms distances to \code{center} with:
24 | #' \eqn{{d}' = \sqrt(d)}{%
25 | #' d' = sqrt(d)}
26 | #'
27 | #' @return A transformed sf object is returned.
28 | #' @importFrom sf st_coordinates st_centroid st_geometry st_geometry_type
29 | #' st_linestring st_point st_crs st_crs<- st_geometry<-
30 | #' @export
31 | #'
32 | #' @examples
33 | #' library(sf)
34 | #' ncraw <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)
35 | #' nc <- st_transform(ncraw, 3857)
36 | #' ncfe <- fisheye(nc, centre = nc[100, ], method = 'log', k = 4)
37 | #' plot(st_geometry(ncfe), col = "grey70", lwd = .2)
38 | #' plot(st_geometry(ncfe[100,]), col = NA, lwd = 2, border = "red", add = TRUE)
39 | fisheye <- function(x, centre, method = "log", k = 1){
40 |
41 |
42 |
43 |
44 | # center geometries around center
45 | centre <- st_coordinates(st_centroid(st_geometry(centre)))
46 | geom <- st_geometry(x)
47 | geom <- geom - c(centre[1], centre[2])
48 | pts <- st_coordinates(geom)
49 |
50 |
51 |
52 |
53 | # original distance
54 | dist <- sqrt((pts[,"X"]^2) + (pts[,"Y"]^2))
55 | # angle
56 | ta <- atan(pts[,"Y"] / pts[,"X"])
57 |
58 |
59 | # modified distances
60 | if (method == 'sqrt'){
61 | d <- sqrt(dist)
62 | } else if (method =="log"){
63 | # d <- log(1 + dist + min(dist)*2)
64 | d <- log(1 + 10^(-k) * dist)
65 |
66 | } else {
67 | stop("method should be either 'log' or 'sqrt'",
68 | call. = FALSE)
69 | }
70 |
71 | # get new coordinates
72 | sx <- sign(pts[,"X"])
73 | sx[sx==0] <- 1
74 | pts[,"X"] <- d * cos(ta) * sx
75 | pts[,"Y"] <- d * sin(ta) * sx
76 |
77 |
78 |
79 | # asigned new coordinates
80 | gtype <- st_geometry_type(x, by_geometry = FALSE)
81 |
82 | if(gtype == "MULTIPOLYGON"){
83 | uu <- unique(pts[, c("L1", "L2", "L3")])
84 | for (i in 1:nrow(uu)){
85 | geom[[rev(uu[i, ])]] <- pts[pts[,"L1"]==uu[i,"L1"] &
86 | pts[,"L2"]==uu[i,"L2"] &
87 | pts[,"L3"]==uu[i,"L3"], 1:2]
88 | }
89 | }
90 | if(gtype %in% c("POLYGON", "MULTILINESTRING")){
91 | uu <- unique(pts[, c("L1", "L2")])
92 | for (i in 1:nrow(uu)){
93 | geom[[rev(uu[i, ])]] <- pts[pts[,"L1"]==uu[i,"L1"] &
94 | pts[,"L2"]==uu[i,"L2"], 1:2]
95 | }
96 | }
97 | if(gtype %in% c("LINESTRING")){
98 | uu <- unique(pts[, c("L1")])
99 | for (i in 1:length(uu)){
100 | geom[[uu[i]]] <- st_linestring(pts[pts[,"L1"]==uu[i], 1:2])
101 | }
102 | }
103 | if(gtype %in% c("POINT")){
104 | for (i in 1:nrow(x)){
105 | geom[[i]] <- st_point(pts[i, 1:2])
106 | }
107 | }
108 |
109 | st_geometry(x) <- geom
110 |
111 | # update bbox
112 | cc <- st_coordinates(x)
113 | xmin <- min(cc[,1])
114 | xmax <- max(cc[,1])
115 | ymin <- min(cc[,2])
116 | ymax <- max(cc[,2])
117 | new_bb <- c(xmin, ymin, xmax, ymax)
118 | attr(new_bb, "class") = "bbox"
119 | attr(st_geometry(x), "bbox") = new_bb
120 | st_crs(x) <- NA
121 |
122 | return(x)
123 | }
124 |
--------------------------------------------------------------------------------
/R/package.R:
--------------------------------------------------------------------------------
1 | #' @title Package description
2 | #' @name fisheye-package
3 | #' @description
4 | #' Base maps are transformed to focus on a specific location using an
5 | #' azimuthal logarithmic distance transformation.
6 | #' @references Hägerstrand, T. (1957). Migration and Area: A Survey of a Sample
7 | #' of Swedish Migration Fields and Hypothetical Considerations of their Genesis.
8 | #' Lund Studies in Geography, Series B, Human Geography, Department of
9 | #' Geography, University of Lund, Lund.
10 | "_PACKAGE"
11 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 | ```{r, include = FALSE}
6 | knitr::opts_chunk$set(
7 | collapse = TRUE,
8 | comment = "#>",
9 | fig.path = "man/figures/README-",
10 | out.width = "100%"
11 | )
12 | ```
13 |
14 | # fisheye
15 |
16 |
17 | 
18 | [](https://app.codecov.io/gh/riatelab/fisheye?branch=main)
19 | [](https://github.com/riatelab/fisheye/actions/workflows/R-CMD-check.yaml)
20 |
21 |
22 | The goal of fisheye is to create base maps focusing on a specific location using an azimuthal logarithmic distance transformation.
23 |
24 |
25 |
26 |
27 | John Bachmann, [New York and environs](https://digitalcollections.nypl.org/items/510d47e3-b9bd-a3d9-e040-e00a18064a99), 1859.
28 |
29 |
30 | ## Installation
31 |
32 | You can install the released version of `fisheye` from
33 | [CRAN](https://cran.r-project.org/package=fisheye) with:
34 |
35 | ``` r
36 | install.packages("fisheye")
37 | ```
38 |
39 | Alternatively, you can install the development version of `fisheye` from
40 | GitHub with:
41 |
42 | ``` r
43 | remotes::install_github("riatelab/fisheye")
44 | ```
45 | ## Example
46 |
47 | This is a basic example:
48 |
49 | ```{r example, fig.width=10, fig.height = 3, out.width="100%"}
50 | library(sf)
51 | library(fisheye)
52 | library(mapsf)
53 | # Import dataset
54 | ncraw <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)
55 | nc <- st_transform(ncraw, 3857)
56 | par(mfrow = c(1,2))
57 | mf_map(nc, col ="grey90")
58 | mf_map(nc[51, ], add = TRUE, col = "grey40")
59 | mf_title("Original Map")
60 | # transform the basemap
61 | nc_fe <- fisheye(nc, centre = nc[51, ])
62 | mf_map(nc_fe, col ="grey90")
63 | mf_map(nc_fe[51, ], add = TRUE, col = "grey40")
64 | mf_title("Log-Azimuthal Projection")
65 | ```
66 |
67 | ```{r example2,fig.width=10, fig.height = 3, out.width="100%", echo=FALSE }
68 | # data import
69 | par(mfrow = c(1,2))
70 | mf_theme(mar = c(0.5,0.5,0.5,0.5))
71 | center <- st_centroid(st_geometry(nc[51, ]))
72 |
73 | buf_size <- c(
74 | seq(100,1000, 100),
75 | seq(1000,10000,1000),
76 | seq(10000, 100000, 10000)
77 | )
78 | lb <- vector("list", length(buf_size))
79 | for (i in seq_along(lb)){
80 | lb[[i]] <- st_buffer(center, buf_size[i])
81 | }
82 | buf <- st_sf(geom = do.call(c, lb))
83 |
84 |
85 | mf_init(nc)
86 | mf_map(nc, col ="grey90", border = "white", add = TRUE)
87 | mf_map(buf, add = TRUE, border = "red", col = NA, lwd = .4, lty = 3)
88 | mf_map(buf[c(10,20,30), ], add = TRUE, border = "red", col = NA,
89 | lwd = 1, lty = 1)
90 | mf_map(center, pch = 20, add = TRUE)
91 | for (i in c(20, 30)){
92 | text(x = st_coordinates(center)[1,1],
93 | y = st_bbox(buf[i, ])[4],
94 | labels = paste0(round(buf_size[i]/1000, 0), "km")
95 | )
96 | }
97 |
98 |
99 | buffe <- fisheye(buf, centre = center, method = "log", k = 1)
100 | ncfe <- fisheye(nc, centre = center, method = "log", k = 1)
101 | mf_init(buffe)
102 | mf_map(ncfe, add = TRUE)
103 | mf_map(buffe, add = TRUE, border = "red", col = NA, lwd = .4, lty = 3)
104 | mf_map(buffe[c(1,10,20,30), ], add = TRUE, border = "red", col = NA,
105 | lwd = 1, lty = 1)
106 | points(0,0,pch = 20)
107 | for (i in c(1,10,20,30)){
108 | text(x = 0,
109 | y = st_bbox(buffe[i, ])[4],
110 | labels = paste0(signif(buf_size[i]/1000, 0), "km")
111 | )
112 | }
113 |
114 |
115 | ```
116 |
117 | See a more detailed example [here](https://github.com/rcarto/fisheye-example/):
118 |
119 | 
120 |
121 | ## References
122 |
123 | * Hägerstrand, T. (1957). Migration and Area: A Survey of a Sample of Swedish Migration Fields and Hypothetical Considerations of their Genesis. Lund Studies in Geography, Series B, Human Geography, Department of Geography, University of Lund, Lund.
124 |
125 | * Snyder, J.P. (1987). "Magnifying-Glass" Azimuthal Map Projections. The American Cartographer, 14:1, 61-68, https://doi.org/10.1559/152304087783875318
126 |
127 | * Fairbairn, D., & Taylor, G. (1995). Developing a variable-scale map projection for urban areas. Computers & Geosciences, 21:9, 1053-1064, https://doi.org/10.1016/0098-3004(95)00041-6
128 |
129 | * Boutoura, C., Tsioukas, V., & Tsorlini, A. (2012). Experimenting “fisheye-lens functions” in studying digitally particular historic maps. e-Perimetron (ISSN 1790 - 3769). 7. 111-123. http://www.e-perimetron.org/Vol_7_3/Boutoura_et_al.pdf
130 |
131 | * Roughan, M. (2017). Log-azimuthal maps. https://roughan.info/math/log-az/
132 |
133 | * Rivière, P. (2018). The Log-Azimuthal projection. https://observablehq.com/@fil/log-azimuthal
134 |
135 | * Jansen, T. (2018). “Magnifying-Glass” projections. https://observablehq.com/@toja/magnifying-glass-projections
136 |
137 | * Sahasrabuddhe, R., Lambiotte, R., & Alessandretti, L. (2021). From centre to centres: polycentric structures in individual mobility. https://arxiv.org/pdf/2108.08113.pdf
138 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # fisheye
3 |
4 |
5 |
6 | 
7 | [](https://app.codecov.io/gh/riatelab/fisheye?branch=main)
8 | [](https://github.com/riatelab/fisheye/actions/workflows/R-CMD-check.yaml)
9 |
10 |
11 | The goal of fisheye is to create base maps focusing on a specific
12 | location using an azimuthal logarithmic distance transformation.
13 |
14 |
15 |
16 | John Bachmann, [New York and
17 | environs](https://digitalcollections.nypl.org/items/510d47e3-b9bd-a3d9-e040-e00a18064a99),
18 | 1859.
19 |
20 | ## Installation
21 |
22 | You can install the released version of `fisheye` from
23 | [CRAN](https://cran.r-project.org/package=fisheye) with:
24 |
25 | ``` r
26 | install.packages("fisheye")
27 | ```
28 |
29 | Alternatively, you can install the development version of `fisheye` from
30 | GitHub with:
31 |
32 | ``` r
33 | remotes::install_github("riatelab/fisheye")
34 | ```
35 |
36 | ## Example
37 |
38 | This is a basic example:
39 |
40 | ``` r
41 | library(sf)
42 | #> Linking to GEOS 3.11.1, GDAL 3.6.2, PROJ 9.1.1; sf_use_s2() is TRUE
43 | library(fisheye)
44 | library(mapsf)
45 | # Import dataset
46 | ncraw <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)
47 | nc <- st_transform(ncraw, 3857)
48 | par(mfrow = c(1,2))
49 | mf_map(nc, col ="grey90")
50 | mf_map(nc[51, ], add = TRUE, col = "grey40")
51 | mf_title("Original Map")
52 | # transform the basemap
53 | nc_fe <- fisheye(nc, centre = nc[51, ])
54 | mf_map(nc_fe, col ="grey90")
55 | mf_map(nc_fe[51, ], add = TRUE, col = "grey40")
56 | mf_title("Log-Azimuthal Projection")
57 | ```
58 |
59 |
60 |
61 |
62 |
63 | See a more detailed example
64 | [here](https://github.com/rcarto/fisheye-example/):
65 |
66 | 
67 |
68 | ## References
69 |
70 | - Hägerstrand, T. (1957). Migration and Area: A Survey of a Sample of
71 | Swedish Migration Fields and Hypothetical Considerations of their
72 | Genesis. Lund Studies in Geography, Series B, Human Geography,
73 | Department of Geography, University of Lund, Lund.
74 |
75 | - Snyder, J.P. (1987). “Magnifying-Glass” Azimuthal Map Projections. The
76 | American Cartographer, 14:1, 61-68,
77 |
78 |
79 | - Fairbairn, D., & Taylor, G. (1995). Developing a variable-scale map
80 | projection for urban areas. Computers & Geosciences, 21:9, 1053-1064,
81 |
82 |
83 | - Boutoura, C., Tsioukas, V., & Tsorlini, A. (2012). Experimenting
84 | “fisheye-lens functions” in studying digitally particular historic
85 | maps. e-Perimetron (ISSN 1790 - 3769). 7. 111-123.
86 |
87 |
88 | - Roughan, M. (2017). Log-azimuthal maps.
89 |
90 |
91 | - Rivière, P. (2018). The Log-Azimuthal projection.
92 |
93 |
94 | - Jansen, T. (2018). “Magnifying-Glass” projections.
95 |
96 |
97 | - Sahasrabuddhe, R., Lambiotte, R., & Alessandretti, L. (2021). From
98 | centre to centres: polycentric structures in individual mobility.
99 |
100 |
--------------------------------------------------------------------------------
/codemeta.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "https://doi.org/10.5063/schema/codemeta-2.0",
3 | "@type": "SoftwareSourceCode",
4 | "identifier": "fisheye",
5 | "description": "Base maps are transformed to focus on a specific location using an azimuthal logarithmic distance transformation.",
6 | "name": "fisheye: Transform Base Maps Using Log-Azimuthal Projection",
7 | "codeRepository": "https://github.com/riatelab/fisheye",
8 | "issueTracker": "https://github.com/riatelab/fisheye/issues",
9 | "license": "https://spdx.org/licenses/GPL-3.0",
10 | "version": "0.2.0",
11 | "programmingLanguage": {
12 | "@type": "ComputerLanguage",
13 | "name": "R",
14 | "url": "https://r-project.org"
15 | },
16 | "runtimePlatform": "R version 4.3.2 (2023-10-31)",
17 | "provider": {
18 | "@id": "https://cran.r-project.org",
19 | "@type": "Organization",
20 | "name": "Comprehensive R Archive Network (CRAN)",
21 | "url": "https://cran.r-project.org"
22 | },
23 | "author": [
24 | {
25 | "@type": "Person",
26 | "givenName": "Timothée",
27 | "familyName": "Giraud",
28 | "email": "timothee.giraud@cnrs.fr",
29 | "@id": "https://orcid.org/0000-0002-1932-3323"
30 | },
31 | {
32 | "@type": "Person",
33 | "givenName": "Luc",
34 | "familyName": "Guibard"
35 | }
36 | ],
37 | "maintainer": [
38 | {
39 | "@type": "Person",
40 | "givenName": "Timothée",
41 | "familyName": "Giraud",
42 | "email": "timothee.giraud@cnrs.fr",
43 | "@id": "https://orcid.org/0000-0002-1932-3323"
44 | }
45 | ],
46 | "softwareSuggestions": [
47 | {
48 | "@type": "SoftwareApplication",
49 | "identifier": "covr",
50 | "name": "covr",
51 | "provider": {
52 | "@id": "https://cran.r-project.org",
53 | "@type": "Organization",
54 | "name": "Comprehensive R Archive Network (CRAN)",
55 | "url": "https://cran.r-project.org"
56 | },
57 | "sameAs": "https://CRAN.R-project.org/package=covr"
58 | },
59 | {
60 | "@type": "SoftwareApplication",
61 | "identifier": "tinytest",
62 | "name": "tinytest",
63 | "provider": {
64 | "@id": "https://cran.r-project.org",
65 | "@type": "Organization",
66 | "name": "Comprehensive R Archive Network (CRAN)",
67 | "url": "https://cran.r-project.org"
68 | },
69 | "sameAs": "https://CRAN.R-project.org/package=tinytest"
70 | }
71 | ],
72 | "softwareRequirements": {
73 | "1": {
74 | "@type": "SoftwareApplication",
75 | "identifier": "R",
76 | "name": "R",
77 | "version": ">= 3.5.0"
78 | },
79 | "2": {
80 | "@type": "SoftwareApplication",
81 | "identifier": "sf",
82 | "name": "sf",
83 | "provider": {
84 | "@id": "https://cran.r-project.org",
85 | "@type": "Organization",
86 | "name": "Comprehensive R Archive Network (CRAN)",
87 | "url": "https://cran.r-project.org"
88 | },
89 | "sameAs": "https://CRAN.R-project.org/package=sf"
90 | },
91 | "SystemRequirements": null
92 | },
93 | "fileSize": "11.216KB"
94 | }
95 |
--------------------------------------------------------------------------------
/fisheye.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: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageInstallArgs: --no-multiarch --with-keep.source
20 | PackageRoxygenize: rd,collate,namespace,vignette
21 |
--------------------------------------------------------------------------------
/inst/tinytest/test_fisheye.R:
--------------------------------------------------------------------------------
1 | suppressPackageStartupMessages(library(sf))
2 | nc <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)
3 | nc <- st_transform(nc, 3857)
4 | nc1 <- nc[1,]
5 | ncmp <- st_cast(nc, "MULTIPOLYGON")
6 | suppressWarnings(ncp <- st_cast(nc, "POLYGON"))
7 | ncml <- st_cast(nc, "MULTILINESTRING")
8 | suppressWarnings(ncl <- st_cast(ncml, "LINESTRING"))
9 | suppressWarnings(ncpt <- st_cast(ncl, "POINT"))
10 |
11 | expect_silent(fisheye(ncmp, nc1, "log", 1))
12 | expect_silent(fisheye(ncml, nc1, "log", 1))
13 | expect_silent(fisheye(ncl, nc1, "log", 1))
14 | expect_silent(fisheye(ncp, nc1, "log", 1))
15 | expect_silent(fisheye(ncpt, nc1, "sqrt"))
16 |
17 | # test garbage input
18 | expect_error(fisheye(ncmp, nc1, "logs", 1))
19 |
--------------------------------------------------------------------------------
/man/figures/README-example-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/README-example-1.png
--------------------------------------------------------------------------------
/man/figures/README-example-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/README-example-2.png
--------------------------------------------------------------------------------
/man/figures/README-example2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/README-example2-1.png
--------------------------------------------------------------------------------
/man/figures/README-example2-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/README-example2-2.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/README-unnamed-chunk-2-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-2-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/README-unnamed-chunk-2-2.png
--------------------------------------------------------------------------------
/man/figures/fig.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/fig.jpg
--------------------------------------------------------------------------------
/man/figures/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riatelab/fisheye/9b45777cd31cb2623cf0f0ed4d8a5d8ab81e117c/man/figures/logo.png
--------------------------------------------------------------------------------
/man/fisheye-package.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/package.R
3 | \docType{package}
4 | \name{fisheye-package}
5 | \alias{fisheye-package}
6 | \title{Package description}
7 | \description{
8 | Base maps are transformed to focus on a specific location using an
9 | azimuthal logarithmic distance transformation.
10 | }
11 | \references{
12 | Hägerstrand, T. (1957). Migration and Area: A Survey of a Sample
13 | of Swedish Migration Fields and Hypothetical Considerations of their Genesis.
14 | Lund Studies in Geography, Series B, Human Geography, Department of
15 | Geography, University of Lund, Lund.
16 | }
17 | \seealso{
18 | Useful links:
19 | \itemize{
20 | \item \url{https://github.com/riatelab/fisheye}
21 | \item Report bugs at \url{https://github.com/riatelab/fisheye/issues}
22 | }
23 |
24 | }
25 | \author{
26 | \strong{Maintainer}: Timothée Giraud \email{timothee.giraud@cnrs.fr} (\href{https://orcid.org/0000-0002-1932-3323}{ORCID})
27 |
28 | Authors:
29 | \itemize{
30 | \item Luc Guibard
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/man/fisheye.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/main.R
3 | \name{fisheye}
4 | \alias{fisheye}
5 | \title{fisheye}
6 | \usage{
7 | fisheye(x, centre, method = "log", k = 1)
8 | }
9 | \arguments{
10 | \item{x}{an sf object (POINT, LINESTRING, MULTILINESTRING, POLYGON,
11 | MULTIPOLYGON) to be transformed. This object needs to be projected
12 | (no lon/lat).}
13 |
14 | \item{centre}{an sf object, the center of the transformation. This object
15 | must use the same projection as x.}
16 |
17 | \item{method}{transfomation method, either 'log' or 'sqrt'. See Details.}
18 |
19 | \item{k}{integer, factor to adjust the log transformation, higher values
20 | soften the deformation. See Details.}
21 | }
22 | \value{
23 | A transformed sf object is returned.
24 | }
25 | \description{
26 | This function transform an sf layer with a fisheye
27 | transformation. Several methods are available. This is a visualisation
28 | method that should not be used for geospatial calculation (area,
29 | distances...).
30 | The output sf object has no CRS as it is not relevant.
31 | }
32 | \details{
33 | The 'log' method transforms distances to \code{center} with:
34 | \eqn{{d}' = \log(1 + 10^{-k} * d)}{%
35 | d' = log(1 + 10^(-k) * d)}
36 | \cr
37 | The 'sqrt' method transforms distances to \code{center} with:
38 | \eqn{{d}' = \sqrt(d)}{%
39 | d' = sqrt(d)}
40 | }
41 | \examples{
42 | library(sf)
43 | ncraw <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)
44 | nc <- st_transform(ncraw, 3857)
45 | ncfe <- fisheye(nc, centre = nc[100, ], method = 'log', k = 4)
46 | plot(st_geometry(ncfe), col = "grey70", lwd = .2)
47 | plot(st_geometry(ncfe[100,]), col = NA, lwd = 2, border = "red", add = TRUE)
48 | }
49 |
--------------------------------------------------------------------------------
/tests/tinytest.R:
--------------------------------------------------------------------------------
1 | if ( requireNamespace("tinytest", quietly=TRUE) ){
2 | tinytest::test_package("fisheye")
3 | }
4 |
--------------------------------------------------------------------------------