Skip to content

Commit

Permalink
finish rewrite of osmdata_sc; closes #158
Browse files Browse the repository at this point in the history
  • Loading branch information
mpadge committed Nov 29, 2018
1 parent 4301d96 commit 0fc6daa
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 46 deletions.
36 changes: 17 additions & 19 deletions R/get-osmdata.R
Original file line number Diff line number Diff line change
Expand Up @@ -381,34 +381,32 @@ osmdata_sc <- function(q, doc, directed = FALSE, quiet=TRUE, encoding) {
message ('converting OSM data to sc format')
res <- rcpp_osmdata_sc (temp$doc)

# res has the $vertex, $edge and $object_link_edge tables ready to go. The
# $object table is mostly just key-val pairs, but the relations have
# additional members - called "ref" and "role" entries. The key-val tables
# are therefore expanded to add these two columns before rbind-ing the whole
# lot to the one table:
if (nrow (res$obj_rel) > 0)
res$obj_rel$obj_type <- "relation"
res$rel_kv$obj_type <- "relation"
# res has the $vertex, $edge and $object_link_edge tables ready to go.
# The rest are (node, way, rel) key-val tables which can just be rbind-ed,
# except for `obj_rel_memb`, which maps relations members onto roles and
# requires this bit of fidding:
if (nrow (res$obj_rel_memb) > 0)
{
res$obj_rel_memb <- data.frame ("object_" = res$obj_rel_memb$object_,
"key" = paste0 (res$obj_rel_memb$type, "_",
res$obj_rel_memb$role),
"val" = res$obj_rel_memb$ref,
"obj_type" = "relation",
stringsAsFactors = FALSE)
}
if (nrow (res$obj_rel_kv) > 0)
res$obj_rel_kv$obj_type <- "relation"
if (nrow (res$obj_way) > 0)
res$obj_way$obj_type <- "way"
if (nrow (res$obj_node) > 0)
res$obj_node$obj_type <- "node"

#if (nrow (res$rel) > 0)
#{
# # Change res$rel from ("ref", "role") to ("value", "key")
# res$rel <- data.frame (object_ = res$rel$object,
# key = paste0 ("rel_role_", res$rel$role),
# value = res$rel$ref,
# obj_type = "relation",
# stringsAsFactors = FALSE)
#}

res$object_link_edge$native_ <- TRUE
#res <- duplicate_twoway_edges (res, directed)

obj <- list () # SC **does not** use osmdata class definition
obj$object <- tibble::as.tibble (rbind (res$obj_rel,
obj$object <- tibble::as.tibble (rbind (res$obj_rel_memb,
res$obj_rel_kv,
res$obj_way,
res$obj_node))
obj$object_link_edge <- tibble::as.tibble (res$object_link_edge)
Expand Down
17 changes: 13 additions & 4 deletions src/osmdata-sc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,23 +311,32 @@ Rcpp::List rcpp_osmdata_sc (const std::string& st)
Rcpp::Named ("val") = xml.get_way_val (),
Rcpp::_["stringsAsFactors"] = false );

Rcpp::DataFrame obj_rel = Rcpp::DataFrame::create (
Rcpp::DataFrame obj_rel_memb = Rcpp::DataFrame::create (
Rcpp::Named ("object_") = xml.get_rel_memb_id (),
Rcpp::Named ("type") = xml.get_rel_memb_type (),
Rcpp::Named ("ref") = xml.get_rel_ref (),
Rcpp::Named ("role") = xml.get_rel_role (),
Rcpp::_["stringsAsFactors"] = false );

Rcpp::DataFrame obj_rel_kv = Rcpp::DataFrame::create (
Rcpp::Named ("object_") = xml.get_rel_kv_id (),
Rcpp::Named ("key") = xml.get_rel_key (),
Rcpp::Named ("val") = xml.get_rel_val (),
Rcpp::_["stringsAsFactors"] = false );

Rcpp::List ret (6);
Rcpp::List ret (7);
ret [0] = vertex;
ret [1] = edge;
ret [2] = oXe;
ret [3] = obj_node;
ret [4] = obj_way;
ret [5] = obj_rel;
ret [5] = obj_rel_memb;
ret [6] = obj_rel_kv;

std::vector <std::string> retnames {"vertex",
"edge", "object_link_edge",
"obj_node", "obj_way", "obj_rel"};
"obj_node", "obj_way",
"obj_rel_memb", "obj_rel_kv"};
ret.attr ("names") = retnames;

return ret;
Expand Down
59 changes: 36 additions & 23 deletions src/osmdata-sc.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ class XmlDataSC
zeroCounters (counters);
getSizes (p->first_node ());
vectorsResize (vectors, counters);
Rcpp::Rcout << "n(nodes, ways, rels, edges) = (" << counters.nnodes << ", " <<
counters.nways << ", " << counters.nrels << ", " << counters.nedges << "); kv = (" <<
counters.nnode_kv << ", " << counters.nway_kv << ", " << counters.nrel_kv << ")" <<
std::endl;

zeroCounters (counters);
traverseWays (p->first_node ());
Expand All @@ -133,13 +129,16 @@ class XmlDataSC
const std::vector <std::string>& get_rel_kv_id() const { return vectors.rel_kv_id; }
const std::vector <std::string>& get_rel_key() const { return vectors.rel_key; }
const std::vector <std::string>& get_rel_val() const { return vectors.rel_val; }

const std::vector <std::string>& get_rel_memb_id() const { return vectors.rel_memb_id; }
const std::vector <std::string>& get_rel_memb_type() const { return vectors.rel_memb_type; }
const std::vector <std::string>& get_rel_ref() const { return vectors.rel_ref; }
const std::vector <std::string>& get_rel_role() const { return vectors.rel_role; }

const std::vector <std::string>& get_way_id() const { return vectors.way_id; }
const std::vector <std::string>& get_way_key() const { return vectors.way_key; }
const std::vector <std::string>& get_way_val() const { return vectors.way_val; }

const std::vector <std::string>& get_node_id() const { return vectors.node_id; }
const std::vector <std::string>& get_node_key() const { return vectors.node_key; }
const std::vector <std::string>& get_node_val() const { return vectors.node_val; }
Expand Down Expand Up @@ -167,8 +166,8 @@ class XmlDataSC

void traverseWays (XmlNodePtr pt); // The primary function

void traverseRelation (XmlNodePtr pt);
void traverseWay (XmlNodePtr pt, int& node_num);
void traverseRelation (XmlNodePtr pt, std::string &id);
void traverseWay (XmlNodePtr pt, int& node_num, std::string& id);
void traverseNode (XmlNodePtr pt);

}; // end Class::XmlDataSC
Expand Down Expand Up @@ -345,7 +344,7 @@ inline void XmlDataSC::countNode (XmlNodePtr pt)

inline void XmlDataSC::traverseWays (XmlNodePtr pt)
{
RawWay rway;
std::string this_id;

for (XmlNodePtr it = pt->first_node (); it != nullptr;
it = it->next_sibling())
Expand All @@ -365,13 +364,12 @@ inline void XmlDataSC::traverseWays (XmlNodePtr pt)
} else if (!strcmp (it->name(), "way"))
{
int node_num = 0;
traverseWay (it, node_num);
counters.nedges--;
traverseWay (it, node_num, this_id);
counters.nways++;
}
else if (!strcmp (it->name(), "relation"))
{
traverseRelation (it);
traverseRelation (it, this_id);
counters.nrels++;
}
else
Expand All @@ -391,30 +389,35 @@ inline void XmlDataSC::traverseWays (XmlNodePtr pt)
************************************************************************
************************************************************************/

inline void XmlDataSC::traverseRelation (XmlNodePtr pt)
inline void XmlDataSC::traverseRelation (XmlNodePtr pt, std::string& id)
{
for (XmlAttrPtr it = pt->first_attribute (); it != nullptr;
it = it->next_attribute())
{
if (!strcmp (it->name(), "id"))
{
vectors.rel_kv_id [counters.nrel_kv] = it->value();
vectors.rel_memb_id [counters.nrel_memb] = it->value();
// These values are always first, so all other clauses are executed
// after this one
id = it->value();
} else if (!strcmp (it->name(), "k"))
{
vectors.rel_kv_id [counters.nrel_kv] = id;
vectors.rel_key [counters.nrel_kv] = it->value();
else if (!strcmp (it->name(), "v"))
} else if (!strcmp (it->name(), "v"))
vectors.rel_val [counters.nrel_kv++] = it->value();
else if (!strcmp (it->name(), "type"))
{
vectors.rel_memb_type [counters.nrel_memb] = it->value();
else if (!strcmp (it->name(), "ref"))
vectors.rel_memb_id [counters.nrel_memb] = id;
} else if (!strcmp (it->name(), "ref"))
vectors.rel_ref [counters.nrel_memb] = it->value();
else if (!strcmp (it->name(), "role"))
vectors.rel_role [counters.nrel_memb++] = it->value();
}
// allows for >1 child nodes
for (XmlNodePtr it = pt->first_node(); it != nullptr; it = it->next_sibling())
{
traverseRelation (it);
traverseRelation (it, id);
}
} // end function XmlDataSC::traverseRelation

Expand All @@ -427,18 +430,22 @@ inline void XmlDataSC::traverseRelation (XmlNodePtr pt)
************************************************************************
************************************************************************/

inline void XmlDataSC::traverseWay (XmlNodePtr pt, int& node_num)
inline void XmlDataSC::traverseWay (XmlNodePtr pt, int& node_num,
std::string& id)
{
for (XmlAttrPtr it = pt->first_attribute (); it != nullptr;
it = it->next_attribute())
{
if (!strcmp (it->name(), "id"))
{
vectors.way_id [counters.nway_kv] = it->value();
vectors.object [counters.nedges] = it->value();
// These values are always first, so all other clauses are executed
// after this one
id = it->value();
} else if (!strcmp (it->name(), "k"))
{
vectors.way_id [counters.nway_kv] = id;
vectors.way_key [counters.nway_kv] = it->value();
else if (!strcmp (it->name(), "v"))
} else if (!strcmp (it->name(), "v"))
vectors.way_val [counters.nway_kv++] = it->value();
else if (!strcmp (it->name(), "ref"))
{
Expand All @@ -447,10 +454,15 @@ inline void XmlDataSC::traverseWay (XmlNodePtr pt, int& node_num)
else
{
vectors.vx1 [counters.nedges] = it->value();
vectors.object [counters.nedges] = id;
vectors.edge [counters.nedges] = random_id (10);
if (node_num != waySizes.at (counters.nways))
vectors.vx0 [counters.nedges + 1] = it->value();
counters.nedges++;
// TODO: Very last value has nedges > vx0.size() - why?
if (node_num < waySizes.at (counters.nways) &
counters.nedges < vectors.vx0.size ())
{
vectors.vx0 [counters.nedges] = it->value();
}
}
node_num++;
}
Expand All @@ -459,7 +471,7 @@ inline void XmlDataSC::traverseWay (XmlNodePtr pt, int& node_num)
// allows for >1 child nodes
for (XmlNodePtr it = pt->first_node(); it != nullptr; it = it->next_sibling())
{
traverseWay (it, node_num);
traverseWay (it, node_num, id);
}
} // end function XmlDataSC::traverseWay

Expand Down Expand Up @@ -489,6 +501,7 @@ inline void XmlDataSC::traverseNode (XmlNodePtr pt)
{
vectors.node_val [counters.nnode_kv] = it->value();
vectors.node_id [counters.nnode_kv] = vectors.vert_id [counters.nnodes]; // will always be pre-set
counters.nnode_kv++;
}
}
// allows for >1 child nodes
Expand Down

0 comments on commit 0fc6daa

Please sign in to comment.