···11# Generated by using Rcpp::compileAttributes() -> do not edit by hand
22# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
3344+#' get_osm_relations
55+#'
66+#' Return a dual Rcpp::List containing all OSM relations, the firmt element of
77+#' which holds `multipolygon` relations, while the second holds all others,
88+#' which are stored as `multilinestring` objects.
99+#'
1010+#' @param rels Pointer to the vector of Relation objects
1111+#' @param nodes Pointer to the vector of node objects
1212+#' @param ways Pointer to the vector of way objects
1313+#' @param unique_vals Pointer to a UniqueVals object containing std::sets of all
1414+#' unique IDs and keys for each kind of OSM object (nodes, ways, rels).
1515+#'
1616+#' @return A dual Rcpp::List, the first of which contains the multipolygon
1717+#' relations; the second the multilinestring relations.
1818+#'
1919+#' @noRd
2020+NULL
2121+2222+#' get_osm_ways
2323+#'
2424+#' Store key-val pairs for OSM ways as a list/data.frame
2525+#'
2626+#' @param kv_df Pointer to Rcpp::DataFrame to hold key-value pairs
2727+#' @param way_ids Vector of <osmid_t> IDs of ways to trace
2828+#' @param ways Pointer to all ways in data set
2929+#' @param nodes Pointer to all nodes in data set
3030+#' @param unique_vals pointer to all unique values (OSM IDs and keys) in data set
3131+#'
3232+#' @noRd
3333+NULL
3434+3535+#' get_osm_nodes
3636+#'
3737+#' Store OSM nodes as `sf::POINT` objects
3838+#'
3939+#' @param kv_df Pointer to Rcpp::DataFrame to hold key-value pairs
4040+#' @param nodes Pointer to all nodes in data set
4141+#' @param unique_vals pointer to all unique values (OSM IDs and keys) in data set
4242+#'
4343+#' @noRd
4444+NULL
4545+4646+#' rcpp_osmdata_df
4747+#'
4848+#' Return OSM data key-value pairs in series of data.frame objects, without any
4949+#' spatial/geometrtic information.
5050+#'
5151+#' @param st Text contents of an overpass API query
5252+#' @return Rcpp::List objects of OSM data
5353+#'
5454+#' @noRd
5555+rcpp_osmdata_df <- function(st) {
5656+ .Call(`_osmdata_rcpp_osmdata_df`, st)
5757+}
5858+459#' rcpp_osmdata_sc
560#'
661#' Return OSM data in silicate (SC) format
···11+/***************************************************************************
22+ * Project: osmdata
33+ * File: osmdata-data_frame.cpp
44+ * Language: C++
55+ *
66+ * osmdata is free software: you can redistribute it and/or modify it under
77+ * the terms of the GNU General Public License as published by the Free
88+ * Software Foundation, either version 3 of the License, or (at your option)
99+ * any later version.
1010+ *
1111+ * osmdata is distributed in the hope that it will be useful, but WITHOUT ANY
1212+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1313+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1414+ * details.
1515+ *
1616+ * You should have received a copy of the GNU General Public License along with
1717+ * osmdata. If not, see <https://www.gnu.org/licenses/>.
1818+ *
1919+ * Author: Mark Padgham
2020+ * E-Mail: mark.padgham@email.com
2121+ *
2222+ * Description: Modified version of 'osmdata-sf' to extract OSM data from an
2323+ * object of class XmlData and return it in Rcpp::List format,
2424+ * but in this case ignoring the actual geometric data. The
2525+ * returned object contains key-value data only, for return
2626+ * from the R function 'osmdata_data_frame'.
2727+ *
2828+ * Limitations:
2929+ *
3030+ * Dependencies: none (rapidXML header included in osmdata)
3131+ *
3232+ * Compiler Options: -std=c++11
3333+ ***************************************************************************/
3434+3535+#include "osmdata.h"
3636+3737+#include <Rcpp.h>
3838+3939+// Note: This code uses explicit index counters within most loops which use Rcpp
4040+// objects, because these otherwise require a
4141+// static_cast <size_t> (std::distance (...)). This operation copies each
4242+// instance and can slow the loops down by several orders of magnitude!
4343+4444+/************************************************************************
4545+ ************************************************************************
4646+ ** **
4747+ ** 1. PRIMARY FUNCTIONS TO TRACE WAYS AND RELATIONS **
4848+ ** **
4949+ ************************************************************************
5050+ ************************************************************************/
5151+5252+5353+//' get_osm_relations
5454+//'
5555+//' Return a dual Rcpp::List containing all OSM relations, the firmt element of
5656+//' which holds `multipolygon` relations, while the second holds all others,
5757+//' which are stored as `multilinestring` objects.
5858+//'
5959+//' @param rels Pointer to the vector of Relation objects
6060+//' @param nodes Pointer to the vector of node objects
6161+//' @param ways Pointer to the vector of way objects
6262+//' @param unique_vals Pointer to a UniqueVals object containing std::sets of all
6363+//' unique IDs and keys for each kind of OSM object (nodes, ways, rels).
6464+//'
6565+//' @return A dual Rcpp::List, the first of which contains the multipolygon
6666+//' relations; the second the multilinestring relations.
6767+//'
6868+//' @noRd
6969+Rcpp::DataFrame osm_df::get_osm_relations (const Relations &rels,
7070+ const UniqueVals &unique_vals)
7171+{
7272+ std::vector <std::string> ids_mp, rel_id_mp;
7373+ std::vector <std::string> roles;
7474+7575+ const unsigned int nmp = rels.size ();
7676+7777+ size_t ncol = unique_vals.k_rel.size ();
7878+ rel_id_mp.reserve (nmp);
7979+8080+ Rcpp::CharacterMatrix kv_mat (Rcpp::Dimension (nmp, ncol));
8181+ unsigned int count = 0;
8282+8383+ for (auto itr = rels.begin (); itr != rels.end (); ++itr)
8484+ {
8585+ Rcpp::checkUserInterrupt ();
8686+8787+ rel_id_mp.push_back (std::to_string (itr->id));
8888+8989+ osm_convert::get_value_mat_rel (itr, unique_vals, kv_mat, count++);
9090+ }
9191+9292+ Rcpp::DataFrame kv_df;
9393+ if (rel_id_mp.size () > 0)
9494+ {
9595+ kv_mat.attr ("names") = unique_vals.k_rel;
9696+ kv_mat.attr ("dimnames") = Rcpp::List::create (rel_id_mp, unique_vals.k_rel);
9797+ kv_df = osm_convert::restructure_kv_mat (kv_mat, false);
9898+ } else
9999+ kv_df = R_NilValue;
100100+101101+ return kv_df;
102102+}
103103+104104+//' get_osm_ways
105105+//'
106106+//' Store key-val pairs for OSM ways as a list/data.frame
107107+//'
108108+//' @param kv_df Pointer to Rcpp::DataFrame to hold key-value pairs
109109+//' @param way_ids Vector of <osmid_t> IDs of ways to trace
110110+//' @param ways Pointer to all ways in data set
111111+//' @param nodes Pointer to all nodes in data set
112112+//' @param unique_vals pointer to all unique values (OSM IDs and keys) in data set
113113+//'
114114+//' @noRd
115115+void osm_df::get_osm_ways (Rcpp::DataFrame &kv_df,
116116+ const std::set <osmid_t> &way_ids, const Ways &ways,
117117+ const UniqueVals &unique_vals)
118118+{
119119+120120+ size_t nrow = way_ids.size (), ncol = unique_vals.k_way.size ();
121121+ std::vector <std::string> waynames;
122122+ waynames.reserve (way_ids.size ());
123123+124124+ Rcpp::CharacterMatrix kv_mat (Rcpp::Dimension (nrow, ncol));
125125+ std::fill (kv_mat.begin (), kv_mat.end (), NA_STRING);
126126+ unsigned int count = 0;
127127+ for (auto wi = way_ids.begin (); wi != way_ids.end (); ++wi)
128128+ {
129129+ Rcpp::checkUserInterrupt ();
130130+ waynames.push_back (std::to_string (*wi));
131131+ auto wj = ways.find (*wi);
132132+ osm_convert::get_value_mat_way (wj, unique_vals, kv_mat, count);
133133+ count++;
134134+ }
135135+136136+ kv_df = R_NilValue;
137137+ if (way_ids.size () > 0)
138138+ {
139139+ kv_mat.attr ("names") = unique_vals.k_way;
140140+ kv_mat.attr ("dimnames") = Rcpp::List::create (waynames, unique_vals.k_way);
141141+ if (kv_mat.nrow () > 0 && kv_mat.ncol () > 0)
142142+ kv_df = osm_convert::restructure_kv_mat (kv_mat, false);
143143+ }
144144+}
145145+146146+//' get_osm_nodes
147147+//'
148148+//' Store OSM nodes as `sf::POINT` objects
149149+//'
150150+//' @param kv_df Pointer to Rcpp::DataFrame to hold key-value pairs
151151+//' @param nodes Pointer to all nodes in data set
152152+//' @param unique_vals pointer to all unique values (OSM IDs and keys) in data set
153153+//'
154154+//' @noRd
155155+void osm_df::get_osm_nodes (Rcpp::DataFrame &kv_df,
156156+ const Nodes &nodes, const UniqueVals &unique_vals)
157157+{
158158+ size_t nrow = nodes.size (), ncol = unique_vals.k_point.size ();
159159+160160+ Rcpp::CharacterMatrix kv_mat (Rcpp::Dimension (nrow, ncol));
161161+ std::fill (kv_mat.begin (), kv_mat.end (), NA_STRING);
162162+163163+ std::vector <std::string> ptnames;
164164+ ptnames.reserve (nodes.size ());
165165+ unsigned int count = 0;
166166+ for (auto ni = nodes.begin (); ni != nodes.end (); ++ni)
167167+ {
168168+ if (count % 1000 == 0)
169169+ Rcpp::checkUserInterrupt ();
170170+171171+ ptnames.push_back (std::to_string (ni->first));
172172+ for (auto kv_iter = ni->second.key_val.begin ();
173173+ kv_iter != ni->second.key_val.end (); ++kv_iter)
174174+ {
175175+ const std::string &key = kv_iter->first;
176176+ unsigned int ndi = unique_vals.k_point_index.at (key);
177177+ kv_mat (count, ndi) = kv_iter->second;
178178+ }
179179+ count++;
180180+ }
181181+ if (unique_vals.k_point.size () > 0)
182182+ {
183183+ kv_mat.attr ("dimnames") = Rcpp::List::create (ptnames, unique_vals.k_point);
184184+ kv_df = osm_convert::restructure_kv_mat (kv_mat, false);
185185+ } else
186186+ kv_df = R_NilValue;
187187+188188+ ptnames.clear ();
189189+}
190190+191191+192192+/************************************************************************
193193+ ************************************************************************
194194+ ** **
195195+ ** THE FINAL RCPP FUNCTION CALLED BY osmdata_df **
196196+ ** **
197197+ ************************************************************************
198198+ ************************************************************************/
199199+200200+//' rcpp_osmdata_df
201201+//'
202202+//' Return OSM data key-value pairs in series of data.frame objects, without any
203203+//' spatial/geometrtic information.
204204+//'
205205+//' @param st Text contents of an overpass API query
206206+//' @return Rcpp::List objects of OSM data
207207+//'
208208+//' @noRd
209209+// [[Rcpp::export]]
210210+Rcpp::List rcpp_osmdata_df (const std::string& st)
211211+{
212212+ XmlData xml (st);
213213+214214+ const std::map <osmid_t, Node>& nodes = xml.nodes ();
215215+ const std::map <osmid_t, OneWay>& ways = xml.ways ();
216216+ const std::vector <Relation>& rels = xml.relations ();
217217+ const UniqueVals& unique_vals = xml.unique_vals ();
218218+219219+ /* --------------------------------------------------------------
220220+ * 1. Extract OSM Relations
221221+ * --------------------------------------------------------------*/
222222+223223+ Rcpp::DataFrame kv_rels = osm_df::get_osm_relations (rels, unique_vals);
224224+225225+ /* --------------------------------------------------------------
226226+ * 2. Extract OSM ways
227227+ * --------------------------------------------------------------*/
228228+229229+ std::set <osmid_t> way_ids;
230230+ for (auto itw = ways.begin (); itw != ways.end (); ++itw)
231231+ {
232232+ way_ids.insert ((*itw).first);
233233+ }
234234+235235+ Rcpp::List polyList (way_ids.size ());
236236+ Rcpp::DataFrame kv_df_ways;
237237+ osm_df::get_osm_ways (kv_df_ways, way_ids, ways, unique_vals);
238238+239239+ /* --------------------------------------------------------------
240240+ * 3. Extract OSM nodes
241241+ * --------------------------------------------------------------*/
242242+243243+ Rcpp::DataFrame kv_df_points;
244244+ osm_df::get_osm_nodes (kv_df_points, nodes, unique_vals);
245245+246246+ /* --------------------------------------------------------------
247247+ * 4. Collate all data
248248+ * --------------------------------------------------------------*/
249249+250250+ Rcpp::List ret (3);
251251+ ret [0] = kv_df_points;
252252+ ret [1] = kv_df_ways;
253253+ ret [2] = kv_rels;
254254+255255+ std::vector <std::string> retnames {"points_kv", "ways_kv", "rels_kv"};
256256+ ret.attr ("names") = retnames;
257257+258258+ return ret;
259259+}