├── .Rbuildignore ├── .gitattributes ├── .github ├── .gitignore ├── FUNDING.yml └── workflows │ ├── R-CMD-check.yaml │ └── pkgdown.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── RcppExports.R ├── cast.R ├── df.R ├── sf.R ├── sf_helpers.R ├── sfc.R ├── sfg.R ├── sfheaders-package.R └── utils.R ├── README.Rmd ├── README.md ├── codecov.yml ├── docs ├── .nojekyll ├── 404.html ├── LICENSE-text.html ├── LICENSE.html ├── articles │ ├── Cpp.html │ ├── examples.html │ ├── images │ │ ├── gpx_description.png │ │ ├── gpx_functions.png │ │ └── gpx_include.png │ └── index.html ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── index.html ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── index.html │ ├── sf_bbox.html │ ├── sf_boxes.html │ ├── sf_cast.html │ ├── sf_line.html │ ├── sf_linestring.html │ ├── sf_mline.html │ ├── sf_mpoly.html │ ├── sf_mpt.html │ ├── sf_multilinestring.html │ ├── sf_multipoint.html │ ├── sf_multipolygon.html │ ├── sf_point.html │ ├── sf_poly.html │ ├── sf_polygon.html │ ├── sf_pt.html │ ├── sf_remove_holes.html │ ├── sf_to_df.html │ ├── sfc_cast.html │ ├── sfc_linestring.html │ ├── sfc_multilinestring.html │ ├── sfc_multipoint.html │ ├── sfc_multipolygon.html │ ├── sfc_point.html │ ├── sfc_polygon.html │ ├── sfc_to_df.html │ ├── sfg_linestring.html │ ├── sfg_multilinestring.html │ ├── sfg_multipoint.html │ ├── sfg_multipolygon.html │ ├── sfg_point.html │ ├── sfg_polygon.html │ └── sfg_to_df.html └── sitemap.xml ├── inst └── include │ └── sfheaders │ ├── cast │ ├── list_cast.hpp │ ├── sf_cast.hpp │ ├── sfc_cast.hpp │ └── sfg_cast.hpp │ ├── df │ ├── sf.hpp │ ├── sfc.hpp │ ├── sfg.hpp │ └── utils.hpp │ ├── sf │ ├── linestring │ │ └── sf_linestring.hpp │ ├── multilinestring │ │ └── sf_multilinestring.hpp │ ├── multipoint │ │ └── sf_multipoint.hpp │ ├── multipolygon │ │ └── sf_multipolygon.hpp │ ├── point │ │ └── sf_point.hpp │ ├── polygon │ │ └── sf_polygon.hpp │ ├── sf.hpp │ └── sf_utils.hpp │ ├── sfc │ ├── bbox.hpp │ ├── linestring │ │ ├── sfc_linestring.hpp │ │ └── sfc_linestrings.hpp │ ├── m_range.hpp │ ├── multilinestring │ │ ├── sfc_multilinestring.hpp │ │ └── sfc_multilinestrings.hpp │ ├── multipoint │ │ ├── sfc_multipoint.hpp │ │ └── sfc_multipoints.hpp │ ├── multipolygon │ │ ├── sfc_multipolygon.hpp │ │ └── sfc_multipolygons.hpp │ ├── point │ │ ├── sfc_point.hpp │ │ └── sfc_points.hpp │ ├── polygon │ │ ├── sfc_polygon.hpp │ │ └── sfc_polygons.hpp │ ├── sfc.hpp │ ├── sfc_attributes.hpp │ ├── sfc_types.hpp │ ├── z_range.hpp │ └── zm_range.hpp │ ├── sfg │ ├── linestring │ │ ├── sfg_linestring.hpp │ │ └── sfg_linestrings.hpp │ ├── multilinestring │ │ ├── sfg_multilinestring.hpp │ │ └── sfg_multilinestrings.hpp │ ├── multipoint │ │ ├── sfg_multipoint.hpp │ │ └── sfg_multipoints.hpp │ ├── multipolygon │ │ ├── sfg_multipolygon.hpp │ │ └── sfg_multipolygons.hpp │ ├── point │ │ ├── sfg_point.hpp │ │ └── sfg_points.hpp │ ├── polygon │ │ ├── close_polygon.hpp │ │ ├── sfg_polygon.hpp │ │ └── sfg_polygons.hpp │ ├── sfg.hpp │ ├── sfg_attributes.hpp │ ├── sfg_dimension.hpp │ └── sfg_types.hpp │ ├── sfheaders.hpp │ └── utils │ └── utils.hpp ├── man ├── sf_bbox.Rd ├── sf_boxes.Rd ├── sf_cast.Rd ├── sf_line.Rd ├── sf_linestring.Rd ├── sf_mline.Rd ├── sf_mpoly.Rd ├── sf_mpt.Rd ├── sf_multilinestring.Rd ├── sf_multipoint.Rd ├── sf_multipolygon.Rd ├── sf_point.Rd ├── sf_poly.Rd ├── sf_polygon.Rd ├── sf_pt.Rd ├── sf_remove_holes.Rd ├── sf_to_df.Rd ├── sfc_cast.Rd ├── sfc_linestring.Rd ├── sfc_multilinestring.Rd ├── sfc_multipoint.Rd ├── sfc_multipolygon.Rd ├── sfc_point.Rd ├── sfc_polygon.Rd ├── sfc_to_df.Rd ├── sfg_linestring.Rd ├── sfg_multilinestring.Rd ├── sfg_multipoint.Rd ├── sfg_multipolygon.Rd ├── sfg_point.Rd ├── sfg_polygon.Rd └── sfg_to_df.Rd ├── sfheaders.Rproj ├── src ├── .gitignore ├── Makevars ├── Makevars.win ├── RcppExports.cpp ├── bbox.cpp ├── cast.cpp ├── lists.cpp ├── sfg_dimension.cpp ├── shapes.cpp ├── to_df.cpp ├── to_sf.cpp ├── to_sfc.cpp ├── to_sfg.cpp └── utils.cpp ├── tests ├── testthat.R └── testthat │ ├── test-bbox.R │ ├── test-cast.R │ ├── test-close_polygon.R │ ├── test-df.R │ ├── test-df_attributes.R │ ├── test-empty.R │ ├── test-error_handling.R │ ├── test-holes.R │ ├── test-lists.R │ ├── test-sf.R │ ├── test-sf_boxes.R │ ├── test-sf_creator-helpers.R │ ├── test-sf_linestring.R │ ├── test-sf_multilinestring.R │ ├── test-sf_multipoint.R │ ├── test-sf_multipolygon.R │ ├── test-sf_point.R │ ├── test-sf_polygon.R │ ├── test-sfc_attributes.R │ ├── test-sfc_linestring.R │ ├── test-sfc_multilinestring.R │ ├── test-sfc_multipoint.R │ ├── test-sfc_multipolygon.R │ ├── test-sfc_point.R │ ├── test-sfc_polygon.R │ ├── test-sfg.R │ ├── test-sfg_dimension.R │ ├── test-sfg_linestring.R │ ├── test-sfg_multilinestring.R │ ├── test-sfg_multipoint.R │ ├── test-sfg_multipolygon.R │ ├── test-sfg_point.R │ ├── test-sfg_polygon.R │ ├── test-update_by_reference.R │ └── test-utils.R └── vignettes ├── .gitignore ├── Cpp.Rmd ├── examples.Rmd └── images ├── gpx_description.png ├── gpx_functions.png └── gpx_include.png /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^cran-comments\.md$ 2 | ^CRAN-RELEASE$ 3 | ^codecov\.yml$ 4 | ^\.travis\.yml$ 5 | ^README\.Rmd$ 6 | ^.*\.Rproj$ 7 | ^\.Rproj\.user$ 8 | ^docs/ 9 | ^Vignettes/Cpp* 10 | ^Vignettes/examples* 11 | ^vignettes/images/* 12 | ^Vignettes* 13 | ^\.github$ 14 | ^LICENSE\.md$ 15 | ^CRAN-SUBMISSION$ 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | tests/* linguist-documentation 2 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [dcooley] 4 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request: 6 | branches: 7 | - master 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: windows-latest, r: '3.6'} 22 | - {os: macOS-latest, r: '3.6'} 23 | - {os: macOS-latest, r: 'devel'} 24 | - {os: ubuntu-16.04, r: '3.2', rspm: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"} 25 | - {os: ubuntu-16.04, r: '3.3', rspm: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"} 26 | - {os: ubuntu-16.04, r: '3.4', rspm: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"} 27 | - {os: ubuntu-16.04, r: '3.5', rspm: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"} 28 | - {os: ubuntu-16.04, r: '3.6', rspm: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"} 29 | 30 | env: 31 | R_REMOTES_NO_ERRORS_FROM_WARNINGS: true 32 | RSPM: ${{ matrix.config.rspm }} 33 | 34 | steps: 35 | - uses: actions/checkout@v2 36 | 37 | - uses: r-lib/actions/setup-r@master 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | 41 | - uses: r-lib/actions/setup-pandoc@master 42 | 43 | - name: Query dependencies 44 | run: | 45 | install.packages('remotes') 46 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), "depends.Rds", version = 2) 47 | shell: Rscript {0} 48 | 49 | - name: Cache R packages 50 | if: runner.os != 'Windows' 51 | uses: actions/cache@v1 52 | with: 53 | path: ${{ env.R_LIBS_USER }} 54 | key: ${{ runner.os }}-r-${{ matrix.config.r }}-${{ hashFiles('depends.Rds') }} 55 | restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}- 56 | 57 | - name: Install system dependencies 58 | if: runner.os == 'Linux' 59 | env: 60 | RHUB_PLATFORM: linux-x86_64-ubuntu-gcc 61 | run: | 62 | Rscript -e "remotes::install_github('r-hub/sysreqs')" 63 | sysreqs=$(Rscript -e "cat(sysreqs::sysreq_commands('DESCRIPTION'))") 64 | sudo -s eval "$sysreqs" 65 | 66 | - name: Install dependencies 67 | run: | 68 | remotes::install_deps(dependencies = TRUE) 69 | remotes::install_cran("rcmdcheck") 70 | shell: Rscript {0} 71 | 72 | - name: Check 73 | run: rcmdcheck::rcmdcheck(args = "--no-manual", error_on = "warning", check_dir = "check") 74 | shell: Rscript {0} 75 | 76 | - name: Upload check results 77 | if: failure() 78 | uses: actions/upload-artifact@master 79 | with: 80 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 81 | path: check 82 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | inst/doc 2 | .Rproj.user 3 | .Rhistory 4 | .RData 5 | .Ruserdata 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: sfheaders 2 | Type: Package 3 | Title: Converts Between R Objects and Simple Feature Objects 4 | Date: 2024-07-30 5 | Version: 0.4.5 6 | Authors@R: c( 7 | person("David", "Cooley", ,"david.cooley.au@gmail.com", role = c("aut", "cre")), 8 | person(given = "Michael", family = "Sumner", role = "ctb") 9 | ) 10 | Description: Converts between R and Simple Feature 'sf' objects, without depending 11 | on the Simple Feature library. Conversion functions are available at both the R level, 12 | and through 'Rcpp'. 13 | License: MIT + file LICENSE 14 | URL: https://dcooley.github.io/sfheaders/ 15 | BugReports: https://github.com/dcooley/sfheaders/issues 16 | Encoding: UTF-8 17 | RoxygenNote: 7.2.3 18 | Depends: R (>= 3.0.2) 19 | LinkingTo: 20 | geometries (>= 0.2.4), 21 | Rcpp 22 | Imports: 23 | Rcpp (>= 1.0.10) 24 | Suggests: 25 | covr, 26 | knitr, 27 | testthat 28 | Roxygen: list(markdown = TRUE) 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2020 2 | COPYRIGHT HOLDER: D Cooley 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2020 D Cooley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(calculate_bbox,default) 4 | S3method(calculate_bbox,sf) 5 | S3method(calculate_boxes,sf) 6 | S3method(calculate_boxes,sfc) 7 | S3method(calculate_boxes,sfg) 8 | S3method(remove_holes,default) 9 | S3method(remove_holes,sf) 10 | S3method(remove_holes,sfc) 11 | S3method(remove_holes,sfg) 12 | export(sf_bbox) 13 | export(sf_boxes) 14 | export(sf_cast) 15 | export(sf_line) 16 | export(sf_linestring) 17 | export(sf_mline) 18 | export(sf_mpoly) 19 | export(sf_mpt) 20 | export(sf_multilinestring) 21 | export(sf_multipoint) 22 | export(sf_multipolygon) 23 | export(sf_point) 24 | export(sf_poly) 25 | export(sf_polygon) 26 | export(sf_pt) 27 | export(sf_remove_holes) 28 | export(sf_to_df) 29 | export(sfc_cast) 30 | export(sfc_linestring) 31 | export(sfc_multilinestring) 32 | export(sfc_multipoint) 33 | export(sfc_multipolygon) 34 | export(sfc_point) 35 | export(sfc_polygon) 36 | export(sfc_to_df) 37 | export(sfg_linestring) 38 | export(sfg_multilinestring) 39 | export(sfg_multipoint) 40 | export(sfg_multipolygon) 41 | export(sfg_point) 42 | export(sfg_polygon) 43 | export(sfg_to_df) 44 | importFrom(Rcpp,sourceCpp) 45 | useDynLib(sfheaders, .registration = TRUE) 46 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # v0.4.5 2 | 3 | * Checks for missing Z and M values [issue 100](https://github.com/dcooley/sfheaders/issues/100) 4 | 5 | # v0.4.4 6 | 7 | * bumped {geometries} dependency 8 | 9 | # v0.4.3 10 | 11 | * removed C++ system requirements 12 | 13 | # v0.4.2 14 | 15 | * updated C++ dependencies 16 | 17 | # v0.4 18 | 19 | * list-column properties are better supported for nested geometries (MULTILINESTRING, POLYGON, MULTIPOLYGON) 20 | 21 | # v0.3.1 22 | 23 | * `z_range` and `m_range` only created if those dimensions exist 24 | 25 | # v0.3.0 26 | 27 | * changed licence to MIT 28 | * Faster sf object creation by Linking-To [geometries](https://github.com/dcooley/geometries) library 29 | 30 | # v0.2.2 31 | 32 | * crs structure matches new `sf` definition [issue49](https://github.com/dcooley/sfheaders/issues/49) 33 | * `sf_to_df()` adds `sfc_columns` attributes to identify which of the columns form the coordinates [issue50](https://github.com/dcooley/sfheaders/issues/50) 34 | * `XYM` dimensions correctly handled 35 | * `unlist` argument in `sf_to_df()` to specify columns you want to unlist when converted to data.frame 36 | * helper functions with easier syntax - thanks to @mdsumner 37 | * `list_columns` argument in `sf_` functions to specify which columns should be filled with all the values in a list 38 | 39 | # v 0.2.1 40 | 41 | * `sf_remove_holes()` removes holes from polygons 42 | * `calculate_bbox()` function for (re) calculating the bounding box of an `sfc` object 43 | * `sf_cast()` functions for casting between geometry types 44 | * optimised converting `sfc_POINT`-only objects to data.frames 45 | * `sf_to_df()` adds `sfc_columns` attributes to identify which of the columns form the coordinates 46 | 47 | # v 0.1 48 | 49 | * `keep = TRUE` argument to keep other data columns when converting to `sf` 50 | * `sf_to_df` functions for converting sf objects to data.frames 51 | * `fill = TRUE` argument to fill the data.frame columns with data 52 | -------------------------------------------------------------------------------- /R/df.R: -------------------------------------------------------------------------------- 1 | #' sfg to df 2 | #' 3 | #' Converts an sfg object to a data.frame 4 | #' 5 | #' @param sfg sfg object 6 | #' 7 | #' @examples 8 | #' sfg <- sfg_point( obj = c(1,2) ) 9 | #' df <- sfg_to_df( sfg ) 10 | #' 11 | #' m <- cbind( matrix( 1:24, ncol = 2 ), c(rep(1, 6), rep(2, 6) ) ) 12 | #' sfg <- sfg_polygon( obj = m, x = 1, y = 2, linestring_id = 3 ) 13 | #' df <- sfg_to_df( sfg ) 14 | #' 15 | #' 16 | #' @export 17 | sfg_to_df <- function( sfg ) return( rcpp_sfg_to_df( sfg ) ) 18 | 19 | 20 | #' sfc to df 21 | #' 22 | #' Converts an sfc object to a data.frame 23 | #' 24 | #' @param sfc sfc object 25 | #' 26 | #' @examples 27 | #' 28 | #' x <- matrix( c(1:16), ncol = 2 ) 29 | #' sfc <- sfc_linestring( x ) 30 | #' df <- sfc_to_df( sfc ) 31 | #' 32 | #' df <- data.frame( 33 | #' ml_id = c(1,1,1,1,1,1,1,1,2,2,2,2,2) 34 | #' , l_id = c(1,1,1,2,2,3,3,3,1,1,1,2,2) 35 | #' , x = rnorm(13) 36 | #' , y = rnorm(13) 37 | #' , z = rnorm(13) 38 | #' , m = rnorm(13) 39 | #' ) 40 | #' sfc <- sfc_multilinestring( obj = df, multilinestring_id = "ml_id", linestring_id = "l_id" ) 41 | #' 42 | #' df <- sfc_to_df( sfc ) 43 | #' 44 | #' @export 45 | sfc_to_df <- function( sfc ) return( rcpp_sfc_to_df( sfc ) ) 46 | 47 | 48 | #' sf to df 49 | #' 50 | #' Converts an sf object to a data.frame 51 | #' 52 | #' @param sf sf object 53 | #' @param fill logical indicating if the resulting data.frame should be filled 54 | #' with the data columns from the sf object. If \code{TRUE}, each row of data will 55 | #' be replicated for every coordinate in every geometry. 56 | #' @param unlist string vector of columns to unlist. Each list element is equivalent 57 | #' to a row of the input object, and is expected to be the same 58 | #' length as the number of coordinates in the geometry. 59 | #' 60 | #' @examples 61 | #' 62 | #' df <- data.frame( 63 | #' ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 64 | #' , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 65 | #' , x = rnorm(15) 66 | #' , y = rnorm(15) 67 | #' , z = rnorm(15) 68 | #' , m = rnorm(15) 69 | #' ) 70 | #' 71 | #' sf <- sf_polygon( obj = df, polygon_id = "ml_id", linestring_id = "l_id" ) 72 | #' df <- sf_to_df( sf ) 73 | #' 74 | #' ## with associated data 75 | #' sf$val1 <- c("a","b") 76 | #' sf$val2 <- c(1L, 2L) 77 | #' 78 | #' df <- sf_to_df( sf, fill = TRUE ) 79 | #' 80 | #' ## Unlisting list columns 81 | #' 82 | #' df <- data.frame( 83 | #' l_id = c(1,1,1,2,2,2,3,3,3,3) 84 | #' , x = rnorm(10) 85 | #' , y = rnorm(10) 86 | #' ) 87 | #' 88 | #' sf <- sf_linestring( obj = df, linestring_id = "l_id" , x = "x", y = "y") 89 | #' 90 | #' ## put on a list column 91 | #' sf$l <- list( c(1,2,3),c(3,2,1),c(10,11,12,13)) 92 | #' 93 | #' sf_to_df( sf, unlist = "l" ) 94 | #' 95 | #' 96 | #' @export 97 | sf_to_df <- function( sf, fill = FALSE, unlist = NULL ) { 98 | if( is.null( unlist ) ) { 99 | return( rcpp_sf_to_df( sf, fill )) 100 | } 101 | return( rcpp_sf_to_df_unlist( sf, unlist, fill ) ) 102 | } 103 | -------------------------------------------------------------------------------- /R/sfheaders-package.R: -------------------------------------------------------------------------------- 1 | #' @useDynLib sfheaders, .registration = TRUE 2 | #' @importFrom Rcpp sourceCpp 3 | NULL 4 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | 2 | ## convert R-index to c++-index 3 | index_correct <- function( geometry_columns ) { 4 | if( is.numeric( geometry_columns ) ) { 5 | return( as.integer( geometry_columns ) - 1L ) 6 | } 7 | 8 | return( geometry_columns ) 9 | } 10 | 11 | xyzm <- function(x,y,z,m) { 12 | if(is.null(x) & is.null(y) & is.null(z) & is.null(m)) { 13 | return("") ## TODO: need to 'guess' what this is when in C++ 14 | } 15 | if(!is.null(x) & !is.null(y) & is.null(z) & is.null(m) ) { 16 | return("XY") 17 | } 18 | if(!is.null(x) & !is.null(y) & !is.null(z) & is.null(m) ) { 19 | return("XYZ") 20 | } 21 | if(!is.null(x) & !is.null(y) & is.null(z) & !is.null(m) ) { 22 | return("XYM") 23 | } 24 | if(!is.null(x) & !is.null(y) & !is.null(z) & !is.null(m) ) { 25 | return("XYZM") 26 | } 27 | stop("sfheaders - unknown combination of x, y, z and m arguments") 28 | } 29 | 30 | 31 | #' remove holes 32 | #' 33 | #' Removes holes from polygons and multipolygons. Points and linestrings are unaffected. 34 | #' 35 | #' @param obj sfg, sfc or sf object. 36 | #' @inheritParams sfc_polygon 37 | #' 38 | #' @examples 39 | #' df <- data.frame( 40 | #' ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 41 | #' , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 42 | #' , x = rnorm(15) 43 | #' , y = rnorm(15) 44 | #' , z = rnorm(15) 45 | #' , m = rnorm(15) 46 | #' ) 47 | #' 48 | #' sfg <- sfg_polygon( obj = df, x = "x", y = "y", linestring_id = "ml_id" ) 49 | #' sfc <- sfc_polygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id" ) 50 | #' sf <- sf_polygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id" ) 51 | #' 52 | #' sf_remove_holes( sfg ) 53 | #' sf_remove_holes( sfc ) 54 | #' sf_remove_holes( sf ) 55 | #' 56 | #' @export 57 | sf_remove_holes <- function( obj, close = TRUE ) remove_holes( obj, close ) 58 | 59 | remove_holes <- function( obj, close = TRUE ) UseMethod("remove_holes") 60 | 61 | #' @export 62 | remove_holes.sfg <- function( obj, close = TRUE ) { 63 | return( rcpp_sfg_remove_holes( obj, close ) ) 64 | } 65 | 66 | #' @export 67 | remove_holes.sfc <- function( obj, close = TRUE ) { 68 | return( rcpp_sfc_remove_holes( obj, close ) ) 69 | } 70 | 71 | #' @export 72 | remove_holes.sf <- function( obj, close = TRUE ) { 73 | geom_col <- attr(obj, "sf_column") 74 | obj[[ geom_col ]] <- remove_holes( obj[[ geom_col ]], close ) 75 | return( obj ) 76 | } 77 | 78 | #' @export 79 | remove_holes.default <- function( obj, close = TRUE ) stop("only sfg, sfc and sf objects are supported") 80 | 81 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | ```{r setup, 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 | 15 | [![R build status](https://github.com/dcooley/sfheaders/workflows/R-CMD-check/badge.svg)](https://github.com/dcooley/sfheaders/actions) 16 | [![Coverage status](https://codecov.io/gh/dcooley/sfheaders/branch/master/graph/badge.svg)](https://app.codecov.io/github/dcooley/sfheaders?branch=master) 17 | ![downloads](http://cranlogs.r-pkg.org/badges/grand-total/sfheaders) 18 | [![CRAN RStudio mirror downloads](http://cranlogs.r-pkg.org/badges/sfheaders)](https://CRAN.R-project.org/package=sfheaders) 19 | 20 | ## Another spatial library? 21 | 22 | Yep. In a few of my other libraries I've made use of `sf` objects, but without importing the `sf` library itself. This is by design because `sf` is quite a 'heavy' library. 23 | 24 | Therefore I've written / copied these methods for constructing the `sf` objects across a few different libraries. 25 | 26 | So I thought it would be useful to have these in one place. And here they are. 27 | 28 | ## Does it really make `sf` objects? 29 | 30 | Yes and No. 31 | 32 | These functions do not perform any validity checks on the geometries. Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 33 | 34 | What they do is convert R and Rcpp objects (vectors, matrices and data.frames) into the correct `sf` class structure, so you can then assign these values yourself. 35 | 36 | 37 | ## Are there any catches? 38 | 39 | Yes. Your data has to be ordered before coverting to `sf`. 40 | 41 | ## Where are the examples? 42 | 43 | They're on the [website](https://dcooley.github.io/sfheaders/articles/examples.html). GO NOW! 44 | 45 | (however, here's a taster) 46 | 47 | 48 | ```r 49 | 50 | df <- data.frame( 51 | id = c(1,1,1,1,1,2,2,2,2,2) 52 | , x = c(1,2,2,1,1,3,4,4,3,3) 53 | , y = c(1,1,2,2,1,3,3,4,4,3) 54 | ) 55 | 56 | df$val <- letters[df$id] 57 | 58 | sfheaders::sf_linestring( df, x = "x", y = "y", linestring_id = "id", keep = TRUE ) 59 | 60 | # Simple feature collection with 2 features and 2 fields 61 | # geometry type: LINESTRING 62 | # dimension: XY 63 | # bbox: xmin: 1 ymin: 1 xmax: 4 ymax: 4 64 | # epsg (SRID): NA 65 | # proj4string: NA 66 | # id val geometry 67 | # 1 1 a LINESTRING (1 1, 2 1, 2 2, ... 68 | # 2 2 b LINESTRING (3 3, 4 3, 4 4, ... 69 | 70 | sfheaders::sf_polygon( df, x = "x", y = "y", polygon_id = "id" , keep = TRUE ) 71 | 72 | # Simple feature collection with 2 features and 2 fields 73 | # geometry type: POLYGON 74 | # dimension: XY 75 | # bbox: xmin: 1 ymin: 1 xmax: 4 ymax: 4 76 | # epsg (SRID): NA 77 | # proj4string: NA 78 | # id val geometry 79 | # 1 1 a POLYGON ((1 1, 2 1, 2 2, 1 ... 80 | # 2 2 b POLYGON ((3 3, 4 3, 4 4, 3 ... 81 | 82 | ``` 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![R build 3 | status](https://github.com/dcooley/sfheaders/workflows/R-CMD-check/badge.svg)](https://github.com/dcooley/sfheaders/actions) 4 | [![Coverage 5 | status](https://codecov.io/gh/dcooley/sfheaders/branch/master/graph/badge.svg)](https://app.codecov.io/github/dcooley/sfheaders?branch=master) 6 | ![downloads](http://cranlogs.r-pkg.org/badges/grand-total/sfheaders) 7 | [![CRAN RStudio mirror 8 | downloads](http://cranlogs.r-pkg.org/badges/sfheaders)](https://CRAN.R-project.org/package=sfheaders) 9 | 10 | ## Another spatial library? 11 | 12 | Yep. In a few of my other libraries I’ve made use of `sf` objects, but 13 | without importing the `sf` library itself. This is by design because 14 | `sf` is quite a ‘heavy’ library. 15 | 16 | Therefore I’ve written / copied these methods for constructing the `sf` 17 | objects across a few different libraries. 18 | 19 | So I thought it would be useful to have these in one place. And here 20 | they are. 21 | 22 | ## Does it really make `sf` objects? 23 | 24 | Yes and No.  25 | 26 | These functions do not perform any validity checks on the geometries. 27 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision 28 | attributes. 29 | 30 | What they do is convert R and Rcpp objects (vectors, matrices and 31 | data.frames) into the correct `sf` class structure, so you can then 32 | assign these values yourself. 33 | 34 | ## Are there any catches? 35 | 36 | Yes. Your data has to be ordered before coverting to `sf`. 37 | 38 | ## Where are the examples? 39 | 40 | They’re on the 41 | [website](https://dcooley.github.io/sfheaders/articles/examples.html). 42 | GO NOW! 43 | 44 | (however, here’s a taster) 45 | 46 | ``` r 47 | 48 | df <- data.frame( 49 | id = c(1,1,1,1,1,2,2,2,2,2) 50 | , x = c(1,2,2,1,1,3,4,4,3,3) 51 | , y = c(1,1,2,2,1,3,3,4,4,3) 52 | ) 53 | 54 | df$val <- letters[df$id] 55 | 56 | sfheaders::sf_linestring( df, x = "x", y = "y", linestring_id = "id", keep = TRUE ) 57 | 58 | # Simple feature collection with 2 features and 2 fields 59 | # geometry type: LINESTRING 60 | # dimension: XY 61 | # bbox: xmin: 1 ymin: 1 xmax: 4 ymax: 4 62 | # epsg (SRID): NA 63 | # proj4string: NA 64 | # id val geometry 65 | # 1 1 a LINESTRING (1 1, 2 1, 2 2, ... 66 | # 2 2 b LINESTRING (3 3, 4 3, 4 4, ... 67 | 68 | sfheaders::sf_polygon( df, x = "x", y = "y", polygon_id = "id" , keep = TRUE ) 69 | 70 | # Simple feature collection with 2 features and 2 fields 71 | # geometry type: POLYGON 72 | # dimension: XY 73 | # bbox: xmin: 1 ymin: 1 xmax: 4 ymax: 4 74 | # epsg (SRID): NA 75 | # proj4string: NA 76 | # id val geometry 77 | # 1 1 a POLYGON ((1 1, 2 1, 2 2, 1 ... 78 | # 2 2 b POLYGON ((3 3, 4 3, 4 4, 3 ... 79 | ``` 80 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | patch: 10 | default: 11 | target: auto 12 | threshold: 1% 13 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/articles/images/gpx_description.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/docs/articles/images/gpx_description.png -------------------------------------------------------------------------------- /docs/articles/images/gpx_functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/docs/articles/images/gpx_functions.png -------------------------------------------------------------------------------- /docs/articles/images/gpx_include.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/docs/articles/images/gpx_include.png -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $("div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 3.1.1 2 | pkgdown: 2.0.7 3 | pkgdown_sha: ~ 4 | articles: 5 | Cpp: Cpp.html 6 | examples: examples.html 7 | last_built: 2023-07-19T00:27Z 8 | 9 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /404.html 5 | 6 | 7 | /LICENSE-text.html 8 | 9 | 10 | /LICENSE.html 11 | 12 | 13 | /articles/Cpp.html 14 | 15 | 16 | /articles/examples.html 17 | 18 | 19 | /articles/index.html 20 | 21 | 22 | /authors.html 23 | 24 | 25 | /index.html 26 | 27 | 28 | /news/index.html 29 | 30 | 31 | /reference/index.html 32 | 33 | 34 | /reference/sf_bbox.html 35 | 36 | 37 | /reference/sf_boxes.html 38 | 39 | 40 | /reference/sf_cast.html 41 | 42 | 43 | /reference/sf_line.html 44 | 45 | 46 | /reference/sf_linestring.html 47 | 48 | 49 | /reference/sf_mline.html 50 | 51 | 52 | /reference/sf_mpoly.html 53 | 54 | 55 | /reference/sf_mpt.html 56 | 57 | 58 | /reference/sf_multilinestring.html 59 | 60 | 61 | /reference/sf_multipoint.html 62 | 63 | 64 | /reference/sf_multipolygon.html 65 | 66 | 67 | /reference/sf_point.html 68 | 69 | 70 | /reference/sf_poly.html 71 | 72 | 73 | /reference/sf_polygon.html 74 | 75 | 76 | /reference/sf_pt.html 77 | 78 | 79 | /reference/sf_remove_holes.html 80 | 81 | 82 | /reference/sf_to_df.html 83 | 84 | 85 | /reference/sfc_cast.html 86 | 87 | 88 | /reference/sfc_linestring.html 89 | 90 | 91 | /reference/sfc_multilinestring.html 92 | 93 | 94 | /reference/sfc_multipoint.html 95 | 96 | 97 | /reference/sfc_multipolygon.html 98 | 99 | 100 | /reference/sfc_point.html 101 | 102 | 103 | /reference/sfc_polygon.html 104 | 105 | 106 | /reference/sfc_to_df.html 107 | 108 | 109 | /reference/sfg_linestring.html 110 | 111 | 112 | /reference/sfg_multilinestring.html 113 | 114 | 115 | /reference/sfg_multipoint.html 116 | 117 | 118 | /reference/sfg_multipolygon.html 119 | 120 | 121 | /reference/sfg_point.html 122 | 123 | 124 | /reference/sfg_polygon.html 125 | 126 | 127 | /reference/sfg_to_df.html 128 | 129 | 130 | -------------------------------------------------------------------------------- /inst/include/sfheaders/cast/sf_cast.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_CAST_SF_H 2 | #define R_SFHEADERS_CAST_SF_H 3 | 4 | #include "sfheaders/sf/sf_utils.hpp" 5 | #include "sfheaders/cast/sfc_cast.hpp" 6 | 7 | #include "geometries/utils/vectors/vectors.hpp" 8 | 9 | #include 10 | 11 | namespace sfheaders { 12 | namespace cast { 13 | 14 | inline Rcpp::List cast_sf( 15 | Rcpp::DataFrame& sf, 16 | std::string& cast_to, 17 | SEXP list_columns, 18 | bool close = true 19 | ) { 20 | if( !sf.hasAttribute("sf_column") ) { 21 | Rcpp::stop("sfheaders - sf_column not found"); 22 | } 23 | 24 | Rcpp::IntegerVector iv_list_columns; 25 | Rcpp::IntegerVector iv_geom_column; 26 | 27 | if( !Rf_isNull( list_columns ) ) { 28 | // need to use 'obj' here because 'list_columns' may be a string, but 'data' 29 | // has been made into an unnamed list 30 | iv_list_columns = geometries::utils::sexp_col_int( sf, list_columns ); 31 | } 32 | 33 | Rcpp::StringVector df_names = sf.names(); 34 | R_xlen_t n_names = df_names.length(); 35 | R_xlen_t i, j; 36 | R_xlen_t n_row = sf.nrow(); 37 | R_xlen_t n_col = sf.ncol(); 38 | 39 | std::string geom_column = sf.attr("sf_column"); 40 | iv_geom_column = geometries::utils::sexp_col_int( df_names, geom_column ); 41 | 42 | Rcpp::List sfc = sf[ geom_column ]; 43 | Rcpp::IntegerVector n_results = count_new_sfc_objects( sfc, cast_to ); 44 | 45 | R_xlen_t total_coordinates = Rcpp::sum( n_results ); 46 | 47 | Rcpp::IntegerVector expanded_index( total_coordinates ); 48 | 49 | // other than the sfc column, expand all the other (non-list) columns by 'n_results' 50 | R_xlen_t counter = 0; 51 | for( i = 0; i < n_row; ++i ) { 52 | R_xlen_t expand_by = n_results[ i ]; 53 | 54 | for( j = 0; j < expand_by; ++j ) { 55 | expanded_index[ counter + j ] = i; 56 | } 57 | counter = counter + expand_by; 58 | } 59 | 60 | Rcpp::List casted_sfc = sfheaders::cast::cast_sfc( sfc, n_results, cast_to, close ); 61 | 62 | Rcpp::List sf_res( n_names ); 63 | // loop over each of the df_names which aren't the geometry or list-columns 64 | // then add on the created_sfc; 65 | Rcpp::StringVector res_names( n_col ); 66 | R_xlen_t column_counter = 0; 67 | 68 | 69 | for( i = 0; i < n_names; ++i ) { 70 | // iff this_name != geom_column, expand the vector and doene. 71 | Rcpp::String this_name = df_names[ i ]; 72 | std::string str_name = this_name; 73 | 74 | if( str_name != geom_column ) { 75 | 76 | int is_in = geometries::utils::where_is( i, iv_list_columns ); 77 | 78 | if( is_in >= 0 ) { 79 | 80 | Rcpp::List v = sf[ i ]; 81 | 82 | sf_res[ column_counter ] = sfheaders::cast::cast_list( v, sfc, n_results, cast_to ); 83 | } else { 84 | 85 | SEXP v = sf[ i ]; 86 | geometries::utils::expand_vector( sf_res, v, expanded_index, column_counter ); 87 | } 88 | 89 | res_names[ column_counter ] = str_name; 90 | ++column_counter; 91 | } 92 | } 93 | 94 | // append 'geom_column' to res_columns; 95 | res_names[ column_counter ] = geom_column; 96 | 97 | sf_res[ column_counter ] = casted_sfc; 98 | sf_res.names() = res_names; 99 | sfheaders::sf::attach_dataframe_attributes( sf_res, total_coordinates, geom_column ); 100 | return sf_res; 101 | 102 | } 103 | 104 | } // cast 105 | } // sfheaders 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /inst/include/sfheaders/df/utils.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef R_SFHEADERS_DF_UTILS_H 3 | #define R_SFHEADERS_DF_UTILS_H 4 | 5 | #include "geometries/utils/vectors/vectors.hpp" 6 | 7 | namespace sfheaders { 8 | namespace utils { 9 | 10 | inline Rcpp::String unique_name( Rcpp::String this_name, Rcpp::StringVector& existing_names ) { 11 | int is_in = geometries::utils::where_is( this_name, existing_names ); 12 | 13 | if( is_in != -1 ) { 14 | // the name already exists, so we need to uniqueify it 15 | int counter = 1; 16 | std::string new_name; 17 | do { // #nocov 18 | std::ostringstream os; 19 | os << this_name.get_cstring() << ".." << counter; 20 | new_name = os.str(); 21 | is_in = geometries::utils::where_is( new_name, existing_names ); 22 | counter += 1; 23 | } while ( is_in != -1 ); 24 | this_name = new_name; 25 | } 26 | 27 | return this_name; 28 | } 29 | 30 | template 31 | inline Rcpp::CharacterVector sfgClass( Rcpp::Vector v ) { 32 | return v.attr("class"); 33 | } 34 | 35 | inline Rcpp::CharacterVector getSfgClass( SEXP sfg ) { 36 | switch( TYPEOF( sfg ) ) { 37 | case REALSXP: 38 | return sfgClass( sfg ); 39 | case VECSXP: 40 | return sfgClass( sfg ); 41 | case INTSXP: 42 | return sfgClass( sfg ); 43 | default: Rcpp::stop("unknown sf type"); // #nocov 44 | } 45 | return Rcpp::CharacterVector(); 46 | } 47 | 48 | inline Rcpp::List make_dataframe( 49 | Rcpp::List& res, 50 | R_xlen_t& total_rows, 51 | Rcpp::StringVector& column_names 52 | ) { 53 | 54 | res.attr("class") = Rcpp::CharacterVector("data.frame"); 55 | 56 | if( total_rows > 0 ) { 57 | Rcpp::IntegerVector rownames = Rcpp::seq( 1, total_rows ); 58 | res.attr("row.names") = rownames; 59 | } else { 60 | res.attr("row.names") = Rcpp::IntegerVector(0); // #nocov 61 | } 62 | 63 | res.attr("names") = column_names; 64 | return res; 65 | } 66 | 67 | inline Rcpp::List make_dataframe( 68 | Rcpp::List& res, 69 | R_xlen_t& total_rows 70 | ) { 71 | Rcpp::StringVector res_names = res.names(); 72 | return make_dataframe( res, total_rows, res_names ); 73 | } 74 | 75 | } // utils 76 | } // sfheaders 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sf/linestring/sf_linestring.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SF_LINESTRING_H 2 | #define R_SFHEADERS_SF_LINESTRING_H 3 | 4 | #include 5 | #include "geometries/utils/sexp/sexp.hpp" 6 | #include "geometries/utils/unique/unique.hpp" 7 | 8 | #include "geometries/utils/rleid/rleid.hpp" 9 | 10 | #include "sfheaders/sf/sf_utils.hpp" 11 | #include "sfheaders/sfc/linestring/sfc_linestring.hpp" 12 | 13 | namespace sfheaders { 14 | namespace sf { 15 | 16 | // this function won't keep any attributes 17 | inline SEXP sf_linestring( 18 | SEXP& x, 19 | SEXP& geometry_cols, 20 | SEXP& linestring_id, 21 | std::string xyzm 22 | ) { 23 | 24 | Rcpp::List sfc = sfheaders::sfc::sfc_linestring( x, geometry_cols, linestring_id, xyzm ); 25 | // TODO: we're getting the linestring_ids inside sfc_linestring, 26 | // and re-doing it here... say what... 27 | SEXP ids = geometries::utils::get_ids( x, linestring_id ); 28 | sfheaders::sf::id_length_check( ids, sfc ); 29 | 30 | Rcpp::DataFrame sf = sfheaders::sf::make_sf( sfc, ids ); 31 | return sf; 32 | } 33 | 34 | inline SEXP sf_linestring( 35 | SEXP& x, 36 | SEXP& geometry_cols, 37 | SEXP& linestring_id, 38 | std::string xyzm, 39 | bool& keep 40 | ) { 41 | 42 | if( !keep ) { 43 | return sf_linestring( x, geometry_cols, linestring_id, xyzm ); 44 | } 45 | 46 | Rcpp::List lst = geometries::utils::as_list( x ); 47 | Rcpp::List sfc = sfheaders::sfc::sfc_linestring( x, geometry_cols, linestring_id, xyzm ); 48 | 49 | SEXP property_cols = geometries::utils::other_columns( x, geometry_cols, linestring_id ); 50 | Rcpp::IntegerVector int_property_cols = geometries::utils::sexp_col_int( x, property_cols ); 51 | 52 | if( Rf_isNull( linestring_id ) ) { 53 | 54 | Rcpp::IntegerVector geometry_index(1); 55 | geometry_index[0] = 0; 56 | 57 | return Rcpp::List::create( 58 | Rcpp::_["x"] = lst, 59 | Rcpp::_["sfc"] = sfc, 60 | Rcpp::_["property_cols"] = int_property_cols, 61 | Rcpp::_["geometry_idx"] = geometry_index 62 | // no id_column because it's null 63 | ); 64 | } 65 | 66 | Rcpp::IntegerVector int_linestring_id = geometries::utils::sexp_col_int( x, linestring_id ); 67 | 68 | // TODO: 69 | // - can I get this during 'sfc_linestring()' so I don't have to do it twice? 70 | Rcpp::IntegerVector geometry_idx = geometries::utils::rleid_indices( lst, int_linestring_id ); 71 | 72 | Rcpp::List res = Rcpp::List::create( 73 | Rcpp::_["x"] = lst, 74 | Rcpp::_["sfc"] = sfc, 75 | Rcpp::_["property_cols"] = int_property_cols, 76 | Rcpp::_["geometry_idx"] = geometry_idx, 77 | Rcpp::_["id_column"] = int_linestring_id 78 | ); 79 | 80 | return res; 81 | } 82 | 83 | inline SEXP sf_linestring( 84 | SEXP& x, 85 | SEXP& geometry_cols, 86 | SEXP& linestring_id 87 | ) { 88 | std::string xyzm; 89 | return sf_linestring( x, geometry_cols, linestring_id, xyzm ); 90 | } 91 | 92 | inline SEXP sf_linestring( 93 | SEXP& x, 94 | SEXP& geometry_cols, 95 | SEXP& linestring_id, 96 | bool& keep 97 | ) { 98 | std::string xyzm; 99 | return sf_linestring( x, geometry_cols, linestring_id, xyzm, keep ); 100 | } 101 | 102 | } // sf 103 | } // sfheaders 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sf/multilinestring/sf_multilinestring.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SF_MULTILINESTRING_H 2 | #define R_SFHEADERS_SF_MULTILINESTRING_H 3 | 4 | #include 5 | #include "geometries/utils/sexp/sexp.hpp" 6 | #include "geometries/utils/unique/unique.hpp" 7 | 8 | #include "geometries/utils/rleid/rleid.hpp" 9 | 10 | #include "sfheaders/sf/sf_utils.hpp" 11 | #include "sfheaders/sfc/multilinestring/sfc_multilinestring.hpp" 12 | 13 | namespace sfheaders { 14 | namespace sf { 15 | 16 | // this function won't keep any attributes 17 | inline SEXP sf_multilinestring( 18 | SEXP& x, 19 | SEXP& geometry_cols, 20 | SEXP& multilinestring_id, 21 | SEXP& linestring_id, 22 | std::string xyzm 23 | ) { 24 | 25 | Rcpp::List sfc = sfheaders::sfc::sfc_multilinestring( x, geometry_cols, multilinestring_id, linestring_id, xyzm ); 26 | // TODO: we're getting the linestring_ids inside sfc_linestring, 27 | // and re-doing it here... say what... 28 | SEXP ids = geometries::utils::get_ids( x, multilinestring_id ); 29 | sfheaders::sf::id_length_check( ids, sfc ); 30 | 31 | Rcpp::DataFrame sf = sfheaders::sf::make_sf( sfc, ids ); 32 | return sf; 33 | } 34 | 35 | inline SEXP sf_multilinestring( 36 | SEXP& x, 37 | SEXP& geometry_cols, 38 | SEXP& multilinestring_id, 39 | SEXP& linestring_id, 40 | std::string xyzm, 41 | bool& keep 42 | ) { 43 | 44 | if( !keep ) { 45 | return sf_multilinestring( x, geometry_cols, multilinestring_id, linestring_id, xyzm ); 46 | } 47 | 48 | Rcpp::List lst = geometries::utils::as_list( x ); 49 | Rcpp::List sfc = sfheaders::sfc::sfc_multilinestring( x, geometry_cols, multilinestring_id, linestring_id, xyzm ); 50 | 51 | SEXP property_cols = geometries::utils::other_columns( x, geometry_cols, multilinestring_id, linestring_id ); 52 | Rcpp::IntegerVector int_property_cols = geometries::utils::sexp_col_int( x, property_cols ); 53 | 54 | if( Rf_isNull( multilinestring_id ) ) { 55 | 56 | Rcpp::IntegerVector geometry_index(1); 57 | geometry_index[0] = 0; 58 | 59 | return Rcpp::List::create( 60 | Rcpp::_["x"] = lst, 61 | Rcpp::_["sfc"] = sfc, 62 | Rcpp::_["property_cols"] = int_property_cols, 63 | Rcpp::_["geometry_idx"] = geometry_index 64 | // no id_column because it's null 65 | ); 66 | } 67 | 68 | Rcpp::IntegerVector int_multilinestring_id = geometries::utils::sexp_col_int( x, multilinestring_id ); 69 | 70 | // TODO: 71 | // - can I get this during 'sfc_linestring()' so I don't have to do it twice? 72 | Rcpp::IntegerVector geometry_idx = geometries::utils::rleid_indices( lst, int_multilinestring_id ); 73 | 74 | Rcpp::List res = Rcpp::List::create( 75 | Rcpp::_["x"] = lst, 76 | Rcpp::_["sfc"] = sfc, 77 | Rcpp::_["property_cols"] = int_property_cols, 78 | Rcpp::_["geometry_idx"] = geometry_idx, 79 | Rcpp::_["id_column"] = int_multilinestring_id 80 | ); 81 | 82 | return res; 83 | } 84 | 85 | inline SEXP sf_multilinestring( 86 | SEXP& x, 87 | SEXP& geometry_cols, 88 | SEXP& multilinestring_id, 89 | SEXP& linestring_id 90 | ) { 91 | std::string xyzm; 92 | return sf_multilinestring( x, geometry_cols, multilinestring_id, linestring_id, xyzm ); 93 | } 94 | 95 | inline SEXP sf_multilinestring( 96 | SEXP& x, 97 | SEXP& geometry_cols, 98 | SEXP& multilinestring_id, 99 | SEXP& linestring_id, 100 | bool& keep 101 | ) { 102 | std::string xyzm; 103 | return sf_multilinestring( x, geometry_cols, multilinestring_id, linestring_id, xyzm, keep); 104 | } 105 | 106 | } // sf 107 | } // sfheaders 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sf/multipoint/sf_multipoint.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SF_MULTIPOINT_H 2 | #define R_SFHEADERS_SF_MULTIPOINT_H 3 | 4 | #include 5 | #include "geometries/utils/sexp/sexp.hpp" 6 | #include "geometries/utils/unique/unique.hpp" 7 | 8 | #include "geometries/utils/rleid/rleid.hpp" 9 | 10 | #include "sfheaders/sf/sf_utils.hpp" 11 | #include "sfheaders/sfc/multipoint/sfc_multipoint.hpp" 12 | 13 | namespace sfheaders { 14 | namespace sf { 15 | 16 | inline SEXP sf_multipoint( 17 | SEXP& x, 18 | SEXP& geometry_cols, 19 | SEXP& multipoint_id, 20 | std::string xyzm 21 | ) { 22 | Rcpp::List sfc = sfheaders::sfc::sfc_multipoint( x, geometry_cols, multipoint_id, xyzm ); 23 | 24 | SEXP ids = geometries::utils::get_ids( x, multipoint_id ); 25 | sfheaders::sf::id_length_check( ids, sfc ); 26 | 27 | Rcpp::DataFrame sf = sfheaders::sf::make_sf( sfc, ids ); 28 | return sf; 29 | } 30 | 31 | inline SEXP sf_multipoint( 32 | SEXP& x, 33 | SEXP& geometry_cols, 34 | SEXP& multipoint_id, 35 | std::string xyzm, 36 | bool& keep 37 | ) { 38 | 39 | if( !keep ) { 40 | return sf_multipoint( x, geometry_cols, multipoint_id, xyzm ); 41 | } 42 | 43 | Rcpp::List lst = geometries::utils::as_list( x ); 44 | Rcpp::List sfc = sfheaders::sfc::sfc_multipoint( x, geometry_cols, multipoint_id, xyzm ); 45 | 46 | SEXP property_cols = geometries::utils::other_columns( x, geometry_cols, multipoint_id ); 47 | Rcpp::IntegerVector int_property_cols = geometries::utils::sexp_col_int( x, property_cols ); 48 | 49 | if( Rf_isNull( multipoint_id ) ) { 50 | 51 | Rcpp::IntegerVector geometry_index(1); 52 | geometry_index[0] = 0; 53 | 54 | return Rcpp::List::create( 55 | Rcpp::_["x"] = lst, 56 | Rcpp::_["sfc"] = sfc, 57 | Rcpp::_["property_cols"] = int_property_cols, 58 | Rcpp::_["geometry_idx"] = geometry_index 59 | // no id_column because it's null 60 | ); 61 | } 62 | 63 | Rcpp::IntegerVector int_multipoint_id = geometries::utils::sexp_col_int( x, multipoint_id ); 64 | 65 | // TODO: 66 | // - can I get this during 'sfc_linestring()' so I don't have to do it twice? 67 | Rcpp::IntegerVector geometry_idx = geometries::utils::rleid_indices( lst, int_multipoint_id ); 68 | 69 | Rcpp::List res = Rcpp::List::create( 70 | Rcpp::_["x"] = lst, 71 | Rcpp::_["sfc"] = sfc, 72 | Rcpp::_["property_cols"] = int_property_cols, 73 | Rcpp::_["geometry_idx"] = geometry_idx, 74 | Rcpp::_["id_column"] = int_multipoint_id 75 | ); 76 | 77 | return res; 78 | } 79 | 80 | inline SEXP sf_multipoint( 81 | SEXP& x, 82 | SEXP& geometry_cols, 83 | SEXP& multipoint_id 84 | ) { 85 | std::string xyzm; 86 | return sf_multipoint( x, geometry_cols, multipoint_id, xyzm ); 87 | } 88 | 89 | inline SEXP sf_multipoint( 90 | SEXP& x, 91 | SEXP& geometry_cols, 92 | SEXP& multipoint_id, 93 | bool& keep 94 | ) { 95 | std::string xyzm; 96 | return sf_multipoint( x, geometry_cols, multipoint_id, xyzm, keep ); 97 | } 98 | 99 | } // sf 100 | } // sfheaders 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sf/multipolygon/sf_multipolygon.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SF_MULTIPOLYGON_H 2 | #define R_SFHEADERS_SF_MULTIPOLYGON_H 3 | 4 | #include 5 | #include "geometries/utils/sexp/sexp.hpp" 6 | #include "geometries/utils/unique/unique.hpp" 7 | 8 | #include "geometries/utils/rleid/rleid.hpp" 9 | 10 | #include "sfheaders/sf/sf_utils.hpp" 11 | #include "sfheaders/sfc/multipolygon/sfc_multipolygon.hpp" 12 | 13 | namespace sfheaders { 14 | namespace sf { 15 | 16 | // this function won't keep any attributes 17 | inline SEXP sf_multipolygon( 18 | SEXP& x, 19 | SEXP& geometry_cols, 20 | SEXP& multipolygon_id, 21 | SEXP& polygon_id, 22 | SEXP& linestring_id, 23 | std::string xyzm, 24 | bool close, 25 | bool closed_attribute 26 | ) { 27 | 28 | Rcpp::List sfc = sfheaders::sfc::sfc_multipolygon( x, geometry_cols, multipolygon_id, polygon_id, linestring_id, xyzm, close, closed_attribute ); 29 | // TODO: we're getting the linestring_ids inside sfc_linestring, 30 | // and re-doing it here... say what... 31 | SEXP ids = geometries::utils::get_ids( x, multipolygon_id ); 32 | sfheaders::sf::id_length_check( ids, sfc ); 33 | 34 | Rcpp::DataFrame sf = sfheaders::sf::make_sf( sfc, ids ); 35 | return sf; 36 | } 37 | 38 | inline SEXP sf_multipolygon( 39 | SEXP& x, 40 | SEXP& geometry_cols, 41 | SEXP& multipolygon_id, 42 | SEXP& polygon_id, 43 | SEXP& linestring_id, 44 | std::string xyzm, 45 | bool keep, 46 | bool close, 47 | bool closed_attribute 48 | ) { 49 | 50 | if( !keep ) { 51 | return sf_multipolygon( x, geometry_cols, multipolygon_id, polygon_id, linestring_id, xyzm, close, closed_attribute ); 52 | } 53 | 54 | Rcpp::List lst = geometries::utils::as_list( x ); 55 | Rcpp::List sfc = sfheaders::sfc::sfc_multipolygon( x, geometry_cols, multipolygon_id, polygon_id, linestring_id, xyzm, close, closed_attribute ); 56 | 57 | // return sfc; 58 | 59 | SEXP id_cols = geometries::utils::concatenate_vectors( polygon_id, linestring_id ); 60 | SEXP property_cols = geometries::utils::other_columns( x, geometry_cols, multipolygon_id, id_cols ); 61 | Rcpp::IntegerVector int_property_cols = geometries::utils::sexp_col_int( x, property_cols ); 62 | 63 | if( Rf_isNull( multipolygon_id ) ) { 64 | 65 | Rcpp::IntegerVector geometry_index(1); 66 | geometry_index[0] = 0; 67 | 68 | return Rcpp::List::create( 69 | Rcpp::_["x"] = lst, 70 | Rcpp::_["sfc"] = sfc, 71 | Rcpp::_["property_cols"] = int_property_cols, 72 | Rcpp::_["geometry_idx"] = geometry_index 73 | // no id_column because it's null 74 | ); 75 | } 76 | 77 | Rcpp::IntegerVector int_multipolygon_id = geometries::utils::sexp_col_int( x, multipolygon_id ); 78 | 79 | // TODO: 80 | // - can I get this during 'sfc_linestring()' so I don't have to do it twice? 81 | Rcpp::IntegerVector geometry_idx = geometries::utils::rleid_indices( lst, int_multipolygon_id ); 82 | 83 | Rcpp::List res = Rcpp::List::create( 84 | Rcpp::_["x"] = lst, 85 | Rcpp::_["sfc"] = sfc, 86 | Rcpp::_["property_cols"] = int_property_cols, 87 | Rcpp::_["geometry_idx"] = geometry_idx, 88 | Rcpp::_["id_column"] = int_multipolygon_id 89 | ); 90 | 91 | return res; 92 | } 93 | 94 | inline SEXP sf_multipolygon( 95 | SEXP& x, 96 | SEXP& geometry_cols, 97 | SEXP& multipolygon_id, 98 | SEXP& polygon_id, 99 | SEXP& linestring_id, 100 | bool close, 101 | bool closed_attribute 102 | ) { 103 | std::string xyzm; 104 | return sf_multipolygon( x, geometry_cols, multipolygon_id, polygon_id, linestring_id, xyzm, close, closed_attribute ); 105 | } 106 | 107 | inline SEXP sf_multipolygon( 108 | SEXP& x, 109 | SEXP& geometry_cols, 110 | SEXP& multipolygon_id, 111 | SEXP& polygon_id, 112 | SEXP& linestring_id, 113 | bool keep, 114 | bool close, 115 | bool closed_attribute 116 | ) { 117 | std::string xyzm; 118 | return sf_multipolygon( x, geometry_cols, multipolygon_id, polygon_id, linestring_id, xyzm, keep, close, closed_attribute); 119 | } 120 | 121 | } // sf 122 | } // sfheaders 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sf/point/sf_point.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SF_POINT_H 2 | #define R_SFHEADERS_SF_POINT_H 3 | 4 | #include 5 | #include "geometries/utils/sexp/sexp.hpp" 6 | #include "geometries/utils/unique/unique.hpp" 7 | 8 | #include "geometries/utils/rleid/rleid.hpp" 9 | 10 | #include "sfheaders/sf/sf_utils.hpp" 11 | #include "sfheaders/sfc/point/sfc_point.hpp" 12 | 13 | namespace sfheaders { 14 | namespace sf { 15 | 16 | inline SEXP sf_point( 17 | SEXP& x, 18 | SEXP& geometry_cols, 19 | std::string xyzm 20 | ) { 21 | 22 | Rcpp::List sfc = sfheaders::sfc::sfc_point( x, geometry_cols, xyzm ); 23 | Rcpp::DataFrame sf = sfheaders::sf::make_sf( sfc ); 24 | return sf; 25 | } 26 | 27 | inline SEXP sf_point( 28 | SEXP& x, 29 | SEXP& geometry_cols, 30 | std::string xyzm, 31 | bool& keep 32 | ) { 33 | 34 | if( !keep ) { 35 | return sf_point( x, geometry_cols, xyzm ); 36 | } 37 | 38 | Rcpp::List lst = geometries::utils::as_list( x ); 39 | Rcpp::List sfc = sfheaders::sfc::sfc_point( x, geometry_cols, xyzm ); 40 | 41 | SEXP property_cols = geometries::utils::other_columns( x, geometry_cols ); 42 | Rcpp::IntegerVector int_property_cols = geometries::utils::sexp_col_int( x, property_cols ); 43 | 44 | R_xlen_t n_row = Rf_length( VECTOR_ELT( lst, 0 ) ); 45 | Rcpp::IntegerVector geometry_index = Rcpp::seq( 0, n_row - 1 ); 46 | 47 | return Rcpp::List::create( 48 | Rcpp::_["x"] = lst, 49 | Rcpp::_["sfc"] = sfc, 50 | Rcpp::_["property_cols"] = int_property_cols, 51 | Rcpp::_["geometry_idx"] = geometry_index 52 | // no id_column because it's null 53 | ); 54 | } 55 | 56 | inline SEXP sf_point( 57 | SEXP& x, 58 | SEXP& geometry_cols 59 | ) { 60 | std::string xyzm; 61 | return sf_point( x, geometry_cols, xyzm ); 62 | } 63 | 64 | inline SEXP sf_point( 65 | SEXP& x, 66 | SEXP& geometry_cols, 67 | bool& keep 68 | ) { 69 | std::string xyzm; 70 | return sf_point( x, geometry_cols, xyzm, keep ); 71 | } 72 | 73 | } // sf 74 | } // sfheaders 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sf/polygon/sf_polygon.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SF_POLYGON_H 2 | #define R_SFHEADERS_SF_POLYGON_H 3 | 4 | #include 5 | #include "geometries/utils/sexp/sexp.hpp" 6 | #include "geometries/utils/unique/unique.hpp" 7 | 8 | #include "geometries/utils/rleid/rleid.hpp" 9 | 10 | #include "sfheaders/sf/sf_utils.hpp" 11 | #include "sfheaders/sfc/polygon/sfc_polygon.hpp" 12 | 13 | namespace sfheaders { 14 | namespace sf { 15 | 16 | // this function won't keep any attributes 17 | inline SEXP sf_polygon( 18 | SEXP& x, 19 | SEXP& geometry_cols, 20 | SEXP& polygon_id, 21 | SEXP& linestring_id, 22 | std::string xyzm, 23 | bool close, 24 | bool closed_attribute 25 | ) { 26 | 27 | Rcpp::List sfc = sfheaders::sfc::sfc_polygon( x, geometry_cols, polygon_id, linestring_id, xyzm, close, closed_attribute ); 28 | // TODO: we're getting the linestring_ids inside sfc_linestring, 29 | // and re-doing it here... say what... 30 | SEXP ids = geometries::utils::get_ids( x, polygon_id ); 31 | sfheaders::sf::id_length_check( ids, sfc ); 32 | 33 | Rcpp::DataFrame sf = sfheaders::sf::make_sf( sfc, ids ); 34 | return sf; 35 | } 36 | 37 | inline SEXP sf_polygon( 38 | SEXP& x, 39 | SEXP& geometry_cols, 40 | SEXP& polygon_id, 41 | SEXP& linestring_id, 42 | std::string xyzm, 43 | bool keep, 44 | bool close, 45 | bool closed_attribute 46 | ) { 47 | 48 | if( !keep ) { 49 | return sf_polygon( x, geometry_cols, polygon_id, linestring_id, xyzm, close, closed_attribute ); 50 | } 51 | 52 | Rcpp::List lst = geometries::utils::as_list( x ); 53 | Rcpp::List sfc = sfheaders::sfc::sfc_polygon( x, geometry_cols, polygon_id, linestring_id, xyzm, close, closed_attribute ); 54 | 55 | SEXP property_cols = geometries::utils::other_columns( x, geometry_cols, polygon_id, linestring_id ); 56 | Rcpp::IntegerVector int_property_cols = geometries::utils::sexp_col_int( x, property_cols ); 57 | 58 | if( Rf_isNull( polygon_id ) ) { 59 | 60 | Rcpp::IntegerVector geometry_index(1); 61 | geometry_index[0] = 0; 62 | 63 | return Rcpp::List::create( 64 | Rcpp::_["x"] = lst, 65 | Rcpp::_["sfc"] = sfc, 66 | Rcpp::_["property_cols"] = int_property_cols, 67 | Rcpp::_["geometry_idx"] = geometry_index 68 | // no id_column because it's null 69 | ); 70 | } 71 | 72 | Rcpp::IntegerVector int_polygon_id = geometries::utils::sexp_col_int( x, polygon_id ); 73 | Rcpp::IntegerVector geometry_idx = geometries::utils::rleid_indices( lst, int_polygon_id ); 74 | 75 | Rcpp::List res = Rcpp::List::create( 76 | Rcpp::_["x"] = lst, 77 | Rcpp::_["sfc"] = sfc, 78 | Rcpp::_["property_cols"] = int_property_cols, 79 | Rcpp::_["geometry_idx"] = geometry_idx, 80 | Rcpp::_["id_column"] = int_polygon_id 81 | ); 82 | 83 | return res; 84 | } 85 | 86 | inline SEXP sf_polygon( 87 | SEXP& x, 88 | SEXP& geometry_cols, 89 | SEXP& polygon_id, 90 | SEXP& linestring_id, 91 | bool close, 92 | bool closed_attribute 93 | ) { 94 | std::string xyzm; 95 | return sf_polygon( x, geometry_cols, polygon_id, linestring_id, xyzm, close, closed_attribute ); 96 | } 97 | 98 | inline SEXP sf_polygon( 99 | SEXP& x, 100 | SEXP& geometry_cols, 101 | SEXP& polygon_id, 102 | SEXP& linestring_id, 103 | bool keep, 104 | bool close, 105 | bool closed_attribute 106 | ) { 107 | std::string xyzm; 108 | return sf_polygon( x, geometry_cols, polygon_id, linestring_id, xyzm, keep, close, closed_attribute ); 109 | } 110 | 111 | } // sf 112 | } // sfheaders 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/bbox.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_BBOX_H 2 | #define R_SFHEADERS_BBOX_H 3 | 4 | #include 5 | #include "geometries/utils/utils.hpp" 6 | 7 | namespace sfheaders { 8 | namespace bbox { 9 | 10 | inline void attach_bbox_attributes( Rcpp::NumericVector& bbox ) { 11 | bbox.attr("class") = Rcpp::CharacterVector::create("bbox"); 12 | bbox.attr("names") = Rcpp::CharacterVector::create("xmin", "ymin", "xmax", "ymax"); 13 | } 14 | 15 | inline Rcpp::NumericVector start_bbox() { 16 | Rcpp::NumericVector bbox(4); // xmin, ymin, xmax, ymax 17 | bbox(0) = bbox(1) = bbox(2) = bbox(3) = NA_REAL; 18 | return bbox; 19 | } 20 | 21 | // inline void get_bbox( 22 | // Rcpp::NumericVector& bbox, 23 | // SEXP sfg 24 | // ) { 25 | // // iff it's a list, recurse 26 | // if( Rf_isNewList( sfg ) ) { 27 | // // round we go 28 | // Rcpp::List lst = Rcpp::as< Rcpp::List >( sfg ); 29 | // R_xlen_t i; 30 | // for( i = 0; i < lst.size(); ++i ) { 31 | // SEXP s = lst[ i ]; 32 | // get_bbox( bbox, s ); 33 | // } 34 | // 35 | // } else { 36 | // calculate_bbox( bbox, sfg ); 37 | // } 38 | // } 39 | // 40 | // // issue 59 41 | // // get_bbox for sfc (sfg) objects 42 | // inline void get_bbox( 43 | // Rcpp::NumericVector& bbox, 44 | // Rcpp::List& sfc 45 | // ) { 46 | // // iterate over the sfc and re-calculate the bounding box 47 | // //Rcpp::NumericVector bbox = start_bbox(); 48 | // R_xlen_t i; 49 | // R_xlen_t n_sfgs = sfc.size(); 50 | // for( i = 0; i < n_sfgs; ++i ) { 51 | // SEXP sfg = sfc[ i ]; 52 | // get_bbox( bbox, sfg ); 53 | // } 54 | // attach_bbox_attributes( bbox ); 55 | // //return bbox; 56 | // } 57 | 58 | 59 | } // bbox 60 | } // sfheaders 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/linestring/sfc_linestring.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_LINESTRING_H 2 | #define R_SFHEADERS_SFC_LINESTRING_H 3 | 4 | #include 5 | #include "sfheaders/sfc/sfc_attributes.hpp" 6 | #include "sfheaders/sfc/sfc_types.hpp" 7 | #include "sfheaders/sfc/zm_range.hpp" 8 | 9 | #include "sfheaders/utils/utils.hpp" 10 | 11 | #include "geometries/bbox/bbox.hpp" 12 | #include "geometries/utils/columns/columns.hpp" 13 | #include "geometries/geometries.hpp" 14 | 15 | namespace sfheaders { 16 | namespace sfc { 17 | 18 | inline SEXP sfc_linestring( 19 | SEXP& x, 20 | SEXP& geometry_cols, 21 | SEXP& linestring_id, 22 | std::string xyzm 23 | ) { 24 | 25 | if( Rf_isNull( geometry_cols ) ) { 26 | // make this all the other columns, then send back in 27 | SEXP geometry_cols2 = geometries::utils::other_columns( x, linestring_id ); 28 | return sfc_linestring( x, geometry_cols2, linestring_id, xyzm ); 29 | } 30 | 31 | int n_id_cols = 1; 32 | R_xlen_t col_counter = geometries::utils::sexp_length( geometry_cols ); 33 | 34 | // After subset_geometries we have moved the geometry columns 35 | // into the 0:(n_geometry-1) positions 36 | Rcpp::IntegerVector int_geometry_cols = Rcpp::seq( 0, ( col_counter - 1 ) ); 37 | 38 | xyzm = sfheaders::utils::validate_xyzm( xyzm, col_counter ); 39 | 40 | Rcpp::StringVector class_attribute = { xyzm.c_str(), "LINESTRING","sfg" }; 41 | Rcpp::List attributes = Rcpp::List::create( 42 | Rcpp::_["class"] = class_attribute 43 | ); 44 | 45 | Rcpp::NumericVector bbox = sfheaders::bbox::start_bbox(); 46 | Rcpp::NumericVector z_range = sfheaders::zm::start_z_range(); 47 | Rcpp::NumericVector m_range = sfheaders::zm::start_m_range(); 48 | geometries::bbox::calculate_bbox( bbox, x, geometry_cols ); 49 | sfheaders::zm::calculate_zm_ranges( z_range, m_range, x, geometry_cols, xyzm ); 50 | 51 | R_xlen_t required_cols = col_counter + n_id_cols; 52 | 53 | Rcpp::IntegerVector geometry_cols_int = geometries::utils::sexp_col_int( x, geometry_cols ); 54 | 55 | Rcpp::List lst = geometries::utils::as_list( x ); 56 | Rcpp::List res( required_cols ); 57 | 58 | sfheaders::utils::subset_geometries( lst, res, geometry_cols_int ); 59 | 60 | Rcpp::IntegerVector int_linestring_id(1); 61 | sfheaders::utils::resolve_id( x, linestring_id, int_linestring_id, res, lst, col_counter ); 62 | 63 | Rcpp::List sfc = geometries::make_geometries( res, int_linestring_id, int_geometry_cols, attributes ); 64 | return sfheaders::sfc::make_sfc( sfc, sfheaders::sfc::SFC_LINESTRING, bbox, z_range, m_range ); 65 | } 66 | 67 | inline SEXP sfc_linestring( 68 | SEXP& x 69 | ) { 70 | SEXP geometry_cols = R_NilValue; 71 | SEXP linestring_id = R_NilValue; 72 | std::string xyzm; 73 | return sfc_linestring( x, geometry_cols, linestring_id, xyzm ); 74 | } 75 | 76 | } // sfc 77 | } // sfheaders 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/linestring/sfc_linestrings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_LINESTRINGS_H 2 | #define R_SFHEADERS_SFC_LINESTRINGS_H 3 | 4 | #include 5 | #include "sfheaders/sfc/linestring/sfc_linestring.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfc { 9 | 10 | inline Rcpp::List sfc_linestrings( Rcpp::List& lst, std::string xyzm ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | SEXP linestring_id = R_NilValue; 17 | 18 | for( i = 0; i < n; ++i ) { 19 | SEXP x = lst[i]; 20 | sfcs[i] = sfheaders::sfc::sfc_linestring( x, geometry_cols, linestring_id, xyzm ); 21 | } 22 | return sfcs; 23 | } 24 | 25 | } // sfc 26 | } // sfheaders 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/multilinestring/sfc_multilinestring.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_MULTILINESTRING_H 2 | #define R_SFHEADERS_SFC_MULTILINESTRING_H 3 | 4 | #include 5 | #include "sfheaders/sfc/sfc_attributes.hpp" 6 | #include "sfheaders/sfc/sfc_types.hpp" 7 | #include "sfheaders/sfc/zm_range.hpp" 8 | 9 | #include "sfheaders/utils/utils.hpp" 10 | 11 | #include "geometries/bbox/bbox.hpp" 12 | #include "geometries/utils/columns/columns.hpp" 13 | #include "geometries/geometries.hpp" 14 | #include "geometries/utils/lists/as_list.hpp" 15 | 16 | namespace sfheaders { 17 | namespace sfc { 18 | 19 | inline SEXP sfc_multilinestring( 20 | SEXP& x, 21 | SEXP& geometry_cols, 22 | SEXP& multilinestring_id, 23 | SEXP& linestring_id, 24 | std::string xyzm 25 | ) { 26 | 27 | if( Rf_isNull( geometry_cols ) ) { 28 | // make this all the other columns, then send back in 29 | SEXP geometry_cols2 = geometries::utils::other_columns( x, multilinestring_id, linestring_id ); 30 | return sfc_multilinestring( x, geometry_cols2, multilinestring_id, linestring_id, xyzm ); 31 | } 32 | 33 | int n_id_cols = 2; 34 | R_xlen_t col_counter = geometries::utils::sexp_length( geometry_cols ); 35 | 36 | // After subset_geometries we have moved the geometry columns 37 | // into the 0:(n_geometry-1) positions 38 | Rcpp::IntegerVector int_geometry_cols = Rcpp::seq( 0, ( col_counter - 1 ) ); 39 | 40 | xyzm = sfheaders::utils::validate_xyzm( xyzm, col_counter ); 41 | 42 | Rcpp::StringVector class_attribute = { xyzm.c_str(), "MULTILINESTRING","sfg" }; 43 | Rcpp::List attributes = Rcpp::List::create( 44 | Rcpp::_["class"] = class_attribute 45 | ); 46 | 47 | 48 | Rcpp::NumericVector bbox = sfheaders::bbox::start_bbox(); 49 | Rcpp::NumericVector z_range = sfheaders::zm::start_z_range(); 50 | Rcpp::NumericVector m_range = sfheaders::zm::start_m_range(); 51 | geometries::bbox::calculate_bbox( bbox, x, geometry_cols ); 52 | sfheaders::zm::calculate_zm_ranges( z_range, m_range, x, geometry_cols, xyzm ); 53 | 54 | R_xlen_t required_cols = col_counter + n_id_cols; 55 | 56 | Rcpp::IntegerVector geometry_cols_int = geometries::utils::sexp_col_int( x, geometry_cols ); 57 | 58 | 59 | Rcpp::List lst = geometries::utils::as_list( x ); 60 | Rcpp::List res( required_cols ); 61 | 62 | sfheaders::utils::subset_geometries( lst, res, geometry_cols_int ); 63 | 64 | Rcpp::IntegerVector int_multilinestring_id(1); 65 | sfheaders::utils::resolve_id( x, multilinestring_id, int_multilinestring_id, res, lst, col_counter ); 66 | 67 | Rcpp::IntegerVector int_linestring_id(1); 68 | sfheaders::utils::resolve_id( x, linestring_id, int_linestring_id, res, lst, col_counter ); 69 | 70 | Rcpp::IntegerVector int_id_cols = geometries::utils::concatenate_vectors( int_multilinestring_id, int_linestring_id ); 71 | 72 | Rcpp::List sfc = geometries::make_geometries( res, int_id_cols, int_geometry_cols, attributes ); 73 | return sfheaders::sfc::make_sfc( sfc, sfheaders::sfc::SFC_MULTILINESTRING, bbox, z_range, m_range ); 74 | 75 | } 76 | 77 | inline SEXP sfc_multilinestring( 78 | SEXP& x 79 | ) { 80 | SEXP geometry_cols = R_NilValue; 81 | SEXP multilinestring_id = R_NilValue; 82 | SEXP linestring_id = R_NilValue; 83 | std::string xyzm; 84 | return sfc_multilinestring( x, geometry_cols, multilinestring_id, linestring_id, xyzm ); 85 | } 86 | 87 | } // sfc 88 | } // sfheaders 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/multilinestring/sfc_multilinestrings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_MULTILINESTRINGS_H 2 | #define R_SFHEADERS_SFC_MULTILINESTRINGS_H 3 | 4 | #include 5 | #include "sfheaders/sfc/multilinestring/sfc_multilinestring.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfc { 9 | 10 | inline Rcpp::List sfc_multilinestrings( Rcpp::List& lst, std::string xyzm ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | SEXP multilinestring_id = R_NilValue; 17 | SEXP linestring_id = R_NilValue; 18 | 19 | for( i = 0; i < n; ++i ) { 20 | SEXP x = lst[i]; 21 | sfcs[i] = sfheaders::sfc::sfc_multilinestring( x, geometry_cols, multilinestring_id, linestring_id, xyzm ); 22 | } 23 | return sfcs; 24 | } 25 | 26 | } // sfc 27 | } // sfheaders 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/multipoint/sfc_multipoint.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_MULTIPOINT_H 2 | #define R_SFHEADERS_SFC_MULTIPOINT_H 3 | 4 | #include 5 | #include "sfheaders/sfc/sfc_attributes.hpp" 6 | #include "sfheaders/sfc/sfc_types.hpp" 7 | #include "sfheaders/sfc/zm_range.hpp" 8 | 9 | #include "sfheaders/utils/utils.hpp" 10 | 11 | #include "geometries/bbox/bbox.hpp" 12 | #include "geometries/utils/columns/columns.hpp" 13 | #include "geometries/geometries.hpp" 14 | 15 | namespace sfheaders { 16 | namespace sfc { 17 | 18 | inline SEXP sfc_multipoint( 19 | SEXP& x, 20 | SEXP& geometry_cols, 21 | SEXP& multipoint_id, 22 | std::string xyzm 23 | ) { 24 | 25 | if( Rf_isNull( geometry_cols ) ) { 26 | // make this all the other columns, then send back in 27 | SEXP geometry_cols2 = geometries::utils::other_columns( x, multipoint_id ); 28 | return sfc_multipoint( x, geometry_cols2, multipoint_id, xyzm ); 29 | } 30 | 31 | int n_id_cols = 1; 32 | R_xlen_t col_counter = geometries::utils::sexp_length( geometry_cols ); 33 | 34 | // After subset_geometries we have moved the geometry columns 35 | // into the 0:(n_geometry-1) positions 36 | Rcpp::IntegerVector int_geometry_cols = Rcpp::seq( 0, ( col_counter - 1 ) ); 37 | 38 | xyzm = sfheaders::utils::validate_xyzm( xyzm, col_counter ); 39 | 40 | Rcpp::StringVector class_attribute = { xyzm.c_str(), "MULTIPOINT","sfg" }; 41 | Rcpp::List attributes = Rcpp::List::create( 42 | Rcpp::_["class"] = class_attribute 43 | ); 44 | 45 | 46 | Rcpp::NumericVector bbox = sfheaders::bbox::start_bbox(); 47 | Rcpp::NumericVector z_range = sfheaders::zm::start_z_range(); 48 | Rcpp::NumericVector m_range = sfheaders::zm::start_m_range(); 49 | geometries::bbox::calculate_bbox( bbox, x, geometry_cols ); 50 | 51 | sfheaders::zm::calculate_zm_ranges( z_range, m_range, x, geometry_cols, xyzm ); 52 | 53 | R_xlen_t required_cols = col_counter + n_id_cols; 54 | 55 | Rcpp::IntegerVector geometry_cols_int = geometries::utils::sexp_col_int( x, geometry_cols ); 56 | 57 | Rcpp::List lst = geometries::utils::as_list( x ); 58 | Rcpp::List res( required_cols ); 59 | 60 | sfheaders::utils::subset_geometries( lst, res, geometry_cols_int ); 61 | 62 | Rcpp::IntegerVector int_multipoint_id(1); 63 | 64 | sfheaders::utils::resolve_id( x, multipoint_id, int_multipoint_id, res, lst, col_counter ); 65 | 66 | Rcpp::List sfc = geometries::make_geometries( res, int_multipoint_id, int_geometry_cols, attributes ); 67 | return sfheaders::sfc::make_sfc( sfc, sfheaders::sfc::SFC_MULTIPOINT, bbox, z_range, m_range ); 68 | 69 | } 70 | 71 | inline SEXP sfc_multipoint( 72 | SEXP& x 73 | ) { 74 | SEXP geometry_cols = R_NilValue; 75 | SEXP multipoint_id = R_NilValue; 76 | std::string xyzm; 77 | return sfc_multipoint( x, geometry_cols, multipoint_id, xyzm ); 78 | } 79 | 80 | } // sfc 81 | } // sfheaders 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/multipoint/sfc_multipoints.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_MULTIPOINTS_H 2 | #define R_SFHEADERS_SFC_MULTIPOINTS_H 3 | 4 | #include 5 | #include "sfheaders/sfc/multipoint/sfc_multipoint.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfc { 9 | 10 | inline Rcpp::List sfc_multipoints( Rcpp::List& lst, std::string xyzm ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | SEXP multipoint_id = R_NilValue; 17 | 18 | for( i = 0; i < n; ++i ) { 19 | SEXP x = lst[i]; 20 | sfcs[i] = sfheaders::sfc::sfc_multipoint( x, geometry_cols, multipoint_id, xyzm ); 21 | } 22 | return sfcs; 23 | } 24 | 25 | } // sfc 26 | } // sfheaders 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/multipolygon/sfc_multipolygon.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_MULTIPOLYGON_H 2 | #define R_SFHEADERS_SFC_MULTIPOLYGON_H 3 | 4 | #include 5 | #include "sfheaders/sfc/sfc_attributes.hpp" 6 | #include "sfheaders/sfc/sfc_types.hpp" 7 | #include "sfheaders/sfc/zm_range.hpp" 8 | 9 | #include "sfheaders/utils/utils.hpp" 10 | 11 | #include "geometries/bbox/bbox.hpp" 12 | #include "geometries/utils/columns/columns.hpp" 13 | #include "geometries/geometries.hpp" 14 | 15 | namespace sfheaders { 16 | namespace sfc { 17 | 18 | inline SEXP sfc_multipolygon( 19 | SEXP& x, 20 | SEXP& geometry_cols, 21 | SEXP& multipolygon_id, 22 | SEXP& polygon_id, 23 | SEXP& linestring_id, 24 | std::string xyzm, 25 | bool close = true, 26 | bool closed_attribute = false 27 | ) { 28 | 29 | if( Rf_isNull( geometry_cols ) ) { 30 | // make this all the other columns, then send back in 31 | SEXP geometry_cols2 = geometries::utils::other_columns( x, multipolygon_id, polygon_id, linestring_id ); 32 | return sfc_multipolygon( x, geometry_cols2, multipolygon_id, polygon_id, linestring_id, xyzm, close ); 33 | } 34 | 35 | 36 | int n_id_cols = 3; 37 | R_xlen_t col_counter = geometries::utils::sexp_length( geometry_cols ); 38 | 39 | // After subset_geometries we have moved the geometry columns 40 | // into the 0:(n_geometry-1) positions 41 | Rcpp::IntegerVector int_geometry_cols = Rcpp::seq( 0, ( col_counter - 1 ) ); 42 | 43 | xyzm = sfheaders::utils::validate_xyzm( xyzm, col_counter ); 44 | 45 | Rcpp::StringVector class_attribute = { xyzm.c_str(), "MULTIPOLYGON","sfg" }; 46 | Rcpp::List attributes = Rcpp::List::create( 47 | Rcpp::_["class"] = class_attribute 48 | ); 49 | 50 | Rcpp::NumericVector bbox = sfheaders::bbox::start_bbox(); 51 | Rcpp::NumericVector z_range = sfheaders::zm::start_z_range(); 52 | Rcpp::NumericVector m_range = sfheaders::zm::start_m_range(); 53 | 54 | geometries::bbox::calculate_bbox( bbox, x, geometry_cols ); 55 | sfheaders::zm::calculate_zm_ranges( z_range, m_range, x, geometry_cols, xyzm ); 56 | 57 | R_xlen_t required_cols = col_counter + n_id_cols; 58 | 59 | Rcpp::IntegerVector geometry_cols_int = geometries::utils::sexp_col_int( x, geometry_cols ); 60 | 61 | Rcpp::List lst = geometries::utils::as_list( x ); 62 | Rcpp::List res( required_cols ); 63 | 64 | sfheaders::utils::subset_geometries( lst, res, geometry_cols_int ); 65 | 66 | Rcpp::IntegerVector int_multipolygon_id(1); 67 | sfheaders::utils::resolve_id( x, multipolygon_id, int_multipolygon_id, res, lst, col_counter ); 68 | 69 | Rcpp::IntegerVector int_polygon_id(1); 70 | sfheaders::utils::resolve_id( x, polygon_id, int_polygon_id, res, lst, col_counter ); 71 | 72 | Rcpp::IntegerVector int_linestring_id(1); 73 | sfheaders::utils::resolve_id( x, linestring_id, int_linestring_id, res, lst, col_counter ); 74 | 75 | Rcpp::IntegerVector int_id_cols = geometries::utils::concatenate_vectors( int_multipolygon_id, int_polygon_id ); 76 | int_id_cols = geometries::utils::concatenate_vectors( int_id_cols, int_linestring_id ); 77 | 78 | Rcpp::List sfc = geometries::make_geometries( res, int_id_cols, int_geometry_cols, attributes, close, closed_attribute ); 79 | return sfheaders::sfc::make_sfc( sfc, sfheaders::sfc::SFC_MULTIPOLYGON, bbox, z_range, m_range ); 80 | 81 | } 82 | 83 | inline SEXP sfc_multipolygon( 84 | SEXP& x 85 | ) { 86 | SEXP geometry_cols = R_NilValue; 87 | SEXP multipolygon_id = R_NilValue; 88 | SEXP polygon_id = R_NilValue; 89 | SEXP linestring_id = R_NilValue; 90 | std::string xyzm; 91 | return sfc_multipolygon( x, geometry_cols, multipolygon_id, polygon_id, linestring_id, xyzm ); 92 | } 93 | 94 | } // sfc 95 | } // sfheaders 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/multipolygon/sfc_multipolygons.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_MULTIPOLYGONS_H 2 | #define R_SFHEADERS_SFC_MULTIPOLYGONS_H 3 | 4 | #include 5 | #include "sfheaders/sfc/multipolygon/sfc_multipolygon.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfc { 9 | 10 | inline Rcpp::List sfc_multipolygons( Rcpp::List& lst, std::string xyzm, bool close = true ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | SEXP multipolygon_id = R_NilValue; 17 | SEXP polygon_id = R_NilValue; 18 | SEXP linestring_id = R_NilValue; 19 | 20 | for( i = 0; i < n; ++i ) { 21 | SEXP x = lst[i]; 22 | sfcs[i] = sfheaders::sfc::sfc_multipolygon( x, geometry_cols, multipolygon_id, polygon_id, linestring_id, xyzm, close ); 23 | } 24 | return sfcs; 25 | } 26 | 27 | } // sfc 28 | } // sfheaders 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/point/sfc_point.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_POINT_H 2 | #define R_SFHEADERS_SFC_POINT_H 3 | 4 | #include 5 | #include "sfheaders/sfc/sfc_attributes.hpp" 6 | #include "sfheaders/sfc/sfc_types.hpp" 7 | #include "sfheaders/sfc/zm_range.hpp" 8 | 9 | #include "sfheaders/utils/utils.hpp" 10 | 11 | #include "geometries/bbox/bbox.hpp" 12 | #include "geometries/utils/columns/columns.hpp" 13 | #include "geometries/geometries.hpp" 14 | 15 | namespace sfheaders { 16 | namespace sfc { 17 | 18 | inline SEXP sfc_point( 19 | SEXP& x, 20 | SEXP& geometry_cols, 21 | std::string xyzm 22 | ) { 23 | 24 | if( Rf_isNull( geometry_cols ) ) { 25 | // make this all the other columns, then send back in 26 | SEXP geometry_cols2 = geometries::utils::other_columns( x ); 27 | return sfc_point( x, geometry_cols2, xyzm ); 28 | } 29 | 30 | int n_empty = 0; // can have empty POINT objects 31 | int n_id_cols = 0; 32 | R_xlen_t col_counter = geometries::utils::sexp_length( geometry_cols ); 33 | 34 | // After subset_geometries we have moved the geometry columns 35 | // into the 0:(n_geometry-1) positions 36 | xyzm = sfheaders::utils::validate_xyzm( xyzm, col_counter ); 37 | 38 | Rcpp::StringVector class_attribute = { xyzm.c_str(), "POINT","sfg" }; 39 | Rcpp::List attributes = Rcpp::List::create( 40 | Rcpp::_["class"] = class_attribute 41 | ); 42 | 43 | 44 | Rcpp::NumericVector bbox = sfheaders::bbox::start_bbox(); 45 | Rcpp::NumericVector z_range = sfheaders::zm::start_z_range(); 46 | Rcpp::NumericVector m_range = sfheaders::zm::start_m_range(); 47 | geometries::bbox::calculate_bbox( bbox, x, geometry_cols ); 48 | sfheaders::zm::calculate_zm_ranges( z_range, m_range, x, geometry_cols, xyzm ); 49 | 50 | R_xlen_t required_cols = col_counter + n_id_cols; 51 | 52 | Rcpp::IntegerVector geometry_cols_int = geometries::utils::sexp_col_int( x, geometry_cols ); 53 | 54 | Rcpp::List lst = geometries::utils::as_list( x ); 55 | Rcpp::List res( required_cols ); 56 | 57 | sfheaders::utils::subset_geometries( lst, res, geometry_cols_int ); 58 | 59 | // POINTs need to be done slightly differnetly 60 | // because they can be NULLL 61 | // 62 | // return lst; 63 | 64 | Rcpp::List sfc = geometries::make_geometries( res, attributes, n_empty ); 65 | 66 | return sfheaders::sfc::make_sfc( sfc, sfheaders::sfc::SFC_POINT, bbox, z_range, m_range, n_empty ); 67 | 68 | } 69 | 70 | inline SEXP sfc_point( 71 | SEXP& x 72 | ) { 73 | SEXP geometry_cols = R_NilValue; 74 | std::string xyzm; 75 | return sfc_point( x, geometry_cols, xyzm ); 76 | } 77 | 78 | 79 | } // sfc 80 | } // sfheaders 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/point/sfc_points.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_POINTS_H 2 | #define R_SFHEADERS_SFC_POINTS_H 3 | 4 | #include 5 | #include "sfheaders/sfc/point/sfc_point.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfc { 9 | 10 | inline Rcpp::List sfc_points( Rcpp::List& lst, std::string xyzm ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs( n ); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | 17 | for( i = 0; i < n; ++i ) { 18 | SEXP x = lst[i]; 19 | sfcs[i] = sfheaders::sfc::sfc_point( x, geometry_cols, xyzm ); 20 | } 21 | return sfcs; 22 | } 23 | 24 | } // sfc 25 | } // sfheaders 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/polygon/sfc_polygon.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_POLYGON_H 2 | #define R_SFHEADERS_SFC_POLYGON_H 3 | 4 | #include 5 | #include "sfheaders/sfc/sfc_attributes.hpp" 6 | #include "sfheaders/sfc/sfc_types.hpp" 7 | #include "sfheaders/sfc/zm_range.hpp" 8 | 9 | #include "sfheaders/utils/utils.hpp" 10 | 11 | #include "geometries/bbox/bbox.hpp" 12 | #include "geometries/utils/columns/columns.hpp" 13 | #include "geometries/geometries.hpp" 14 | 15 | namespace sfheaders { 16 | namespace sfc { 17 | 18 | inline SEXP sfc_polygon( 19 | SEXP& x, 20 | SEXP& geometry_cols, 21 | SEXP& polygon_id, 22 | SEXP& linestring_id, 23 | std::string xyzm, 24 | bool close = true, 25 | bool closed_attribute = false 26 | ) { 27 | 28 | 29 | if( Rf_isNull( geometry_cols ) ) { 30 | // make this all the other columns, then send back in 31 | SEXP geometry_cols2 = geometries::utils::other_columns( x, polygon_id, linestring_id ); 32 | return sfc_polygon( x, geometry_cols2, polygon_id, linestring_id, xyzm, close ); 33 | } 34 | 35 | int n_id_cols = 2; 36 | R_xlen_t col_counter = geometries::utils::sexp_length( geometry_cols ); 37 | 38 | // After subset_geometries we have moved the geometry columns 39 | // into the 0:(n_geometry-1) positions 40 | Rcpp::IntegerVector int_geometry_cols = Rcpp::seq( 0, ( col_counter - 1 ) ); 41 | 42 | xyzm = sfheaders::utils::validate_xyzm( xyzm, col_counter ); 43 | 44 | Rcpp::StringVector class_attribute = { xyzm.c_str(), "POLYGON","sfg" }; 45 | Rcpp::List attributes = Rcpp::List::create( 46 | Rcpp::_["class"] = class_attribute 47 | ); 48 | 49 | Rcpp::NumericVector bbox = sfheaders::bbox::start_bbox(); 50 | Rcpp::NumericVector z_range = sfheaders::zm::start_z_range(); 51 | Rcpp::NumericVector m_range = sfheaders::zm::start_m_range(); 52 | 53 | geometries::bbox::calculate_bbox( bbox, x, geometry_cols ); 54 | 55 | sfheaders::zm::calculate_zm_ranges( z_range, m_range, x, geometry_cols, xyzm ); 56 | 57 | R_xlen_t required_cols = col_counter + n_id_cols; 58 | 59 | Rcpp::IntegerVector geometry_cols_int = geometries::utils::sexp_col_int( x, geometry_cols ); 60 | 61 | Rcpp::List lst = geometries::utils::as_list( x ); 62 | Rcpp::List res( required_cols ); 63 | 64 | sfheaders::utils::subset_geometries( lst, res, geometry_cols_int ); 65 | 66 | Rcpp::IntegerVector int_polygon_id(1); 67 | sfheaders::utils::resolve_id( x, polygon_id, int_polygon_id, res, lst, col_counter ); 68 | 69 | 70 | Rcpp::IntegerVector int_linestring_id(1); 71 | sfheaders::utils::resolve_id( x, linestring_id, int_linestring_id, res, lst, col_counter ); 72 | 73 | Rcpp::IntegerVector int_id_cols = geometries::utils::concatenate_vectors( int_polygon_id, int_linestring_id ); 74 | 75 | // TODO: 76 | // iff close == TRUE && sf_polygon() list_columns != NULL 77 | // we need to know IFF any matrix will be closed 78 | // so we need to konw where each matrix starts and ends 79 | // and test closure 80 | // This can only really happen inside geometries::split_by_id 81 | // becaues here is where we close the matrix 82 | // 83 | // Here I can attach an 'has_been_closed attribute to each matrix (ring) 84 | // then just extract those as a vector, right? 85 | // so those which 'have-been-closed' need an extra element on their list columns 86 | 87 | Rcpp::List sfc = geometries::make_geometries( res, int_id_cols, int_geometry_cols, attributes, close, closed_attribute ); 88 | 89 | return sfheaders::sfc::make_sfc( sfc, sfheaders::sfc::SFC_POLYGON, bbox, z_range, m_range ); 90 | 91 | } 92 | 93 | inline SEXP sfc_polygon( 94 | SEXP& x 95 | ) { 96 | SEXP geometry_cols = R_NilValue; 97 | SEXP polygon_id = R_NilValue; 98 | SEXP linestring_id = R_NilValue; 99 | std::string xyzm; 100 | return sfc_polygon( x, geometry_cols, polygon_id, linestring_id, xyzm ); 101 | } 102 | 103 | } // sfc 104 | } // sfheaders 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/polygon/sfc_polygons.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_POLYGONS_H 2 | #define R_SFHEADERS_SFC_POLYGONS_H 3 | 4 | #include 5 | #include "sfheaders/sfc/polygon/sfc_polygon.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfc { 9 | 10 | 11 | inline Rcpp::List sfc_polygons( Rcpp::List& lst, std::string xyzm, bool close = true ) { 12 | R_xlen_t n = lst.size(); 13 | R_xlen_t i; 14 | Rcpp::List sfcs(n); 15 | 16 | SEXP geometry_cols = R_NilValue; 17 | SEXP polygon_id = R_NilValue; 18 | SEXP linestring_id = R_NilValue; 19 | 20 | for( i = 0; i < n; ++i ) { 21 | SEXP x = lst[i]; 22 | sfcs[i] = sfheaders::sfc::sfc_polygon( x, geometry_cols, polygon_id, linestring_id, xyzm, close ); 23 | } 24 | return sfcs; 25 | } 26 | 27 | } // sfc 28 | } // sfheaders 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/sfc.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_H 2 | #define R_SFHEADERS_SFC_H 3 | 4 | #include 5 | #include "sfheaders/sfc/point/sfc_point.hpp" 6 | #include "sfheaders/sfc/point/sfc_points.hpp" 7 | #include "sfheaders/sfc/multipoint/sfc_multipoint.hpp" 8 | #include "sfheaders/sfc/multipoint/sfc_multipoints.hpp" 9 | #include "sfheaders/sfc/linestring/sfc_linestring.hpp" 10 | #include "sfheaders/sfc/linestring/sfc_linestrings.hpp" 11 | #include "sfheaders/sfc/multilinestring/sfc_multilinestring.hpp" 12 | #include "sfheaders/sfc/multilinestring/sfc_multilinestrings.hpp" 13 | #include "sfheaders/sfc/polygon/sfc_polygon.hpp" 14 | #include "sfheaders/sfc/polygon/sfc_polygons.hpp" 15 | #include "sfheaders/sfc/multipolygon/sfc_multipolygon.hpp" 16 | #include "sfheaders/sfc/multipolygon/sfc_multipolygons.hpp" 17 | 18 | // #include "sfheaders/sfc/sfc_types.hpp" 19 | // #include "geometries/bbox/bbox.hpp" 20 | // #include "sfheaders/sfc/zm_range.hpp" 21 | 22 | namespace sfheaders { 23 | namespace sfc { 24 | 25 | // // inline SEXP to_sfc( SEXP& x, Rcpp::List params ) { 26 | // // 27 | // // if( params.containsElementNamed("multipolygon_id") ) { 28 | // // if( !params.containsElementNamed("polygon_id") || !params.containsElementNamed("line_id") ) { 29 | // // Rcpp::stop("MULTIPOLYGONs require polygon_id and line_id arguments" ); 30 | // // // return to_multipolygon( ) ; 31 | // // } 32 | // // } 33 | // // 34 | // // if( params.containsElementNamed("point_id") ) { 35 | // // SEXP point_id = params["point_id"]; 36 | // // // can be a char giving column of data.frame, or numeric / int for column of matrix 37 | // // switch( TYPEOF( point_id ) ) { 38 | // // case INTSXP: {} 39 | // // case REALSXP: { 40 | // // // the parameters should be column indices, so int should be fine? 41 | // // Rcpp::IntegerVector pt_id = Rcpp::as< Rcpp::IntegerVector >( point_id ); 42 | // // // if the point_id column has been supplied, 43 | // // // we need to loop on those values and create sfc objects 44 | // // // because sfg is a single object, not a collection? 45 | // // 46 | // // //return sfheaders::sfg::sfc_multipoint( x, pt_id ); 47 | // // } 48 | // // } 49 | // // } 50 | // // 51 | // // return Rcpp::List::create(); // never reaches 52 | // // } 53 | // 54 | // 55 | // inline SEXP to_sfc( SEXP& x, std::string geom_type, std::string xyzm ) { 56 | // if( geom_type == "POINT" ) { 57 | // return sfheaders::sfc::sfc_point( x, xyzm ); 58 | // } else if ( geom_type == "MULTIPOINT" ) { 59 | // return sfheaders::sfc::sfc_multipoint( x, xyzm ); 60 | // } else if ( geom_type == "LINESTRING" ) { 61 | // return sfheaders::sfc::sfc_linestring( x, xyzm ); 62 | // } else if ( geom_type == "MULTIILNESTRING" ) { 63 | // return sfheaders::sfc::sfc_multilinestring( x, xyzm ); 64 | // } else if ( geom_type == "POLYGON" ) { 65 | // return sfheaders::sfc::sfc_polygon( x, xyzm ); 66 | // } else if ( geom_type == "MULTIPOLYGON" ) { 67 | // return sfheaders::sfc::sfc_multipolygon( x, xyzm ); 68 | // } 69 | // 70 | // Rcpp::stop("sfheaders - unknown sfc geometry type"); 71 | // return Rcpp::List::create(); 72 | // } 73 | // 74 | // inline SEXP to_sfc( SEXP& x, std::string geom_type, SEXP geometry_columns, std::string xyzm ) { 75 | // if( geom_type == "POINT" ) { 76 | // return sfheaders::sfc::sfc_point( x, geometry_columns, xyzm ); 77 | // } else if ( geom_type == "MULTIPOINT" ) { 78 | // return sfheaders::sfc::sfc_multipoint( x, geometry_columns, xyzm ); 79 | // } else if ( geom_type == "LINESTRING" ) { 80 | // return sfheaders::sfc::sfc_linestring( x, geometry_columns, xyzm ); 81 | // } else if ( geom_type == "MULTIILNESTRING" ) { 82 | // return sfheaders::sfc::sfc_multilinestring( x, geometry_columns, xyzm ); 83 | // } else if ( geom_type == "POLYGON" ) { 84 | // return sfheaders::sfc::sfc_polygon( x, geometry_columns, xyzm ); 85 | // } else if ( geom_type == "MULTIPOLYGON" ) { 86 | // return sfheaders::sfc::sfc_multipolygon( x, geometry_columns, xyzm ); 87 | // } 88 | // 89 | // Rcpp::stop("sfheaders - unknown sfc geometry type"); 90 | // return Rcpp::List::create(); // never reaches 91 | // } 92 | 93 | } // sfc 94 | } // sfheaders 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfc/sfc_types.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFC_TYPES_H 2 | #define R_SFHEADERS_SFC_TYPES_H 3 | 4 | #include 5 | 6 | #include "sfheaders/sfc/sfc_attributes.hpp" 7 | 8 | namespace sfheaders { 9 | namespace sfc { 10 | 11 | inline std::string get_sfc_type( int sfc_type ) { 12 | switch( sfc_type ) { 13 | case SFC_POINT: { return "POINT"; } 14 | case SFC_MULTIPOINT: { return "MULTIPOINT"; } 15 | case SFC_LINESTRING: { return "LINESTRING"; } 16 | case SFC_MULTILINESTRING: { return "MULTILINESTRING"; } 17 | case SFC_POLYGON: { return "POLYGON"; } 18 | case SFC_MULTIPOLYGON: { return "MULTIPOLYGON"; } 19 | default: { 20 | Rcpp::stop("sfheaders - unknown sfc type"); // #nocov 21 | } 22 | } 23 | return ""; // never reaches 24 | } 25 | 26 | inline SEXP make_sfc( 27 | Rcpp::List& sfc, 28 | int sfc_type, 29 | Rcpp::NumericVector& bbox, 30 | Rcpp::NumericVector& z_range, 31 | Rcpp::NumericVector& m_range, 32 | int n_empty = 0 33 | ) { 34 | 35 | std::string geom = get_sfc_type( sfc_type ); 36 | std::unordered_set< std::string > geometry_types{ geom }; 37 | 38 | Rcpp::String crs_input = NA_STRING; 39 | Rcpp::String crs_wkt = NA_STRING; 40 | 41 | Rcpp::List crs = Rcpp::List::create( 42 | Rcpp::_["input"] = crs_input, 43 | Rcpp::_["wkt"] = crs_wkt 44 | ); 45 | //int n_empty = 0; 46 | double precision = 0.0; 47 | 48 | return sfheaders::sfc::create_sfc( 49 | sfc, geom, geometry_types, bbox, z_range, m_range, crs, n_empty, precision 50 | ); 51 | } 52 | 53 | // inline SEXP make_sfc( 54 | // Rcpp::IntegerVector& im, 55 | // int sfc_type 56 | // ) { 57 | // 58 | // } 59 | // 60 | // inline SEXP make_sfc( 61 | // Rcpp::NumericVector& nm, 62 | // int sfc_type 63 | // ) { 64 | // 65 | // } 66 | // 67 | // inline SEXP make_sfc( 68 | // Rcpp::IntegerMatrix& im, 69 | // int sfc_type 70 | // ) { 71 | // 72 | // } 73 | // 74 | // inline SEXP make_sfc( 75 | // Rcpp::NumericMatrix& nm, 76 | // int sfc_type 77 | // ) { 78 | // 79 | // } 80 | 81 | 82 | inline SEXP make_sfc( 83 | SEXP& x, 84 | int sfc_type, 85 | Rcpp::NumericVector& bbox, 86 | Rcpp::NumericVector& z_range, 87 | Rcpp::NumericVector& m_range 88 | ) { 89 | 90 | // std::string geom = get_sfc_type( sfc_type ); 91 | // std::unordered_set< std::string > geometry_types{ geom }; 92 | // 93 | // Rcpp::String epsg = NA_STRING; 94 | // Rcpp::String proj4string = NA_STRING; 95 | // int n_empty = 0; 96 | // double precision = 0.0; 97 | 98 | switch( TYPEOF( x ) ) { 99 | // case INTSXP: { 100 | // if( Rf_isMatrix( x ) ) { 101 | // Rcpp::IntegerMatrix im = Rcpp::as< Rcpp::IntegerMatrix >( x ); 102 | // return make_sfc( im, sfc_type ); 103 | // } else { 104 | // Rcpp::IntegerVector iv = Rcpp::as< Rcpp::IntegerVector >( x ); 105 | // return make_sfc( iv, sfc_type ); 106 | // } 107 | // case REALSXP: { 108 | // if( Rf_isMatrix( x ) ) { 109 | // Rcpp::NumericMatrix nm = Rcpp::as< Rcpp::NumericMatrix >( x ); 110 | // return make_sfc( nm, sfc_type ); 111 | // } else { 112 | // Rcpp::NumericVector nv = Rcpp::as< Rcpp::NumericVector >( x ); 113 | // return make_sfc( nv, sfc_type ); 114 | // } 115 | // } 116 | case VECSXP: { 117 | Rcpp::List lst = Rcpp::as< Rcpp::List > ( x ); 118 | return make_sfc( lst, sfc_type, bbox, z_range, m_range ); 119 | } 120 | default: { 121 | Rcpp::stop("sfheaders - unexpected sfc type"); 122 | } 123 | } 124 | } 125 | 126 | 127 | } // sfg 128 | } // sfheaders 129 | 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/linestring/sfg_linestring.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_LINESTRING_H 2 | #define R_SFHEADERS_SFG_LINESTRING_H 3 | 4 | #include 5 | #include "sfheaders/sfg/sfg_types.hpp" 6 | #include "sfheaders/utils/utils.hpp" 7 | 8 | #include "geometries/utils/columns/columns.hpp" 9 | #include "geometries/geometries.hpp" 10 | #include "geometries/nest/nest.hpp" 11 | 12 | 13 | namespace sfheaders { 14 | namespace sfg { 15 | 16 | template< int RTYPE > 17 | inline SEXP sfg_linestring( 18 | Rcpp::Matrix< RTYPE >& mat, 19 | std::string xyzm 20 | ) { 21 | sfheaders::sfg::make_sfg( mat, sfheaders::sfg::SFG_LINESTRING, xyzm ); 22 | return mat; 23 | } 24 | 25 | template< int RTYPE > 26 | inline SEXP sfg_linestring( 27 | Rcpp::Vector< RTYPE >& vec, 28 | std::string xyzm 29 | ) { 30 | R_xlen_t n = vec.length(); 31 | Rcpp::Matrix< RTYPE > mat( 1, n ); 32 | mat( 0, Rcpp::_ ) = vec; 33 | return sfg_linestring( mat, xyzm ); 34 | } 35 | 36 | inline SEXP sfg_linestring( 37 | Rcpp::List& lst, 38 | std::string xyzm 39 | ) { 40 | sfheaders::sfg::make_sfg( lst, sfheaders::sfg::SFG_LINESTRING, xyzm ); 41 | return lst; 42 | } 43 | 44 | inline SEXP sfg_linestring( 45 | SEXP& x, 46 | SEXP& geometry_cols, 47 | std::string xyzm 48 | ) { 49 | SEXP geometry_mat = geometries::matrix::to_geometry_matrix( x, geometry_cols ); 50 | R_xlen_t n_col = geometries::utils::sexp_n_col( geometry_mat ); 51 | xyzm = sfheaders::utils::validate_xyzm( xyzm, n_col ); 52 | sfheaders::sfg::make_sfg( geometry_mat, n_col, sfheaders::sfg::SFG_LINESTRING, xyzm ); 53 | return geometry_mat; 54 | } 55 | 56 | inline SEXP sfg_linestring( 57 | SEXP& x, 58 | std::string xyzm 59 | ) { 60 | SEXP geometry_cols = R_NilValue; 61 | return sfg_linestring( x, geometry_cols, xyzm ); 62 | } 63 | 64 | inline SEXP sfg_linestring( 65 | SEXP& x 66 | ) { 67 | SEXP geometry_cols = R_NilValue; 68 | std::string xyzm; 69 | return sfg_linestring( x, geometry_cols, xyzm ); 70 | } 71 | 72 | } // sfg 73 | } // sfheaders 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/linestring/sfg_linestrings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_LINESTRINGS_H 2 | #define R_SFHEADERS_SFG_LINESTRINGS_H 3 | 4 | #include 5 | #include "sfheaders/sfg/linestring/sfg_linestring.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfg { 9 | 10 | inline Rcpp::List sfg_linestrings( Rcpp::List& lst, std::string xyzm ) { 11 | R_xlen_t n = lst.size(); 12 | 13 | R_xlen_t i; 14 | Rcpp::List sfcs(n); 15 | 16 | for( i = 0; i < n; ++i ) { 17 | Rcpp::NumericMatrix x = lst[i]; // linestrings are matrices 18 | sfcs[i] = sfheaders::sfg::sfg_linestring( x, xyzm ); 19 | } 20 | return sfcs; 21 | } 22 | 23 | // inline Rcpp::List sfg_linestrings( SEXP& obj, std::string xyzm ) { 24 | // Rcpp::List lst = Rcpp::as< Rcpp::List >( obj ); 25 | // return sfg_linestrings( lst, xyzm ); 26 | // } 27 | 28 | } // sfg 29 | } // sfheaders 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/multilinestring/sfg_multilinestring.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_MULTILINESTRING_H 2 | #define R_SFHEADERS_SFG_MULTILINESTRING_H 3 | 4 | #include 5 | #include "sfheaders/sfg/sfg_types.hpp" 6 | #include "sfheaders/utils/utils.hpp" 7 | 8 | #include "geometries/utils/utils.hpp" 9 | #include "geometries/geometries.hpp" 10 | 11 | namespace sfheaders { 12 | namespace sfg { 13 | 14 | template < int RTYPE > 15 | inline SEXP sfg_multilinestring( 16 | Rcpp::Matrix< RTYPE >& mat, 17 | std::string xyzm 18 | ) { 19 | Rcpp::List mls( 1 ); 20 | mls[0] = mat; 21 | R_xlen_t n_col = mat.ncol(); 22 | sfheaders::sfg::make_sfg( mls, n_col, sfheaders::sfg::SFG_MULTILINESTRING, xyzm ); 23 | return mls; 24 | } 25 | 26 | template < int RTYPE > 27 | inline SEXP sfg_multilinestring( 28 | Rcpp::Vector< RTYPE >& vec, 29 | std::string xyzm 30 | ) { 31 | R_xlen_t n = vec.length(); 32 | Rcpp::Matrix< RTYPE > mat( 1, n ); 33 | mat( 0, Rcpp::_ ) = vec; 34 | return sfg_multilinestring( mat, xyzm ); 35 | } 36 | 37 | inline SEXP sfg_multilinestring( 38 | Rcpp::List& lst, 39 | std::string xyzm 40 | ) { 41 | sfheaders::sfg::make_sfg( lst, sfheaders::sfg::SFG_MULTILINESTRING, xyzm ); 42 | return lst; 43 | } 44 | 45 | inline SEXP sfg_multilinestring( 46 | SEXP& x, 47 | SEXP& geometry_cols, 48 | SEXP& linestring_id, 49 | std::string xyzm 50 | ) { 51 | 52 | if( !Rf_inherits( x, "data.frame") && Rf_isNewList( x ) ) { 53 | Rcpp::List lst = Rcpp::as< Rcpp::List >( x ); 54 | return sfg_multilinestring( lst, xyzm ); 55 | } 56 | 57 | if( Rf_isNull( geometry_cols ) ) { 58 | // make this all the other columns, then send back in 59 | SEXP geometry_cols2 = geometries::utils::other_columns( x, linestring_id ); 60 | return sfg_multilinestring( x, geometry_cols2, linestring_id, xyzm ); 61 | } 62 | 63 | int n_id_cols = 1; 64 | R_xlen_t col_counter = geometries::utils::sexp_length( geometry_cols ); 65 | 66 | // After subset_geometries we have moved the geometry columns 67 | // into the 0:(n_geometry-1) positions 68 | Rcpp::IntegerVector int_geometry_cols = Rcpp::seq( 0, ( col_counter - 1 ) ); 69 | 70 | xyzm = sfheaders::utils::validate_xyzm( xyzm, col_counter ); 71 | 72 | R_xlen_t required_cols = col_counter + n_id_cols; 73 | 74 | Rcpp::IntegerVector geometry_cols_int = geometries::utils::sexp_col_int( x, geometry_cols ); 75 | 76 | Rcpp::List lst = geometries::utils::as_list( x ); 77 | Rcpp::List res( required_cols ); 78 | 79 | sfheaders::utils::subset_geometries( lst, res, geometry_cols_int ); 80 | 81 | Rcpp::IntegerVector int_linestring_id(1); 82 | 83 | sfheaders::utils::resolve_id( x, linestring_id, int_linestring_id, res, lst, col_counter ); 84 | 85 | Rcpp::List attributes = Rcpp::List::create(); 86 | Rcpp::List sfg = geometries::make_geometries( res, int_linestring_id, int_geometry_cols, attributes ); 87 | 88 | 89 | Rcpp::StringVector class_attribute = { xyzm.c_str(), "MULTILINESTRING","sfg" }; 90 | Rcpp::List atts = Rcpp::List::create( 91 | Rcpp::_["class"] = class_attribute 92 | ); 93 | geometries::utils::attach_attributes( sfg, atts ); 94 | 95 | return sfg; 96 | } 97 | 98 | inline SEXP sfg_multilinestring( 99 | SEXP& x, 100 | std::string xyzm 101 | ) { 102 | SEXP geometry_cols = R_NilValue; 103 | SEXP linestring_id = R_NilValue; 104 | return sfg_multilinestring( x, geometry_cols, linestring_id, xyzm ); 105 | } 106 | 107 | inline SEXP sfg_multilinestring( 108 | SEXP& x 109 | ) { 110 | SEXP geometry_cols = R_NilValue; 111 | SEXP linestring_id = R_NilValue; 112 | std::string xyzm; 113 | return sfg_multilinestring( x, geometry_cols, linestring_id, xyzm ); 114 | } 115 | 116 | 117 | } // sfg 118 | } // sfheaders 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/multilinestring/sfg_multilinestrings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_MULTILINESTRINGS_H 2 | #define R_SFHEADERS_SFG_MULTILINESTRINGS_H 3 | 4 | #include 5 | #include "sfheaders/sfg/multilinestring/sfg_multilinestring.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfg { 9 | 10 | inline Rcpp::List sfg_multilinestrings( Rcpp::List& lst, std::string xyzm ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | SEXP linestring_id = R_NilValue; 17 | 18 | for( i = 0; i < n; ++i ) { 19 | SEXP x = lst[i]; // mlutilinestrings are lists of matrices 20 | sfcs[i] = sfheaders::sfg::sfg_multilinestring( x, geometry_cols, linestring_id, xyzm ); 21 | } 22 | return sfcs; 23 | } 24 | 25 | // inline Rcpp::List sfg_multilinestrings( SEXP& obj, std::string xyzm ) { 26 | // Rcpp::List lst = Rcpp::as< Rcpp::List >( obj ); 27 | // return sfg_multilinestrings( lst, xyzm ); 28 | // } 29 | 30 | } // sfg 31 | } // sfheaders 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/multipoint/sfg_multipoint.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_MULTIPOINT_H 2 | #define R_SFHEADERS_SFG_MULTIPOINT_H 3 | 4 | #include 5 | 6 | #include "sfheaders/sfg/sfg_types.hpp" 7 | #include "sfheaders/utils/utils.hpp" 8 | 9 | #include "geometries/utils/columns/columns.hpp" 10 | #include "geometries/geometries.hpp" 11 | #include "geometries/nest/nest.hpp" 12 | 13 | 14 | namespace sfheaders { 15 | namespace sfg { 16 | 17 | template< int RTYPE > 18 | inline SEXP sfg_multipoint( 19 | Rcpp::Matrix< RTYPE >& mat, 20 | std::string xyzm 21 | ) { 22 | sfheaders::sfg::make_sfg( mat, sfheaders::sfg::SFG_MULTIPOINT, xyzm ); 23 | return mat; 24 | } 25 | 26 | template< int RTYPE > 27 | inline SEXP sfg_multipoint( 28 | Rcpp::Vector< RTYPE >& vec, 29 | std::string xyzm 30 | ) { 31 | R_xlen_t n = vec.length(); 32 | Rcpp::Matrix< RTYPE > mat( 1, n ); 33 | mat( 0, Rcpp::_ ) = vec; 34 | return sfg_multipoint( mat, xyzm ); 35 | } 36 | 37 | inline SEXP sfg_multipoint( 38 | Rcpp::List& lst, 39 | std::string xyzm 40 | ) { 41 | Rcpp::List lst2 = Rcpp::clone( lst ); 42 | sfheaders::sfg::make_sfg( lst2, sfheaders::sfg::SFG_MULTIPOINT, xyzm ); 43 | return lst2; 44 | } 45 | 46 | inline SEXP sfg_multipoint( 47 | SEXP& x, 48 | SEXP& geometry_cols, 49 | std::string xyzm 50 | ) { 51 | 52 | //Rcpp::stop("stopping"); 53 | SEXP geometry_mat = geometries::matrix::to_geometry_matrix( x, geometry_cols ); 54 | R_xlen_t n_col = geometries::utils::sexp_n_col( geometry_mat ); 55 | xyzm = sfheaders::utils::validate_xyzm( xyzm, n_col ); 56 | sfheaders::sfg::make_sfg( geometry_mat, sfheaders::sfg::SFG_MULTIPOINT, xyzm ); 57 | return geometry_mat; 58 | } 59 | 60 | inline SEXP sfg_multipoint( 61 | SEXP& x, 62 | std::string xyzm 63 | ) { 64 | SEXP geometry_cols = R_NilValue; 65 | return sfg_multipoint( x, geometry_cols, xyzm ); 66 | } 67 | 68 | inline SEXP sfg_multipoint( 69 | SEXP& x 70 | ) { 71 | SEXP geometry_cols = R_NilValue; 72 | std::string xyzm; 73 | return sfg_multipoint( x, geometry_cols, xyzm ); 74 | } 75 | 76 | } // sfg 77 | } // sfheaders 78 | 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/multipoint/sfg_multipoints.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_MULTIPOINTS_H 2 | #define R_SFHEADERS_SFG_MULTIPOINTS_H 3 | 4 | #include 5 | #include "sfheaders/sfg/multipoint/sfg_multipoint.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfg { 9 | 10 | inline Rcpp::List sfg_multipoints( Rcpp::List& lst, std::string xyzm ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | for( i = 0; i < n; ++i ) { 16 | Rcpp::NumericMatrix x = lst[i]; // multipoints are matrices 17 | sfcs[i] = sfheaders::sfg::sfg_multipoint( x, xyzm ); 18 | } 19 | return sfcs; 20 | } 21 | 22 | // inline Rcpp::List sfg_multipoints( SEXP& obj, std::string xyzm ) { 23 | // Rcpp::List lst = geometries::utils::as_list( obj ); 24 | // return sfg_multipoints( lst, xyzm ); 25 | // } 26 | 27 | } // sfg 28 | } // sfheaders 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/multipolygon/sfg_multipolygons.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_MULTIPOLYGONS_H 2 | #define R_SFHEADERS_SFG_MULTIPOLYGONS_H 3 | 4 | #include 5 | #include "sfheaders/sfg/multipolygon/sfg_multipolygon.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfg { 9 | 10 | inline Rcpp::List sfg_multipolygons( Rcpp::List& lst, std::string xyzm, bool close = true ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | SEXP polygon_id = R_NilValue; 17 | SEXP linestring_id = R_NilValue; 18 | 19 | for( i = 0; i < n; ++i ) { 20 | SEXP x = lst[i]; 21 | sfcs[i] = sfheaders::sfg::sfg_multipolygon( x, geometry_cols, polygon_id, linestring_id, xyzm, close ); 22 | } 23 | return sfcs; 24 | } 25 | 26 | // inline Rcpp::List sfg_multipolygons( SEXP& obj, std::string xyzm, bool close = true ) { 27 | // Rcpp::List lst = Rcpp::as< Rcpp::List >( obj ); 28 | // return sfg_multipolygons( lst, xyzm, close ); 29 | // } 30 | 31 | 32 | } // sfg 33 | } // sfheaders 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/point/sfg_point.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_POINT_H 2 | #define R_SFHEADERS_SFG_POINT_H 3 | 4 | #include 5 | #include "sfheaders/utils/utils.hpp" 6 | #include "sfheaders/sfg/sfg_types.hpp" 7 | 8 | #include "geometries/utils/columns/columns.hpp" 9 | #include "geometries/geometries.hpp" 10 | #include "geometries/nest/nest.hpp" 11 | 12 | namespace sfheaders { 13 | namespace sfg { 14 | 15 | template < int RTYPE > 16 | inline SEXP sfg_point( 17 | Rcpp::Vector< RTYPE >& vec, 18 | std::string xyzm 19 | ) { 20 | SEXP geometry_mat = geometries::matrix::to_geometry_matrix< RTYPE >( vec ); 21 | sfheaders::sfg::make_sfg( geometry_mat, sfheaders::sfg::SFG_POINT, xyzm ); 22 | return geometry_mat; 23 | } 24 | 25 | inline SEXP sfg_point( 26 | SEXP& x, 27 | SEXP& geometry_cols, 28 | std::string xyzm 29 | ) { 30 | 31 | SEXP geometry_mat = geometries::matrix::to_geometry_matrix( x, geometry_cols ); 32 | R_xlen_t n_row = geometries::utils::sexp_n_row( geometry_mat ); 33 | if( n_row > 1 ) { 34 | Rcpp::stop("sfheaders - points can only be one row"); 35 | } 36 | R_xlen_t n_col = geometries::utils::sexp_n_col( geometry_mat ); 37 | xyzm = sfheaders::utils::validate_xyzm( xyzm, n_col ); 38 | sfheaders::sfg::make_sfg( geometry_mat, sfheaders::sfg::SFG_POINT, xyzm ); 39 | return geometry_mat; 40 | } 41 | 42 | inline SEXP sfg_point( 43 | SEXP& x, 44 | std::string xyzm 45 | ) { 46 | SEXP geometry_cols = R_NilValue; 47 | return sfg_point( x, geometry_cols, xyzm ); 48 | } 49 | 50 | inline SEXP sfg_point( 51 | SEXP& x 52 | ) { 53 | SEXP geometry_cols = R_NilValue; 54 | std::string xyzm; 55 | return sfg_point( x, geometry_cols, xyzm ); 56 | } 57 | 58 | } // sfg 59 | } // sfheaders 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/point/sfg_points.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_POINTS_H 2 | #define R_SFHEADERS_SFG_POINTS_H 3 | 4 | #include 5 | #include "sfheaders/sfg/point/sfg_point.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfg { 9 | 10 | inline Rcpp::List sfg_points( Rcpp::List& lst, std::string xyzm ) { 11 | // assumes a lsit of POINT objects 12 | R_xlen_t n = lst.size(); 13 | R_xlen_t i; 14 | Rcpp::List sfcs( n ); 15 | 16 | SEXP geometry_cols = R_NilValue; 17 | for( i = 0; i < n; ++i ) { 18 | SEXP x = lst[ i ]; 19 | sfcs[ i ] = sfheaders::sfg::sfg_point( x, geometry_cols, xyzm ); 20 | } 21 | return sfcs; 22 | } 23 | 24 | template < int RTYPE > 25 | inline Rcpp::List sfg_points( Rcpp::Matrix< RTYPE >& mat, std::string xyzm ) { 26 | R_xlen_t n = mat.nrow(); 27 | R_xlen_t i; 28 | Rcpp::List sfcs( n ); 29 | 30 | for( i = 0; i < n; ++i ) { 31 | Rcpp::Vector< RTYPE > vec = mat( i, Rcpp::_ ); 32 | sfcs[ i ] = sfheaders::sfg::sfg_point< RTYPE >( vec, xyzm ); 33 | } 34 | return sfcs; 35 | } 36 | 37 | // inline Rcpp::List sfg_points( SEXP& obj, std::string xyzm ) { 38 | // Rcpp::NumericMatrix mat = geometries::matrix::to_geometry_matrix( obj ); 39 | // return sfg_points( mat, xyzm ); 40 | // } 41 | 42 | } // sfg 43 | } // sfheaders 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/polygon/close_polygon.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_POLYGON_CLOSE_POLYGON_H 2 | #define R_SFHEADERS_POLYGON_CLOSE_POLYGON_H 3 | 4 | #include 5 | #include "geometries/utils/close/close.hpp" 6 | 7 | namespace sfheaders { 8 | namespace polygon_utils { 9 | 10 | template < int RTYPE > 11 | inline Rcpp::Matrix< RTYPE > close_polygon( 12 | Rcpp::Matrix< RTYPE >& mat, 13 | bool close = true 14 | ) { 15 | 16 | if( !close ) { 17 | return mat; 18 | } 19 | 20 | R_xlen_t n_row = mat.nrow(); 21 | R_xlen_t n_col = mat.ncol(); 22 | R_xlen_t i; 23 | 24 | bool is_closed = true; 25 | 26 | Rcpp::Vector< RTYPE > first_row = mat( 0, Rcpp::_ ); 27 | Rcpp::Vector< RTYPE > last_row = mat( n_row - 1, Rcpp::_ ); 28 | 29 | for( i = 0; i < n_col; ++i ) { 30 | if( first_row[i] != last_row[i] ) { 31 | is_closed = false; 32 | break; 33 | } 34 | } 35 | 36 | if( !is_closed ) { 37 | Rcpp::Matrix< RTYPE > mat2( n_row + 1, n_col ); 38 | for( i = 0; i < n_col; ++i ) { 39 | Rcpp::Vector< RTYPE > v( n_row + 1); 40 | Rcpp::Range rng( 0, n_row - 1 ); 41 | 42 | v[ rng ] = mat( Rcpp::_, i ); 43 | v[ n_row ] = first_row[i]; 44 | mat2( Rcpp::_ , i ) = v; 45 | } 46 | geometries::utils::check_closed_rows( mat2.nrow() ); 47 | return mat2; 48 | } 49 | 50 | // it is closed 51 | geometries::utils::check_closed_rows( mat.nrow() ); // #nocov 52 | return mat; // #nocov 53 | } 54 | 55 | inline Rcpp::List close_polygon( 56 | Rcpp::List& lst, 57 | bool close = true 58 | ) { 59 | 60 | if( !close ) { 61 | return lst; 62 | } 63 | 64 | R_xlen_t n_items = lst.size(); 65 | R_xlen_t i; 66 | 67 | for( i = 0; i < n_items; ++i ) { 68 | SEXP x = lst[i]; 69 | switch( TYPEOF(x) ) { 70 | case INTSXP: { 71 | Rcpp::IntegerMatrix im = Rcpp::as< Rcpp::IntegerMatrix >( x ); // #nocov 72 | lst[i] = close_polygon( im, close ); // #nocov 73 | break; // #nocov 74 | } 75 | case REALSXP: { 76 | Rcpp::NumericMatrix nm = Rcpp::as< Rcpp::NumericMatrix >( x ); 77 | lst[i] = close_polygon( nm, close ); 78 | break; 79 | } 80 | case VECSXP: { 81 | Rcpp::List lst2 = Rcpp::as< Rcpp::List >( x ); 82 | lst[i] = close_polygon( lst2 ); 83 | break; 84 | } 85 | default: { 86 | Rcpp::stop("sfheaders - closing polygons requires matrices"); // #nocov 87 | } 88 | } 89 | } 90 | 91 | return lst; 92 | 93 | } 94 | 95 | } // polygon 96 | } // sfheaders 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/polygon/sfg_polygons.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_POLYGONS_H 2 | #define R_SFHEADERS_SFG_POLYGONS_H 3 | 4 | #include 5 | #include "sfheaders/sfg/polygon/sfg_polygon.hpp" 6 | 7 | namespace sfheaders { 8 | namespace sfg { 9 | 10 | inline Rcpp::List sfg_polygons( Rcpp::List& lst, std::string xyzm, bool close = true ) { 11 | R_xlen_t n = lst.size(); 12 | R_xlen_t i; 13 | Rcpp::List sfcs(n); 14 | 15 | SEXP geometry_cols = R_NilValue; 16 | SEXP linestring_id = R_NilValue; 17 | 18 | for( i = 0; i < n; ++i ) { 19 | SEXP x = lst[i]; // polygon is a list of matrices 20 | sfcs[i] = sfheaders::sfg::sfg_polygon( x, geometry_cols, linestring_id, xyzm, close ); 21 | } 22 | return sfcs; 23 | } 24 | 25 | // inline Rcpp::List sfg_polygons( SEXP& obj, std::string xyzm, bool close = true ) { 26 | // Rcpp::List lst = Rcpp::as< Rcpp::List >( obj ); 27 | // return sfg_polygons( lst, xyzm, close ); 28 | // } 29 | 30 | } // sfg 31 | } // sfheaders 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/sfg_attributes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_ATTRIBUTES_H 2 | #define R_SFHEADERS_SFG_ATTRIBUTES_H 3 | 4 | #include 5 | 6 | namespace sfheaders { 7 | namespace sfg { 8 | 9 | template 10 | inline Rcpp::CharacterVector sfgClass( Rcpp::Vector v ) { 11 | return v.attr("class"); 12 | } 13 | 14 | inline Rcpp::CharacterVector getSfgClass( SEXP sf ) { 15 | 16 | switch( TYPEOF(sf) ) { 17 | case REALSXP: 18 | return sfgClass( sf ); 19 | case VECSXP: 20 | return sfgClass( sf ); 21 | case INTSXP: 22 | return sfgClass( sf ); 23 | default: Rcpp::stop("unknown sf type"); 24 | } 25 | return ""; 26 | } 27 | 28 | // inline Rcpp::CharacterVector sfg_attributes( std::string& dimension, std::string& geom_type ) { 29 | // return Rcpp::CharacterVector::create( dimension, geom_type, "sfg" ); 30 | // } 31 | // 32 | // template < typename T > 33 | // inline SEXP attach_sfg_attribute( T x, std::string& dim, std::string& geom_type ) { 34 | // x.attr("class") = sfg_attributes( dim, geom_type ); 35 | // return x; 36 | // } 37 | // 38 | // inline SEXP attach_sfg_attribute( SEXP x, std::string& dim, std::string& geom_type ) { 39 | // switch (TYPEOF( x ) ) { 40 | // case INTSXP: { 41 | // if( !Rf_isMatrix( x ) ) { 42 | // return attach_sfg_attribute< Rcpp::IntegerVector >( x, dim, geom_type ); 43 | // } else { 44 | // return attach_sfg_attribute< Rcpp::IntegerMatrix >( x, dim, geom_type ); 45 | // } 46 | // } 47 | // case REALSXP: { 48 | // if( !Rf_isMatrix( x ) ) { 49 | // return attach_sfg_attribute< Rcpp::NumericVector>( x, dim, geom_type ); 50 | // } else { 51 | // return attach_sfg_attribute< Rcpp::NumericMatrix >( x, dim, geom_type ); 52 | // } 53 | // } 54 | // case VECSXP: { 55 | // return attach_sfg_attribute< Rcpp::List >( x, dim, geom_type ); 56 | // } 57 | // default: { 58 | // Rcpp::stop("sfheaders - attach_attribute invalid type"); 59 | // } 60 | // } 61 | // return Rcpp::List::create(); // never reaches 62 | // } 63 | 64 | 65 | } // sfg 66 | } // sfheaders 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/sfg_dimension.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_DIMENSION_H 2 | #define R_SFHEADERS_SFG_DIMENSION_H 3 | 4 | #include 5 | 6 | namespace sfheaders { 7 | namespace sfg { 8 | 9 | inline void dimension_check( R_xlen_t& n ) { 10 | if( n < 2 || n > 4 ) { 11 | Rcpp::stop("sfheaders - invalid dimension "); 12 | } 13 | } 14 | 15 | inline std::string guess_xyzm( R_xlen_t n_col ) { 16 | 17 | switch( n_col ) { 18 | case 2: { return "XY"; } 19 | case 3: { return "XYZ"; } 20 | case 4: { return "XYZM"; } 21 | default: { Rcpp::stop("sfheaders - can't work out the dimension"); } 22 | } 23 | return ""; // #nocov - never reaches 24 | } 25 | 26 | // re-write 27 | // it can be XYM, and we'll know from R based on the x, y, m columns specified. 28 | // but if none are specified, and just 3 columns, it will defualt to XYZ 29 | // 30 | // for c++ will need an overloaded function, or a flag, to say 'm-first', 31 | // and R will use something similar after the x, y, m args are defined 32 | // then enter teh appropriate C++ function. 33 | 34 | 35 | inline std::string sfg_dimension( 36 | R_xlen_t& n, 37 | std::string xyzm = "" 38 | ) { 39 | 40 | if( !xyzm.empty() ) { 41 | return xyzm; 42 | } 43 | 44 | dimension_check( n ); 45 | std::string dim = "XY"; 46 | 47 | switch ( n ) { 48 | case 3: { 49 | return "XYZ"; // default to XYZ if dimension is not provided, and n == 3 50 | } 51 | case 4: { 52 | return "XYZM"; 53 | } 54 | } 55 | return dim; 56 | } 57 | 58 | template< int RTYPE > 59 | inline std::string sfg_dimension( Rcpp::Vector< RTYPE >& vec, std::string xyzm = "" ) { 60 | R_xlen_t n = vec.size(); 61 | return sfg_dimension( n, xyzm ); 62 | } 63 | 64 | template< int RTYPE > 65 | inline std::string sfg_dimension( Rcpp::Matrix< RTYPE >& mat, std::string xyzm = "" ) { 66 | R_xlen_t n_col = mat.ncol(); 67 | return sfg_dimension( n_col, xyzm ); 68 | } 69 | 70 | inline std::string sfg_dimension( Rcpp::DataFrame& df, std::string xyzm = "" ) { 71 | R_xlen_t n_col = df.ncol(); 72 | return sfg_dimension( n_col, xyzm ); 73 | } 74 | 75 | inline std::string sfg_dimension( SEXP x, std::string xyzm = "" ) { 76 | 77 | switch ( TYPEOF( x ) ) { 78 | case INTSXP: { 79 | if( Rf_isMatrix( x ) ) { 80 | Rcpp::IntegerMatrix im = Rcpp::as< Rcpp::IntegerMatrix >( x ); 81 | return sfg_dimension( im, xyzm ); 82 | } else { 83 | Rcpp::IntegerVector iv = Rcpp::as< Rcpp::IntegerVector >( x ); 84 | return sfg_dimension( iv, xyzm ); 85 | } 86 | } 87 | case REALSXP: { 88 | if( Rf_isMatrix( x ) ) { 89 | Rcpp::NumericMatrix im = Rcpp::as< Rcpp::NumericMatrix >( x ); 90 | return sfg_dimension( im, xyzm ); 91 | } else { 92 | Rcpp::NumericVector iv = Rcpp::as< Rcpp::NumericVector >( x ); 93 | return sfg_dimension( iv, xyzm ); 94 | } 95 | } 96 | case VECSXP: { // data.frame && list? 97 | if( Rf_inherits( x, "data.frame" ) ) { 98 | Rcpp::DataFrame df = Rcpp::as< Rcpp::DataFrame >( x ); 99 | return sfg_dimension( df, xyzm ); 100 | } else if ( Rf_isNewList( x ) ) { 101 | // we can just get the first element, because by this point 102 | // all the elements should have been made correctly (?) 103 | Rcpp::List lst = Rcpp::as< Rcpp::List >( x ); 104 | SEXP list_element = lst[ 0 ]; 105 | return sfg_dimension( list_element, xyzm ); 106 | } // else default 107 | 108 | 109 | } 110 | default: { 111 | Rcpp::stop("sfheaders - unsupported sfg type"); // #nocov 112 | } 113 | } 114 | 115 | return ""; // never reaches 116 | } 117 | 118 | } // sfg 119 | } // sfheaders 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfg/sfg_types.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_SFG_TYPES_H 2 | #define R_SFHEADERS_SFG_TYPES_H 3 | 4 | #include 5 | 6 | #include "sfheaders/sfg/sfg_attributes.hpp" 7 | #include "sfheaders/sfg/sfg_dimension.hpp" 8 | 9 | #include "geometries/utils/sexp/sexp.hpp" 10 | #include "geometries/utils/attributes/attributes.hpp" 11 | 12 | namespace sfheaders { 13 | namespace sfg { 14 | 15 | const int SFG_POINT = 1; 16 | const int SFG_MULTIPOINT = 2; 17 | const int SFG_LINESTRING = 3; 18 | const int SFG_MULTILINESTRING = 4; 19 | const int SFG_POLYGON = 5; 20 | const int SFG_MULTIPOLYGON = 6; 21 | 22 | const int VECTOR = 1; 23 | const int MATRIX = 2; 24 | const int LIST_MATRIX = 3; 25 | const int LIST_LIST_MATRIX = 4; 26 | 27 | inline std::string get_sfg_type( int sfg_type ) { 28 | switch( sfg_type ) { 29 | case SFG_POINT: { return "POINT"; } 30 | case SFG_MULTIPOINT: { return "MULTIPOINT"; } 31 | case SFG_LINESTRING: { return "LINESTRING"; } 32 | case SFG_MULTILINESTRING: { return "MULTILINESTRING"; } 33 | case SFG_POLYGON: { return "POLYGON"; } 34 | case SFG_MULTIPOLYGON: { return "MULTIPOLYGON"; } 35 | default: { 36 | Rcpp::stop("sfheaders - unknown sfg type"); 37 | } 38 | } 39 | return ""; // never reaches 40 | } 41 | 42 | 43 | template < int RTYPE > 44 | inline void make_sfg( 45 | Rcpp::Vector< RTYPE >& vec, 46 | int sfg_type, 47 | std::string& xyzm 48 | ) { 49 | R_xlen_t n_col = vec.length(); 50 | std::string dim = sfheaders::sfg::sfg_dimension( n_col, xyzm ); 51 | 52 | std::string geom_type = get_sfg_type( sfg_type ); 53 | 54 | Rcpp::List attributes = Rcpp::List::create( 55 | Rcpp::_["class"] = Rcpp::CharacterVector::create( dim, geom_type, "sfg" ) 56 | ); 57 | geometries::utils::attach_attributes( vec, attributes ); 58 | } 59 | 60 | 61 | template < int RTYPE > 62 | inline void make_sfg( 63 | Rcpp::Matrix< RTYPE >& mat, 64 | int sfg_type, 65 | std::string& xyzm 66 | ) { 67 | 68 | R_xlen_t n_col = mat.ncol(); 69 | std::string dim = sfheaders::sfg::sfg_dimension( n_col, xyzm ); 70 | 71 | std::string geom_type = get_sfg_type( sfg_type ); 72 | 73 | Rcpp::List attributes = Rcpp::List::create( 74 | Rcpp::_["class"] = Rcpp::CharacterVector::create( dim, geom_type, "sfg" ) 75 | ); 76 | geometries::utils::attach_attributes( mat, attributes ); 77 | } 78 | 79 | inline void make_sfg( 80 | Rcpp::List& lst, 81 | int sfg_type, 82 | std::string& xyzm 83 | ) { 84 | std::string dim = sfheaders::sfg::sfg_dimension( lst, xyzm ); 85 | 86 | std::string geom_type = get_sfg_type( sfg_type ); 87 | 88 | Rcpp::List attributes = Rcpp::List::create( 89 | Rcpp::_["class"] = Rcpp::CharacterVector::create( dim, geom_type, "sfg" ) 90 | ); 91 | geometries::utils::attach_attributes( lst, attributes ); 92 | } 93 | 94 | inline void make_sfg( 95 | Rcpp::List& lst, 96 | R_xlen_t n_col, 97 | int sfg_type, 98 | std::string& xyzm 99 | ) { 100 | std::string dim = sfheaders::sfg::sfg_dimension( n_col, xyzm ); 101 | 102 | std::string geom_type = get_sfg_type( sfg_type ); 103 | 104 | Rcpp::List attributes = Rcpp::List::create( 105 | Rcpp::_["class"] = Rcpp::CharacterVector::create( dim, geom_type, "sfg" ) 106 | ); 107 | geometries::utils::attach_attributes( lst, attributes ); 108 | } 109 | 110 | inline void make_sfg( 111 | SEXP& x, 112 | R_xlen_t n_col, 113 | int sfg_type, 114 | std::string& xyzm 115 | ) { 116 | std::string dim = sfheaders::sfg::sfg_dimension( n_col, xyzm ); 117 | std::string geom_type = get_sfg_type( sfg_type ); 118 | Rcpp::List attributes = Rcpp::List::create( 119 | Rcpp::_["class"] = Rcpp::CharacterVector::create( dim, geom_type, "sfg" ) 120 | ); 121 | geometries::utils::attach_attributes( x, attributes ); 122 | } 123 | 124 | inline void make_sfg( 125 | SEXP& x, 126 | int sfg_type, 127 | std::string& xyzm 128 | ) { 129 | R_xlen_t n_col = geometries::utils::sexp_n_col( x ); 130 | make_sfg( x, n_col, sfg_type, xyzm ); 131 | } 132 | 133 | 134 | } // sfg 135 | } // sfheaders 136 | 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /inst/include/sfheaders/sfheaders.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_H 2 | #define R_SFHEADERS_H 3 | 4 | #include 5 | 6 | #include "geometries/utils/utils.hpp" 7 | 8 | #include "sfheaders/sfg/sfg.hpp" 9 | #include "sfheaders/sfc/sfc.hpp" 10 | #include "sfheaders/sf/sf.hpp" 11 | 12 | 13 | // // from r-spatial/sf 14 | // #define SF_Unknown 0 /* sfc_GEOMETRY */ 15 | // #define SF_Point 1 16 | // #define SF_LineString 2 17 | // #define SF_Polygon 3 18 | // #define SF_MultiPoint 4 19 | // #define SF_MultiLineString 5 20 | // #define SF_MultiPolygon 6 21 | // #define SF_GeometryCollection 7 22 | // #define SF_CircularString 8 23 | // #define SF_CompoundCurve 9 24 | // #define SF_CurvePolygon 10 25 | // #define SF_MultiCurve 11 26 | // #define SF_MultiSurface 12 27 | // #define SF_Curve 13 28 | // #define SF_Surface 14 29 | // #define SF_PolyhedralSurface 15 30 | // #define SF_TIN 16 31 | // #define SF_Triangle 17 32 | 33 | // #define SFC_POINT 1; 34 | // #define SFC_MULTIPOINT 2; 35 | // #define SFC_LINESTRING 3; 36 | // #define SFC_MULTILINESTRING 4; 37 | // #define SFC_POLYGON 5; 38 | // #define SFC_MULTIPOLYGON 6; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /inst/include/sfheaders/utils/utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef R_SFHEADERS_UTILS_H 2 | #define R_SFHEADERS_UTILS_H 3 | 4 | #include 5 | #include "sfheaders/sfg/sfg_dimension.hpp" 6 | #include "geometries/utils/utils.hpp" 7 | #include "geometries/utils/sexp/sexp.hpp" 8 | 9 | namespace sfheaders { 10 | namespace utils { 11 | 12 | inline bool is_null_geometry( Rcpp::IntegerVector& iv, std::string geom_type ) { 13 | R_xlen_t n = iv.length(); 14 | if( geom_type == "POINT" ) { 15 | if ( iv[0] == NA_INTEGER || iv[1] == NA_INTEGER ) { 16 | return true; 17 | } 18 | } else if ( n == 0 ) { // #nocov 19 | return true; // #nocov 20 | } 21 | return false; 22 | } 23 | inline bool is_null_geometry( Rcpp::NumericVector& nv, std::string geom_type ) { 24 | R_xlen_t n = nv.length(); 25 | if( geom_type == "POINT" ) { 26 | if (ISNAN( nv[0] ) || ISNAN( nv[1] ) ) { 27 | return true; 28 | } 29 | } else if ( n == 0 ) { // #nocov 30 | return true; // #nocov 31 | } 32 | return false; 33 | } 34 | 35 | inline bool is_null_geometry( SEXP& sfg, std::string geom_type ) { 36 | R_xlen_t n = geometries::utils::sexp_length( sfg ); 37 | if( geom_type == "POINT" ) { 38 | Rcpp::NumericVector nv = Rcpp::as< Rcpp::NumericVector >( sfg ); 39 | if (ISNAN( nv[0] ) ) { 40 | return true; 41 | } 42 | } else if ( n == 0 ) { // #nocov 43 | return true; // #nocov 44 | } 45 | return false; 46 | } 47 | 48 | inline Rcpp::IntegerVector validate_id_column( SEXP& x, SEXP& id_col ) { 49 | if( TYPEOF( id_col ) == INTSXP ) { 50 | return Rcpp::as< Rcpp::IntegerVector >( id_col ); 51 | } 52 | return geometries::utils::sexp_col_int( x, id_col ); 53 | } 54 | 55 | inline void append_id_column( Rcpp::List& res, R_xlen_t col_counter ) { 56 | 57 | R_xlen_t n_col = Rf_length( res ); 58 | if( n_col == 0 ) { 59 | Rcpp::stop("sfheaders - not enough columns"); 60 | } 61 | R_xlen_t n_row = Rf_length( VECTOR_ELT( res, 0 ) ); 62 | 63 | Rcpp::IntegerVector ids( n_row, 1 ); 64 | res[ col_counter ] = ids; 65 | } 66 | 67 | // inline Rcpp::List append_id_column( Rcpp::List& lst ) { 68 | // // appends a column of 1s to a list 69 | // R_xlen_t n_col = lst.length(); 70 | // if( n_col == 0 ) { 71 | // Rcpp::stop("sfheaders - not enough columns"); 72 | // } 73 | // R_xlen_t n_row = Rf_length( VECTOR_ELT( lst, 0 ) ); 74 | // R_xlen_t i; 75 | // Rcpp::List res( n_col + 1 ); 76 | // for( i = 0; i < n_col; ++i ) { 77 | // res[ i ] = lst[ i ]; 78 | // } 79 | // Rcpp::IntegerVector ids( n_row, 1 ); 80 | // res[ n_col ] = ids; 81 | // return res; 82 | // } 83 | 84 | inline void subset_geometries( Rcpp::List& x, Rcpp::List& res, Rcpp::IntegerVector& geometry_cols ) { 85 | 86 | // fill res with the geometry columns. 87 | R_xlen_t n_col = geometries::utils::sexp_length( geometry_cols ); 88 | R_xlen_t i; 89 | for( i = 0; i < n_col; ++i ) { 90 | res[ i ] = VECTOR_ELT( x, geometry_cols[i] ); 91 | } 92 | } 93 | 94 | inline std::string validate_xyzm( std::string xyzm, R_xlen_t n_col ) { 95 | std::string chk = ""; 96 | if( strcmp( xyzm.c_str(), chk.c_str() ) == 0 ) { 97 | return sfheaders::sfg::guess_xyzm( n_col ); 98 | } 99 | return xyzm; 100 | } 101 | 102 | inline void resolve_id( 103 | SEXP& x, 104 | SEXP& id_columns, 105 | Rcpp::IntegerVector& int_id_column, 106 | Rcpp::List& res, 107 | Rcpp::List& lst, 108 | R_xlen_t& col_counter 109 | ) { 110 | if( Rf_isNull( id_columns ) ) { 111 | // add a vector / column to x 112 | append_id_column( res, col_counter ); 113 | int_id_column = col_counter; 114 | } else { 115 | 116 | Rcpp::IntegerVector iv = validate_id_column( x, id_columns ); 117 | // make sure it exists before subsetting it 118 | geometries::utils::column_exists( lst, iv ); 119 | 120 | int col = iv[0]; 121 | 122 | int_id_column[0] = col_counter; 123 | res[ col_counter ] = VECTOR_ELT( lst, col ); 124 | } 125 | col_counter++; 126 | } 127 | 128 | } // utils 129 | } // sfheaders 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /man/sf_bbox.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sf_bbox} 4 | \alias{sf_bbox} 5 | \title{sf bbox} 6 | \usage{ 7 | sf_bbox(obj, x = NULL, y = NULL) 8 | } 9 | \arguments{ 10 | \item{obj}{matrix, data.frame, \code{sfg}, \code{sfc} or \code{sf} object.} 11 | 12 | \item{x}{x geometry column} 13 | 14 | \item{y}{y geometry column} 15 | } 16 | \description{ 17 | Calculates the bounding box of coordinates. This does not read the "bbox" attribute, 18 | it re-calculates the bounding box from the geometry coordinates 19 | } 20 | \examples{ 21 | 22 | ## data.frame 23 | df <- data.frame( 24 | id1 = c(1,1,1,1,1,1,1,1,2,2,2,2) 25 | , id2 = c(1,1,1,1,2,2,2,2,1,1,1,1) 26 | , x = c(0,0,1,1,1,1,2,2,3,4,4,3) 27 | , y = c(0,1,1,0,1,2,2,1,3,3,4,4) 28 | ) 29 | 30 | sf_bbox( obj = df[, c("x","y")] ) 31 | sf_bbox( obj = df, x = "x", y = "y" ) 32 | 33 | ## sfg objects 34 | pt <- sfg_point(obj = df[1, ], x = "x", y = "y", z = "id1") 35 | mpt <- sfg_multipoint(obj = df, x = "x", y = "y") 36 | ls <- sfg_linestring(obj = df, x = "x", y = "y") 37 | mls <- sfg_multilinestring(obj = df, x = "x", y = "y") 38 | p <- sfg_polygon(obj = df, x = "x" , y = "y") 39 | mp <- sfg_multipolygon(obj = df, x = "x", y = "y", close = FALSE ) 40 | 41 | sf_bbox( pt ) 42 | sf_bbox( mpt ) 43 | sf_bbox( ls ) 44 | sf_bbox( mls ) 45 | sf_bbox( p ) 46 | sf_bbox( mp ) 47 | 48 | ## sfc objects 49 | pt <- sfc_point(obj = df, x = "x", y = "y", z = "id1") 50 | mpt <- sfc_multipoint(obj = df, x = "x", y = "y", multipoint_id = "id1") 51 | ls <- sfc_linestring(obj = df, x = "x", y = "y", linestring_id = "id1") 52 | mls <- sfc_multilinestring(obj = df, x = "x", y = "y", multilinestring_id = "id1") 53 | p <- sfc_polygon( 54 | obj = df 55 | , x = "x" 56 | , y = "y" 57 | , polygon_id = "id1" 58 | , linestring_id = "id2" 59 | , close = FALSE 60 | ) 61 | mp <- sfc_multipolygon( 62 | obj = df 63 | , x = "x" 64 | , y = "y" 65 | , multipolygon_id = "id1" 66 | , linestring_id = "id2" 67 | , close = FALSE 68 | ) 69 | 70 | sf_bbox( pt ) 71 | sf_bbox( mpt ) 72 | sf_bbox( ls ) 73 | sf_bbox( mls ) 74 | sf_bbox( p ) 75 | sf_bbox( mp ) 76 | 77 | ## sf objects 78 | pt <- sf_point(obj = df, x = "x", y = "y", z = "id1") 79 | mpt <- sf_multipoint(obj = df, x = "x", y = "y", multipoint_id = "id1") 80 | ls <- sf_linestring(obj = df, x = "x", y = "y", linestring_id = "id1") 81 | mls <- sf_multilinestring(obj = df, x = "x", y = "y", multilinestring_id = "id1") 82 | p <- sf_polygon( 83 | obj = df 84 | , x = "x" 85 | , y = "y" 86 | , polygon_id = "id1" 87 | , linestring_id = "id2" 88 | , close = FALSE 89 | ) 90 | mp <- sf_multipolygon( 91 | obj = df 92 | , x = "x" 93 | , y = "y" 94 | , multipolygon_id = "id1" 95 | , linestring_id = "id2" 96 | , close = FALSE 97 | ) 98 | 99 | sf_bbox( pt ) 100 | sf_bbox( mpt ) 101 | sf_bbox( ls ) 102 | sf_bbox( mls ) 103 | sf_bbox( p ) 104 | sf_bbox( mp ) 105 | 106 | ## you can use it to update a bounding-box if it gets corrupted 107 | attr( mpt, "bbox" ) <- c(1:5) 108 | mpt ## incorrect values 109 | attr( mpt, "bbox" ) <- sf_bbox( mpt ) 110 | mpt ## back to correct values 111 | 112 | } 113 | -------------------------------------------------------------------------------- /man/sf_boxes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sf_boxes} 4 | \alias{sf_boxes} 5 | \title{sf boxes} 6 | \usage{ 7 | sf_boxes(obj) 8 | } 9 | \arguments{ 10 | \item{obj}{sf, sfc or sfg object} 11 | } 12 | \description{ 13 | returns the bounding box of each geometry 14 | } 15 | \examples{ 16 | 17 | df <- data.frame( 18 | id1 = c(1,1,1,1,1,1,1,1,2,2,2,2) 19 | , id2 = c(1,1,1,1,2,2,2,2,1,1,1,1) 20 | , x = c(0,0,1,1,1,1,2,2,3,4,4,3) 21 | , y = c(0,1,1,0,1,2,2,1,3,3,4,4) 22 | ) 23 | 24 | sf_line <- sfheaders::sf_linestring( 25 | obj = df 26 | , x = "x" 27 | , y = "y" 28 | , linestring_id = "id1" 29 | ) 30 | 31 | sf_boxes( sf_line ) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /man/sf_cast.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cast.R 3 | \name{sf_cast} 4 | \alias{sf_cast} 5 | \title{sf cast} 6 | \usage{ 7 | sf_cast(sf, to, close = TRUE, list_columns = NULL) 8 | } 9 | \arguments{ 10 | \item{sf}{object to convert} 11 | 12 | \item{to}{the geometry to convert to.} 13 | 14 | \item{close}{logical indicating if polygons should be closed} 15 | 16 | \item{list_columns}{vector of column names or indexes. List columns are columns 17 | of data where there is a value corresponding to each coordinate in the geometry (sfc). 18 | List columns get cast with the geometries.} 19 | } 20 | \description{ 21 | convert the input \code{sf} to a different geometry 22 | } 23 | \examples{ 24 | 25 | df <- data.frame( 26 | id1 = c(1,1,1,1,1,1,1,1,2,2,2,2) 27 | , id2 = c(1,1,1,1,2,2,2,2,1,1,1,1) 28 | , x = c(0,0,1,1,1,1,2,2,3,4,4,3) 29 | , y = c(0,1,1,0,1,2,2,1,3,3,4,4) 30 | ) 31 | 32 | pt <- sf_point(obj = df, x = "x", y = "y", z = "id1") 33 | mpt <- sf_multipoint(obj = df, x = "x", y = "y", multipoint_id = "id1") 34 | ls <- sf_linestring(obj = df, x = "x", y = "y", linestring_id = "id1") 35 | mls <- sf_multilinestring(obj = df, x = "x", y = "y", multilinestring_id = "id1") 36 | p <- sf_polygon( 37 | obj = df 38 | , x = "x" 39 | , y = "y" 40 | , polygon_id = "id1" 41 | , linestring_id = "id2" 42 | , close = FALSE 43 | ) 44 | mp <- sf_multipolygon( 45 | obj = df 46 | , x = "x" 47 | , y = "y" 48 | , multipolygon_id = "id1" 49 | , linestring_id = "id2" 50 | , close = FALSE 51 | ) 52 | 53 | sf_cast( pt, "LINESTRING" ) 54 | sf_cast( mpt, "POLYGON" ) 55 | sf_cast( ls, "POINT" ) 56 | sf_cast( mls, "MULTIPOLYGON" ) 57 | sf_cast( p, "POINT" ) 58 | sf_cast( mp, "LINESTRING" ) 59 | 60 | 61 | ## List Columns 62 | 63 | df <- data.frame( 64 | id1 = c(1,1,1,1,1,1,1,1,2,2,2,2) 65 | , id2 = c(1,1,1,1,2,2,2,2,1,1,1,1) 66 | , x = c(0,0,1,1,1,1,2,2,3,4,4,3) 67 | , y = c(0,1,1,0,1,2,2,1,3,3,4,4) 68 | ) 69 | 70 | ## Add a column where each value is an attribute of each coordinate 71 | df$val <- letters[1:nrow(df)] 72 | 73 | ## Make a multipolygon, and specify `val` as a list_column 74 | mp <- sf_multipolygon( 75 | obj = df 76 | , x = "x" 77 | , y = "y" 78 | , multipolygon_id = "id1" 79 | , linestring_id = "id2" 80 | , list_column = "val" 81 | , keep = TRUE 82 | , close = FALSE 83 | ) 84 | 85 | ## The 'val' attributes follow the same structure as the geometry column 86 | ## So each 'val' corresponds to a single coordinate in the geometry 87 | str( mp ) 88 | 89 | ## specifying `list_columns = "val"` when casting will retain the association 90 | ## between the 'val' attribute and each coordinate. 91 | res <- sf_cast( mp, "LINESTRING", list_columns = "val" ) 92 | 93 | ## The 'val' attribute still follows the same structure as the geometry column 94 | str( res ) 95 | 96 | } 97 | -------------------------------------------------------------------------------- /man/sf_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sf_helpers.R 3 | \name{sf_line} 4 | \alias{sf_line} 5 | \title{Helper for sf LINESTRING} 6 | \usage{ 7 | sf_line(obj, keep = FALSE, list_columns = NULL) 8 | } 9 | \arguments{ 10 | \item{obj}{sorted matrix or data.frame} 11 | 12 | \item{keep}{logical indicating if the non-geometry and non-id columns should be kept. 13 | if TRUE you must supply the geometry and id columns, and only the first row of 14 | each geometry is kept. See Keeping Properties.} 15 | 16 | \item{list_columns}{vector of column names to turn into a list.} 17 | } 18 | \value{ 19 | \code{sf} object of LINESTRING geometries 20 | } 21 | \description{ 22 | Constructs sf of LINESTRING objects, a helper for \code{\link[=sf_linestring]{sf_linestring()}} with a 23 | simpler syntax. 24 | } 25 | \section{Helpers}{ 26 | 27 | These are simpler versions of the main functions \code{\link[=sf_point]{sf_point()}}, 28 | \code{\link[=sf_multipoint]{sf_multipoint()}}, \code{\link[=sf_linestring]{sf_linestring()}}, \code{\link[=sf_multilinestring]{sf_multilinestring()}}, \code{\link[=sf_polygon]{sf_polygon()}}, 29 | and \code{\link[=sf_multipolygon]{sf_multipolygon()}} for input data frame or matrix that contains columns 30 | appropriately of 'x', 'y', 'z', 'm', ' multipolygon_id', polygon_id', 31 | 'multilinestring_id', 'linestring_id', 'multipoint_id'. 32 | 33 | This puts the onus of the naming and identification of entities onto the 34 | input data set, rather than when calling the creator function. This has pros 35 | and cons, so is not necessarily always 'simpler'. Please choose the 36 | appropriate constructor for the context you have. For examples a data frame 37 | from the real world with columns 'lon', 'lat', 'line' will be best used with 38 | 39 | \code{sf_linestring(df, x = "lon", y = "lat", linestring_id = "line")} 40 | 41 | whereas a heavy user of sfheaders might always create a data frame with 'x', 42 | 'y', 'linestring_id' precisely because they are expecting to call 43 | \code{sf_line(df)} and no further work is required. These are very different 44 | contexts and both equally valid. 45 | 46 | Some columns are mandatory, such as 'x' and 'y' (always), while others depend 47 | on the output type where each column for that type is mandatory. The 'z' 48 | and/or 'm' values are included for 'XYZ', 'XYM', or 'XYZM' geometry types if 49 | and as they are present. 50 | 51 | In summary these helpers: 52 | \itemize{ 53 | \item do not require arguments declaring column names. 54 | \item use assumed default column names, with no variation or absence allowed for 55 | a given type. 56 | \item use \code{z}, and/or \code{m} if present. 57 | \item use \code{close = FALSE} and \code{keep = FALSE} same as proper constructors. 58 | \item unlike \code{\link[=sf_point]{sf_point()}} \code{\link[=sf_pt]{sf_pt()}} does not accept a flat vector for a single 59 | point. 60 | \item require a matrix or data frame with complete column names. 61 | } 62 | 63 | None of the helpers allow partial name matching for column names. 64 | } 65 | 66 | \section{notes}{ 67 | 68 | sfheaders functions do not perform any validity checks on the geometries. 69 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 70 | 71 | The data.frame and matrices you send into the sfheader functions must be ordered. 72 | } 73 | 74 | \section{Keeping Properties}{ 75 | 76 | 77 | Setting \code{keep = TRUE} will retain any columns not specified as a 78 | coordinate (x, y, z, m) or an id (e.g., linestring_id, polygon_id) of the input \code{obj}. 79 | 80 | You can use \code{list_columns} to specify which of the properties will be turned into 81 | a list, thus keeping all the values in the column. For columns not specified in \code{list_columns}, 82 | only the first row of the column is kept 83 | 84 | The \code{sf_*} functions assume the input \code{obj} is a long data.frame / matrix, 85 | where any properties are repeated down the table for the same geometry. 86 | } 87 | 88 | \examples{ 89 | 90 | x <- cbind(x = 1:2, y = 3:4, linestring_id = 1) 91 | sf_line( x ) 92 | 93 | x <- data.frame( linestring_id = rep(1:2, each = 2), x = 1:4, y = 4:1 ) 94 | (sfx <- sf_line( x )) 95 | 96 | ## we trivially round-trip with sf_line() 97 | sf_line(sf_to_df(sfx)) 98 | } 99 | -------------------------------------------------------------------------------- /man/sf_linestring.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sf.R 3 | \name{sf_linestring} 4 | \alias{sf_linestring} 5 | \title{sf LINESTRING} 6 | \usage{ 7 | sf_linestring( 8 | obj = NULL, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | linestring_id = NULL, 14 | keep = FALSE, 15 | list_columns = NULL 16 | ) 17 | } 18 | \arguments{ 19 | \item{obj}{sorted matrix or data.frame} 20 | 21 | \item{x}{x geometry column} 22 | 23 | \item{y}{y geometry column} 24 | 25 | \item{z}{z geometry column} 26 | 27 | \item{m}{m geometry column} 28 | 29 | \item{linestring_id}{column of ids for linestrings} 30 | 31 | \item{keep}{logical indicating if the non-geometry and non-id columns should be kept. 32 | if TRUE you must supply the geometry and id columns, and only the first row of 33 | each geometry is kept. See Keeping Properties.} 34 | 35 | \item{list_columns}{vector of column names to turn into a list.} 36 | } 37 | \value{ 38 | \code{sf} object of LINESTRING geometries 39 | } 40 | \description{ 41 | constructs sf of LINESTRING objects 42 | } 43 | \section{notes}{ 44 | 45 | sfheaders functions do not perform any validity checks on the geometries. 46 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 47 | 48 | The data.frame and matrices you send into the sfheader functions must be ordered. 49 | } 50 | 51 | \section{Keeping Properties}{ 52 | 53 | 54 | Setting \code{keep = TRUE} will retain any columns not specified as a 55 | coordinate (x, y, z, m) or an id (e.g., linestring_id, polygon_id) of the input \code{obj}. 56 | 57 | You can use \code{list_columns} to specify which of the properties will be turned into 58 | a list, thus keeping all the values in the column. For columns not specified in \code{list_columns}, 59 | only the first row of the column is kept 60 | 61 | The \code{sf_*} functions assume the input \code{obj} is a long data.frame / matrix, 62 | where any properties are repeated down the table for the same geometry. 63 | } 64 | 65 | \examples{ 66 | 67 | x <- matrix( c(1:8), ncol = 2 ) 68 | sf_linestring( x ) 69 | 70 | x <- cbind( x, c(1,1,2,2) ) 71 | sf_linestring( obj = x, x = 1, y = 2 ) 72 | sf_linestring( obj = x, x = 1, y = 2, linestring_id = 3 ) 73 | 74 | x <- data.frame( line_id = 1:2, x = 1:2, y = 2:1 ) 75 | sf_linestring( x ) 76 | sf_linestring( x, x = "x", y = "y" ) 77 | sf_linestring( x, x = "y", y = "x" ) 78 | sf_linestring( x, linestring_id = "line_id", x = "x", y = "y") 79 | 80 | ## keeping properties 81 | x <- data.frame( 82 | line_id = c(1,1,2,2) 83 | , x = 1:4 84 | , y = 4:1 85 | , val = letters[1:4] 86 | , stringsAsFactors = FALSE 87 | ) 88 | 89 | ## first-row of 'val' is kept 90 | sf_linestring( x, x = "x", y = "y", keep = TRUE ) 91 | sf_linestring( x, linestring_id = "line_id", x = "x", y = "y", keep = TRUE ) 92 | 93 | ## 'val' column converted to a list 94 | sf_linestring( x, linestring_id = "id", x = "x", y = "y", keep = TRUE, list_columns = "val" ) 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /man/sf_multilinestring.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sf.R 3 | \name{sf_multilinestring} 4 | \alias{sf_multilinestring} 5 | \title{sf MULTILINESTRING} 6 | \usage{ 7 | sf_multilinestring( 8 | obj = NULL, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | multilinestring_id = NULL, 14 | linestring_id = NULL, 15 | keep = FALSE, 16 | list_columns = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{obj}{sorted matrix or data.frame} 21 | 22 | \item{x}{x geometry column} 23 | 24 | \item{y}{y geometry column} 25 | 26 | \item{z}{z geometry column} 27 | 28 | \item{m}{m geometry column} 29 | 30 | \item{multilinestring_id}{column of ids for multilinestrings} 31 | 32 | \item{linestring_id}{column of ids for linestrings (within multilinestrings)} 33 | 34 | \item{keep}{logical indicating if the non-geometry and non-id columns should be kept. 35 | if TRUE you must supply the geometry and id columns, and only the first row of 36 | each geometry is kept. See Keeping Properties.} 37 | 38 | \item{list_columns}{vector of column names to turn into a list.} 39 | } 40 | \value{ 41 | \code{sf} object of MULTILINESTRING geometries 42 | } 43 | \description{ 44 | constructs an sf of MULTILINESTRING objects 45 | } 46 | \section{notes}{ 47 | 48 | sfheaders functions do not perform any validity checks on the geometries. 49 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 50 | 51 | The data.frame and matrices you send into the sfheader functions must be ordered. 52 | } 53 | 54 | \section{Keeping Properties}{ 55 | 56 | 57 | Setting \code{keep = TRUE} will retain any columns not specified as a 58 | coordinate (x, y, z, m) or an id (e.g., linestring_id, polygon_id) of the input \code{obj}. 59 | 60 | You can use \code{list_columns} to specify which of the properties will be turned into 61 | a list, thus keeping all the values in the column. For columns not specified in \code{list_columns}, 62 | only the first row of the column is kept 63 | 64 | The \code{sf_*} functions assume the input \code{obj} is a long data.frame / matrix, 65 | where any properties are repeated down the table for the same geometry. 66 | } 67 | 68 | \examples{ 69 | 70 | m <- matrix(c(0,0,0,0,1,1), ncol = 3 ) 71 | sf_multilinestring( m ) 72 | 73 | m <- matrix(c(0,0,0,0,0,1,0,1,1,1,2,2,1,2,3), ncol = 3, byrow = TRUE) 74 | sf_multilinestring( obj = m ) 75 | sf_multilinestring( obj = m, multilinestring_id = 1 ) 76 | sf_multilinestring( obj = m, linestring_id = 1 ) 77 | 78 | sf_multilinestring( obj = m, linestring_id = 1, multilinestring_id = 1 ) 79 | 80 | sf_multilinestring( obj = m, x = 2, y = 3 ) 81 | sf_multilinestring( obj = m, x = 1, y = 2, z = 3 ) 82 | sf_multilinestring( obj = m, x = 2, y = 3, linestring_id = 1, multilinestring_id = 1 ) 83 | 84 | df <- data.frame( 85 | ml_id = c(1,1,1,1,1,1,1,1,2,2,2,2,2) 86 | , l_id = c(1,1,1,2,2,3,3,3,1,1,1,2,2) 87 | , x = rnorm(13) 88 | , y = rnorm(13) 89 | , z = rnorm(13) 90 | , m = rnorm(13) 91 | ) 92 | 93 | sf_multilinestring( obj = df, x = "x", y = "y") 94 | sf_multilinestring( obj = df, x = "x", y = "y", z = "z") 95 | sf_multilinestring( obj = df, x = "x", y = "y", z = "z", m = "m") 96 | 97 | sf_multilinestring( obj = df, x = 3, y = 4) 98 | sf_multilinestring( obj = df, x = 3, y = 4, z = 5) 99 | sf_multilinestring( obj = df, x = 3, y = 4, z = 5, m = 6 ) 100 | 101 | sf_multilinestring( obj = df, multilinestring_id = "ml_id", linestring_id = "l_id" ) 102 | sf_multilinestring( obj = df, multilinestring_id = 1, linestring_id = 2 ) 103 | 104 | 105 | 106 | } 107 | -------------------------------------------------------------------------------- /man/sf_multipoint.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sf.R 3 | \name{sf_multipoint} 4 | \alias{sf_multipoint} 5 | \title{sf MULTIPOINT} 6 | \usage{ 7 | sf_multipoint( 8 | obj, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | multipoint_id = NULL, 14 | keep = FALSE, 15 | list_columns = NULL 16 | ) 17 | } 18 | \arguments{ 19 | \item{obj}{sorted matrix or data.frame} 20 | 21 | \item{x}{x geometry column} 22 | 23 | \item{y}{y geometry column} 24 | 25 | \item{z}{z geometry column} 26 | 27 | \item{m}{m geometry column} 28 | 29 | \item{multipoint_id}{column of ids for multipoints} 30 | 31 | \item{keep}{logical indicating if the non-geometry and non-id columns should be kept. 32 | if TRUE you must supply the geometry and id columns, and only the first row of 33 | each geometry is kept. See Keeping Properties.} 34 | 35 | \item{list_columns}{vector of column names to turn into a list.} 36 | } 37 | \value{ 38 | \code{sf} object of MULTIPOINT geometries 39 | } 40 | \description{ 41 | constructs sf of MULTIPOINT objects 42 | } 43 | \section{notes}{ 44 | 45 | sfheaders functions do not perform any validity checks on the geometries. 46 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 47 | 48 | The data.frame and matrices you send into the sfheader functions must be ordered. 49 | } 50 | 51 | \section{Keeping Properties}{ 52 | 53 | 54 | Setting \code{keep = TRUE} will retain any columns not specified as a 55 | coordinate (x, y, z, m) or an id (e.g., linestring_id, polygon_id) of the input \code{obj}. 56 | 57 | You can use \code{list_columns} to specify which of the properties will be turned into 58 | a list, thus keeping all the values in the column. For columns not specified in \code{list_columns}, 59 | only the first row of the column is kept 60 | 61 | The \code{sf_*} functions assume the input \code{obj} is a long data.frame / matrix, 62 | where any properties are repeated down the table for the same geometry. 63 | } 64 | 65 | \examples{ 66 | 67 | x <- matrix( c(1:4), ncol = 2 ) 68 | sf_multipoint( x ) 69 | 70 | x <- data.frame( id = 1:2, x = 1:2, y = 2:1 ) 71 | sf_multipoint( x ) 72 | sf_multipoint( x, x = "x", y = "y" ) 73 | sf_multipoint( x, x = "y", y = "x" ) 74 | sf_multipoint( x, multipoint_id = "id", x = "x", y = "y") 75 | 76 | } 77 | -------------------------------------------------------------------------------- /man/sf_point.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sf.R 3 | \name{sf_point} 4 | \alias{sf_point} 5 | \title{sf POINT} 6 | \usage{ 7 | sf_point(obj, x = NULL, y = NULL, z = NULL, m = NULL, keep = FALSE) 8 | } 9 | \arguments{ 10 | \item{obj}{sorted vector, matrix or data.frame} 11 | 12 | \item{x}{x geometry column} 13 | 14 | \item{y}{y geometry column} 15 | 16 | \item{z}{z geometry column} 17 | 18 | \item{m}{m geometry column} 19 | 20 | \item{keep}{logical indicating if the non-geometry and non-id columns should be kept. 21 | if TRUE you must supply the geometry and id columns, and only the first row of 22 | each geometry is kept. See Keeping Properties.} 23 | } 24 | \value{ 25 | \code{sf} object of POINT geometries 26 | } 27 | \description{ 28 | constructs sf of POINT objects 29 | } 30 | \section{Keeping Properties}{ 31 | 32 | 33 | Setting \code{keep = TRUE} will retain any columns not specified as a 34 | coordinate (x, y, z, m) or an id (e.g., linestring_id, polygon_id) of the input \code{obj}. 35 | 36 | You can use \code{list_columns} to specify which of the properties will be turned into 37 | a list, thus keeping all the values in the column. For columns not specified in \code{list_columns}, 38 | only the first row of the column is kept 39 | 40 | The \code{sf_*} functions assume the input \code{obj} is a long data.frame / matrix, 41 | where any properties are repeated down the table for the same geometry. 42 | } 43 | 44 | \section{notes}{ 45 | 46 | sfheaders functions do not perform any validity checks on the geometries. 47 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 48 | 49 | The data.frame and matrices you send into the sfheader functions must be ordered. 50 | } 51 | 52 | \examples{ 53 | 54 | x <- c(1:3) 55 | sf_point( x ) 56 | 57 | x <- matrix( c(1:10) , ncol = 2 ) 58 | sf_point( x ) 59 | 60 | x <- setNames( as.data.frame( x ), c("x","y") ) 61 | sf_point( x ) 62 | sf_point( obj = x, x = "x", y = "y" ) 63 | sf_point( obj = x, x = "y", y = "x" ) 64 | 65 | # keeping properties 66 | x$val <- letters[1:5] 67 | sf_point( x, x = "x", y = "y", keep = TRUE ) 68 | 69 | } 70 | -------------------------------------------------------------------------------- /man/sf_polygon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sf.R 3 | \name{sf_polygon} 4 | \alias{sf_polygon} 5 | \title{sf POLYGON} 6 | \usage{ 7 | sf_polygon( 8 | obj = NULL, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | polygon_id = NULL, 14 | linestring_id = NULL, 15 | close = TRUE, 16 | keep = FALSE, 17 | list_columns = NULL 18 | ) 19 | } 20 | \arguments{ 21 | \item{obj}{sorted matrix or data.frame} 22 | 23 | \item{x}{x geometry column} 24 | 25 | \item{y}{y geometry column} 26 | 27 | \item{z}{z geometry column} 28 | 29 | \item{m}{m geometry column} 30 | 31 | \item{polygon_id}{column of ids for polygons} 32 | 33 | \item{linestring_id}{column of ids for lines (within polygons)} 34 | 35 | \item{close}{logical indicating whether polygons should be closed. If \code{TRUE}, 36 | all polygons will be checked and force closed if possible} 37 | 38 | \item{keep}{logical indicating if the non-geometry and non-id columns should be kept. 39 | if TRUE you must supply the geometry and id columns, and only the first row of 40 | each geometry is kept. See Keeping Properties.} 41 | 42 | \item{list_columns}{vector of column names to turn into a list.} 43 | } 44 | \value{ 45 | \code{sf} object of POLYGON geometries 46 | } 47 | \description{ 48 | constructs an sf of POLYGON objects 49 | } 50 | \section{notes}{ 51 | 52 | sfheaders functions do not perform any validity checks on the geometries. 53 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 54 | 55 | The data.frame and matrices you send into the sfheader functions must be ordered. 56 | } 57 | 58 | \section{Keeping Properties}{ 59 | 60 | 61 | Setting \code{keep = TRUE} will retain any columns not specified as a 62 | coordinate (x, y, z, m) or an id (e.g., linestring_id, polygon_id) of the input \code{obj}. 63 | 64 | You can use \code{list_columns} to specify which of the properties will be turned into 65 | a list, thus keeping all the values in the column. For columns not specified in \code{list_columns}, 66 | only the first row of the column is kept 67 | 68 | The \code{sf_*} functions assume the input \code{obj} is a long data.frame / matrix, 69 | where any properties are repeated down the table for the same geometry. 70 | } 71 | 72 | \examples{ 73 | 74 | m <- matrix(c(0,0,0,0,1,1), ncol = 2 ) 75 | sf_polygon( m ) 76 | 77 | m <- matrix(c(0,0,0,0,0,1,0,1,1,1,2,2,1,2,3,1,3,4), ncol = 3, byrow = TRUE) 78 | sf_polygon( obj = m ) 79 | sf_polygon( obj = m, polygon_id = 1 ) 80 | sf_polygon( obj = m, linestring_id = 1 ) 81 | 82 | sf_polygon( obj = m, linestring_id = 1, polygon_id = 1 ) 83 | 84 | sf_polygon( obj = m, x = 2, y = 3 ) 85 | sf_polygon( obj = m, x = 1, y = 2, z = 3 ) 86 | sf_polygon( obj = m, x = 2, y = 3, linestring_id = 1, polygon_id = 1 ) 87 | 88 | df <- data.frame( 89 | ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 90 | , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 91 | , x = rnorm(15) 92 | , y = rnorm(15) 93 | , z = rnorm(15) 94 | , m = rnorm(15) 95 | ) 96 | 97 | sf_polygon( obj = df, x = "x", y = "y") 98 | sf_polygon( obj = df, x = "x", y = "y", z = "z") 99 | sf_polygon( obj = df, x = "x", y = "y", z = "z", m = "m") 100 | 101 | sf_polygon( obj = df, x = 2, y = 3) 102 | sf_polygon( obj = df, x = 2, y = 3, z = 4) 103 | sf_polygon( obj = df, x = 2, y = 3, z = 4, m = 5) 104 | 105 | sf_polygon( obj = df, polygon_id = "ml_id", linestring_id = "l_id" ) 106 | sf_polygon( obj = df, polygon_id = 1, linestring_id = 2 ) 107 | 108 | ## keeping properties 109 | df <- data.frame( 110 | ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 111 | , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 112 | , x = rnorm(15) 113 | , y = rnorm(15) 114 | , z = rnorm(15) 115 | , m = rnorm(15) 116 | , val = letters[1:15] 117 | , stringsAsFactors = FALSE 118 | ) 119 | 120 | ## using keep = TRUE means the first row of all non-geometries are kept 121 | sf_polygon( 122 | obj = df 123 | , polygon_id = "ml_id" 124 | , linestring_id = "l_id" 125 | , x = "x" 126 | , y = "y" 127 | , keep = TRUE 128 | ) 129 | 130 | ## use 'list_column' to specify columns where you want to keep all the values 131 | sf_polygon( 132 | obj = df 133 | , polygon_id = "ml_id" 134 | , linestring_id = "l_id" 135 | , x = "x" 136 | , y = "y" 137 | , keep = TRUE 138 | , list_columns = "val" 139 | ) 140 | 141 | } 142 | -------------------------------------------------------------------------------- /man/sf_pt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sf_helpers.R 3 | \name{sf_pt} 4 | \alias{sf_pt} 5 | \title{Helper for sf POINT} 6 | \usage{ 7 | sf_pt(obj, keep = FALSE) 8 | } 9 | \arguments{ 10 | \item{obj}{sorted vector, matrix or data.frame} 11 | 12 | \item{keep}{logical indicating if the non-geometry and non-id columns should be kept. 13 | if TRUE you must supply the geometry and id columns, and only the first row of 14 | each geometry is kept. See Keeping Properties.} 15 | } 16 | \value{ 17 | \code{sf} object of POINT geometries 18 | } 19 | \description{ 20 | Constructs sf of POINT objects, a helper for \code{\link[=sf_point]{sf_point()}} with a simpler 21 | syntax. 22 | } 23 | \section{Helpers}{ 24 | 25 | These are simpler versions of the main functions \code{\link[=sf_point]{sf_point()}}, 26 | \code{\link[=sf_multipoint]{sf_multipoint()}}, \code{\link[=sf_linestring]{sf_linestring()}}, \code{\link[=sf_multilinestring]{sf_multilinestring()}}, \code{\link[=sf_polygon]{sf_polygon()}}, 27 | and \code{\link[=sf_multipolygon]{sf_multipolygon()}} for input data frame or matrix that contains columns 28 | appropriately of 'x', 'y', 'z', 'm', ' multipolygon_id', polygon_id', 29 | 'multilinestring_id', 'linestring_id', 'multipoint_id'. 30 | 31 | This puts the onus of the naming and identification of entities onto the 32 | input data set, rather than when calling the creator function. This has pros 33 | and cons, so is not necessarily always 'simpler'. Please choose the 34 | appropriate constructor for the context you have. For examples a data frame 35 | from the real world with columns 'lon', 'lat', 'line' will be best used with 36 | 37 | \code{sf_linestring(df, x = "lon", y = "lat", linestring_id = "line")} 38 | 39 | whereas a heavy user of sfheaders might always create a data frame with 'x', 40 | 'y', 'linestring_id' precisely because they are expecting to call 41 | \code{sf_line(df)} and no further work is required. These are very different 42 | contexts and both equally valid. 43 | 44 | Some columns are mandatory, such as 'x' and 'y' (always), while others depend 45 | on the output type where each column for that type is mandatory. The 'z' 46 | and/or 'm' values are included for 'XYZ', 'XYM', or 'XYZM' geometry types if 47 | and as they are present. 48 | 49 | In summary these helpers: 50 | \itemize{ 51 | \item do not require arguments declaring column names. 52 | \item use assumed default column names, with no variation or absence allowed for 53 | a given type. 54 | \item use \code{z}, and/or \code{m} if present. 55 | \item use \code{close = FALSE} and \code{keep = FALSE} same as proper constructors. 56 | \item unlike \code{\link[=sf_point]{sf_point()}} \code{\link[=sf_pt]{sf_pt()}} does not accept a flat vector for a single 57 | point. 58 | \item require a matrix or data frame with complete column names. 59 | } 60 | 61 | None of the helpers allow partial name matching for column names. 62 | } 63 | 64 | \section{notes}{ 65 | 66 | sfheaders functions do not perform any validity checks on the geometries. 67 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 68 | 69 | The data.frame and matrices you send into the sfheader functions must be ordered. 70 | } 71 | 72 | \section{Keeping Properties}{ 73 | 74 | 75 | Setting \code{keep = TRUE} will retain any columns not specified as a 76 | coordinate (x, y, z, m) or an id (e.g., linestring_id, polygon_id) of the input \code{obj}. 77 | 78 | You can use \code{list_columns} to specify which of the properties will be turned into 79 | a list, thus keeping all the values in the column. For columns not specified in \code{list_columns}, 80 | only the first row of the column is kept 81 | 82 | The \code{sf_*} functions assume the input \code{obj} is a long data.frame / matrix, 83 | where any properties are repeated down the table for the same geometry. 84 | } 85 | 86 | \examples{ 87 | 88 | x <- cbind(x = 1, y= 3) 89 | sf_pt( x ) 90 | sf_pt(cbind(x, z = 2)) 91 | 92 | x <- matrix( c(1:10) , ncol = 2 , dimnames = list(NULL, c("x", "y"))) 93 | sf_pt( x ) 94 | 95 | x <- setNames( as.data.frame( x ), c("x","y") ) 96 | sf_pt( x ) 97 | 98 | # keeping properties 99 | x$val <- letters[1:5] 100 | (sfx <- sf_pt( x, keep = TRUE )) 101 | 102 | ## we trivially round-trip with sf_pt() 103 | sf_pt(sf_to_df(sfx, fill = TRUE), keep = TRUE) 104 | } 105 | -------------------------------------------------------------------------------- /man/sf_remove_holes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{sf_remove_holes} 4 | \alias{sf_remove_holes} 5 | \title{remove holes} 6 | \usage{ 7 | sf_remove_holes(obj, close = TRUE) 8 | } 9 | \arguments{ 10 | \item{obj}{sfg, sfc or sf object.} 11 | 12 | \item{close}{logical indicating whether polygons should be closed. If \code{TRUE}, 13 | all polygons will be checked and force closed if possible} 14 | } 15 | \description{ 16 | Removes holes from polygons and multipolygons. Points and linestrings are unaffected. 17 | } 18 | \examples{ 19 | df <- data.frame( 20 | ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 21 | , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 22 | , x = rnorm(15) 23 | , y = rnorm(15) 24 | , z = rnorm(15) 25 | , m = rnorm(15) 26 | ) 27 | 28 | sfg <- sfg_polygon( obj = df, x = "x", y = "y", linestring_id = "ml_id" ) 29 | sfc <- sfc_polygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id" ) 30 | sf <- sf_polygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id" ) 31 | 32 | sf_remove_holes( sfg ) 33 | sf_remove_holes( sfc ) 34 | sf_remove_holes( sf ) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /man/sf_to_df.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/df.R 3 | \name{sf_to_df} 4 | \alias{sf_to_df} 5 | \title{sf to df} 6 | \usage{ 7 | sf_to_df(sf, fill = FALSE, unlist = NULL) 8 | } 9 | \arguments{ 10 | \item{sf}{sf object} 11 | 12 | \item{fill}{logical indicating if the resulting data.frame should be filled 13 | with the data columns from the sf object. If \code{TRUE}, each row of data will 14 | be replicated for every coordinate in every geometry.} 15 | 16 | \item{unlist}{string vector of columns to unlist. Each list element is equivalent 17 | to a row of the input object, and is expected to be the same 18 | length as the number of coordinates in the geometry.} 19 | } 20 | \description{ 21 | Converts an sf object to a data.frame 22 | } 23 | \examples{ 24 | 25 | df <- data.frame( 26 | ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 27 | , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 28 | , x = rnorm(15) 29 | , y = rnorm(15) 30 | , z = rnorm(15) 31 | , m = rnorm(15) 32 | ) 33 | 34 | sf <- sf_polygon( obj = df, polygon_id = "ml_id", linestring_id = "l_id" ) 35 | df <- sf_to_df( sf ) 36 | 37 | ## with associated data 38 | sf$val1 <- c("a","b") 39 | sf$val2 <- c(1L, 2L) 40 | 41 | df <- sf_to_df( sf, fill = TRUE ) 42 | 43 | ## Unlisting list columns 44 | 45 | df <- data.frame( 46 | l_id = c(1,1,1,2,2,2,3,3,3,3) 47 | , x = rnorm(10) 48 | , y = rnorm(10) 49 | ) 50 | 51 | sf <- sf_linestring( obj = df, linestring_id = "l_id" , x = "x", y = "y") 52 | 53 | ## put on a list column 54 | sf$l <- list( c(1,2,3),c(3,2,1),c(10,11,12,13)) 55 | 56 | sf_to_df( sf, unlist = "l" ) 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /man/sfc_cast.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cast.R 3 | \name{sfc_cast} 4 | \alias{sfc_cast} 5 | \title{sfc cast} 6 | \usage{ 7 | sfc_cast(sfc, to, close = TRUE) 8 | } 9 | \arguments{ 10 | \item{sfc}{geometry object to convert to a different geometry} 11 | 12 | \item{to}{the geometry to convert to.} 13 | 14 | \item{close}{logical indicating if polygons should be closed} 15 | } 16 | \description{ 17 | convert the input \code{sfc} to a different geometry 18 | } 19 | \examples{ 20 | df <- data.frame( 21 | id1 = c(1,1,1,1,1,1,1,1,2,2,2,2) 22 | , id2 = c(1,1,1,1,2,2,2,2,1,1,1,1) 23 | , x = c(0,0,1,1,1,1,2,2,3,4,4,3) 24 | , y = c(0,1,1,0,1,2,2,1,3,3,4,4) 25 | ) 26 | 27 | pt <- sfc_point(obj = df, x = "x", y = "y", z = "id1") 28 | mpt <- sfc_multipoint(obj = df, x = "x", y = "y", multipoint_id = "id1") 29 | ls <- sfc_linestring(obj = df, x = "x", y = "y", linestring_id = "id1") 30 | mls <- sfc_multilinestring(obj = df, x = "x", y = "y", multilinestring_id = "id1") 31 | p <- sfc_polygon( 32 | obj = df 33 | , x = "x" 34 | , y = "y" 35 | , polygon_id = "id1" 36 | , linestring_id = "id2" 37 | , close = FALSE 38 | ) 39 | mp <- sfc_multipolygon( 40 | obj = df 41 | , x = "x" 42 | , y = "y" 43 | , multipolygon_id = "id1" 44 | , linestring_id = "id2" 45 | , close = FALSE 46 | ) 47 | 48 | sfc_cast( pt, "LINESTRING" ) 49 | sfc_cast( mpt, "POLYGON" ) 50 | sfc_cast( ls, "POINT" ) 51 | sfc_cast( mls, "MULTIPOLYGON" ) 52 | sfc_cast( p, "POINT" ) 53 | sfc_cast( mp, "LINESTRING" ) 54 | 55 | } 56 | -------------------------------------------------------------------------------- /man/sfc_linestring.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sfc_linestring} 4 | \alias{sfc_linestring} 5 | \title{sfc LINESTRING} 6 | \usage{ 7 | sfc_linestring( 8 | obj = NULL, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | linestring_id = NULL 14 | ) 15 | } 16 | \arguments{ 17 | \item{obj}{sorted matrix or data.frame} 18 | 19 | \item{x}{x geometry column} 20 | 21 | \item{y}{y geometry column} 22 | 23 | \item{z}{z geometry column} 24 | 25 | \item{m}{m geometry column} 26 | 27 | \item{linestring_id}{column of ids for linestrings} 28 | } 29 | \value{ 30 | \code{sfc} object of LINESTRING geometries 31 | } 32 | \description{ 33 | constructs sfc of LINESTRING objects 34 | } 35 | \section{notes}{ 36 | 37 | sfheaders functions do not perform any validity checks on the geometries. 38 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 39 | 40 | The data.frame and matrices you send into the sfheader functions must be ordered. 41 | } 42 | 43 | \examples{ 44 | 45 | x <- matrix( c(1:4), ncol = 2 ) 46 | sfc_linestring( x ) 47 | 48 | x <- data.frame( id = 1:2, x = 1:2, y = 2:1 ) 49 | sfc_linestring( x ) 50 | sfc_linestring( x, x = "x", y = "y" ) 51 | sfc_linestring( x, x = "y", y = "x" ) 52 | sfc_linestring( x, linestring_id = "id", x = "x", y = "y") 53 | 54 | df <- data.frame( 55 | id = c(1,1,1,1,2,2,2) 56 | , x = 1:7 57 | , y = 7:1 58 | , z = 14:8 59 | , m = 8:14 60 | ) 61 | 62 | sfc_linestring(df, x = "x", y = "y", linestring_id = "id") 63 | sfc_linestring(df, x = "x", y = "y", z = "z", linestring_id = "id") 64 | sfc_linestring(df, x = "x", y = "y", m = "m", linestring_id = "id") 65 | sfc_linestring(df, x = "x", y = "y", z = "z", m = "m", linestring_id = "id") 66 | 67 | } 68 | -------------------------------------------------------------------------------- /man/sfc_multilinestring.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sfc_multilinestring} 4 | \alias{sfc_multilinestring} 5 | \title{sfc MULTILINESTRING} 6 | \usage{ 7 | sfc_multilinestring( 8 | obj = NULL, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | multilinestring_id = NULL, 14 | linestring_id = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{obj}{sorted matrix or data.frame} 19 | 20 | \item{x}{x geometry column} 21 | 22 | \item{y}{y geometry column} 23 | 24 | \item{z}{z geometry column} 25 | 26 | \item{m}{m geometry column} 27 | 28 | \item{multilinestring_id}{column of ids for multilinestrings} 29 | 30 | \item{linestring_id}{column of ids for linestrings (within multilinestrings)} 31 | } 32 | \value{ 33 | \code{sfc} object of MULTILINESTRING geometries 34 | } 35 | \description{ 36 | constructs an sfc of MULTILINESTRING objects 37 | } 38 | \section{notes}{ 39 | 40 | sfheaders functions do not perform any validity checks on the geometries. 41 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 42 | 43 | The data.frame and matrices you send into the sfheader functions must be ordered. 44 | } 45 | 46 | \examples{ 47 | 48 | m <- matrix(c(0,0,0,0,1,1), ncol = 3 ) 49 | sfc_multilinestring( m ) 50 | 51 | m <- matrix(c(0,0,0,0,0,1,0,1,1,1,2,2,1,2,3), ncol = 3, byrow = TRUE) 52 | sfc_multilinestring( obj = m ) 53 | sfc_multilinestring( obj = m, multilinestring_id = 1 ) 54 | sfc_multilinestring( obj = m, linestring_id = 1 ) 55 | 56 | sfc_multilinestring( obj = m, linestring_id = 1, multilinestring_id = 1 ) 57 | 58 | sfc_multilinestring( obj = m, x = 2, y = 3 ) 59 | sfc_multilinestring( obj = m, x = 1, y = 2, z = 3 ) 60 | sfc_multilinestring( obj = m, x = 2, y = 3, linestring_id = 1, multilinestring_id = 1 ) 61 | 62 | df <- data.frame( 63 | ml_id = c(1,1,1,1,1,1,1,1,2,2,2,2,2) 64 | , l_id = c(1,1,1,2,2,3,3,3,1,1,1,2,2) 65 | , x = rnorm(13) 66 | , y = rnorm(13) 67 | , z = rnorm(13) 68 | , m = rnorm(13) 69 | ) 70 | 71 | sfc_multilinestring( obj = df, x = "x", y = "y") 72 | sfc_multilinestring( obj = df, x = "x", y = "y", z = "z") 73 | sfc_multilinestring( obj = df, x = "x", y = "y", z = "z", m = "m") 74 | 75 | sfc_multilinestring( obj = df, x = 2, y = 3) 76 | sfc_multilinestring( obj = df, x = 2, y = 3, z = 4) 77 | sfc_multilinestring( obj = df, x = 2, y = 3, z = 4, m = 5) 78 | 79 | sfc_multilinestring( obj = df, multilinestring_id = "ml_id", linestring_id = "l_id" ) 80 | sfc_multilinestring( obj = df, multilinestring_id = 1, linestring_id = 2 ) 81 | 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /man/sfc_multipoint.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sfc_multipoint} 4 | \alias{sfc_multipoint} 5 | \title{sfc MULTIPOINT} 6 | \usage{ 7 | sfc_multipoint( 8 | obj, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | multipoint_id = NULL 14 | ) 15 | } 16 | \arguments{ 17 | \item{obj}{sorted matrix or data.frame} 18 | 19 | \item{x}{x geometry column} 20 | 21 | \item{y}{y geometry column} 22 | 23 | \item{z}{z geometry column} 24 | 25 | \item{m}{m geometry column} 26 | 27 | \item{multipoint_id}{column of ids for multipoints} 28 | } 29 | \value{ 30 | \code{sfc} object of MULTIPOINT geometries 31 | } 32 | \description{ 33 | constructs sfc of MULTIPOINT objects 34 | } 35 | \section{notes}{ 36 | 37 | sfheaders functions do not perform any validity checks on the geometries. 38 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 39 | 40 | The data.frame and matrices you send into the sfheader functions must be ordered. 41 | } 42 | 43 | \examples{ 44 | 45 | x <- matrix( c(1:4), ncol = 2 ) 46 | sfc_multipoint( x ) 47 | 48 | x <- data.frame( id = 1:2, x = 1:2, y = 2:1 ) 49 | sfc_multipoint( x ) 50 | sfc_multipoint( x, x = "x", y = "y" ) 51 | sfc_multipoint( x, x = "y", y = "x" ) 52 | sfc_multipoint( x, multipoint_id = "id", x = "x", y = "y") 53 | 54 | } 55 | -------------------------------------------------------------------------------- /man/sfc_multipolygon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sfc_multipolygon} 4 | \alias{sfc_multipolygon} 5 | \title{sfc MULTIPOLYGON} 6 | \usage{ 7 | sfc_multipolygon( 8 | obj = NULL, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | multipolygon_id = NULL, 14 | polygon_id = NULL, 15 | linestring_id = NULL, 16 | close = TRUE 17 | ) 18 | } 19 | \arguments{ 20 | \item{obj}{sorted matrix or data.frame} 21 | 22 | \item{x}{x geometry column} 23 | 24 | \item{y}{y geometry column} 25 | 26 | \item{z}{z geometry column} 27 | 28 | \item{m}{m geometry column} 29 | 30 | \item{multipolygon_id}{column of ids for multipolygons} 31 | 32 | \item{polygon_id}{column of ids for polygons} 33 | 34 | \item{linestring_id}{column of ids for lines (within polygons)} 35 | 36 | \item{close}{logical indicating whether polygons should be closed. If \code{TRUE}, 37 | all polygons will be checked and force closed if possible} 38 | } 39 | \value{ 40 | \code{sfc} object of MULTIPOLYGON geometries 41 | } 42 | \description{ 43 | constructs an sfc of MULTIPOLYGON objects 44 | } 45 | \section{notes}{ 46 | 47 | sfheaders functions do not perform any validity checks on the geometries. 48 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 49 | 50 | The data.frame and matrices you send into the sfheader functions must be ordered. 51 | } 52 | 53 | \examples{ 54 | 55 | m <- matrix(c(0,0,0,0,1,0,0,1,1,0,0,1,0,0,0), ncol = 3, byrow = TRUE ) 56 | sfc_multipolygon( m ) 57 | 58 | df <- data.frame( 59 | id = c(1,1,1,1,1) 60 | , x = c(0,0,1,1,0) 61 | , y = c(0,1,1,0,0) 62 | ) 63 | 64 | sfc_multipolygon( df, x = "x", y = "y" ) 65 | 66 | df <- data.frame( 67 | id = c(1,1,1,1,1,2,2,2,2,2) 68 | , x = c(0,0,1,1,0,1,1,2,2,1) 69 | , y = c(0,1,1,0,0,1,2,2,1,1) 70 | ) 71 | 72 | sfc_multipolygon( df, multipolygon_id = "id", polygon_id = "id", linestring_id = "id") 73 | 74 | df <- data.frame( 75 | id1 = c(1,1,1,1,1,1,1,1,1,1) 76 | , id2 = c(1,1,1,1,1,2,2,2,2,2) 77 | , x = c(0,0,1,1,0,1,1,2,2,1) 78 | , y = c(0,1,1,0,0,1,2,2,1,1) 79 | ) 80 | 81 | sfc_multipolygon( df, multipolygon_id = "id1", polygon_id = "id2") 82 | 83 | df <- data.frame( 84 | id1 = c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2) 85 | , id2 = c(1,1,1,1,1,2,2,2,2,2,1,1,1,1,1) 86 | , x = c(0,0,1,1,0,1,1,2,2,1,3,3,4,4,3) 87 | , y = c(0,1,1,0,0,1,2,2,1,1,3,4,4,3,3) 88 | ) 89 | 90 | sfc_multipolygon( df, multipolygon_id = "id1", polygon_id = "id2") 91 | 92 | df <- data.frame( 93 | id1 = c(1,1,1,1,1,2,2,2,2,2) 94 | , id2 = c(1,1,1,1,1,1,1,1,1,1) 95 | , x = c(0,0,1,1,0,1,1,2,2,1) 96 | , y = c(0,1,1,0,0,1,2,2,1,1) 97 | ) 98 | 99 | sfc_multipolygon( df, multipolygon_id = "id1", polygon_id = "id2" ) 100 | sfc_multipolygon( df, polygon_id = "id1", linestring_id = "id2" ) 101 | sfc_multipolygon( df, x = "x", y = "y", polygon_id = "id1") 102 | sfc_multipolygon( df, x = "x", y = "y", polygon_id = "id1", linestring_id = "id2") 103 | sfc_multipolygon( df, x = "x", y = "y", linestring_id = "id1") 104 | sfc_multipolygon( df, x = "x", y = "y", linestring_id = "id2") 105 | 106 | df <- data.frame( 107 | id1 = c('a','a','a','a','a','b','b','b','b','b') 108 | , id2 = c(1,1,1,1,1,1,1,1,1,1) 109 | , x = c(0,0,1,1,0,1,1,2,2,1) 110 | , y = c(0,1,1,0,0,1,2,2,1,1) 111 | ) 112 | 113 | sfc_multipolygon( df, x = "x", y = "y", polygon_id = "id1") 114 | 115 | } 116 | -------------------------------------------------------------------------------- /man/sfc_point.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sfc_point} 4 | \alias{sfc_point} 5 | \title{sfc POINT} 6 | \usage{ 7 | sfc_point(obj, x = NULL, y = NULL, z = NULL, m = NULL) 8 | } 9 | \arguments{ 10 | \item{obj}{sorted vector, matrix or data.frame} 11 | 12 | \item{x}{x geometry column} 13 | 14 | \item{y}{y geometry column} 15 | 16 | \item{z}{z geometry column} 17 | 18 | \item{m}{m geometry column} 19 | } 20 | \value{ 21 | \code{sfc} object of POINT geometries 22 | } 23 | \description{ 24 | constructs sfc of POINT objects 25 | } 26 | \section{notes}{ 27 | 28 | sfheaders functions do not perform any validity checks on the geometries. 29 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 30 | 31 | The data.frame and matrices you send into the sfheader functions must be ordered. 32 | } 33 | 34 | \examples{ 35 | 36 | x <- c(1:3) 37 | sfc_point( x ) 38 | 39 | x <- matrix( c(1:10) , ncol = 2 ) 40 | sfc_point( x ) 41 | 42 | x <- setNames( as.data.frame( x ), c("x","y") ) 43 | sfc_point( x ) 44 | sfc_point( obj = x, x = "x", y = "y" ) 45 | sfc_point( obj = x, x = "y", y = "x" ) 46 | 47 | } 48 | -------------------------------------------------------------------------------- /man/sfc_polygon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfc.R 3 | \name{sfc_polygon} 4 | \alias{sfc_polygon} 5 | \title{sfc POLYGON} 6 | \usage{ 7 | sfc_polygon( 8 | obj = NULL, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | polygon_id = NULL, 14 | linestring_id = NULL, 15 | close = TRUE 16 | ) 17 | } 18 | \arguments{ 19 | \item{obj}{sorted matrix or data.frame} 20 | 21 | \item{x}{x geometry column} 22 | 23 | \item{y}{y geometry column} 24 | 25 | \item{z}{z geometry column} 26 | 27 | \item{m}{m geometry column} 28 | 29 | \item{polygon_id}{column of ids for polygons} 30 | 31 | \item{linestring_id}{column of ids for lines (within polygons)} 32 | 33 | \item{close}{logical indicating whether polygons should be closed. If \code{TRUE}, 34 | all polygons will be checked and force closed if possible} 35 | } 36 | \value{ 37 | \code{sfc} object of POLYGON geometries 38 | } 39 | \description{ 40 | constructs an sfc of POLYGON objects 41 | } 42 | \section{notes}{ 43 | 44 | sfheaders functions do not perform any validity checks on the geometries. 45 | Nor do they set Coordinate Reference Systems, EPSG, PROJ4 or precision attributes. 46 | 47 | The data.frame and matrices you send into the sfheader functions must be ordered. 48 | } 49 | 50 | \examples{ 51 | 52 | m <- matrix(c(0,0,0,0,1,1), ncol = 2 ) 53 | sfc_polygon( m ) 54 | 55 | m <- matrix(c(0,0,0,0,0,1,0,1,1,1,2,2,1,2,3,1,3,2), ncol = 3, byrow = TRUE) 56 | sfc_polygon( obj = m ) 57 | sfc_polygon( obj = m, polygon_id = 1 ) 58 | sfc_polygon( obj = m, linestring_id = 1 ) 59 | 60 | sfc_polygon( obj = m, linestring_id = 1, polygon_id = 1 ) 61 | 62 | sfc_polygon( obj = m, x = 2, y = 3 ) 63 | sfc_polygon( obj = m, x = 1, y = 2, z = 3 ) 64 | sfc_polygon( obj = m, x = 2, y = 3, linestring_id = 1, polygon_id = 1 ) 65 | 66 | df <- data.frame( 67 | ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 68 | , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 69 | , x = rnorm(15) 70 | , y = rnorm(15) 71 | , z = rnorm(15) 72 | , m = rnorm(15) 73 | ) 74 | 75 | sfc_polygon( obj = df, x = "x", y = "y") 76 | sfc_polygon( obj = df, x = "x", y = "y", z = "z") 77 | sfc_polygon( obj = df, x = "x", y = "y", z = "z", m = "m") 78 | 79 | sfc_polygon( obj = df, x = 2, y = 3) 80 | sfc_polygon( obj = df, x = 2, y = 3, z = 4) 81 | sfc_polygon( obj = df, x = 2, y = 3, z = 4, m = 5) 82 | 83 | sfc_polygon( obj = df, polygon_id = "ml_id", linestring_id = "l_id" ) 84 | sfc_polygon( obj = df, polygon_id = 1, linestring_id = 2 ) 85 | 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /man/sfc_to_df.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/df.R 3 | \name{sfc_to_df} 4 | \alias{sfc_to_df} 5 | \title{sfc to df} 6 | \usage{ 7 | sfc_to_df(sfc) 8 | } 9 | \arguments{ 10 | \item{sfc}{sfc object} 11 | } 12 | \description{ 13 | Converts an sfc object to a data.frame 14 | } 15 | \examples{ 16 | 17 | x <- matrix( c(1:16), ncol = 2 ) 18 | sfc <- sfc_linestring( x ) 19 | df <- sfc_to_df( sfc ) 20 | 21 | df <- data.frame( 22 | ml_id = c(1,1,1,1,1,1,1,1,2,2,2,2,2) 23 | , l_id = c(1,1,1,2,2,3,3,3,1,1,1,2,2) 24 | , x = rnorm(13) 25 | , y = rnorm(13) 26 | , z = rnorm(13) 27 | , m = rnorm(13) 28 | ) 29 | sfc <- sfc_multilinestring( obj = df, multilinestring_id = "ml_id", linestring_id = "l_id" ) 30 | 31 | df <- sfc_to_df( sfc ) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /man/sfg_linestring.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfg.R 3 | \name{sfg_linestring} 4 | \alias{sfg_linestring} 5 | \title{sfg linestring} 6 | \usage{ 7 | sfg_linestring(obj, x = NULL, y = NULL, z = NULL, m = NULL) 8 | } 9 | \arguments{ 10 | \item{obj}{matrix or data.frame} 11 | 12 | \item{x}{x geometry column} 13 | 14 | \item{y}{y geometry column} 15 | 16 | \item{z}{z geometry column} 17 | 18 | \item{m}{m geometry column} 19 | } 20 | \value{ 21 | \code{sfg} object of LINESTRING geometry 22 | } 23 | \description{ 24 | constructs sfg LINESTRING object 25 | } 26 | \examples{ 27 | 28 | sfg_linestring( 1:2 ) 29 | sfg_linestring( 1:3 ) 30 | sfg_linestring( 1:4 ) 31 | 32 | sfg_linestring( matrix( 1:24, ncol = 2 ) ) 33 | sfg_linestring( matrix( 1:24, ncol = 3 ) ) 34 | sfg_linestring( matrix( 1:24, ncol = 4 ) ) 35 | 36 | sfg_linestring( matrix( 1:24, ncol = 4 ), x = 3, y = 2, z = 3) 37 | 38 | sfg_linestring( data.frame( x = 1:10, y = 11:20 ) ) 39 | sfg_linestring( data.frame( x = 1:10, y = 11:20, z = 21:30 ) ) 40 | sfg_linestring( data.frame( x = 1:10, y = 11:20, z = 21:30 ), x = "x", y = "z" ) 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /man/sfg_multilinestring.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfg.R 3 | \name{sfg_multilinestring} 4 | \alias{sfg_multilinestring} 5 | \title{sfg multilinestring} 6 | \usage{ 7 | sfg_multilinestring( 8 | obj, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | linestring_id = NULL 14 | ) 15 | } 16 | \arguments{ 17 | \item{obj}{matrix or data.frame} 18 | 19 | \item{x}{x geometry column} 20 | 21 | \item{y}{y geometry column} 22 | 23 | \item{z}{z geometry column} 24 | 25 | \item{m}{m geometry column} 26 | 27 | \item{linestring_id}{column of ids for lines} 28 | } 29 | \value{ 30 | \code{sfg} object of MULTILINESTRING geometry 31 | } 32 | \description{ 33 | constructs sfg MULTILINESTRING object 34 | } 35 | \examples{ 36 | 37 | sfg_multilinestring( matrix( 1:24, ncol = 2 ) ) 38 | sfg_multilinestring( matrix( 1:24, ncol = 3 ) ) 39 | sfg_multilinestring( matrix( 1:24, ncol = 4 ) ) 40 | 41 | ## different lines 42 | m <- cbind( matrix( 1:24, ncol = 2 ), c(rep(1, 6), rep(2, 6) ) ) 43 | sfg_multilinestring( obj = m, x = 1, y = 2, linestring_id = 3 ) 44 | 45 | ## just specifying linestring_id will use all others as the geometries 46 | sfg_multilinestring( obj = m, linestring_id = 3 ) 47 | 48 | df <- data.frame( x = 1:12, y = 1:12, z = 13:24, id = c(rep(1,6), rep(2,6))) 49 | sfg_multilinestring( df, x = "x", y = "y" ) 50 | sfg_multilinestring( df, x = "x", y = "y", linestring_id = "id" ) 51 | 52 | sfg_multilinestring( df, linestring_id = "id" ) 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /man/sfg_multipoint.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfg.R 3 | \name{sfg_multipoint} 4 | \alias{sfg_multipoint} 5 | \title{sfg multipoint} 6 | \usage{ 7 | sfg_multipoint(obj, x = NULL, y = NULL, z = NULL, m = NULL) 8 | } 9 | \arguments{ 10 | \item{obj}{matrix or data.frame} 11 | 12 | \item{x}{x geometry column} 13 | 14 | \item{y}{y geometry column} 15 | 16 | \item{z}{z geometry column} 17 | 18 | \item{m}{m geometry column} 19 | } 20 | \value{ 21 | \code{sfg} object of MULTIPOINT geometry 22 | } 23 | \description{ 24 | constructs sfg MULTIPOINT object 25 | } 26 | \examples{ 27 | 28 | sfg_multipoint( 1:2 ) 29 | sfg_multipoint( 1:3 ) 30 | sfg_multipoint( 1:4 ) 31 | 32 | sfg_multipoint( matrix( 1:3, ncol = 3 ) ) 33 | sfg_multipoint( data.frame( x = 1, y = 2, z = 3 ) ) 34 | 35 | sfg_multipoint( matrix( 1:4, ncol = 2 ) ) 36 | sfg_multipoint( matrix( 1:24, ncol = 2, byrow = TRUE ) ) 37 | sfg_multipoint( matrix( 1:24, ncol = 3, byrow = TRUE ) ) 38 | sfg_multipoint( matrix( 1:24, ncol = 4, byrow = TRUE ) ) 39 | 40 | sfg_multipoint( data.frame( x = 1:5, y = 1:5 ) ) 41 | 42 | ## using columns 43 | 44 | sfg_multipoint( matrix( 1:24, ncol = 4, byrow = TRUE ), x = 1, y = 2 ) 45 | sfg_multipoint( matrix( 1:24, ncol = 4, byrow = TRUE ), x = 1, y = 2, z = 3 ) 46 | sfg_multipoint( matrix( 1:24, ncol = 4, byrow = TRUE ), x = 3, y = 4 ) 47 | 48 | df <- data.frame( x = 1:5, y = 1:5, z = 11:15, m = 11:15 ) 49 | sfg_multipoint( df, x = "x", y = "y" ) 50 | sfg_multipoint( df, x = "x", y = "y", z = "z" ) 51 | sfg_multipoint( df, x = "x", y = "y", z = "z", m = "m" ) 52 | 53 | } 54 | -------------------------------------------------------------------------------- /man/sfg_multipolygon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfg.R 3 | \name{sfg_multipolygon} 4 | \alias{sfg_multipolygon} 5 | \title{sfg multipolygon} 6 | \usage{ 7 | sfg_multipolygon( 8 | obj, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | polygon_id = NULL, 14 | linestring_id = NULL, 15 | close = TRUE 16 | ) 17 | } 18 | \arguments{ 19 | \item{obj}{matrix or data.frame} 20 | 21 | \item{x}{x geometry column} 22 | 23 | \item{y}{y geometry column} 24 | 25 | \item{z}{z geometry column} 26 | 27 | \item{m}{m geometry column} 28 | 29 | \item{polygon_id}{column of ids for polygons (within the multipolygon)} 30 | 31 | \item{linestring_id}{column of ids for lines (within polygons)} 32 | 33 | \item{close}{logical indicating whether polygons should be closed. If \code{TRUE}, 34 | all polygons will be checked and force closed if possible} 35 | } 36 | \value{ 37 | \code{sfg} object of MULTIPOLYGON geometry 38 | } 39 | \description{ 40 | constructs sfg MULTIPOLYGON object 41 | } 42 | \examples{ 43 | 44 | df <- data.frame( 45 | polygon_id = c(rep(1, 5), rep(2, 10)) 46 | , line_id = c(rep(1, 10), rep(2, 5)) 47 | , x = c(0,0,1,1,0,2,2,5,5,2,3,3,4,4,3) 48 | , y = c(0,1,1,0,0,2,5,5,2,2,3,4,4,3,3) 49 | , z = c(1) 50 | , m = c(1) 51 | ) 52 | 53 | m <- as.matrix( df ) 54 | 55 | sfg_multipolygon( df[, c("x","y") ] ) 56 | 57 | sfg_multipolygon( 58 | df, x = "x", y = "y", polygon_id = "polygon_id", linestring_id = "line_id" 59 | ) 60 | sfg_multipolygon( 61 | df, x = "x", y = "y", z = "z", polygon_id = "polygon_id", linestring_id = "line_id" 62 | ) 63 | sfg_multipolygon( 64 | df, x = "x", y = "y", z = "z", m = "m", polygon_id = "polygon_id", linestring_id = "line_id" 65 | ) 66 | 67 | 68 | sfg_multipolygon( m[, c("x","y") ] ) 69 | 70 | sfg_multipolygon( 71 | m, x = "x", y = "y", polygon_id = "polygon_id", linestring_id = "line_id" 72 | ) 73 | sfg_multipolygon( 74 | m, x = "x", y = "y", z = "z", polygon_id = "polygon_id", linestring_id = "line_id" 75 | ) 76 | sfg_multipolygon( 77 | m, x = "x", y = "y", z = "z", m = "m", polygon_id = "polygon_id", linestring_id = "line_id" 78 | ) 79 | 80 | } 81 | -------------------------------------------------------------------------------- /man/sfg_point.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfg.R 3 | \name{sfg_point} 4 | \alias{sfg_point} 5 | \title{sfg point} 6 | \usage{ 7 | sfg_point(obj, x = NULL, y = NULL, z = NULL, m = NULL) 8 | } 9 | \arguments{ 10 | \item{obj}{matrix or data.frame} 11 | 12 | \item{x}{x geometry column} 13 | 14 | \item{y}{y geometry column} 15 | 16 | \item{z}{z geometry column} 17 | 18 | \item{m}{m geometry column} 19 | } 20 | \value{ 21 | \code{sfg} object of POINT geometry 22 | } 23 | \description{ 24 | constructs sfg POINT object 25 | } 26 | \examples{ 27 | 28 | sfg_point( 1:2 ) 29 | sfg_point( 1:3 ) 30 | sfg_point( 1:4 ) 31 | 32 | sfg_point( matrix( 1:3, ncol = 3 ) ) 33 | sfg_point( data.frame( x = 1, y = 2, z = 3 ) ) 34 | 35 | sfg_point( data.frame( x = 1, y = 2, z = 3 ), x = "x", y = "y" ) 36 | sfg_point( data.frame( x = 1, y = 2, z = 3 ), x = 1, y = 3 ) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /man/sfg_polygon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sfg.R 3 | \name{sfg_polygon} 4 | \alias{sfg_polygon} 5 | \title{sfg polygon} 6 | \usage{ 7 | sfg_polygon( 8 | obj, 9 | x = NULL, 10 | y = NULL, 11 | z = NULL, 12 | m = NULL, 13 | linestring_id = NULL, 14 | close = TRUE 15 | ) 16 | } 17 | \arguments{ 18 | \item{obj}{matrix or data.frame} 19 | 20 | \item{x}{x geometry column} 21 | 22 | \item{y}{y geometry column} 23 | 24 | \item{z}{z geometry column} 25 | 26 | \item{m}{m geometry column} 27 | 28 | \item{linestring_id}{column of ids for lines (within polygons)} 29 | 30 | \item{close}{logical indicating whether polygons should be closed. If \code{TRUE}, 31 | all polygons will be checked and force closed if possible} 32 | } 33 | \value{ 34 | \code{sfg} object of POLYGON geometry 35 | } 36 | \description{ 37 | constructs sfg POLYGON object 38 | } 39 | \examples{ 40 | 41 | sfg_polygon( matrix( 1:24, ncol = 2 ) ) 42 | sfg_polygon( matrix( 1:24, ncol = 3 ) ) 43 | sfg_polygon( matrix( 1:24, ncol = 4 ) ) 44 | 45 | ## different lines 46 | m <- cbind( matrix( 1:24, ncol = 2 ), c(rep(1, 6), rep(2, 6) ) ) 47 | sfg_polygon( obj = m, x = 1, y = 2, linestring_id = 3 ) 48 | 49 | ## just specifying linestring_id will use all others as the geometries 50 | sfg_polygon( obj = m, linestring_id = 3 ) 51 | 52 | df <- data.frame( x = 1:12, y = 1:12, z = 13:24, id = c(rep(1,6), rep(2,6))) 53 | sfg_polygon( df, x = "x", y = "y" ) 54 | sfg_polygon( df, x = "x", y = "y", linestring_id = "id" ) 55 | 56 | sfg_polygon( df, linestring_id = "id" ) 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /man/sfg_to_df.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/df.R 3 | \name{sfg_to_df} 4 | \alias{sfg_to_df} 5 | \title{sfg to df} 6 | \usage{ 7 | sfg_to_df(sfg) 8 | } 9 | \arguments{ 10 | \item{sfg}{sfg object} 11 | } 12 | \description{ 13 | Converts an sfg object to a data.frame 14 | } 15 | \examples{ 16 | sfg <- sfg_point( obj = c(1,2) ) 17 | df <- sfg_to_df( sfg ) 18 | 19 | m <- cbind( matrix( 1:24, ncol = 2 ), c(rep(1, 6), rep(2, 6) ) ) 20 | sfg <- sfg_polygon( obj = m, x = 1, y = 2, linestring_id = 3 ) 21 | df <- sfg_to_df( sfg ) 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /sfheaders.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 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace,vignette 22 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | PKG_CXXFLAGS = -I../inst/include/ 2 | PKG_CPPFLAGS=-DSTRICT_R_HEADERS 3 | -------------------------------------------------------------------------------- /src/Makevars.win: -------------------------------------------------------------------------------- 1 | PKG_CXXFLAGS = -I../inst/include/ 2 | PKG_CPPFLAGS=-DSTRICT_R_HEADERS 3 | -------------------------------------------------------------------------------- /src/bbox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | #include "geometries/bbox/bbox.hpp" 5 | #include "sfheaders/sfc/bbox.hpp" 6 | #include "sfheaders/sfc/z_range.hpp" 7 | #include "sfheaders/sfc/m_range.hpp" 8 | 9 | /* 10 | * calculate bbox 11 | * 12 | * assumes 2-column object, in the order x, y 13 | */ 14 | // [[Rcpp::export]] 15 | SEXP rcpp_calculate_bbox( SEXP x, SEXP geometry_cols ) { 16 | Rcpp::NumericVector bbox = sfheaders::bbox::start_bbox(); 17 | geometries::bbox::calculate_bbox( bbox, x, geometry_cols ); 18 | sfheaders::bbox::attach_bbox_attributes( bbox ); 19 | return bbox; 20 | } 21 | 22 | // [[Rcpp::export]] 23 | SEXP rcpp_calculate_z_range( SEXP x ) { 24 | Rcpp::NumericVector z_range = sfheaders::zm::start_z_range(); 25 | sfheaders::zm::calculate_z_range( z_range, x ); 26 | return z_range; 27 | } 28 | 29 | // [[Rcpp::export]] 30 | SEXP rcpp_calculate_m_range( SEXP x, std::string xyzm ) { 31 | Rcpp::NumericVector m_range = sfheaders::zm::start_m_range(); 32 | sfheaders::zm::calculate_m_range( m_range, x, xyzm ); 33 | return m_range; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/cast.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sfheaders/cast/sfg_cast.hpp" 3 | #include "sfheaders/cast/sfc_cast.hpp" 4 | #include "sfheaders/cast/sf_cast.hpp" 5 | // #include "sfheaders/cast/list_cast.hpp" 6 | #include "sfheaders/sfc/sfc.hpp" 7 | 8 | // [[Rcpp::export]] 9 | Rcpp::IntegerVector rcpp_count_new_objects( SEXP sfg, std::string cast_to ) { 10 | R_xlen_t x = sfheaders::cast::count_new_objects( sfg, cast_to ); 11 | Rcpp::IntegerVector res(1); 12 | res[0] = x; 13 | return res; 14 | } 15 | 16 | // [[Rcpp::export]] 17 | Rcpp::IntegerVector rcpp_count_new_sfc_objects( Rcpp::List sfc, std::string cast_to ) { 18 | return sfheaders::cast::count_new_sfc_objects( sfc, cast_to ); 19 | } 20 | 21 | // [[Rcpp::export]] 22 | Rcpp::List rcpp_cast_sfc( Rcpp::List sfc, std::string cast_to, bool close = true ) { 23 | Rcpp::List sfc2 = Rcpp::clone( sfc ); 24 | return sfheaders::cast::cast_sfc( sfc2, cast_to, close ); 25 | } 26 | 27 | // [[Rcpp::export]] 28 | Rcpp::DataFrame rcpp_cast_sf( Rcpp::DataFrame sf, std::string cast_to, SEXP list_columns, bool close = true ) { 29 | return sfheaders::cast::cast_sf( sf, cast_to, list_columns, close ); 30 | } 31 | 32 | // // [[Rcpp::export]] 33 | // SEXP rcpp_cast_remove_one( Rcpp::List lst ) { 34 | // return sfheaders::cast::remove_one( lst ); 35 | // } 36 | -------------------------------------------------------------------------------- /src/lists.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "geometries/utils/lists/list.hpp" 3 | 4 | // [[Rcpp::export]] 5 | Rcpp::List rcpp_fill_list( Rcpp::NumericVector v, Rcpp::IntegerMatrix line_ids ) { 6 | return geometries::utils::fill_list( v, line_ids ); 7 | } 8 | 9 | // [[Rcpp::export]] 10 | Rcpp::List rcpp_list_sizes( Rcpp::List lst ) { 11 | R_xlen_t total_size = 0; 12 | int existing_type = 10; 13 | Rcpp::List lst_sizes = geometries::utils::list_size( lst, total_size, existing_type ); 14 | return Rcpp::List::create( 15 | Rcpp::_["elements"] = lst_sizes, 16 | Rcpp::_["total"] = total_size 17 | ); 18 | } 19 | 20 | // [[Rcpp::export]] 21 | int rcpp_list_type( Rcpp::List lst ) { 22 | R_xlen_t total_size = 0; 23 | int existing_type = 10; 24 | Rcpp::List lst_sizes = geometries::utils::list_size( lst, total_size, existing_type ); 25 | return existing_type; 26 | } 27 | 28 | // [[Rcpp::export]] 29 | SEXP rcpp_unlist_list( Rcpp::List lst ) { 30 | R_xlen_t total_size = 0; 31 | int existing_type = 10; 32 | R_xlen_t position = 0; 33 | Rcpp::List lst_sizes = geometries::utils::list_size( lst, total_size, existing_type ); 34 | switch( existing_type ) { 35 | case LGLSXP: { 36 | Rcpp::LogicalVector lv( total_size ); 37 | geometries::utils::unlist_list( lst, lst_sizes, lv, position ); 38 | return lv; 39 | } 40 | case INTSXP: { 41 | Rcpp::IntegerVector iv( total_size ); 42 | geometries::utils::unlist_list( lst, lst_sizes, iv, position ); 43 | return iv; 44 | } 45 | case REALSXP: { 46 | Rcpp::NumericVector nv( total_size ); 47 | geometries::utils::unlist_list( lst, lst_sizes, nv, position ); 48 | return nv; 49 | } 50 | default: { 51 | Rcpp::StringVector sv( total_size ); 52 | geometries::utils::unlist_list( lst, lst_sizes, sv, position ); 53 | return sv; 54 | } 55 | } 56 | 57 | Rcpp::stop("sfheaders - couldn't unlist this object"); 58 | return lst; // #nocov - never reaches 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/sfg_dimension.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "sfheaders/sfg/sfg_dimension.hpp" 4 | 5 | // [[Rcpp::export]] 6 | std::string rcpp_sfg_dimension( 7 | SEXP x, 8 | std::string xyzm 9 | ) { 10 | return sfheaders::sfg::sfg_dimension( x, xyzm ); 11 | } 12 | -------------------------------------------------------------------------------- /src/shapes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | //#include "geometries/shapes/shapes.hpp" 3 | 4 | // 5 | // // POINTS ----------- 6 | // // [[Rcpp::export]] 7 | // SEXP rcpp_get_vec( 8 | // SEXP x, 9 | // SEXP cols 10 | // ) { 11 | // return geometries::shapes::to_vec( x, cols ); 12 | // } 13 | // 14 | // // LINE ---------- 15 | // // [[Rcpp::export]] 16 | // SEXP rcpp_get_mat( 17 | // SEXP x, 18 | // SEXP cols 19 | // ) { 20 | // return geometries::shapes::to_mat( x, cols ); 21 | // } 22 | // 23 | // // LINES ----------- 24 | // // [[Rcpp::export]] 25 | // SEXP rcpp_get_list_mat( 26 | // SEXP x, 27 | // SEXP cols, 28 | // SEXP id 29 | // ) { 30 | // return geometries::shapes::to_listMat( x, cols, id ); 31 | // } 32 | -------------------------------------------------------------------------------- /src/to_df.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sfheaders/df/sf.hpp" 3 | 4 | // [[Rcpp::export]] 5 | SEXP rcpp_sfg_to_df( SEXP sfg ) { 6 | return sfheaders::df::sfg_to_df( sfg ); 7 | } 8 | 9 | // [[Rcpp::export]] 10 | SEXP rcpp_sfc_to_df( Rcpp::List sfc ) { 11 | return sfheaders::df::sfc_to_df( sfc ); 12 | } 13 | 14 | // [[Rcpp::export]] 15 | SEXP rcpp_sf_to_df( Rcpp::DataFrame sf, bool fill = false ) { 16 | return sfheaders::df::sf_to_df( sf, fill ); 17 | } 18 | 19 | // [[Rcpp::export]] 20 | SEXP rcpp_sf_to_df_unlist( Rcpp::DataFrame sf, Rcpp::StringVector unlist, bool fill = false ) { 21 | return sfheaders::df::sf_to_df( sf, unlist, fill ); 22 | } 23 | -------------------------------------------------------------------------------- /src/to_sf.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include "sfheaders/sf/sf.hpp" 5 | 6 | // #include "sfheaders/sf/sf.hpp" 7 | // //#include "sfheaders/sf/point/sf_point.hpp" 8 | // //#include "sfheaders/sf/multipoint/sf_multipoint.hpp" 9 | // //#include "sfheaders/sf/linestring/sf_linestring.hpp" 10 | // //#include "sfheaders/sf/multilinestring/sf_multilinestring.hpp" 11 | // //#include "sfheaders/sf/polygon/sf_polygon.hpp" 12 | // //#include "sfheaders/sf/multipolygon/sf_multipolygon.hpp" 13 | // 14 | // // /* 15 | // // * rcpp_make_sf 16 | // // * 17 | // // * Creates an 'sf' object from an sfc, and a vector of ids 18 | // // */ 19 | // // // [[Rcpp::export]] 20 | // // SEXP rcpp_make_sf( Rcpp::List sfc, SEXP ids ) { 21 | // // return sfheaders::sf::make_sf( sfc, ids ); 22 | // // } 23 | // 24 | // [[Rcpp::export]] 25 | SEXP rcpp_to_sf( 26 | SEXP obj, 27 | SEXP geometry_columns, 28 | SEXP multipoint_id, 29 | SEXP linestring_id, 30 | SEXP multilinestring_id, 31 | SEXP polygon_id, 32 | SEXP multipolygon_id, 33 | SEXP list_columns, 34 | bool close, 35 | bool keep, 36 | std::string xyzm, 37 | std::string sf_type 38 | ) { 39 | return sfheaders::api::to_sf( 40 | obj, 41 | geometry_columns, 42 | multipoint_id, 43 | linestring_id, 44 | multilinestring_id, 45 | polygon_id, 46 | multipolygon_id, 47 | list_columns, 48 | xyzm, 49 | keep, 50 | close, 51 | sf_type 52 | ); 53 | } 54 | 55 | 56 | // [[Rcpp::export]] 57 | SEXP rcpp_sf_point( SEXP x, SEXP cols, std::string xyzm, bool keep ) { 58 | return sfheaders::api::sf_point( x, cols, xyzm, keep ); 59 | } 60 | 61 | // [[Rcpp::export]] 62 | SEXP rcpp_sf_multipoint( SEXP x, SEXP cols, SEXP multipoint_id, std::string xyzm, bool keep ) { 63 | return sfheaders::api::sf_multipoint( x, cols, multipoint_id, xyzm, keep ); 64 | } 65 | 66 | // [[Rcpp::export]] 67 | SEXP rcpp_sf_linestring( SEXP x, SEXP cols, SEXP linestring_id, std::string xyzm, bool keep ) { 68 | return sfheaders::api::sf_linestring( x, cols, linestring_id, xyzm, keep ); 69 | } 70 | 71 | // [[Rcpp::export]] 72 | SEXP rcpp_sf_multilinestring( SEXP x, SEXP cols, SEXP multilinestring_id, SEXP linestring_id, std::string xyzm, bool keep ) { 73 | return sfheaders::api::sf_multilinestring( x, cols, multilinestring_id, linestring_id, xyzm, keep ); 74 | } 75 | 76 | // [[Rcpp::export]] 77 | SEXP rcpp_sf_polygon( SEXP x, SEXP cols, SEXP polygon_id, SEXP linestring_id, std::string xyzm, bool keep, bool close ) { 78 | return sfheaders::api::sf_polygon( x, cols, polygon_id, linestring_id, xyzm, keep, close ); 79 | } 80 | 81 | // [[Rcpp::export]] 82 | SEXP rcpp_sf_multipolygon( SEXP x, SEXP cols, SEXP multipolygon_id, SEXP polygon_id, SEXP linestring_id, std::string xyzm, bool keep, bool close ) { 83 | return sfheaders::api::sf_multipolygon( x, cols, multipolygon_id, polygon_id, linestring_id, xyzm, keep, close ); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/to_sfg.cpp: -------------------------------------------------------------------------------- 1 | // #include 2 | #include "sfheaders/sfg/sfg.hpp" 3 | // 4 | // [[Rcpp::export]] 5 | std::string rcpp_get_sfg_type( int sfg_type ) { 6 | return sfheaders::sfg::get_sfg_type( sfg_type ); 7 | } 8 | // 9 | // [[Rcpp::export]] 10 | SEXP rcpp_sfg_point( SEXP x, SEXP geometry_columns, std::string xyzm ) { 11 | SEXP x2 = Rcpp::clone( x ); 12 | return sfheaders::sfg::sfg_point( x2, geometry_columns, xyzm ); 13 | } 14 | 15 | // [[Rcpp::export]] 16 | Rcpp::List rcpp_sfg_points( Rcpp::List lst, std::string xyzm ) { 17 | //Rcpp::List lst2 = Rcpp::clone( lst ); 18 | return sfheaders::sfg::sfg_points( lst, xyzm ); 19 | } 20 | 21 | // [[Rcpp::export]] 22 | SEXP rcpp_sfg_multipoint( SEXP x, SEXP geometry_columns, std::string xyzm ) { 23 | SEXP x2 = Rcpp::clone( x ); 24 | return sfheaders::sfg::sfg_multipoint( x2, geometry_columns, xyzm ); 25 | } 26 | 27 | // [[Rcpp::export]] 28 | Rcpp::List rcpp_sfg_multipoints( Rcpp::List& lst, std::string xyzm ) { 29 | return sfheaders::sfg::sfg_multipoints( lst, xyzm ); 30 | } 31 | 32 | // [[Rcpp::export]] 33 | SEXP rcpp_sfg_linestring( SEXP x, SEXP geometry_columns, std::string xyzm ) { 34 | SEXP x2 = Rcpp::clone( x ); 35 | return sfheaders::sfg::sfg_linestring( x2, geometry_columns, xyzm ); 36 | } 37 | 38 | // [[Rcpp::export]] 39 | Rcpp::List rcpp_sfg_linestrings( Rcpp::List& lst, std::string xyzm ) { 40 | return sfheaders::sfg::sfg_linestrings( lst, xyzm ); 41 | } 42 | 43 | 44 | // [[Rcpp::export]] 45 | SEXP rcpp_sfg_multilinestring( SEXP x, SEXP geometry_columns, SEXP line_id, std::string xyzm ) { 46 | SEXP x2 = Rcpp::clone( x ); 47 | return sfheaders::sfg::sfg_multilinestring( x2, geometry_columns, line_id, xyzm ); 48 | } 49 | 50 | // [[Rcpp::export]] 51 | Rcpp::List rcpp_sfg_multilinestrings( Rcpp::List& lst, std::string xyzm ) { 52 | return sfheaders::sfg::sfg_multilinestrings( lst, xyzm ); 53 | } 54 | 55 | // [[Rcpp::export]] 56 | SEXP rcpp_sfg_polygon( SEXP x, SEXP geometry_columns, SEXP line_id, std::string xyzm, bool close ) { 57 | SEXP x2 = Rcpp::clone( x ); 58 | return sfheaders::sfg::sfg_polygon( x2, geometry_columns, line_id, xyzm, close ); 59 | } 60 | 61 | // [[Rcpp::export]] 62 | Rcpp::List rcpp_sfg_polygons( Rcpp::List& lst,std::string xyzm, bool close ) { 63 | return sfheaders::sfg::sfg_polygons( lst, xyzm, close ); 64 | } 65 | 66 | // [[Rcpp::export]] 67 | SEXP rcpp_sfg_multipolygon( SEXP x, SEXP geometry_columns, SEXP polygon_id, SEXP line_id, std::string xyzm, bool close ) { 68 | SEXP x2 = Rcpp::clone( x ); 69 | return sfheaders::sfg::sfg_multipolygon( x2, geometry_columns, polygon_id, line_id, xyzm, close ); 70 | } 71 | 72 | // [[Rcpp::export]] 73 | Rcpp::List rcpp_sfg_multipolygons( Rcpp::List& lst, std::string xyzm, bool close ) { 74 | return sfheaders::sfg::sfg_multipolygons( lst, xyzm, close ); 75 | } 76 | 77 | 78 | // [[Rcpp::export]] 79 | SEXP rcpp_sfg_remove_holes( SEXP sfg, bool close ) { 80 | 81 | Rcpp::CharacterVector cls = sfheaders::sfg::getSfgClass( sfg ); 82 | std::string sfg_type; 83 | sfg_type = cls[1]; 84 | std::string xyzm; 85 | xyzm = cls[0]; 86 | 87 | if( sfg_type == "POLYGON" ) { 88 | Rcpp::List p = Rcpp::as< Rcpp::List >( sfg ); 89 | return sfheaders::sfg::remove_polygon_holes( p, xyzm, close ); 90 | } else if ( sfg_type == "MULTIPOLYGON" ) { 91 | Rcpp::List mp = Rcpp::as< Rcpp::List >( sfg ); 92 | return sfheaders::sfg::remove_multipolygon_holes( mp, xyzm, close ); 93 | } 94 | return sfg; 95 | } 96 | -------------------------------------------------------------------------------- /src/utils.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/src/utils.cpp -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(sfheaders) 3 | 4 | test_check("sfheaders") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-df_attributes.R: -------------------------------------------------------------------------------- 1 | context("sfc_columns_attributes") 2 | 3 | 4 | ## issue 50 5 | test_that("sfc_columns attribute added and column names uniquified",{ 6 | 7 | df <- data.frame( 8 | x = 1:5 9 | , y = 1:5 10 | ) 11 | 12 | sf <- sfheaders::sf_point(df) 13 | sf$x <- letters[1:5] 14 | 15 | df <- sfheaders::sf_to_df(sf, fill = TRUE ) 16 | expect_equal( 17 | names(df) 18 | , c("x", "sfg_id","point_id","x..1","y") 19 | ) 20 | 21 | expect_equal( 22 | attr(df, "sfc_columns") 23 | , c("x..1","y") 24 | ) 25 | 26 | df <- data.frame( 27 | x = 1:5 28 | , y = 1:5 29 | , z = 1:5 30 | ) 31 | 32 | sf <- sfheaders::sf_linestring(df) 33 | sf$y <- "a" 34 | 35 | df <- sfheaders::sf_to_df(sf, fill = TRUE ) 36 | 37 | expect_equal( 38 | names(df) 39 | , c("id", "y", "sfg_id","linestring_id","x","y..1","z") 40 | ) 41 | 42 | expect_equal( 43 | attr(df, "sfc_columns") 44 | , c("x","y..1","z") 45 | ) 46 | 47 | }) 48 | -------------------------------------------------------------------------------- /tests/testthat/test-empty.R: -------------------------------------------------------------------------------- 1 | context("empty") 2 | 3 | test_that("n_empty set for POINT", { 4 | 5 | x <- c(NA_integer_, NA_integer_) 6 | res <- sfheaders::sfc_point( x ) 7 | expect_equal( attr(res, "n_empty"), 1 ) 8 | 9 | x <- c(NA_integer_, 1) 10 | res <- sfheaders::sfc_point( x ) 11 | expect_equal( attr(res, "n_empty"), 1 ) 12 | 13 | x <- c(1, NA_integer_) 14 | res <- sfheaders::sfc_point( x ) 15 | expect_equal( attr(res, "n_empty"), 1 ) 16 | 17 | x <- c(NA_real_, NA_real_) 18 | res <- sfheaders::sfc_point( x ) 19 | expect_equal( attr(res, "n_empty"), 1 ) 20 | 21 | x <- c(NA_real_, 1) 22 | res <- sfheaders::sfc_point( x ) 23 | expect_equal( attr(res, "n_empty"), 1 ) 24 | 25 | x <- c(1,NA_real_) 26 | res <- sfheaders::sfc_point( x ) 27 | expect_equal( attr(res, "n_empty"), 1 ) 28 | 29 | x <- matrix(c(NA_integer_, NA_integer_, 1, 1), ncol = 2) 30 | res <- sfheaders::sfc_point( x ) 31 | expect_equal( attr(res, "n_empty"), 2 ) 32 | 33 | x <- as.data.frame( x ) 34 | res <- sfheaders::sfc_point( x ) 35 | expect_equal( attr(res, "n_empty"), 2 ) 36 | 37 | x <- matrix(c(NA_integer_, NA_integer_, 1, 1, 1, 1), ncol = 3) 38 | res <- sfheaders::sfc_point( x, x = 1L, y = 2L ) 39 | expect_equal( attr(res, "n_empty"), 2 ) 40 | 41 | x <- matrix(c(NA_real_, NA_real_, 1.1, 1, 1, 1), ncol = 3) 42 | res <- sfheaders::sfc_point( x, x = 1, y = 2 ) 43 | expect_equal( attr(res, "n_empty"), 2 ) 44 | 45 | 46 | }) 47 | -------------------------------------------------------------------------------- /tests/testthat/test-holes.R: -------------------------------------------------------------------------------- 1 | context("holes") 2 | 3 | test_that("holes are removed from polygons",{ 4 | 5 | df <- data.frame( 6 | ml_id = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2) 7 | , l_id = c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2) 8 | , x = rnorm(15) 9 | , y = rnorm(15) 10 | , z = rnorm(15) 11 | , m = rnorm(15) 12 | ) 13 | 14 | expect_error( 15 | sf_remove_holes(df) 16 | , "only sfg, sfc and sf objects are supported" 17 | ) 18 | 19 | sfg <- sfg_polygon( obj = df, x = "x", y = "y", linestring_id = "ml_id", close = FALSE) 20 | sfc <- sfc_polygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id", close = FALSE) 21 | sf <- sf_polygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id", close = FALSE ) 22 | 23 | sfg_res <- sf_remove_holes( sfg, close = FALSE ) 24 | sfc_res <- sf_remove_holes( sfc, close = FALSE ) 25 | sf_res <- sf_remove_holes( sf, close = FALSE ) 26 | 27 | expect_true( length( sfg ) == 2 & length( sfg_res ) == 1 ) 28 | expect_equal( sfg_res[[1]][, 1], df[ df$ml_id == 1, "x"] ) 29 | expect_equal( sfg_res[[1]][, 2], df[ df$ml_id == 1, "y"] ) 30 | 31 | expect_true( length( sfc[[1]] ) == 3 & length( sfc_res[[1]] ) == 1 ) 32 | expect_equal( sfc_res[[1]][[1]][, 1], df[ df$ml_id == 1 & df$l_id == 1, "x"] ) 33 | expect_equal( sfc_res[[1]][[1]][, 2], df[ df$ml_id == 1 & df$l_id == 1, "y"] ) 34 | 35 | expect_true( length( sfc[[2]] ) == 2 & length( sfc_res[[2]] ) == 1 ) 36 | expect_equal( sfc_res[[2]][[1]][, 1], df[ df$ml_id == 2 & df$l_id == 1, "x"] ) 37 | expect_equal( sfc_res[[2]][[1]][, 2], df[ df$ml_id == 2 & df$l_id == 1, "y"] ) 38 | 39 | expect_true( length( sf$geometry[[1]] ) == 3 & length( sf_res$geometry[[1]] ) == 1 ) 40 | expect_equal( sf_res$geometry[[1]][[1]][, 1], df[ df$ml_id == 1 & df$l_id == 1, "x"] ) 41 | expect_equal( sf_res$geometry[[1]][[1]][, 2], df[ df$ml_id == 1 & df$l_id == 1, "y"] ) 42 | 43 | expect_true( length( sf$geometry[[2]] ) == 2 & length( sf_res$geometry[[2]] ) == 1 ) 44 | expect_equal( sf_res$geometry[[2]][[1]][, 1], df[ df$ml_id == 2 & df$l_id == 1, "x"] ) 45 | expect_equal( sf_res$geometry[[2]][[1]][, 2], df[ df$ml_id == 2 & df$l_id == 1, "y"] ) 46 | 47 | sfg <- sfg_multipolygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id", close = FALSE) 48 | sfc <- sfc_multipolygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id", close = FALSE) 49 | sf <- sf_multipolygon( obj = df, x = "x", y = "y", polygon_id = "ml_id", linestring_id = "l_id", close = FALSE ) 50 | 51 | sfg_res <- sf_remove_holes( sfg, close = FALSE ) 52 | sfc_res <- sf_remove_holes( sfc, close = FALSE ) 53 | sf_res <- sf_remove_holes( sf, close = FALSE ) 54 | 55 | expect_true( length( sfg[[1]] ) == 3 & length( sfg_res[[1]] ) == 1 ) 56 | expect_equal( sfg_res[[1]][[1]][, 1], df[ df$ml_id == 1 & df$l_id == 1, "x"] ) 57 | expect_equal( sfg_res[[1]][[1]][, 2], df[ df$ml_id == 1 & df$l_id == 1, "y"] ) 58 | 59 | expect_true( length( sfc[[1]][[1]] ) == 3 & length( sfc_res[[1]][[1]] ) == 1 ) 60 | expect_equal( sfc_res[[1]][[1]][[1]][, 1], df[ df$ml_id == 1 & df$l_id == 1, "x"] ) 61 | expect_equal( sfc_res[[1]][[1]][[1]][, 2], df[ df$ml_id == 1 & df$l_id == 1, "y"] ) 62 | 63 | expect_true( length( sfc[[1]][[2]] ) == 2 & length( sfc_res[[1]][[1]] ) == 1 ) 64 | expect_equal( sfc_res[[1]][[2]][[1]][, 1], df[ df$ml_id == 2 & df$l_id == 1, "x"] ) 65 | expect_equal( sfc_res[[1]][[2]][[1]][, 2], df[ df$ml_id == 2 & df$l_id == 1, "y"] ) 66 | 67 | expect_equal( sf_res$geometry, sfc_res ) 68 | 69 | }) 70 | -------------------------------------------------------------------------------- /tests/testthat/test-sf_boxes.R: -------------------------------------------------------------------------------- 1 | context("boxes") 2 | 3 | ## issue 77 4 | test_that("boxes created",{ 5 | 6 | df <- data.frame( 7 | id1 = c(1,1,1,1,1,1,1,1,2,2,2,2) 8 | , id2 = c(1,1,1,1,2,2,2,2,1,1,1,1) 9 | , x = c(0,0,1,1,1,1,2,2,3,4,4,3) 10 | , y = c(0,1,1,0,1,2,2,1,3,3,4,4) 11 | ) 12 | 13 | sf_line <- sfheaders::sf_linestring( 14 | obj = df 15 | , x = "x" 16 | , y = "y" 17 | , linestring_id = "id1" 18 | ) 19 | 20 | sf <- sf_boxes( sf_line ) 21 | sfc <- sf_boxes( sf_line$geometry ) 22 | bbox <- sf_bbox( df, x = "x", y = "y" ) 23 | 24 | expect_equal( 25 | sf$geometry 26 | , sfc 27 | ) 28 | 29 | expect_equal( 30 | attr( sfc, "bbox" ) 31 | , bbox 32 | ) 33 | 34 | expect_equal( 35 | sf_bbox( sfc[1] ) 36 | , sf_bbox( df[ df$id1 == 1, ], x = "x", y = "y" ) 37 | ) 38 | 39 | expect_equal( 40 | sf_bbox( sfc[2] ) 41 | , sf_bbox( df[ df$id1 == 2, ], x = "x", y = "y" ) 42 | ) 43 | 44 | }) 45 | -------------------------------------------------------------------------------- /tests/testthat/test-sf_point.R: -------------------------------------------------------------------------------- 1 | context("sf point") 2 | 3 | test_that("sf_points works for various objects",{ 4 | 5 | x <- c(1:3) 6 | res <- sfheaders:::rcpp_sf_point( x, NULL, "", FALSE ) 7 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 8 | 9 | x <- c(1:10) 10 | expect_error( sfheaders:::rcpp_sf_point( x, NULL, "", FALSE ), "sfheaders - can't work out the dimension" ) 11 | 12 | x <- matrix( c(1:10) , ncol = 2 ) 13 | res <- sfheaders:::rcpp_sf_point( x, NULL, "", FALSE ) 14 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 15 | 16 | x <- matrix( c(1:12) , ncol = 3 ) 17 | res <- sfheaders:::rcpp_sf_point( x, NULL, "", FALSE ) 18 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 19 | 20 | x <- matrix( c(1:12) , ncol = 4 ) 21 | res <- sfheaders:::rcpp_sf_point( x, NULL, "", FALSE ) 22 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 23 | 24 | x <- c(1:3) 25 | res <- sfheaders:::rcpp_sf_point( x, NULL, "", FALSE ) 26 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 27 | 28 | x <- matrix( c(1:10) , ncol = 2 ) 29 | res <- sfheaders:::rcpp_sf_point( x, c(0L,1L), "", TRUE ) 30 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 31 | 32 | x <- as.matrix( as.data.frame( matrix( c(1:10) , ncol = 2 ) ) ) 33 | res <- sfheaders:::rcpp_sf_point( x, c("V1","V2"), "", TRUE ) 34 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 35 | 36 | x <- as.matrix( as.data.frame( matrix( c(1:10) , ncol = 2 ) ) ) 37 | x[1,1] <- 1.1 38 | res <- sfheaders:::rcpp_sf_point( x, c("V1","V2"), "", TRUE ) 39 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 40 | 41 | x <- matrix( c(1:12) , ncol = 3 ) 42 | res <- sfheaders:::rcpp_sf_point( x, c(0L,1L), "", TRUE ) 43 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 44 | 45 | x <- as.data.frame( matrix( c(1:12) , ncol = 3 ) ) 46 | res <- sfheaders:::rcpp_sf_point( x, c(0L,1L), "", TRUE ) 47 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 48 | 49 | x <- matrix( c(1:12) , ncol = 4 ) 50 | x[1,1] <- 1.1 51 | res <- sfheaders:::rcpp_sf_point( x, c(0L,1L), "", TRUE ) 52 | expect_true( all( attr(res, "class") == c("sf", "data.frame") ) ) 53 | 54 | }) 55 | -------------------------------------------------------------------------------- /tests/testthat/test-sfc_attributes.R: -------------------------------------------------------------------------------- 1 | context("sfc_attributes") 2 | 3 | test_that("crs_input and crs_wkt are strings",{ 4 | 5 | ## Issue 33 - superseded issue 49 6 | df <- data.frame(x = 1, y = 2) 7 | sf <- sfheaders::sf_point(df) 8 | a <- attributes( sf$geometry ) 9 | expect_true( is.character( a$crs$input ) ) 10 | expect_true( is.character( a$crs$wkt ) ) 11 | }) 12 | 13 | test_that("issue 44 is fixed",{ 14 | 15 | df <- data.frame( 16 | ml_id = c(1,1,1,1,1,1,1,1,1,2,2) 17 | , l_id = c(1,1,1,2,2,2,3,3,3,1,1) 18 | , x = seq(0.5,5.5, by = 0.5 ) 19 | , y = seq(0.5,5.5, by = 0.5 ) 20 | , z = seq(0.5,5.5, by = 0.5 ) 21 | , m = seq(1.5,6.5, by = 0.5 ) 22 | ) 23 | 24 | sf <- sf_polygon( 25 | obj = df 26 | , x = "x" 27 | , y = "y" 28 | , z = "z" 29 | , m = "m" 30 | , polygon_id = "ml_id" 31 | , linestring_id = "l_id" 32 | , close = F 33 | ) 34 | 35 | expect_true( all( unname( attr( sf$geometry, "z_range" ) ) == c(0.5, 5.5 ) ) ) 36 | expect_true( all( unname( attr( sf$geometry, "m_range" ) ) == c(1.5, 6.5 ) ) ) 37 | 38 | }) 39 | -------------------------------------------------------------------------------- /tests/testthat/test-sfg.R: -------------------------------------------------------------------------------- 1 | context('sfg_type') 2 | 3 | test_that("correct sfg type is returned",{ 4 | 5 | expect_error( sfheaders:::rcpp_get_sfg_type(0), "sfheaders - unknown sfg type" ) 6 | 7 | expect_equal( sfheaders:::rcpp_get_sfg_type(1), "POINT" ) 8 | expect_equal( sfheaders:::rcpp_get_sfg_type(2), "MULTIPOINT" ) 9 | expect_equal( sfheaders:::rcpp_get_sfg_type(3), "LINESTRING" ) 10 | expect_equal( sfheaders:::rcpp_get_sfg_type(4), "MULTILINESTRING" ) 11 | expect_equal( sfheaders:::rcpp_get_sfg_type(5), "POLYGON" ) 12 | expect_equal( sfheaders:::rcpp_get_sfg_type(6), "MULTIPOLYGON" ) 13 | 14 | }) 15 | -------------------------------------------------------------------------------- /tests/testthat/test-utils.R: -------------------------------------------------------------------------------- 1 | context("sfheaders") 2 | 3 | test_that("index_correct works",{ 4 | 5 | x <- 1:4 6 | res <- sfheaders:::index_correct( x ) 7 | expect_equal( x - 1, res ) 8 | 9 | }) 10 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/Cpp.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "C++" 3 | author: "David Cooley" 4 | date: "`r Sys.Date()`" 5 | output: 6 | html_document: 7 | toc: true 8 | toc_float: true 9 | number_sections: false 10 | theme: flatly 11 | header-includes: 12 | - \usepackage{tikz} 13 | - \usetikzlibrary{arrows} 14 | vignette: > 15 | %\VignetteIndexEntry{Rcpp} 16 | %\VignetteEncoding{UTF-8} 17 | %\VignetteEngine{knitr::rmarkdown} 18 | editor_options: 19 | chunk_output_type: console 20 | --- 21 | 22 | ```{r setup, include = FALSE} 23 | knitr::opts_chunk$set( 24 | collapse = TRUE, 25 | comment = "# ", 26 | eval = F 27 | ) 28 | ``` 29 | 30 | ```{r packages, include = FALSE, eval = T} 31 | library(Rcpp) 32 | library(sfheaders) 33 | # library(sf) 34 | ``` 35 | 36 | There are two ways you can use the C++ code 37 | 38 | 1. creating a `Rcpp::cppFunction()` 39 | 2. Linking to `sfheaders` in a package 40 | 41 | The first option works, but is a bit pointless because if you're in R anyway you would probably just call the R functions. 42 | 43 | The second option is the whole reason I build this library! 44 | 45 | 46 | ### Linking to a package 47 | 48 | The reason all the C++ code is in header files in `inst/include` is so you can call this code from another library. To do so 49 | 50 | 1. Set the `LinkingTo` 51 | 52 | For example, here's the [Description](https://github.com/dcooley/gpx/blob/master/DESCRIPTION) file of the `gpx` package I'm working on. 53 | 54 | 55 | ![LinkingTo](./images/gpx_description.png) 56 | 57 | 58 | 2. Include the `sfheaders` header files you need in a .cpp file 59 | 60 | ![include](./images/gpx_include.png) 61 | 62 | 63 | 3. call the functions 64 | 65 | ![functions](./images/gpx_functions.png) 66 | 67 | 68 | These screenshots are taken from my [gpx](https://github.com/dcooley/gpx/blob/master/inst/include/gpx/track/track.hpp) library. Feel free to have a look and see how I use them. 69 | 70 | 71 | ### Using cppFunction 72 | 73 | Here are some example `cppFunction()` calls you can use to make various sf objects 74 | 75 | #### sfg_POINT 76 | 77 | ```{r, eval = T} 78 | 79 | cppFunction( 80 | includes = '#include "sfheaders/sfg/sfg.hpp"' 81 | , code = ' 82 | SEXP a_point( SEXP x ) { 83 | return sfheaders::sfg::sfg_point( x ); 84 | } 85 | ' 86 | , plugins = "cpp11" 87 | , depends = c("geometries", "sfheaders") 88 | ) 89 | 90 | ## vector 91 | a_point( c(1,3) ) 92 | ## single-row matrix 93 | a_point( matrix(c(1,2), ncol = 2) ) 94 | ## single-row data.frame 95 | a_point( data.frame(x = 1, y = 2) ) 96 | ``` 97 | 98 | 99 | #### sfc_MULTIPOINT 100 | 101 | ```{r, eval = T} 102 | 103 | cppFunction( 104 | includes = ' 105 | #include "sfheaders/sfc/multipoint/sfc_multipoint.hpp" 106 | ', 107 | code = ' 108 | SEXP a_multipoint( SEXP x ) { 109 | return sfheaders::sfc::sfc_multipoint( x ); 110 | } 111 | ' 112 | , plugins = "cpp11" 113 | , depends = c("geometries", "sfheaders") 114 | ) 115 | 116 | x <- 1:2 117 | a_multipoint( x ) 118 | 119 | x <- matrix(c(1,2,3,4,5,6), ncol = 2) 120 | a_multipoint( x ) 121 | 122 | x <- data.frame(x = 1:3, y = 4:6) 123 | a_multipoint( x ) 124 | ``` 125 | 126 | #### sf_LINESTRING 127 | 128 | ```{r, eval = T} 129 | 130 | cppFunction( 131 | includes = ' 132 | #include "sfheaders/sf/linestring/sf_linestring.hpp" 133 | ', 134 | code = ' 135 | SEXP a_linestring( SEXP x, SEXP geometry_columns, SEXP id_column ) { 136 | return sfheaders::sf::sf_linestring( x, geometry_columns, id_column ); 137 | } 138 | ', 139 | plugins = "cpp11", 140 | depends = c("geometries", "sfheaders") 141 | ) 142 | 143 | x <- 1:2 144 | a_linestring( x, NULL, NULL ) 145 | 146 | x <- matrix(c(1,2,3,4,5,6), ncol = 2) 147 | a_linestring( x, NULL, NULL ) 148 | 149 | x <- data.frame(x = 1:6, y = 4:9, id = c(rep(1,3), rep(2,3))) 150 | a_linestring( x, NULL, "id" ) 151 | 152 | x <- data.frame(x = 1:6, y = 4:9, z = 8:10, id = c(rep(1,3), rep(2,3))) 153 | a_linestring( x, c("x","y"), "id" ) 154 | 155 | a_linestring( x, c("x","y", "z"), "id" ) 156 | 157 | ``` 158 | 159 | 160 | -------------------------------------------------------------------------------- /vignettes/images/gpx_description.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/vignettes/images/gpx_description.png -------------------------------------------------------------------------------- /vignettes/images/gpx_functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/vignettes/images/gpx_functions.png -------------------------------------------------------------------------------- /vignettes/images/gpx_include.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcooley/sfheaders/c5ed7fc5532fc5f084aec80d0b81755ea47364c6/vignettes/images/gpx_include.png --------------------------------------------------------------------------------