-
Notifications
You must be signed in to change notification settings - Fork 0
/
osm.cpp
170 lines (145 loc) · 3.75 KB
/
osm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*osm.cpp*/
//
// Functions for working with an Open Street Map file.
//
// Mark Fortes
// Northwestern University
// CS 211: Winter 2023
//
// References:
//
// TinyXML:
// files: https://github.com/leethomason/tinyxml2
// docs: http://leethomason.github.io/tinyxml2/
//
// OpenStreetMap: https://www.openstreetmap.org
// OpenStreetMap docs:
// https://wiki.openstreetmap.org/wiki/Main_Page
// https://wiki.openstreetmap.org/wiki/Map_Features
// https://wiki.openstreetmap.org/wiki/Node
// https://wiki.openstreetmap.org/wiki/Way
// https://wiki.openstreetmap.org/wiki/Relation
//
#include <iostream>
#include <string>
#include <cassert>
#include "osm.h"
using namespace std;
using namespace tinyxml2;
//
// osmLoadMapFile
//
// Given the filename for an XML doc, tries to open and load
// that file into the given xmldoc variable (which is passed
// by reference). Returns true if successful, false if the
// file could not be opened OR the file does not contain
// an Open Street Map document.
//
bool osmLoadMapFile(string filename, XMLDocument& xmldoc)
{
//
// load the XML document:
//
xmldoc.LoadFile(filename.c_str());
if (xmldoc.ErrorID() != 0) // failed:
{
cout << "**ERROR: unable to open XML file '" << filename << "'." << endl;
return false;
}
//
// top-level element should be "osm" if the file is a valid open
// street map:
//
XMLElement* osm = xmldoc.FirstChildElement("osm");
if (osm == nullptr)
{
cout << "**ERROR: unable to find top-level 'osm' XML element." << endl;
cout << "**ERROR: this file is probably not an Open Street Map." << endl;
return false;
}
//
// success:
//
return true;
}
//
// osmContainsKeyValue
//
// Given a pointer to an XML Element, searches through all
// the tags associated with this element looking for the
// given (key, value) pair. For example, the call
//
// containsKeyValue(e, "entrance", "yes")
//
// will return true if it comes across the tag
//
// <tag k="entrance" v="yes"/>
//
bool osmContainsKeyValue(XMLElement* e, string key, string value)
{
XMLElement* tag = e->FirstChildElement("tag");
while (tag != nullptr)
{
const XMLAttribute* keyAttribute = tag->FindAttribute("k");
const XMLAttribute* valueAttribute = tag->FindAttribute("v");
if (keyAttribute != nullptr && valueAttribute != nullptr)
{
string elemkey(keyAttribute->Value());
string elemvalue(valueAttribute->Value());
if (elemkey == key && elemvalue == value) // found it:
{
return true;
}
}
//
// not a match, try the next tag:
//
tag = tag->NextSiblingElement("tag");
}
//
// if get here, not found:
//
return false;
}
//
// osmGetKeyValue
//
// Given a pointer to an XML Element, searches through all
// the tags associated with this element looking for the
// given key. If found, returns the associated value. For
// example, given the call
//
// getKeyValue(e, "entrance")
//
// will return "yes" if it comes across the tag
//
// <tag k="entrance" v="yes"/>
//
// If the key is not found, the empty string "" is returned.
//
string osmGetKeyValue(XMLElement* e, string key)
{
XMLElement* tag = e->FirstChildElement("tag");
while (tag != nullptr)
{
const XMLAttribute* keyAttribute = tag->FindAttribute("k");
const XMLAttribute* valueAttribute = tag->FindAttribute("v");
if (keyAttribute != nullptr && valueAttribute != nullptr)
{
string elemkey(keyAttribute->Value());
if (elemkey == key) // found it:
{
string elemvalue(valueAttribute->Value());
return elemvalue;
}
}
//
// not a match, try the next tag:
//
tag = tag->NextSiblingElement("tag");
}
//
// if get here, not found:
//
return "";
}