59 std::set<std::string> result;
60 result.insert(
"highway");
61 result.insert(
"railway");
62 result.insert(
"railway:position");
63 result.insert(
"railway:position:exact");
64 result.insert(
"waterway");
65 result.insert(
"aeroway");
66 result.insert(
"aerialway");
67 result.insert(
"power");
68 result.insert(
"man_made");
69 result.insert(
"building");
70 result.insert(
"leisure");
71 result.insert(
"amenity");
72 result.insert(
"shop");
73 result.insert(
"tourism");
74 result.insert(
"historic");
75 result.insert(
"landuse");
76 result.insert(
"natural");
77 result.insert(
"military");
78 result.insert(
"boundary");
79 result.insert(
"admin_level");
80 result.insert(
"sport");
81 result.insert(
"polygon");
82 result.insert(
"place");
83 result.insert(
"population");
84 result.insert(
"barrier");
85 result.insert(
"openGeoDB:population");
86 result.insert(
"openGeoDB:name");
92 if (!oc.
isSet(
"osm-files")) {
98 std::map<long long int, PCOSMNode*> nodes;
99 bool withAttributes = oc.
getBool(
"all-attributes");
103 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
111 for (std::map<long long int, PCOSMNode*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
121 std::set<long long int> innerEdges;
122 RelationsHandler relationsHandler(additionalWays, relations, innerEdges, withAttributes, *m);
123 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
132 EdgesHandler edgesHandler(nodes, edges, additionalWays, withAttributes, *m);
133 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
141 const bool useName = oc.
getBool(
"osm.use-name");
144 if (mergeRelationsThreshold >= 0) {
146 if (!rel->keep || rel->myWays.empty()) {
151 for (
auto it = rel->myWays.begin(); it != rel->myWays.end();) {
152 if (edges.count(*it) == 0 || edges[*it]->myCurrentNodes.empty()) {
153 it = rel->myWays.erase(it);
154 }
else if (innerEdges.count(*it) > 0) {
158 edges[*it]->standalone =
true;
159 it = rel->myWays.erase(it);
161 numNodes += (int)edges[*it]->myCurrentNodes.size();
166 WRITE_WARNINGF(
TL(
"Could not import polygon from relation '%' (missing ways)"), rel->id);
176 std::vector<std::vector<long long int> > snippets;
177 for (
const long long int wayID : rel->myWays) {
183 while (snippets.size() > 1) {
185 if (maxDist > mergeRelationsThreshold) {
193 double frontBackDist = 0;
199 if (frontBackDist < mergeRelationsThreshold) {
204 std::string frontBackMsg =
"";
205 if (frontBackDist > 0) {
206 frontBackMsg =
TLF(
", (front-to-back dist: %)", frontBackDist);
210 WRITE_WARNINGF(
TL(
"Could not import polygon from relation '%' (name:% reason: found gap of %m)."), rel->id, rel->name, maxDist)
213 for (
long long int wayID : rel->myWays) {
222 for (EdgeMap::iterator i = edges.begin(); i != edges.end(); ++i) {
228 if (!e->
standalone && mergeRelationsThreshold >= 0) {
249 std::string unknownPolyType =
"";
250 bool isInner = mergeRelationsThreshold >= 0 && innerEdges.count(e->
id) != 0 && tm.
has(
"inner");
251 for (std::map<std::string, std::string>::iterator it = e->
myAttributes.begin(); it != e->
myAttributes.end(); ++it) {
252 const std::string& key = it->first;
253 const std::string& value = it->second;
254 const std::string fullType = key +
"." + value;
255 if (tm.
has(key +
"." + value)) {
256 auto def = tm.
get(isInner ?
"inner" : fullType);
257 index =
addPolygon(e, vec, def, fullType, index, useName, toFill, ignorePruning, withAttributes);
258 }
else if (tm.
has(key)) {
259 auto def = tm.
get(isInner ?
"inner" : key);
260 index =
addPolygon(e, vec, def, fullType, index, useName, toFill, ignorePruning, withAttributes);
262 unknownPolyType = fullType;
266 if (index == 0 && !def.
discard && unknownPolyType !=
"") {
267 addPolygon(e, vec, def, unknownPolyType, index, useName, toFill, ignorePruning, withAttributes);
273 for (std::map<long long int, PCOSMNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i) {
286 std::string unKnownPOIType =
"";
287 for (std::map<std::string, std::string>::iterator it = n->
myAttributes.begin(); it != n->
myAttributes.end(); ++it) {
288 const std::string& key = it->first;
289 const std::string& value = it->second;
290 const std::string fullType = key +
"." + value;
291 if (tm.
has(key +
"." + value)) {
292 index =
addPOI(n, pos, tm.
get(fullType), fullType, index, useName, toFill, ignorePruning, withAttributes);
293 }
else if (tm.
has(key)) {
294 index =
addPOI(n, pos, tm.
get(key), fullType, index, useName, toFill, ignorePruning, withAttributes);
296 unKnownPOIType = fullType;
300 if (index == 0 && !def.
discard && unKnownPOIType !=
"") {
301 addPOI(n, pos, def, unKnownPOIType, index, useName, toFill, ignorePruning, withAttributes);
305 for (std::map<long long int, PCOSMNode*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
309 for (EdgeMap::iterator i = edges.begin(); i != edges.end(); ++i) {
313 for (Relations::iterator i = relations.begin(); i != relations.end(); ++i) {
329 auto itH = attrs.find(
"height");
330 if (itH != attrs.end()) {
334 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in way '%'."),
"height", itH->second,
id);
346 const bool closedShape = vec.front() == vec.back();
347 const std::string idSuffix = (index == 0 ?
"" :
"#" +
toString(index));
358 if (withAttributes) {
361 if (!toFill.
add(poly, ignorePruning)) {
372 int index,
bool useName,
PCPolyContainer& toFill,
bool ignorePruning,
bool withAttributes) {
376 const std::string idSuffix = (index == 0 ?
"" :
"#" +
toString(index));
382 if (withAttributes) {
385 if (!toFill.
add(poi, ignorePruning)) {
398 bool withAttributes,
MsgHandler& errorHandler) :
400 myWithAttributes(withAttributes),
401 myErrorHandler(errorHandler),
402 myToFill(toFill), myLastNodeID(-1) {}
410 myParentElements.push_back(element);
413 long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
418 if (myToFill.find(
id) == myToFill.end()) {
430 myToFill[toAdd->
id] = toAdd;
433 if (element ==
SUMO_TAG_TAG && myParentElements.size() > 2 && myParentElements[myParentElements.size() - 2] ==
SUMO_TAG_NODE
434 && myLastNodeID != -1) {
439 myToFill[myLastNodeID]->name = value;
440 }
else if (key ==
"") {
441 myErrorHandler.inform(
"Empty key in a a tag while parsing node '" +
toString(myLastNodeID) +
"' occurred.");
447 myToFill[myLastNodeID]->myAttributes[key] = value;
457 myParentElements.pop_back();
466 std::set<long long int>& innerEdges,
470 myAdditionalWays(additionalWays),
471 myRelations(relations),
472 myInnerEdges(innerEdges),
473 myWithAttributes(withAttributes),
474 myErrorHandler(errorHandler),
475 myCurrentRelation(nullptr) {
485 myParentElements.push_back(element);
488 myCurrentWays.clear();
491 if (action ==
"delete" || !ok) {
492 myCurrentRelation =
nullptr;
495 myCurrentRelation->keep =
false;
496 myCurrentRelation->id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
497 myRelations.push_back(myCurrentRelation);
500 }
else if (myCurrentRelation ==
nullptr) {
508 if (role ==
"outer" || role ==
"inner") {
510 if (memberType ==
"way") {
511 myCurrentWays.push_back(ref);
512 if (role ==
"inner") {
513 myInnerEdges.insert(ref);
521 && myCurrentRelation !=
nullptr) {
526 myErrorHandler.inform(
"Empty key in a a tag while parsing way '" +
toString(myCurrentRelation) +
"' occurred.");
533 myCurrentRelation->name = value;
535 myCurrentRelation->keep =
true;
536 for (std::vector<long long int>::iterator it = myCurrentWays.begin(); it != myCurrentWays.end(); ++it) {
537 myAdditionalWays[*it] = myCurrentRelation;
540 myCurrentRelation->myAttributes[key] = value;
547 myParentElements.pop_back();
549 myCurrentRelation->myWays = myCurrentWays;
550 myCurrentRelation =
nullptr;
551 myCurrentWays.clear();
562 bool withAttributes,
MsgHandler& errorHandler) :
564 myWithAttributes(withAttributes),
565 myErrorHandler(errorHandler),
566 myOSMNodes(osmNodes),
568 myAdditionalWays(additionalWays) {
578 myParentElements.push_back(element);
582 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
584 if (action ==
"delete" || !ok) {
585 myCurrentEdge =
nullptr;
589 myCurrentEdge->id = id;
590 myCurrentEdge->myIsClosed =
false;
591 myCurrentEdge->standalone =
false;
592 myKeep = (myAdditionalWays.find(
id) != myAdditionalWays.end());
595 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
597 const long long int ref = attrs.
get<
long long int>(
SUMO_ATTR_REF,
nullptr, ok);
599 if (myOSMNodes.find(ref) == myOSMNodes.end()) {
600 WRITE_WARNINGF(
TL(
"The referenced geometry information (ref='%') is not known"), ref);
603 myCurrentEdge->myCurrentNodes.push_back(ref);
607 if (element ==
SUMO_TAG_TAG && myParentElements.size() > 2 && myParentElements[myParentElements.size() - 2] ==
SUMO_TAG_WAY
608 && myCurrentEdge !=
nullptr) {
613 myErrorHandler.inform(
"Empty key in a a tag while parsing way '" +
toString(myCurrentEdge->id) +
"' occurred.");
620 myCurrentEdge->name = value;
623 myCurrentEdge->standalone =
true;
625 myCurrentEdge->myAttributes[key] = value;
632 myParentElements.pop_back();
633 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
635 RelationsMap::const_iterator it = myAdditionalWays.find(myCurrentEdge->id);
636 if (it != myAdditionalWays.end()) {
637 myCurrentEdge->myAttributes.insert((*it).second->myAttributes.begin(), (*it).second->myAttributes.end());
639 myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
641 delete myCurrentEdge;
643 myCurrentEdge =
nullptr;
650 double best = std::numeric_limits<double>::max();
656 for (
int i = 0; i < (int)snippets.size(); i++) {
657 for (
int j = i + 1; j < (int)snippets.size(); j++) {
696 std::vector<long long int> merged;
698 merged.insert(merged.end(), snippets[best_i].begin(), snippets[best_i].end());
700 merged.insert(merged.end(), snippets[best_i].rbegin(), snippets[best_i].rend());
703 merged.insert(merged.end(), snippets[best_j].begin(), snippets[best_j].end());
705 merged.insert(merged.end(), snippets[best_j].rbegin(), snippets[best_j].rend());
707 snippets.erase(snippets.begin() + best_j);
708 snippets.erase(snippets.begin() + best_i);
709 snippets.push_back(merged);
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
#define PROGRESS_BEGIN_TIME_MESSAGE(msg)
#define PROGRESS_TIME_MESSAGE(before)
@ SUMO_TAG_NODE
alternative definition for junction
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static bool isReadable(std::string path)
Checks whether the given file is readable.
bool x2cartesian(Position &from, bool includeInBoundary=true)
Converts the given coordinate into a cartesian and optionally update myConvBoundary.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
A storage for options typed value containers)
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
bool isInStringVector(const std::string &optionName, const std::string &itemName) const
Returns the named option is a list of string values containing the specified item.
A class which extracts OSM-edges from a parsed OSM-file.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void myEndElement(int element)
Called when a closing tag occurs.
~EdgesHandler()
Destructor.
EdgesHandler(const std::map< long long int, PCOSMNode * > &osmNodes, EdgeMap &toFill, const RelationsMap &additionalWays, bool withAttributes, MsgHandler &errorHandler)
Constructor.
A class which extracts OSM-nodes from a parsed OSM-file.
NodesHandler(std::map< long long int, PCOSMNode * > &toFill, bool withAttributes, MsgHandler &errorHandler)
Contructor.
void myEndElement(int element)
Called when a closing tag occurs.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
~NodesHandler()
Destructor.
A class which extracts relevant way-ids from relations in a parsed OSM-file.
void myEndElement(int element)
Called when a closing tag occurs.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
~RelationsHandler()
Destructor.
RelationsHandler(RelationsMap &additionalWays, Relations &relations, std::set< long long int > &innerEdges, bool withAttributes, MsgHandler &errorHandler)
Constructor.
static int addPolygon(const PCOSMEdge *edge, const PositionVector &vec, const PCTypeMap::TypeDef &def, const std::string &fullType, int index, bool useName, PCPolyContainer &toFill, bool ignorePruning, bool withAttributes)
try add the polygon and return the next index on success
std::map< long long int, PCOSMEdge * > EdgeMap
static Position convertNodePosition(PCOSMNode *n)
retrieve cartesian coordinate for given node
static int addPOI(const PCOSMNode *node, const Position &pos, const PCTypeMap::TypeDef &def, const std::string &fullType, int index, bool useName, PCPolyContainer &toFill, bool ignorePruning, bool withAttributes)
try add the POI and return the next index on success
static double mergeClosest(const std::map< long long int, PCOSMNode * > &nodes, std::vector< std::vector< long long int > > &snippets)
static void loadIfSet(OptionsCont &oc, PCPolyContainer &toFill, PCTypeMap &tm)
Loads pois/polygons assumed to be stored as OSM-XML.
std::vector< PCOSMRelation * > Relations
static const std::set< std::string > MyKeysToInclude
static bool myFullType
Whether the type id or full type should be used.
std::map< long long int, PCOSMRelation * > RelationsMap
static double parseHeight(const std::map< std::string, std::string > &attrs, long long int id)
static std::set< std::string > initMyKeysToInclude()
A storage for loaded polygons and pois.
bool add(SUMOPolygon *poly, bool ignorePruning=false)
Adds a polygon to the storage.
A storage for type mappings.
const TypeDef & getDefault()
get the default type according to the given options
const TypeDef & get(const std::string &id)
Returns a type definition.
bool has(const std::string &id)
Returns the information whether the named type is known.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
A point in 2D or 3D with translation and scaling methods.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
void push_back_noDoublePos(const Position &p)
insert in back a non double position
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SAX-handler base for SUMO-files.
static const double DEFAULT_HEIGHT
static const std::string DEFAULT_IMG_FILE
static const double DEFAULT_ANGLE
static const std::string DEFAULT_NAME
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
static double parseDist(const std::string &sData)
parse a distance, length or width value with a unit
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
An internal definition of a loaded edge.
bool myIsClosed
Information whether this area is closed.
long long int id
The edge's id.
std::map< std::string, std::string > myAttributes
Additional attributes.
std::vector< long long int > myCurrentNodes
The list of nodes this edge is made of.
std::string name
The edge's name (if any)
An internal representation of an OSM-node.
double lat
The latitude the node is located at.
double lon
The longitude the node is located at.
long long int id
The node's id.
std::map< std::string, std::string > myAttributes
Additional attributes.
An internal definition of a loaded relation.
A single definition of values that shall be used for a given type.
std::string icon
the icon to use
bool discard
Information whether polygons of this type shall be discarded.
std::string prefix
The prefix to use.
double layer
The layer to use.
std::string id
The new type id to use.
RGBColor color
The color to use.
Filltype allowFill
Information whether polygons of this type can be filled.