8000 Add lat and lon columns for `out * center;` queries in `osmdata_data_frame` by jmaspons · Pull Request #316 · ropensci/osmdata · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add lat and lon columns for out * center; queries in osmdata_data_frame #316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: osmdata
Title: Import 'OpenStreetMap' Data as Simple Features or Spatial Objects
Version: 0.2.1.001
Version: 0.2.1.002
Authors@R: c(
person("Mark", "Padgham", , "mark.padgham@email.com", role = c("aut", "cre")),
person("Bob", "Rudis", role = "aut"),
Expand Down
7 changes: 6 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
0.2.1.00x (dev version)
===================

## Major changes:

- `osmdata_data_frame` adds columns `osm_center_lat` and `osm_center_lon` for `out * center;` queries (#316).

## Minor changes

- Fix queries with !match_case and only one value (#317)
- Fix queries with `!match_case` and only one value (#317)
- Fix queries with multiple features & multiple osm_types (#318)


0.2.1
===================

Expand Down
32 changes: 16 additions & 16 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#' unique IDs and keys for each kind of OSM object (nodes, ways, rels).
#'
#' @return A dual Rcpp::DataFrame with the tags and metadata of the relations.
#'
#' @noRd
#'
#' @noRd
NULL

#' get_osm_ways
Expand All @@ -22,8 +22,8 @@ NULL
#' @param way_ids Vector of <osmid_t> IDs of ways to trace
#' @param ways Pointer to all ways in data set
#' @param unique_vals pointer to all unique values (OSM IDs and keys) in data set
#'
#' @noRd
#'
#' @noRd
NULL

#' get_osm_nodes
Expand All @@ -33,8 +33,8 @@ NULL
#' @param kv_df Pointer to Rcpp::DataFrame to hold key-value pairs
#' @param nodes Pointer to all nodes in data set
#' @param unique_vals pointer to all unique values (OSM IDs and keys) in data set
#'
#' @noRd
#'
#' @noRd
NULL

#' rcpp_osmdata_df
Expand All @@ -44,8 +44,8 @@ NULL
#'
#' @param st Text contents of an overpass API query
#' @return Rcpp::List objects of OSM data
#'
#' @noRd
#'
#' @noRd
rcpp_osmdata_df <- function(st) {
.Call(`_osmdata_rcpp_osmdata_df`, st)
}
Expand Down Expand Up @@ -133,8 +133,8 @@ rcpp_osmdata_sf <- function(st) {
#' @param unique_vals pointer to all unique values (OSM IDs and keys) in data set
#' @param bbox Pointer to the bbox needed for `sf` construction
#' @param crs Pointer to the crs needed for `sf` construction
#'
#' @noRd
#'
#' @noRd
NULL

#' get_osm_ways
Expand All @@ -150,8 +150,8 @@ NULL
#' @param geom_type Character string specifying "POLYGON" or "LINESTRING"
#' @param bbox Pointer to the bbox needed for `sf` construction
#' @param crs Pointer to the crs needed for `sf` construction
#'
#' @noRd
#'
#' @noRd
NULL

#' get_osm_relations
Expand All @@ -168,8 +168,8 @@ NULL
#'
#' @return A dual Rcpp::List, the first of which contains the multipolygon
#' relations; the second the multilinestring relations.
#'
#' @noRd
#'
#' @noRd
NULL

#' rcpp_osmdata_sp
Expand All @@ -178,8 +178,8 @@ NULL
#'
#' @param st Text contents of an overpass API query
#' @return A \code{SpatialLinesDataFrame} contains all polygons and associated data
#'
#' @noRd
#'
#' @noRd
rcpp_osmdata_sp <- function(st) {
.Call(`_osmdata_rcpp_osmdata_sp`, st)
}
Expand Down
22 changes: 21 additions & 1 deletion R/get-osmdata-df.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ osmdata_data_frame <- function (q,
df <- unique (df)
}
}

if (!is.null (obj$overpass_call) &&
!grepl (" center;$", obj$overpass_call)
) {
df[, c ("osm_center_lat", "osm_center_lon")] <- NULL
}

attr (df, "bbox") <- obj$bbox
attr (df, "overpass_call") <- obj$overpass_call
attr (df, "meta") <- obj$meta
Expand Down Expand Up @@ -112,10 +119,22 @@ xml_to_df <- function (doc, stringsAsFactors = FALSE) {
return (out)
}, i = res[1:3], k = keysL, SIMPLIFY = FALSE)

center <- lapply (c ("points", "ways", "rels"), function (type) {
get_center_from_cpp_output (res, type)
})
missing_center <- vapply (center, function (x) {
ncol (x) == 0 & nrow (x) > 0
}, FUN.VALUE = logical (1))
if (any (missing_center)) { # not a "out * center;" query
center <- lapply (center, function (x) {
x[, c ("osm_center_lat", "osm_center_lon")] <- NULL
x
})
}

meta <- lapply (c ("points", "ways", "rels"), function (type) {
get_meta_from_cpp_output (res, type)
})
metaCols<- unique (unlist (lapply (meta, names)))

df <- lapply(1:3, function (i) {
osm_type <- if (nrow (res[[i]]) > 0) {
Expand All @@ -126,6 +145,7 @@ xml_to_df <- function (doc, stringsAsFactors = FALSE) {
data.frame(
osm_type,
osm_id = rownames (res[[i]]),
center[[i]],
meta[[i]],
tags[[i]],
stringsAsFactors = stringsAsFactors,
Expand Down
20 changes: 20 additions & 0 deletions R/get-osmdata.R
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,23 @@ get_meta_from_cpp_output <- function (res, what = "points") {

return (as.data.frame (this))
}


#' Extract the center matrices from `rcpp_osmdata_df` output,
#' convert to df, and return only columns with data.
#'
#' The "center" components returns from `rcpp_osmdata_df()` are all named with
#' underscore prefixes. These are prepended here with "osm_center" to provide
#' standardised names.
#' @noRd
get_center_from_cpp_output <- function (res, what = "points") {

this <- res [[paste0 (what, "_center")]]
has_data <- apply (this, 2, function (i) any (!is.na (i)))
this <- this [, which (has_data), drop = FALSE]
if (ncol (this) > 0L) {
colnames (this) <- paste0 ("osm_center", colnames (this))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
} else {
this <- this [-seq_len (nrow (this)), ]
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's necessary because of the rownames. Having those means causes rows to be retained even when all columns are removed, so nrow(this) remains at whatever value it was, and not zero. That line removes all rows any time that the columns are removed, ensuring a null data.frame is returned.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we need that nrows match other data.frames, so a nrows x 0 dimensions data.frame is fine and necessary, otherwise the code will fail around

data.frame(

And all the tests pass so I think it's fine as it is


return (as.data.frame (this))
}
2 changes: 1 addition & 1 deletion codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"codeRepository": "https://github.com/ropensci/osmdata/",
"issueTracker": "https://github.com/ropensci/osmdata/issues",
"license": "https://spdx.org/licenses/GPL-3.0",
"version": "0.2.1.001",
10000 "version": "0.2.1.002",
"programmingLanguage": {
"@type": "ComputerLanguage",
"name": "R",
Expand Down
9 changes: 7 additions & 2 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#pragma once

#include "rapidxml.h"
#include <Rcpp.h> // Only for 'NA_REAL'

// APS not good pratice to have all the headers included here, adds to compile time
// better to #include as and where needed, ideally in source rather than headers,
Expand Down Expand Up @@ -102,15 +103,15 @@ struct RawNode
osmid_t id;
std::string _version = "", _timestamp = "", _changeset = "", _uid = "", _user = ""; // metadata
std::vector <std::string> key, value;
double lat = DOUBLE_MAX, lon = DOUBLE_MAX;
double lat = NA_REAL, lon = NA_REAL;
};

struct Node
{
osmid_t id;
std::string _version = "", _timestamp = "", _changeset = "", _uid = "", _user = ""; // metadata
std::map <std::string, std::string> key_val;
double lat = DOUBLE_MAX, lon = DOUBLE_MAX;
double lat = NA_REAL, lon = NA_REAL;
};

/* Traversing the XML tree means keys and values are read sequentially and
Expand All @@ -121,6 +122,7 @@ struct RawWay
{
osmid_t id;
std::string _version, _timestamp, _changeset, _uid, _user; // metadata
double _lat = NA_REAL, _lon = NA_REAL; // center
std::vector <std::string> key, value;
std::vector <osmid_t> nodes;
};
Expand All @@ -129,6 +131,7 @@ struct OneWay
{
osmid_t id;
std::string _version, _timestamp, _changeset, _uid, _user; // metadata
double _lat = NA_REAL, _lon = NA_REAL; // center
std::map <std::string, std::string> key_val;
std::vector <osmid_t> nodes;
};
Expand All @@ -139,6 +142,7 @@ struct RawRelation
osmid_t id;
std::string member_type;
std::string _version, _timestamp, _changeset, _uid, _user; // metadata
double _lat = NA_REAL, _lon = NA_REAL; // center
// APS would (key,value) be better in a std::map?
std::vector <std::string> key, value, role_node, role_way, role_relation;
std::vector <osmid_t> nodes;
Expand All @@ -152,6 +156,7 @@ struct Relation
osmid_t id;
std::string rel_type;
std::string _version, _timestamp, _changeset, _uid, _user; // metadata
double _lat = NA_REAL, _lon = NA_REAL; // center
std::map <std::string, std::string> key_val;
// Relations may have nodes as members, but these are not used here.
std::vector <std::pair <osmid_t, std::string> > nodes; // str = role
Expand Down
Loading
0