diff --git a/DESCRIPTION b/DESCRIPTION index 25c659c..9f7a85b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -40,4 +40,5 @@ Collate: perimeter.R clockwise.R geod.R + wkt.R RoxygenNote: 6.0.1 diff --git a/NAMESPACE b/NAMESPACE index cba8975..ddb54fb 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -29,6 +29,8 @@ S3method(st_transform_proj,sf) S3method(st_transform_proj,sfc) S3method(st_transform_proj,sfg) export(lwgeom_extSoftVersion) +export(st_asewkt) +export(st_astext) export(st_force_polygon_cw) export(st_geod_area) export(st_geod_azimuth) diff --git a/R/RcppExports.R b/R/RcppExports.R index 1be04ca..b9d9ce5 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -81,6 +81,10 @@ CPL_force_polygon_cw <- function(sfc) { .Call('_lwgeom_CPL_force_polygon_cw', PACKAGE = 'lwgeom', sfc) } +CPL_sfc_to_wkt <- function(sfc, precision) { + .Call('_lwgeom_CPL_sfc_to_wkt', PACKAGE = 'lwgeom', sfc, precision) +} + CPL_proj_version <- function(b = FALSE) { .Call('_lwgeom_CPL_proj_version', PACKAGE = 'lwgeom', b) } diff --git a/R/wkt.R b/R/wkt.R new file mode 100644 index 0000000..6fc4fbd --- /dev/null +++ b/R/wkt.R @@ -0,0 +1,31 @@ +#' Return Well-known Text representation of simple feature geometry +#' +#' Return Well-known Text representation of simple feature geometry or coordinate reference system +#' @param x object of class `sfg`, `sfc` or `crs`` +#' @param precision number of digits to print +#' @param EWKT Use Postgis Enhanced WKT (includes srid) +#' @name st_astext +#' @details The returned WKT representation of simple feature geometry conforms to the +#' [simple features access](http://www.opengeospatial.org/standards/sfa) specification and extensions (if `EWKT = TRUE`), +#' [known as EWKT](http://postgis.net/docs/using_postgis_dbmanagement.html#EWKB_EWKT), supported by +#' PostGIS and other simple features implementations for addition of SRID to a WKT string. +#' @md +#' @examples +#' library(sf) +#' pt <- st_sfc(st_point(c(1.0002,2.3030303)), crs = 4326) +#' st_astext(pt, 3, TRUE) +#' @export +st_astext <- function(x, precision = 12, EWKT = FALSE) { + if (!EWKT) st_crs(x) <- NA_crs_ + CPL_sfc_to_wkt(x, precision = precision) +} + +#' @name st_astext +#' @inheritParams st_astext +#' @details `st_asewkt()` returns the Well-Known Text (WKT) representation of +#' the geometry with SRID meta data. +#' @md +#' @export +st_asewkt <- function(x, precision) { + st_astext(x, precision, EWKT = TRUE) +} diff --git a/lwgeom.Rproj b/lwgeom.Rproj index 4a4e498..4aff1be 100644 --- a/lwgeom.Rproj +++ b/lwgeom.Rproj @@ -17,3 +17,4 @@ AutoAppendNewline: Yes BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/man/st_astext.Rd b/man/st_astext.Rd new file mode 100644 index 0000000..b428619 --- /dev/null +++ b/man/st_astext.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/wkt.R +\name{st_astext} +\alias{st_astext} +\alias{st_astext} +\alias{st_asewkt} +\title{Return Well-known Text representation of simple feature geometry} +\usage{ +st_astext(x, precision = 12, EWKT = FALSE) + +st_asewkt(x, precision) +} +\arguments{ +\item{x}{object of class \code{sfg}, \code{sfc} or `crs``} + +\item{precision}{number of digits to print} + +\item{EWKT}{Use Postgis Enhanced WKT (includes srid)} +} +\description{ +Return Well-known Text representation of simple feature geometry or coordinate reference system +} +\details{ +The returned WKT representation of simple feature geometry conforms to the +\href{http://www.opengeospatial.org/standards/sfa}{simple features access} specification and extensions (if \code{EWKT = TRUE}), +\href{http://postgis.net/docs/using_postgis_dbmanagement.html#EWKB_EWKT}{known as EWKT}, supported by +PostGIS and other simple features implementations for addition of SRID to a WKT string. + +\code{st_asewkt()} returns the Well-Known Text (WKT) representation of +the geometry with SRID meta data. +} +\examples{ +library(sf) +pt <- st_sfc(st_point(c(1.0002,2.3030303)), crs = 4326) +st_astext(pt, 3, TRUE) +} diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 1076197..2febf50 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -246,6 +246,18 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// CPL_sfc_to_wkt +Rcpp::CharacterVector CPL_sfc_to_wkt(const Rcpp::List sfc, const int precision); +RcppExport SEXP _lwgeom_CPL_sfc_to_wkt(SEXP sfcSEXP, SEXP precisionSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< const Rcpp::List >::type sfc(sfcSEXP); + Rcpp::traits::input_parameter< const int >::type precision(precisionSEXP); + rcpp_result_gen = Rcpp::wrap(CPL_sfc_to_wkt(sfc, precision)); + return rcpp_result_gen; +END_RCPP +} // CPL_proj_version std::string CPL_proj_version(bool b); RcppExport SEXP _lwgeom_CPL_proj_version(SEXP bSEXP) { @@ -293,6 +305,7 @@ static const R_CallMethodDef CallEntries[] = { {"_lwgeom_CPL_perimeter", (DL_FUNC) &_lwgeom_CPL_perimeter, 2}, {"_lwgeom_CPL_is_polygon_cw", (DL_FUNC) &_lwgeom_CPL_is_polygon_cw, 1}, {"_lwgeom_CPL_force_polygon_cw", (DL_FUNC) &_lwgeom_CPL_force_polygon_cw, 1}, + {"_lwgeom_CPL_sfc_to_wkt", (DL_FUNC) &_lwgeom_CPL_sfc_to_wkt, 2}, {"_lwgeom_CPL_proj_version", (DL_FUNC) &_lwgeom_CPL_proj_version, 1}, {"_lwgeom_CPL_linesubstring", (DL_FUNC) &_lwgeom_CPL_linesubstring, 4}, {NULL, NULL, 0} diff --git a/src/lwgeom.cpp b/src/lwgeom.cpp index fd45272..25de283 100644 --- a/src/lwgeom.cpp +++ b/src/lwgeom.cpp @@ -244,3 +244,15 @@ Rcpp::List CPL_force_polygon_cw(Rcpp::List sfc) { } return sfc_from_lwgeom(lwgeom_cw); } + +// [[Rcpp::export]] +Rcpp::CharacterVector CPL_sfc_to_wkt(const Rcpp::List sfc, const int precision) { + std::vector lwgeom_cw = lwgeom_from_sfc(sfc); + size_t wkt_size = 0; + Rcpp::CharacterVector out; + for (size_t i = 0; i < lwgeom_cw.size(); i++) { + out.push_back(lwgeom_to_wkt(lwgeom_cw[i], WKT_EXTENDED, precision, &wkt_size)); + } + return out; +} + diff --git a/tests/testthat/test-as_text.R b/tests/testthat/test-as_text.R new file mode 100644 index 0000000..741a6b5 --- /dev/null +++ b/tests/testthat/test-as_text.R @@ -0,0 +1,21 @@ +context("test-as_text.R") +library(sf) + +test_that("Prints Points", { + pt <- st_sfc(st_point(c(1.0002,2.3030303)), crs = 4326) + expect_equal(st_astext(pt, 3), "SRID=4326;POINT(1 2.3)") + expect_equal(st_astext(pt, 3, FALSE), "POINT(1 2.3)") + expect_equal(st_astext(pt, 4, FALSE), "POINT(1 2.303)") + expect_equal(st_astext(pt, 10, FALSE), "POINT(1.0002 2.3030303)") +}) + +test_that("Prints Polygons and Lines", { + pol <- st_sfc(st_polygon(list( + rbind(c(0,0),c(0.5,0),c(0.5,0.5),c(0.5,0),c(1,0),c(1,1),c(0,1),c(0,0)) + ))) + txt <- "POLYGON((0 0,0.5 0,0.5 0.5,0.5 0,1 0,1 1,0 1,0 0))" + expect_equal(st_astext(pol), txt) + ln <- st_cast(pol, "LINESTRING") + txt <- "LINESTRING(0 0,0.5 0,0.5 0.5,0.5 0,1 0,1 1,0 1,0 0)" + expect_equal(st_astext(ln), txt) +})