From 65a65e795b56ee1a0c9cdaaffef8024e82ce21ae Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Mon, 14 Sep 2020 08:14:20 +0200 Subject: [PATCH 01/20] [ci] Improve code quality in tests according to codefactor review. --- tests/testthat/test-cpp_binding.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-cpp_binding.R b/tests/testthat/test-cpp_binding.R index 00ac643..2cbe316 100644 --- a/tests/testthat/test-cpp_binding.R +++ b/tests/testthat/test-cpp_binding.R @@ -77,7 +77,7 @@ test_that("Cpp binding to 'flexpolyline.h' en- and decodes correctly", { # Test encoding expect_equal( any( - sapply(1:length(enc), function(i) { + vapply(seq_along(enc), function(i) { # Omit reserved dimensions and encoding with precision higher than 7 if ( @@ -101,7 +101,7 @@ test_that("Cpp binding to 'flexpolyline.h' en- and decodes correctly", { # Test equality enc[i] != encoded - }) + }, logical(1)) ), FALSE ) @@ -109,7 +109,7 @@ test_that("Cpp binding to 'flexpolyline.h' en- and decodes correctly", { # Test decoding expect_equal( any( - sapply(1:length(dec), function(i) { + vapply(seq_along(dec), function(i) { # Omit reserved dimensions and decoding with precision higher than 7 if ( @@ -130,7 +130,7 @@ test_that("Cpp binding to 'flexpolyline.h' en- and decodes correctly", { # Test equality any(dec[[i]]$coords != decoded) - }) + }, logical(1)) ), FALSE ) From d51e9ccee5757a0f6ff04e6e3bd306840a6fd1b4 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Mon, 14 Sep 2020 08:15:13 +0200 Subject: [PATCH 02/20] [ci] Improve code quality according to codefactor. --- inst/include/hf/flexpolyline.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/inst/include/hf/flexpolyline.h b/inst/include/hf/flexpolyline.h index d7cbffd..20b65a8 100644 --- a/inst/include/hf/flexpolyline.h +++ b/inst/include/hf/flexpolyline.h @@ -1,6 +1,6 @@ /* * Copy from :https://github.com/heremaps/flexible-polyline/blob/master/cpp/ - * Modified :Line 93, 211 + * Modified :Line 93, 210 * Date :2020-06-09, Merlin Unterfinger * * Copyright (C) 2019 HERE Europe B.V. @@ -201,7 +201,6 @@ class Encoder { std::string get_encoded() { return m_result; } - }; class Decoder { From 42d8da7574166f69c3275bb89dff343b037a2c31 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 28 Oct 2020 12:32:24 +0100 Subject: [PATCH 03/20] [ci] Build page on release and add textshaping devs. --- .github/workflows/pkgdown.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 521fd25..cd808f2 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -1,7 +1,6 @@ on: - push: - branches: - - refs/tags/* + release: + types: [created, edited] name: pkgdown @@ -24,7 +23,9 @@ jobs: libgdal-dev \ libgeos-dev \ libproj-dev \ - libcurl4-openssl-dev + libcurl4-openssl-dev \ + libharfbuzz-dev \ + libfribidi-dev - name: Query dependencies run: | install.packages('remotes') From f592fb691ca6446f20bfc41e9ebc0ed14fd927fa Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 28 Oct 2020 15:04:30 +0100 Subject: [PATCH 04/20] [pkg] Add third dimension setter and getter. --- NAMESPACE | 2 + R/RcppExports.R | 47 +++++++++++++++++++ man/get_third_dimension.Rd | 26 +++++++++++ man/set_third_dimension.Rd | 28 ++++++++++++ src/RcppExports.cpp | 25 ++++++++++ src/flexpolyline.cpp | 94 ++++++++++++++++++++++++++++++++++++-- 6 files changed, 219 insertions(+), 3 deletions(-) create mode 100644 man/get_third_dimension.Rd create mode 100644 man/set_third_dimension.Rd diff --git a/NAMESPACE b/NAMESPACE index fabcab6..6ff725b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,5 +9,7 @@ export(decode) export(decode_sf) export(encode) export(encode_sf) +export(get_third_dimension) +export(set_third_dimension) importFrom(Rcpp,sourceCpp) useDynLib(flexpolyline, .registration = TRUE) diff --git a/R/RcppExports.R b/R/RcppExports.R index c1485b3..eefe4a2 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -64,3 +64,50 @@ encode <- function(line, precision = 5L, third_dim = 3L, third_dim_precision = 5 .Call(`_flexpolyline_encode`, line, precision, third_dim, third_dim_precision) } +#' Get third dimension of a flexible polyline encoded string +#' +#' This function calls \code{hf::get_third_dimension} of the C++ implementation +#' of the flexible polyline encoding by HERE and return the type of the third +#' dimension. +#' +#' @param encoded character, encoded flexible polyline string. +#' +#' @return +#' A string describing the third dimension. +#' +#' @export +#' +#' @examples +#' # 2d line +#' get_third_dimension("BFoz5xJ67i1B1B7PzIhaxL7Y") +#' +#' # 3d line +#' get_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU") +get_third_dimension <- function(encoded) { + .Call(`_flexpolyline_get_third_dimension`, encoded) +} + +#' Set third dimension of a flexible polyline encoded string +#' +#' This function decodes the flexible polyline encoded line changes the third +#' dimension and encodes the line again. +#' +#' @param encoded character, encoded flexible polyline string. +#' @param third_dim character, name of the third dimension (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +#' +#' @return +#' The line with the new third dimension as string in the flexible polyline +#' encoding format. +#' +#' @export +#' +#' @examples +#' # 2d line (nothing happens...) +#' set_third_dimension("BFoz5xJ67i1B1B7PzIhaxL7Y", "ELEVATION") +#' +#' # 3d line +#' set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "ELEVATION") +set_third_dimension <- function(encoded, third_dim_name) { + .Call(`_flexpolyline_set_third_dimension`, encoded, third_dim_name) +} + diff --git a/man/get_third_dimension.Rd b/man/get_third_dimension.Rd new file mode 100644 index 0000000..6ab133b --- /dev/null +++ b/man/get_third_dimension.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/RcppExports.R +\name{get_third_dimension} +\alias{get_third_dimension} +\title{Get third dimension of a flexible polyline encoded string} +\usage{ +get_third_dimension(encoded) +} +\arguments{ +\item{encoded}{character, encoded flexible polyline string.} +} +\value{ +A string describing the third dimension. +} +\description{ +This function calls \code{hf::get_third_dimension} of the C++ implementation +of the flexible polyline encoding by HERE and return the type of the third +dimension. +} +\examples{ +# 2d line +get_third_dimension("BFoz5xJ67i1B1B7PzIhaxL7Y") + +# 3d line +get_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU") +} diff --git a/man/set_third_dimension.Rd b/man/set_third_dimension.Rd new file mode 100644 index 0000000..2128568 --- /dev/null +++ b/man/set_third_dimension.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/RcppExports.R +\name{set_third_dimension} +\alias{set_third_dimension} +\title{Set third dimension of a flexible polyline encoded string} +\usage{ +set_third_dimension(encoded, third_dim_name) +} +\arguments{ +\item{encoded}{character, encoded flexible polyline string.} + +\item{third_dim}{character, name of the third dimension (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2).} +} +\value{ +The line with the new third dimension as string in the flexible polyline +encoding format. +} +\description{ +This function decodes the flexible polyline encoded line changes the third +dimension and encodes the line again. +} +\examples{ +# 2d line (nothing happens...) +set_third_dimension("BFoz5xJ67i1B1B7PzIhaxL7Y", "ELEVATION") + +# 3d line +set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "ELEVATION") +} diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index a91c85f..f1074eb 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -30,10 +30,35 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// get_third_dimension +std::string get_third_dimension(SEXP encoded); +RcppExport SEXP _flexpolyline_get_third_dimension(SEXP encodedSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< SEXP >::type encoded(encodedSEXP); + rcpp_result_gen = Rcpp::wrap(get_third_dimension(encoded)); + return rcpp_result_gen; +END_RCPP +} +// set_third_dimension +std::string set_third_dimension(SEXP encoded, SEXP third_dim_name); +RcppExport SEXP _flexpolyline_set_third_dimension(SEXP encodedSEXP, SEXP third_dim_nameSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< SEXP >::type encoded(encodedSEXP); + Rcpp::traits::input_parameter< SEXP >::type third_dim_name(third_dim_nameSEXP); + rcpp_result_gen = Rcpp::wrap(set_third_dimension(encoded, third_dim_name)); + return rcpp_result_gen; +END_RCPP +} static const R_CallMethodDef CallEntries[] = { {"_flexpolyline_decode", (DL_FUNC) &_flexpolyline_decode, 1}, {"_flexpolyline_encode", (DL_FUNC) &_flexpolyline_encode, 4}, + {"_flexpolyline_get_third_dimension", (DL_FUNC) &_flexpolyline_get_third_dimension, 1}, + {"_flexpolyline_set_third_dimension", (DL_FUNC) &_flexpolyline_set_third_dimension, 2}, {NULL, NULL, 0} }; diff --git a/src/flexpolyline.cpp b/src/flexpolyline.cpp index 6ca231f..5248b74 100644 --- a/src/flexpolyline.cpp +++ b/src/flexpolyline.cpp @@ -74,11 +74,9 @@ NumericMatrix decode(SEXP encoded) { coords( i, 1 ) = std::get<0>(polyline[i]); } colnames(coords) = CharacterVector({"LNG", "LAT"}); - } return coords; - } //' Encode a line in the flexible polyline encoding format @@ -151,10 +149,100 @@ String encode(NumericMatrix line, int precision = 5, } else { throw std::invalid_argument("Invalid input dimensions"); - } return encoded; +} + +//' Get third dimension of a flexible polyline encoded string +//' +//' This function calls \code{hf::get_third_dimension} of the C++ implementation +//' of the flexible polyline encoding by HERE and return the type of the third +//' dimension. +//' +//' @param encoded character, encoded flexible polyline string. +//' +//' @return +//' A string describing the third dimension. +//' +//' @export +//' +//' @examples +//' # 2d line +//' get_third_dimension("BFoz5xJ67i1B1B7PzIhaxL7Y") +//' +//' # 3d line +//' get_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU") +// [[Rcpp::export]] +std::string get_third_dimension(SEXP encoded) { + + const char * dim_name[] = { + "ABSENT", "LEVEL", "ALTITUDE", "ELEVATION", + "RESERVED1", "RESERVED2", // Should not be used... + "CUSTOM1", "CUSTOM2" + }; + + // Convert from R SEXP to std::string + std::string encoded_str = Rcpp::as(encoded); + + // Extract third dimension type + hf::ThirdDim thrd = hf::get_third_dimension(encoded_str); + int index = static_cast::type>(thrd); + + return dim_name[index]; } +//' Set third dimension of a flexible polyline encoded string +//' +//' This function decodes the flexible polyline encoded line changes the third +//' dimension and encodes the line again. +//' +//' @param encoded character, encoded flexible polyline string. +//' @param third_dim character, name of the third dimension (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +//' +//' @return +//' The line with the new third dimension as string in the flexible polyline +//' encoding format. +//' +//' @export +//' +//' @examples +//' # 2d line (nothing happens...) +//' set_third_dimension("BFoz5xJ67i1B1B7PzIhaxL7Y", "ELEVATION") +//' +//' # 3d line +//' set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "ELEVATION") +// [[Rcpp::export]] +std::string set_third_dimension(SEXP encoded, SEXP third_dim_name) { + + int third_dim_ind = -1; + const char * dim_name[] = { + "ABSENT", "LEVEL", "ALTITUDE", "ELEVATION", + "RESERVED1", "RESERVED2", // Should not be used... + "CUSTOM1", "CUSTOM2" + }; + + // Convert from R SEXP to std::string + std::string third_dim_str = Rcpp::as(third_dim_name); + + // Decode + NumericMatrix decoded = decode(encoded); + + // Match third dimension type + for (size_t i = 0; i != (sizeof dim_name / sizeof *dim_name); i++) { + if (dim_name[i] == third_dim_str) { + third_dim_ind = i; + } + } + + // Check if dimension is valid. + if (third_dim_ind == -1) { + throw std::invalid_argument("Invalid input name of third dimension."); + } + + // Encode with new third dimension + String encoded_new = encode(decoded, 5, third_dim_ind, 5); + + return encoded_new; +} From 66188275be58992e9144ab146163bf9de6dcb4e1 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 28 Oct 2020 15:04:47 +0100 Subject: [PATCH 05/20] [ci] Update tests. --- tests/testthat/test-cpp_binding.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/testthat/test-cpp_binding.R b/tests/testthat/test-cpp_binding.R index 2cbe316..8d136a3 100644 --- a/tests/testthat/test-cpp_binding.R +++ b/tests/testthat/test-cpp_binding.R @@ -7,6 +7,10 @@ test_that("Cpp binding to 'flexpolyline.h' en- and decodes correctly", { expect_error(encode(matrix(1,2,3), third_dim_precision = -1), "third_dim_precision out of range", class = "std::out_of_range") expect_error(decode("123"), "Invalid encoding", class = "std::invalid_argument") + # Get and set third dimension + expect_equal(get_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU"), "ALTITUDE") + expect_equal(get_third_dimension(set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "ELEVATION")), "ELEVATION") + # Read and preprocess test data parse_test_examples <- function(input) { From 65c1a5d22d52968680bfb93f1ce61d26500e8e6a Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 28 Oct 2020 15:05:02 +0100 Subject: [PATCH 06/20] [doc] NEWS entry. --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index d7dd1bc..bc9b800 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # flexpolyline 0.1.1.9000 +* Added functions to get (`get_third_dimension()`) and set (`set_third_dimension()`) the third dimension type of a flexible polyline encoded string. * Sign in to CodeFactor.io and add badge to continuously track code quality. * Use exception classes when throwing an exception in C++. * Improve coverage of tests. From 965a12da75bf8e14987706d7b61f63e08478ad55 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Mon, 23 Nov 2020 17:16:56 +0100 Subject: [PATCH 07/20] [doc] Update function doc and pass precision parameters to 'set_third_dimension'. --- R/RcppExports.R | 13 +++++++++---- man/set_third_dimension.Rd | 18 +++++++++++++++--- src/RcppExports.cpp | 10 ++++++---- src/flexpolyline.cpp | 16 +++++++++++----- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/R/RcppExports.R b/R/RcppExports.R index eefe4a2..aa9c0e5 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -89,11 +89,16 @@ get_third_dimension <- function(encoded) { #' Set third dimension of a flexible polyline encoded string #' -#' This function decodes the flexible polyline encoded line changes the third +#' This function decodes the flexible polyline encoded line, changes the third #' dimension and encodes the line again. #' +#' @note +#' The precision is not read from the header of the encoded line. Therefore it must be provided as a parameter for re-encoding. +#' #' @param encoded character, encoded flexible polyline string. -#' @param third_dim character, name of the third dimension (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +#' @param third_dim_name character, name of the third dimension to set (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +#' @param precision integer, precision to use in encoding (between 0 and 15, \code{default=5}). +#' @param third_dim_precision integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}). #' #' @return #' The line with the new third dimension as string in the flexible polyline @@ -107,7 +112,7 @@ get_third_dimension <- function(encoded) { #' #' # 3d line #' set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "ELEVATION") -set_third_dimension <- function(encoded, third_dim_name) { - .Call(`_flexpolyline_set_third_dimension`, encoded, third_dim_name) +set_third_dimension <- function(encoded, third_dim_name, precision = 5L, third_dim_precision = 5L) { + .Call(`_flexpolyline_set_third_dimension`, encoded, third_dim_name, precision, third_dim_precision) } diff --git a/man/set_third_dimension.Rd b/man/set_third_dimension.Rd index 2128568..8e1d03d 100644 --- a/man/set_third_dimension.Rd +++ b/man/set_third_dimension.Rd @@ -4,21 +4,33 @@ \alias{set_third_dimension} \title{Set third dimension of a flexible polyline encoded string} \usage{ -set_third_dimension(encoded, third_dim_name) +set_third_dimension( + encoded, + third_dim_name, + precision = 5L, + third_dim_precision = 5L +) } \arguments{ \item{encoded}{character, encoded flexible polyline string.} -\item{third_dim}{character, name of the third dimension (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2).} +\item{third_dim_name}{character, name of the third dimension to set (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2).} + +\item{precision}{integer, precision to use in encoding (between 0 and 15, \code{default=5}).} + +\item{third_dim_precision}{integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}).} } \value{ The line with the new third dimension as string in the flexible polyline encoding format. } \description{ -This function decodes the flexible polyline encoded line changes the third +This function decodes the flexible polyline encoded line, changes the third dimension and encodes the line again. } +\note{ +The precision is not read from the header of the encoded line. Therefore it must be provided as a parameter for re-encoding. +} \examples{ # 2d line (nothing happens...) set_third_dimension("BFoz5xJ67i1B1B7PzIhaxL7Y", "ELEVATION") diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index f1074eb..726f63d 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -42,14 +42,16 @@ BEGIN_RCPP END_RCPP } // set_third_dimension -std::string set_third_dimension(SEXP encoded, SEXP third_dim_name); -RcppExport SEXP _flexpolyline_set_third_dimension(SEXP encodedSEXP, SEXP third_dim_nameSEXP) { +std::string set_third_dimension(SEXP encoded, SEXP third_dim_name, int precision, int third_dim_precision); +RcppExport SEXP _flexpolyline_set_third_dimension(SEXP encodedSEXP, SEXP third_dim_nameSEXP, SEXP precisionSEXP, SEXP third_dim_precisionSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< SEXP >::type encoded(encodedSEXP); Rcpp::traits::input_parameter< SEXP >::type third_dim_name(third_dim_nameSEXP); - rcpp_result_gen = Rcpp::wrap(set_third_dimension(encoded, third_dim_name)); + Rcpp::traits::input_parameter< int >::type precision(precisionSEXP); + Rcpp::traits::input_parameter< int >::type third_dim_precision(third_dim_precisionSEXP); + rcpp_result_gen = Rcpp::wrap(set_third_dimension(encoded, third_dim_name, precision, third_dim_precision)); return rcpp_result_gen; END_RCPP } @@ -58,7 +60,7 @@ static const R_CallMethodDef CallEntries[] = { {"_flexpolyline_decode", (DL_FUNC) &_flexpolyline_decode, 1}, {"_flexpolyline_encode", (DL_FUNC) &_flexpolyline_encode, 4}, {"_flexpolyline_get_third_dimension", (DL_FUNC) &_flexpolyline_get_third_dimension, 1}, - {"_flexpolyline_set_third_dimension", (DL_FUNC) &_flexpolyline_set_third_dimension, 2}, + {"_flexpolyline_set_third_dimension", (DL_FUNC) &_flexpolyline_set_third_dimension, 4}, {NULL, NULL, 0} }; diff --git a/src/flexpolyline.cpp b/src/flexpolyline.cpp index 5248b74..21f7eb0 100644 --- a/src/flexpolyline.cpp +++ b/src/flexpolyline.cpp @@ -195,11 +195,16 @@ std::string get_third_dimension(SEXP encoded) { //' Set third dimension of a flexible polyline encoded string //' -//' This function decodes the flexible polyline encoded line changes the third +//' This function decodes the flexible polyline encoded line, changes the third //' dimension and encodes the line again. //' +//' @note +//' The precision is not read from the header of the encoded line. Therefore it must be provided as a parameter for re-encoding. +//' //' @param encoded character, encoded flexible polyline string. -//' @param third_dim character, name of the third dimension (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +//' @param third_dim_name character, name of the third dimension to set (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +//' @param precision integer, precision to use in encoding (between 0 and 15, \code{default=5}). +//' @param third_dim_precision integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}). //' //' @return //' The line with the new third dimension as string in the flexible polyline @@ -214,7 +219,8 @@ std::string get_third_dimension(SEXP encoded) { //' # 3d line //' set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "ELEVATION") // [[Rcpp::export]] -std::string set_third_dimension(SEXP encoded, SEXP third_dim_name) { +std::string set_third_dimension(SEXP encoded, SEXP third_dim_name, int precision = 5, + int third_dim_precision = 5) { int third_dim_ind = -1; const char * dim_name[] = { @@ -238,11 +244,11 @@ std::string set_third_dimension(SEXP encoded, SEXP third_dim_name) { // Check if dimension is valid. if (third_dim_ind == -1) { - throw std::invalid_argument("Invalid input name of third dimension."); + throw std::invalid_argument("Invalid input name of third dimension"); } // Encode with new third dimension - String encoded_new = encode(decoded, 5, third_dim_ind, 5); + String encoded_new = encode(decoded, precision, third_dim_ind, third_dim_precision); return encoded_new; } From dd8ad8739dacdcd6adeb4070b7e57e275912142b Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Mon, 23 Nov 2020 17:21:22 +0100 Subject: [PATCH 08/20] [ci] Update tests. --- tests/testthat/test-cpp_binding.R | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testthat/test-cpp_binding.R b/tests/testthat/test-cpp_binding.R index 8d136a3..8777460 100644 --- a/tests/testthat/test-cpp_binding.R +++ b/tests/testthat/test-cpp_binding.R @@ -6,6 +6,7 @@ test_that("Cpp binding to 'flexpolyline.h' en- and decodes correctly", { expect_error(encode(matrix(1,2,3), third_dim = -1), "third_dim out of range", class = "std::out_of_range") expect_error(encode(matrix(1,2,3), third_dim_precision = -1), "third_dim_precision out of range", class = "std::out_of_range") expect_error(decode("123"), "Invalid encoding", class = "std::invalid_argument") + expect_error(set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "NOT A DIM"), "Invalid input name of third dimension", class = "std::invalid_argument") # Get and set third dimension expect_equal(get_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU"), "ALTITUDE") From b4c621f400a607f25c6601bfd0631ef4248aec70 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 25 Nov 2020 13:39:37 +0100 Subject: [PATCH 09/20] [pkg] Add support for geometry types POLYGON and LINESTRING, closes #31. --- R/decode_sf.R | 22 ++++++++-------- R/encode_sf.R | 66 +++++++++++++++++++++++------------------------- man/decode_sf.Rd | 8 +++--- man/encode_sf.Rd | 40 +++++++++++++---------------- 4 files changed, 64 insertions(+), 72 deletions(-) diff --git a/R/decode_sf.R b/R/decode_sf.R index ef803e8..9545bb1 100644 --- a/R/decode_sf.R +++ b/R/decode_sf.R @@ -18,22 +18,18 @@ #' @export #' #' @examples -#' # 2d line -#' decode_sf("BFoz5xJ67i1B1B7PzIhaxL7Y") -#' -#' # 3d line -#' decode_sf("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU") +#' decode_sf("B1Voz5xJ67i1Bgkh9B") +#' decode_sf("BFoz5xJ67i1B1B7PlU9yB") +#' decode_sf("BlXoz5xJ67i1Bgkh9B1B7Pgkh9BzIhagkh9BqK-pB_ni6D") decode_sf <- function(encoded, crs = sf::NA_crs_) { UseMethod("decode_sf", encoded) } #' @export decode_sf.character <- function(encoded, crs = sf::NA_crs_) { - dim3 <- character(length(encoded)) ind3 <- 2 sfdi <- "XY" - geom <- sf::st_sfc( lapply(1:length(encoded), function(x) { m <- decode(encoded[[x]]) @@ -51,13 +47,19 @@ decode_sf.character <- function(encoded, crs = sf::NA_crs_) { sfdi <<- "XYM" } } - sf::st_linestring(m, dim = sfdi) + if (nrow(m) <= 1) { + sf::st_point(m, dim = sfdi) + } else { + if (all(m[1, ] == m[nrow(m), ])) { + sf::st_polygon(list(m), dim = sfdi) + } else { + sf::st_linestring(m, dim = sfdi) + } + } }), crs = crs ) - dim3[is.na(dim3)] <- "ABSENT" - return( sf::st_as_sf( data.frame( diff --git a/R/encode_sf.R b/R/encode_sf.R index 3347fc1..1d4ffa5 100644 --- a/R/encode_sf.R +++ b/R/encode_sf.R @@ -3,7 +3,7 @@ #' A wrapper function for \code{\link{encode}} that converts simple feature geometries #' of the sf package to flexible polyline encoded strings. #' -#' @param line simple feature, \code{sf}, \code{sfc} or \code{sfg} object with geometry type \code{"LINESTRING"}. +#' @param geom simple feature, \code{sf}, \code{sfc} or \code{sfg} object with geometry type \code{"POINT"}, \code{"LINESTRING"} or \code{"POLYGON"}. #' @param precision integer, precision to use in encoding (between 0 and 15, \code{default=5}). #' @param third_dim integer, type of the third dimension (0: ABSENT, 1: LEVEL, 2: ALTITUDE, 3: ELEVATION, 4, 6: CUSTOM1, 7: CUSTOM2, \code{default=NULL}). #' @param third_dim_precision integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=precision}). @@ -14,61 +14,57 @@ #' @export #' #' @examples -#' # 2D +#' # 3D point +#' point3d <- sf::st_point( +#' matrix(c(8.69821, 50.10228, 10), ncol = 3, byrow = TRUE), dim = "XYZ") +#' encode_sf(point3d) +#' +#' # 2D linestring #' line2d <- sf::st_linestring( -#' matrix( -#' c(8.69821, 50.10228, -#' 8.69567, 50.10201, -#' 8.69150, 50.10063, -#' 8.68752, 50.09878), -#' ncol = 2, byrow = TRUE -#' ) -#' ) +#' matrix(c(8.69821, 50.10228, +#' 8.69567, 50.10201, +#' 8.68752, 50.09878), ncol = 2, byrow = TRUE)) #' encode_sf(line2d) #' -#' # 3D -#' line3d <- sf::st_linestring( -#' matrix( -#' c(8.69821, 50.10228, 10, -#' 8.69567, 50.10201, 20, -#' 8.69150, 50.10063, 30, -#' 8.68752, 50.09878, 40), -#' ncol = 3, byrow = TRUE -#' ) -#' ) -#' encode_sf(line3d) -encode_sf <- function(line, precision = 5, third_dim = NULL, +#' # 3D polygon +#' poly3d <- sf::st_polygon(list( +#' matrix(c(8.69821, 50.10228, 10, +#' 8.69567, 50.10201, 20, +#' 8.69150, 50.10063, 30, +#' 8.69821, 50.10228, 10), ncol = 3, byrow = TRUE)), dim = "XYM") +#' encode_sf(poly3d) +encode_sf <- function(geom, precision = 5, third_dim = NULL, third_dim_precision = precision) { - UseMethod("encode_sf", line) + UseMethod("encode_sf", geom) } #' @export -encode_sf.sfg <- function(line, precision = 5, third_dim = NULL, +encode_sf.sfg <- function(geom, precision = 5, third_dim = NULL, third_dim_precision = precision) { - if(sf::st_geometry_type(line) != "LINESTRING"){ + if(!sf::st_geometry_type(geom) %in% c("POINT", "LINESTRING", "POLYGON")){ stop( sprintf( - "Invalid geometry type '%s' of input, only 'LINESTRING' is supported.", - sf::st_geometry_type(line) + "Invalid geometry type '%s' of input, only 'POINT', 'LINESTRING' and 'POLYGON' is supported.", + sf::st_geometry_type(geom) ) ) } - if (class(line)[1] == "XY") { + if (class(geom)[1] == "XY") { third_dim <- 0 encoded <- encode( - sf::st_coordinates(line)[, c(1:2)], + sf::st_coordinates(geom)[, c(1:2), drop = FALSE], precision, third_dim, third_dim_precision ) } else { if (is.null(third_dim)) { - if (class(line)[1] == "XYZ") { + if (class(geom)[1] == "XYZ") { third_dim <- 3 } else { third_dim <- 6 } } encoded <- encode( - sf::st_coordinates(line)[, c(1:3)], + sf::st_coordinates(geom)[, c(1:3), drop = FALSE], precision, third_dim, third_dim_precision ) } @@ -76,21 +72,21 @@ encode_sf.sfg <- function(line, precision = 5, third_dim = NULL, } #' @export -encode_sf.sfc <- function(line, precision = 5, third_dim = NULL, +encode_sf.sfc <- function(geom, precision = 5, third_dim = NULL, third_dim_precision = precision) { return( - sapply(line, function(x) { + sapply(geom, function(x) { encode_sf.sfg(x, precision, third_dim, third_dim_precision) }) ) } #' @export -encode_sf.sf <- function(line, precision = 5, third_dim = NULL, +encode_sf.sf <- function(geom, precision = 5, third_dim = NULL, third_dim_precision = precision) { return( encode_sf.sfc( - sf::st_geometry(line), + sf::st_geometry(geom), precision, third_dim, third_dim_precision ) ) diff --git a/man/decode_sf.Rd b/man/decode_sf.Rd index 15333d5..a0e1e37 100644 --- a/man/decode_sf.Rd +++ b/man/decode_sf.Rd @@ -25,9 +25,7 @@ to meet the requirements of the constructor of sf objects. For mixed dimensions use the \code{\link{decode}} function directly. } \examples{ -# 2d line -decode_sf("BFoz5xJ67i1B1B7PzIhaxL7Y") - -# 3d line -decode_sf("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU") +decode_sf("B1Voz5xJ67i1Bgkh9B") +decode_sf("BFoz5xJ67i1B1B7PlU9yB") +decode_sf("BlXoz5xJ67i1Bgkh9B1B7Pgkh9BzIhagkh9BqK-pB_ni6D") } diff --git a/man/encode_sf.Rd b/man/encode_sf.Rd index 10edcb4..50fbe6f 100644 --- a/man/encode_sf.Rd +++ b/man/encode_sf.Rd @@ -5,14 +5,14 @@ \title{Wrapper function for encoding simple features} \usage{ encode_sf( - line, + geom, precision = 5, third_dim = NULL, third_dim_precision = precision ) } \arguments{ -\item{line}{simple feature, \code{sf}, \code{sfc} or \code{sfg} object with geometry type \code{"LINESTRING"}.} +\item{geom}{simple feature, \code{sf}, \code{sfc} or \code{sfg} object with geometry type \code{"POINT"}, \code{"LINESTRING"} or \code{"POLYGON"}.} \item{precision}{integer, precision to use in encoding (between 0 and 15, \code{default=5}).} @@ -28,27 +28,23 @@ A wrapper function for \code{\link{encode}} that converts simple feature geometr of the sf package to flexible polyline encoded strings. } \examples{ -# 2D +# 3D point +point3d <- sf::st_point( + matrix(c(8.69821, 50.10228, 10), ncol = 3, byrow = TRUE), dim = "XYZ") +encode_sf(point3d) + +# 2D linestring line2d <- sf::st_linestring( - matrix( - c(8.69821, 50.10228, - 8.69567, 50.10201, - 8.69150, 50.10063, - 8.68752, 50.09878), - ncol = 2, byrow = TRUE - ) -) + matrix(c(8.69821, 50.10228, + 8.69567, 50.10201, + 8.68752, 50.09878), ncol = 2, byrow = TRUE)) encode_sf(line2d) -# 3D -line3d <- sf::st_linestring( - matrix( - c(8.69821, 50.10228, 10, - 8.69567, 50.10201, 20, - 8.69150, 50.10063, 30, - 8.68752, 50.09878, 40), - ncol = 3, byrow = TRUE - ) -) -encode_sf(line3d) +# 3D polygon +poly3d <- sf::st_polygon(list( + matrix(c(8.69821, 50.10228, 10, + 8.69567, 50.10201, 20, + 8.69150, 50.10063, 30, + 8.69821, 50.10228, 10), ncol = 3, byrow = TRUE)), dim = "XYM") +encode_sf(poly3d) } From 4cb0e4358f9931114237b77e4a8fad8c3b193666 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 25 Nov 2020 13:39:51 +0100 Subject: [PATCH 10/20] [ci] Update tests. --- tests/testthat/test-decode_sf.R | 23 ++++++------ tests/testthat/test-encode_sf.R | 64 +++++++++++++++------------------ 2 files changed, 40 insertions(+), 47 deletions(-) diff --git a/tests/testthat/test-decode_sf.R b/tests/testthat/test-decode_sf.R index 48aedb0..7117fe2 100644 --- a/tests/testthat/test-decode_sf.R +++ b/tests/testthat/test-decode_sf.R @@ -2,24 +2,25 @@ test_that("decode_sf works", { # Encoded lines n <- 5 - encodedXY <- "BFoz5xJ67i1B1B7PzIhaxL7Y" - encodedXYZ <- "BlBoz5xJ67i1BU1B7PUzIhaUxL7YU" - encodedXYM <- as.factor("BlXoz5xJ67i1Bgkh9B1B7Pgkh9BzIhagkh9BxL7Ygkh9B") + encodedXYZ <- "B1Voz5xJ67i1Bgkh9B" + encodedXY <- "BFoz5xJ67i1B1B7PlU9yB" + encodedXYM <- as.factor("BlXoz5xJ67i1Bgkh9B1B7Pgkh9BzIhagkh9BqK-pB_ni6D") # Decode + pointXYZ <- decode_sf(rep(encodedXYZ, n)) lineXY <- decode_sf(rep(encodedXY, n)) - lineXYZ <- decode_sf(rep(encodedXYZ, n)) - lineXYM <- decode_sf(rep(encodedXYM, n)) + polyXYM <- decode_sf(rep(encodedXYM, n)) # Test decode_sf() + expect_s3_class(pointXYZ, c("sf", "data.frame"), exact = TRUE) expect_s3_class(lineXY, c("sf", "data.frame"), exact = TRUE) - expect_s3_class(lineXYZ, c("sf", "data.frame"), exact = TRUE) - expect_s3_class(lineXYM, c("sf", "data.frame"), exact = TRUE) + expect_s3_class(polyXYM, c("sf", "data.frame"), exact = TRUE) + expect_s3_class(decode_sf(c("BlXoz5xJ67i1Bgkh9B", "BlXoz5xJ67i1Bgkh9B1B7Pgkh9BzIhagkh9B", "BlXoz5xJ67i1Bgkh9B1B7Pgkh9BzIhagkh9BqK-pB_ni6D")), c("sf", "data.frame"), exact = TRUE) + expect_true(all(sf::st_geometry_type(pointXYZ) == "POINT")) expect_true(all(sf::st_geometry_type(lineXY) == "LINESTRING")) - expect_true(all(sf::st_geometry_type(lineXYZ) == "LINESTRING")) - expect_true(all(sf::st_geometry_type(lineXYM) == "LINESTRING")) + expect_true(all(sf::st_geometry_type(polyXYM) == "POLYGON")) + expect_equal(nrow(pointXYZ), n) expect_equal(nrow(lineXY), n) - expect_equal(nrow(lineXYZ), n) - expect_equal(nrow(lineXYM), n) + expect_equal(nrow(polyXYM), n) }) diff --git a/tests/testthat/test-encode_sf.R b/tests/testthat/test-encode_sf.R index a152a86..e0249f4 100644 --- a/tests/testthat/test-encode_sf.R +++ b/tests/testthat/test-encode_sf.R @@ -1,47 +1,39 @@ test_that("encode_sf works", { - # 2d line - line2d <- matrix( - c(8.69821, 50.10228, - 8.69567, 50.10201, - 8.69150, 50.10063, - 8.68752, 50.09878), - ncol = 2, byrow = TRUE - ) + # 3D point + point3d <- sf::st_point( + matrix(c(8.69821, 50.10228, 10), ncol = 3, byrow = TRUE), dim = "XYZ") - # 3d line - line3d <- matrix( - c(8.69821, 50.10228, 10.11111, - 8.69567, 50.10201, 20.22222, - 8.69150, 50.10063, 30.33333, - 8.68752, 50.09878, 40.44444), - ncol = 3, byrow = TRUE - ) + # 2D linestring + line2d <- sf::st_linestring( + matrix(c(8.69821, 50.10228, + 8.69567, 50.10201, + 8.68752, 50.09878), ncol = 2, byrow = TRUE)) - # Test encode_sf() - expect_error( - encode_sf(sf::st_point(c(1,2,3))), - "Invalid geometry type 'POINT' of input, only 'LINESTRING' is supported." - ) + # 3D polygon + poly3d <- sf::st_polygon(list( + matrix(c(8.69821, 50.10228, 10, + 8.69567, 50.10201, 20, + 8.69150, 50.10063, 30, + 8.69821, 50.10228, 10), ncol = 3, byrow = TRUE)), dim = "XYM") + # Test encode_sf() + expect_error(encode_sf(sf::st_multilinestring()), + "Invalid geometry type 'MULTILINESTRING' of input, only 'POINT', 'LINESTRING' and 'POLYGON' is supported.") ## sfg (XY, XYZ and XYM) - line2d_sfg <- sf::st_linestring(line2d) - line3d_sfg <- sf::st_linestring(line3d, dim = "XYZ") - line3dm_sfg <- sf::st_linestring(line3d, dim = "XYM") - expect_type(encode_sf(line2d_sfg), "character") - expect_type(encode_sf(line3d_sfg), "character") - expect_type(encode_sf(line3dm_sfg), "character") - + expect_type(encode_sf(point3d), "character") + expect_type(encode_sf(line2d), "character") + expect_type(encode_sf(poly3d), "character") ## sfc (XY and XYZ) - line2d_sfc <- sf::st_as_sfc(list(line2d_sfg, line2d_sfg), crs = 4326) - line3d_sfc <- sf::st_as_sfc(list(line3d_sfg, line3d_sfg), crs = 4326) + point3d_sfc <- sf::st_as_sfc(list(point3d, point3d), crs = 4326) + line2d_sfc <- sf::st_as_sfc(list(line2d, line2d), crs = 4326) + poly3d_sfc <- sf::st_as_sfc(list(poly3d, poly3d), crs = 4326) + expect_type(encode_sf(point3d_sfc), "character") expect_type(encode_sf(line2d_sfc), "character") - expect_type(encode_sf(line3d_sfc), "character") - + expect_type(encode_sf(poly3d_sfc), "character") ## sf (XY and XYZ) - line2d_sf <- sf::st_as_sf(line2d_sfc) - line3d_sf <- sf::st_as_sf(line3d_sfc) - expect_type(encode_sf(line2d_sf), "character") - expect_type(encode_sf(line3d_sf), "character") + expect_type(encode_sf(sf::st_as_sf(point3d_sfc)), "character") + expect_type(encode_sf(sf::st_as_sf(line2d_sfc)), "character") + expect_type(encode_sf(sf::st_as_sf(poly3d_sfc)), "character") }) From 12b37b25a8c5f1d3f17f3448e9290d0a2919ae28 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 25 Nov 2020 13:40:15 +0100 Subject: [PATCH 11/20] [doc] Update vignette and NEWS. --- NEWS.md | 1 + vignettes/sf-support.Rmd | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index bc9b800..74fcc9d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # flexpolyline 0.1.1.9000 +* Support for geometry types `"POLYGON"` and `"POINT"` in `encode_sf()` and `decode_sf()`. * Added functions to get (`get_third_dimension()`) and set (`set_third_dimension()`) the third dimension type of a flexible polyline encoded string. * Sign in to CodeFactor.io and add badge to continuously track code quality. * Use exception classes when throwing an exception in C++. diff --git a/vignettes/sf-support.Rmd b/vignettes/sf-support.Rmd index 14f34c7..a9bb8c2 100644 --- a/vignettes/sf-support.Rmd +++ b/vignettes/sf-support.Rmd @@ -25,8 +25,8 @@ from databases, and which geometrical operations should be defined for them."* The most common geometry types of simple features are: POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON. All geometry types are based on POINTs. -This package only supports the encoding and decoding of the geometry type -LINESTRING. +This package supports the encoding and decoding of the geometry types POINT, +LINESTRING and POLYGON. There are four possible dimension combinations of geometries in the sf package. In the `flexpolyine` package the first three dimension combinations are From e5a6c17a8197b9d078d1049ea7412bb132858206 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 25 Nov 2020 18:58:50 +0100 Subject: [PATCH 12/20] [lib] Fix clang range-loop-analysis warning on MacOS (Apple clang version 12.0.0). --- NEWS.md | 1 + inst/include/hf/flexpolyline.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 74fcc9d..9866077 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # flexpolyline 0.1.1.9000 +* Fix clang range-loop-analysis warning on MacOS in `flexpolyline.h` (Apple clang version 12.0.0). * Support for geometry types `"POLYGON"` and `"POINT"` in `encode_sf()` and `decode_sf()`. * Added functions to get (`get_third_dimension()`) and set (`set_third_dimension()`) the third dimension type of a flexible polyline encoded string. * Sign in to CodeFactor.io and add badge to continuously track code quality. diff --git a/inst/include/hf/flexpolyline.h b/inst/include/hf/flexpolyline.h index 20b65a8..e80ccb2 100644 --- a/inst/include/hf/flexpolyline.h +++ b/inst/include/hf/flexpolyline.h @@ -1,6 +1,6 @@ /* * Copy from :https://github.com/heremaps/flexible-polyline/blob/master/cpp/ - * Modified :Line 93, 210 + * Modified :Line 93, 210, 278 * Date :2020-06-09, Merlin Unterfinger * * Copyright (C) 2019 HERE Europe B.V. @@ -275,7 +275,7 @@ template std::string polyline_encode(Iter iter, int precision, ThirdDim third_dim, int third_dim_precision) { auto enc = encoder::Encoder(precision, third_dim, third_dim_precision); - for (const auto item : iter) { + for (const auto& item : iter) { // Mod: Return by reference to avoid clang (Apple clang version 12.0.0) range-loop-analysis warning on MacOS (loop variable 'item' of type 'const std::__1::pair' creates a copy from type 'const std::__1::pair'). enc.add(&item); } From a6ecc13d1b6633208bf3b46946c912e2b50613b5 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 25 Nov 2020 19:26:05 +0100 Subject: [PATCH 13/20] [lib] Refactor comments. --- inst/include/hf/flexpolyline.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inst/include/hf/flexpolyline.h b/inst/include/hf/flexpolyline.h index e80ccb2..c94fd82 100644 --- a/inst/include/hf/flexpolyline.h +++ b/inst/include/hf/flexpolyline.h @@ -275,9 +275,9 @@ template std::string polyline_encode(Iter iter, int precision, ThirdDim third_dim, int third_dim_precision) { auto enc = encoder::Encoder(precision, third_dim, third_dim_precision); - for (const auto& item : iter) { // Mod: Return by reference to avoid clang (Apple clang version 12.0.0) range-loop-analysis warning on MacOS (loop variable 'item' of type 'const std::__1::pair' creates a copy from type 'const std::__1::pair'). - enc.add(&item); - } + for (const auto& item : iter) { // Mod: Return by reference to avoid clang (Apple clang version 12.0.0) range-loop-analysis + enc.add(&item); // warning on MacOS: "loop variable 'item' of type 'const std::__1::pair' + } // creates a copy from type 'const std::__1::pair'" return enc.get_encoded(); } From 45d03dd316c1950d3ab8110411e68de000aadab7 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 9 Dec 2020 14:55:23 +0100 Subject: [PATCH 14/20] [git] Ignore vscode folder. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 2cdc2bd..434f468 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,6 @@ vignettes/*.pdf *.DS_Store inst/doc docs + +# vscode +.vscode From 632b8c80697c6cb4abace44609945ae38ba0b5f6 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 9 Dec 2020 15:14:07 +0100 Subject: [PATCH 15/20] [pkg] Ignore vscode also in R build. --- .Rbuildignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.Rbuildignore b/.Rbuildignore index 46a8026..a48b34d 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -6,3 +6,4 @@ ^docs$ ^pkgdown$ ^codecov\.yml$ +^.vscode$ From 8d36dd4965eaf63f5c2d73b1158ab8285f1d4c69 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 9 Dec 2020 15:49:35 +0100 Subject: [PATCH 16/20] [pkg] Reformat C++ code using Google Style. --- R/RcppExports.R | 31 +++-- man/decode.Rd | 7 +- man/encode.Rd | 12 +- man/set_third_dimension.Rd | 12 +- src/flexpolyline.cpp | 267 ++++++++++++++++++------------------- 5 files changed, 173 insertions(+), 156 deletions(-) diff --git a/R/RcppExports.R b/R/RcppExports.R index aa9c0e5..2f4247d 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -3,9 +3,10 @@ #' Decode a flexible polyline encoded string #' -#' This function calls \code{hf::polyline_decode} and \code{hf::get_third_dimension} -#' of the C++ implementation of the flexible polyline encoding by HERE. Depending -#' on the dimensions of the encoded line, a two or three dimensional line is decoded. +#' This function calls \code{hf::polyline_decode} and +#' \code{hf::get_third_dimension} of the C++ implementation of the flexible +#' polyline encoding by HERE. Depending on the dimensions of the encoded line, +#' a two or three dimensional line is decoded. #' #' @param encoded character, encoded flexible polyline string. #' @@ -30,10 +31,14 @@ decode <- function(encoded) { #' the flexible polyline encoding by HERE. Depending on the dimensions of the #' input coordinates, a two or three dimensional line is encoded. #' -#' @param line matrix, coordinates of the line in 2d or 3d (column order: LNG, LAT, DIM3). -#' @param precision integer, precision to use in encoding (between 0 and 15, \code{default=5}). -#' @param third_dim integer, type of the third dimension (0: ABSENT, 1: LEVEL, 2: ALTITUDE, 3: ELEVATION, 4, 6: CUSTOM1, 7: CUSTOM2, \code{default=3}). -#' @param third_dim_precision integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}). +#' @param line matrix, coordinates of the line in 2d or 3d (column order: LNG, +#' LAT, DIM3). +#' @param precision integer, precision to use in encoding (between 0 and 15, +#' \code{default=5}). +#' @param third_dim integer, type of the third dimension (0: ABSENT, 1: LEVEL, +#' 2: ALTITUDE, 3: ELEVATION, 4, 6: CUSTOM1, 7: CUSTOM2, \code{default=3}). +#' @param third_dim_precision integer, precision to use in encoding for the +#' third dimension (between 1 and 15, \code{default=5}). #' #' @return #' The line as string in the flexible polyline encoding format. @@ -93,12 +98,16 @@ get_third_dimension <- function(encoded) { #' dimension and encodes the line again. #' #' @note -#' The precision is not read from the header of the encoded line. Therefore it must be provided as a parameter for re-encoding. +#' The precision is not read from the header of the encoded line. Therefore it +#' must be provided as a parameter for re-encoding. #' #' @param encoded character, encoded flexible polyline string. -#' @param third_dim_name character, name of the third dimension to set (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). -#' @param precision integer, precision to use in encoding (between 0 and 15, \code{default=5}). -#' @param third_dim_precision integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}). +#' @param third_dim_name character, name of the third dimension to set (ABSENT, +#' LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +#' @param precision integer, precision to use in encoding (between 0 and 15, +#' \code{default=5}). +#' @param third_dim_precision integer, precision to use in encoding for the +#' third dimension (between 1 and 15, \code{default=5}). #' #' @return #' The line with the new third dimension as string in the flexible polyline diff --git a/man/decode.Rd b/man/decode.Rd index 00f2726..76254f5 100644 --- a/man/decode.Rd +++ b/man/decode.Rd @@ -13,9 +13,10 @@ decode(encoded) A matrix containing the coordinates of the decoded line. } \description{ -This function calls \code{hf::polyline_decode} and \code{hf::get_third_dimension} -of the C++ implementation of the flexible polyline encoding by HERE. Depending -on the dimensions of the encoded line, a two or three dimensional line is decoded. +This function calls \code{hf::polyline_decode} and +\code{hf::get_third_dimension} of the C++ implementation of the flexible +polyline encoding by HERE. Depending on the dimensions of the encoded line, +a two or three dimensional line is decoded. } \examples{ # 2d line diff --git a/man/encode.Rd b/man/encode.Rd index e665060..610ea44 100644 --- a/man/encode.Rd +++ b/man/encode.Rd @@ -7,13 +7,17 @@ encode(line, precision = 5L, third_dim = 3L, third_dim_precision = 5L) } \arguments{ -\item{line}{matrix, coordinates of the line in 2d or 3d (column order: LNG, LAT, DIM3).} +\item{line}{matrix, coordinates of the line in 2d or 3d (column order: LNG, +LAT, DIM3).} -\item{precision}{integer, precision to use in encoding (between 0 and 15, \code{default=5}).} +\item{precision}{integer, precision to use in encoding (between 0 and 15, +\code{default=5}).} -\item{third_dim}{integer, type of the third dimension (0: ABSENT, 1: LEVEL, 2: ALTITUDE, 3: ELEVATION, 4, 6: CUSTOM1, 7: CUSTOM2, \code{default=3}).} +\item{third_dim}{integer, type of the third dimension (0: ABSENT, 1: LEVEL, +2: ALTITUDE, 3: ELEVATION, 4, 6: CUSTOM1, 7: CUSTOM2, \code{default=3}).} -\item{third_dim_precision}{integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}).} +\item{third_dim_precision}{integer, precision to use in encoding for the +third dimension (between 1 and 15, \code{default=5}).} } \value{ The line as string in the flexible polyline encoding format. diff --git a/man/set_third_dimension.Rd b/man/set_third_dimension.Rd index 8e1d03d..b4b50f2 100644 --- a/man/set_third_dimension.Rd +++ b/man/set_third_dimension.Rd @@ -14,11 +14,14 @@ set_third_dimension( \arguments{ \item{encoded}{character, encoded flexible polyline string.} -\item{third_dim_name}{character, name of the third dimension to set (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2).} +\item{third_dim_name}{character, name of the third dimension to set (ABSENT, +LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2).} -\item{precision}{integer, precision to use in encoding (between 0 and 15, \code{default=5}).} +\item{precision}{integer, precision to use in encoding (between 0 and 15, +\code{default=5}).} -\item{third_dim_precision}{integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}).} +\item{third_dim_precision}{integer, precision to use in encoding for the +third dimension (between 1 and 15, \code{default=5}).} } \value{ The line with the new third dimension as string in the flexible polyline @@ -29,7 +32,8 @@ This function decodes the flexible polyline encoded line, changes the third dimension and encodes the line again. } \note{ -The precision is not read from the header of the encoded line. Therefore it must be provided as a parameter for re-encoding. +The precision is not read from the header of the encoded line. Therefore it +must be provided as a parameter for re-encoding. } \examples{ # 2d line (nothing happens...) diff --git a/src/flexpolyline.cpp b/src/flexpolyline.cpp index 21f7eb0..576b43a 100644 --- a/src/flexpolyline.cpp +++ b/src/flexpolyline.cpp @@ -1,16 +1,19 @@ +#include "hf/flexpolyline.h" + #include + +#include #include -#include #include -#include -#include "hf/flexpolyline.h" +#include using namespace Rcpp; //' Decode a flexible polyline encoded string //' -//' This function calls \code{hf::polyline_decode} and \code{hf::get_third_dimension} -//' of the C++ implementation of the flexible polyline encoding by HERE. Depending -//' on the dimensions of the encoded line, a two or three dimensional line is decoded. +//' This function calls \code{hf::polyline_decode} and +//' \code{hf::get_third_dimension} of the C++ implementation of the flexible +//' polyline encoding by HERE. Depending on the dimensions of the encoded line, +//' a two or three dimensional line is decoded. //' //' @param encoded character, encoded flexible polyline string. //' @@ -27,56 +30,52 @@ using namespace Rcpp; //' decode("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU") // [[Rcpp::export]] NumericMatrix decode(SEXP encoded) { - - // Convert from R SEXP to std::string - std::string encoded_str = Rcpp::as(encoded); - - // Initialize decoder - std::vector> polyline; - auto res = hf::polyline_decode( - encoded_str, [&polyline](double lat, double lng, double z) { - polyline.push_back(std::make_tuple(lat, lng, z)); - }); - - // Check valid encoding - if (!res) { - throw std::invalid_argument("Invalid encoding"); - } - - // Extract third dimension type - const char * dim_name[] = { - "ABSENT", "LEVEL", "ALTITUDE", "ELEVATION", - "RESERVED1", "RESERVED2", // Should not be used... - "CUSTOM1", "CUSTOM2" - }; - hf::ThirdDim thrd = hf::get_third_dimension(encoded_str); - int index = static_cast::type>(thrd); - - // Get line coordinates - size_t n = polyline.size(); - NumericMatrix coords(n, 2 + !!index); - - if (!!index) { - - // 3d case (index > 0) - for (size_t i = 0; i < n; ++i) { - coords( i, 0 ) = std::get<1>(polyline[i]); - coords( i, 1 ) = std::get<0>(polyline[i]); - coords( i, 2 ) = std::get<2>(polyline[i]); + // Convert from R SEXP to std::string + std::string encoded_str = Rcpp::as(encoded); + + // Initialize decoder + std::vector> polyline; + auto res = hf::polyline_decode( + encoded_str, [&polyline](double lat, double lng, double z) { + polyline.push_back(std::make_tuple(lat, lng, z)); + }); + + // Check valid encoding + if (!res) { + throw std::invalid_argument("Invalid encoding"); } - colnames(coords) = CharacterVector({"LNG", "LAT", dim_name[index]}); - - } else { - // 2d case, third dimension ABSENT (index == 0) - for (size_t i = 0; i < n; ++i) { - coords( i, 0 ) = std::get<1>(polyline[i]); - coords( i, 1 ) = std::get<0>(polyline[i]); + // Extract third dimension type + const char* dim_name[] = { + "ABSENT", "LEVEL", "ALTITUDE", + "ELEVATION", "RESERVED1", "RESERVED2", // Should not be used... + "CUSTOM1", "CUSTOM2"}; + hf::ThirdDim thrd = hf::get_third_dimension(encoded_str); + int index = static_cast::type>(thrd); + + // Get line coordinates + size_t n = polyline.size(); + NumericMatrix coords(n, 2 + !!index); + + if (!!index) { + // 3d case (index > 0) + for (size_t i = 0; i < n; ++i) { + coords(i, 0) = std::get<1>(polyline[i]); + coords(i, 1) = std::get<0>(polyline[i]); + coords(i, 2) = std::get<2>(polyline[i]); + } + colnames(coords) = CharacterVector({"LNG", "LAT", dim_name[index]}); + + } else { + // 2d case, third dimension ABSENT (index == 0) + for (size_t i = 0; i < n; ++i) { + coords(i, 0) = std::get<1>(polyline[i]); + coords(i, 1) = std::get<0>(polyline[i]); + } + colnames(coords) = CharacterVector({"LNG", "LAT"}); } - colnames(coords) = CharacterVector({"LNG", "LAT"}); - } - return coords; + return coords; } //' Encode a line in the flexible polyline encoding format @@ -85,10 +84,14 @@ NumericMatrix decode(SEXP encoded) { //' the flexible polyline encoding by HERE. Depending on the dimensions of the //' input coordinates, a two or three dimensional line is encoded. //' -//' @param line matrix, coordinates of the line in 2d or 3d (column order: LNG, LAT, DIM3). -//' @param precision integer, precision to use in encoding (between 0 and 15, \code{default=5}). -//' @param third_dim integer, type of the third dimension (0: ABSENT, 1: LEVEL, 2: ALTITUDE, 3: ELEVATION, 4, 6: CUSTOM1, 7: CUSTOM2, \code{default=3}). -//' @param third_dim_precision integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}). +//' @param line matrix, coordinates of the line in 2d or 3d (column order: LNG, +//' LAT, DIM3). +//' @param precision integer, precision to use in encoding (between 0 and 15, +//' \code{default=5}). +//' @param third_dim integer, type of the third dimension (0: ABSENT, 1: LEVEL, +//' 2: ALTITUDE, 3: ELEVATION, 4, 6: CUSTOM1, 7: CUSTOM2, \code{default=3}). +//' @param third_dim_precision integer, precision to use in encoding for the +//' third dimension (between 1 and 15, \code{default=5}). //' //' @return //' The line as string in the flexible polyline encoding format. @@ -116,45 +119,39 @@ NumericMatrix decode(SEXP encoded) { //' ) //' encode(line3d) // [[Rcpp::export]] -String encode(NumericMatrix line, int precision = 5, - int third_dim = 3, int third_dim_precision = 5) { - - String encoded; - size_t n = line.rows(); - - if (line.cols() == 2) { - - // 2d case: Set third dimension to ABSENT and third dimension precision to 0 - std::vector> input; - for (size_t i = 0; i < n; ++i) { - input.push_back( - std::make_pair(line( i, 1 ), line( i, 0 )) - ); +String encode(NumericMatrix line, int precision = 5, int third_dim = 3, + int third_dim_precision = 5) { + String encoded; + size_t n = line.rows(); + + if (line.cols() == 2) { + // 2d case: Set third dimension to ABSENT and third dimension precision + // to 0 + std::vector> input; + for (size_t i = 0; i < n; ++i) { + input.push_back(std::make_pair(line(i, 1), line(i, 0))); + } + encoded = + hf::polyline_encode(input, precision, hf::ThirdDim::ABSENT, 0); + + } else if (line.cols() == 3) { + // 3d case: Use third dimension with third dimension precision + std::vector> input; + for (size_t i = 0; i < n; ++i) { + input.push_back( + std::make_tuple(line(i, 1), line(i, 0), line(i, 2))); + } + encoded = hf::polyline_encode(input, precision, + static_cast(third_dim), + third_dim_precision); + + } else { + throw std::invalid_argument("Invalid input dimensions"); } - encoded = hf::polyline_encode(input, precision, hf::ThirdDim::ABSENT, 0); - } else if (line.cols() == 3) { - - // 3d case: Use third dimension with third dimension precision - std::vector> input; - for (size_t i = 0; i < n; ++i) { - input.push_back( - std::make_tuple(line( i, 1 ), line( i, 0 ), line( i, 2 )) - ); - } - encoded = hf::polyline_encode( - input, precision, static_cast(third_dim), third_dim_precision - ); - - } else { - - throw std::invalid_argument("Invalid input dimensions"); - } - - return encoded; + return encoded; } - //' Get third dimension of a flexible polyline encoded string //' //' This function calls \code{hf::get_third_dimension} of the C++ implementation @@ -176,21 +173,19 @@ String encode(NumericMatrix line, int precision = 5, //' get_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU") // [[Rcpp::export]] std::string get_third_dimension(SEXP encoded) { + const char* dim_name[] = { + "ABSENT", "LEVEL", "ALTITUDE", + "ELEVATION", "RESERVED1", "RESERVED2", // Should not be used... + "CUSTOM1", "CUSTOM2"}; - const char * dim_name[] = { - "ABSENT", "LEVEL", "ALTITUDE", "ELEVATION", - "RESERVED1", "RESERVED2", // Should not be used... - "CUSTOM1", "CUSTOM2" - }; + // Convert from R SEXP to std::string + std::string encoded_str = Rcpp::as(encoded); - // Convert from R SEXP to std::string - std::string encoded_str = Rcpp::as(encoded); + // Extract third dimension type + hf::ThirdDim thrd = hf::get_third_dimension(encoded_str); + int index = static_cast::type>(thrd); - // Extract third dimension type - hf::ThirdDim thrd = hf::get_third_dimension(encoded_str); - int index = static_cast::type>(thrd); - - return dim_name[index]; + return dim_name[index]; } //' Set third dimension of a flexible polyline encoded string @@ -199,12 +194,16 @@ std::string get_third_dimension(SEXP encoded) { //' dimension and encodes the line again. //' //' @note -//' The precision is not read from the header of the encoded line. Therefore it must be provided as a parameter for re-encoding. +//' The precision is not read from the header of the encoded line. Therefore it +//' must be provided as a parameter for re-encoding. //' //' @param encoded character, encoded flexible polyline string. -//' @param third_dim_name character, name of the third dimension to set (ABSENT, LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). -//' @param precision integer, precision to use in encoding (between 0 and 15, \code{default=5}). -//' @param third_dim_precision integer, precision to use in encoding for the third dimension (between 1 and 15, \code{default=5}). +//' @param third_dim_name character, name of the third dimension to set (ABSENT, +//' LEVEL, ALTITUDE, ELEVATION, CUSTOM1, CUSTOM2). +//' @param precision integer, precision to use in encoding (between 0 and 15, +//' \code{default=5}). +//' @param third_dim_precision integer, precision to use in encoding for the +//' third dimension (between 1 and 15, \code{default=5}). //' //' @return //' The line with the new third dimension as string in the flexible polyline @@ -219,36 +218,36 @@ std::string get_third_dimension(SEXP encoded) { //' # 3d line //' set_third_dimension("BlBoz5xJ67i1BU1B7PUzIhaUxL7YU", "ELEVATION") // [[Rcpp::export]] -std::string set_third_dimension(SEXP encoded, SEXP third_dim_name, int precision = 5, +std::string set_third_dimension(SEXP encoded, SEXP third_dim_name, + int precision = 5, int third_dim_precision = 5) { - - int third_dim_ind = -1; - const char * dim_name[] = { - "ABSENT", "LEVEL", "ALTITUDE", "ELEVATION", - "RESERVED1", "RESERVED2", // Should not be used... - "CUSTOM1", "CUSTOM2" - }; - - // Convert from R SEXP to std::string - std::string third_dim_str = Rcpp::as(third_dim_name); - - // Decode - NumericMatrix decoded = decode(encoded); - - // Match third dimension type - for (size_t i = 0; i != (sizeof dim_name / sizeof *dim_name); i++) { - if (dim_name[i] == third_dim_str) { - third_dim_ind = i; + int third_dim_ind = -1; + const char* dim_name[] = { + "ABSENT", "LEVEL", "ALTITUDE", + "ELEVATION", "RESERVED1", "RESERVED2", // Should not be used... + "CUSTOM1", "CUSTOM2"}; + + // Convert from R SEXP to std::string + std::string third_dim_str = Rcpp::as(third_dim_name); + + // Decode + NumericMatrix decoded = decode(encoded); + + // Match third dimension type + for (size_t i = 0; i != (sizeof dim_name / sizeof *dim_name); i++) { + if (dim_name[i] == third_dim_str) { + third_dim_ind = i; + } } - } - // Check if dimension is valid. - if (third_dim_ind == -1) { - throw std::invalid_argument("Invalid input name of third dimension"); - } + // Check if dimension is valid. + if (third_dim_ind == -1) { + throw std::invalid_argument("Invalid input name of third dimension"); + } - // Encode with new third dimension - String encoded_new = encode(decoded, precision, third_dim_ind, third_dim_precision); + // Encode with new third dimension + String encoded_new = + encode(decoded, precision, third_dim_ind, third_dim_precision); - return encoded_new; + return encoded_new; } From 81fb314dcac83129fd2e414596d80596ef317c8e Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 9 Dec 2020 15:59:36 +0100 Subject: [PATCH 17/20] [pkg] Bump version to v0.2.0. --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8430835..56322bb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: flexpolyline Type: Package Title: Flexible Polyline Encoding -Version: 0.1.1.9000 +Version: 0.2.0 Authors@R: c(person(given = "Merlin", family = "Unterfinger", diff --git a/NEWS.md b/NEWS.md index 9866077..83ff30b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# flexpolyline 0.1.1.9000 +# flexpolyline 0.2.0 * Fix clang range-loop-analysis warning on MacOS in `flexpolyline.h` (Apple clang version 12.0.0). * Support for geometry types `"POLYGON"` and `"POINT"` in `encode_sf()` and `decode_sf()`. From 696a485c648345bf7fefc73688dcb76fe904043a Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 9 Dec 2020 16:13:16 +0100 Subject: [PATCH 18/20] [doc] Add issue to NEWS. --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 83ff30b..7056142 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,7 @@ # flexpolyline 0.2.0 * Fix clang range-loop-analysis warning on MacOS in `flexpolyline.h` (Apple clang version 12.0.0). -* Support for geometry types `"POLYGON"` and `"POINT"` in `encode_sf()` and `decode_sf()`. +* Support for geometry types `"POLYGON"` and `"POINT"` in `encode_sf()` and `decode_sf()`, closes #31. * Added functions to get (`get_third_dimension()`) and set (`set_third_dimension()`) the third dimension type of a flexible polyline encoded string. * Sign in to CodeFactor.io and add badge to continuously track code quality. * Use exception classes when throwing an exception in C++. From 62a901c7e48bb630a46ae31bb4f603e87a8e8833 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Wed, 9 Dec 2020 16:13:56 +0100 Subject: [PATCH 19/20] [pkg] Rhub check result complained about missing "/" at the end of the URLs. --- DESCRIPTION | 4 ++-- man/flexpolyline-package.Rd | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 56322bb..62eedfc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -20,8 +20,8 @@ Description: Binding to the C++ implementation of the flexible polyline (3) using variable length for each coordinate delta; and (4) using 64 URL-safe characters to display the result. License: GPL-3 -URL: https://munterfinger.github.io/flexpolyline, https://github.com/munterfinger/flexpolyline -BugReports: https://github.com/munterfinger/flexpolyline/issues +URL: https://munterfinger.github.io/flexpolyline/, https://github.com/munterfinger/flexpolyline/ +BugReports: https://github.com/munterfinger/flexpolyline/issues/ LinkingTo: Rcpp Imports: diff --git a/man/flexpolyline-package.Rd b/man/flexpolyline-package.Rd index 8c49fdb..68ed6fc 100644 --- a/man/flexpolyline-package.Rd +++ b/man/flexpolyline-package.Rd @@ -20,9 +20,9 @@ Binding to the C++ implementation of the flexible polyline \seealso{ Useful links: \itemize{ - \item \url{https://munterfinger.github.io/flexpolyline} - \item \url{https://github.com/munterfinger/flexpolyline} - \item Report bugs at \url{https://github.com/munterfinger/flexpolyline/issues} + \item \url{https://munterfinger.github.io/flexpolyline/} + \item \url{https://github.com/munterfinger/flexpolyline/} + \item Report bugs at \url{https://github.com/munterfinger/flexpolyline/issues/} } } From 727fc7c9b655cfccfb98cd32c54d00ae0f905d87 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Thu, 17 Dec 2020 21:57:31 +0100 Subject: [PATCH 20/20] [doc] Typo. --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 7056142..0b27d79 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # flexpolyline 0.2.0 -* Fix clang range-loop-analysis warning on MacOS in `flexpolyline.h` (Apple clang version 12.0.0). +* Fix clang range-loop-analysis warning on macOS in `flexpolyline.h` (Apple clang version 12.0.0). * Support for geometry types `"POLYGON"` and `"POINT"` in `encode_sf()` and `decode_sf()`, closes #31. * Added functions to get (`get_third_dimension()`) and set (`set_third_dimension()`) the third dimension type of a flexible polyline encoded string. * Sign in to CodeFactor.io and add badge to continuously track code quality.