1 /***************************************************************************
2 * Copyright (C) 2016 by pgRouting developers *
3 * project@pgrouting.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License t &or more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21
22
23 #include "parser/OSMDocumentParserCallback.h"
24
25 #include <math.h>
26 #include <string>
27 #include <cassert>
28 #include <iostream>
29 #include <sstream>
30 #include "osm_elements/OSMDocument.h"
31 #include "osm_elements/Relation.h"
32 #include "osm_elements/osm_tag.h"
33 #include "osm_elements/Way.h"
34 #include "osm_elements/Node.h"
35 #include "utilities/print_progress.h"
36
37
38 namespace osm2pgr {
39
40 /*
41 <relation id ="147411" version="5" timestamp="2010-01-22T17:02:14Z" uid ="24299" user="james_hiebert" changeset="3684904">
42 <member type="way" ref="25584788" role=""/>
43 <member type="way" ref="35064036" role=""/>
44 <member type="way" ref="35064035" role=""/>
45 <member type="way" ref="35064037" role=""/>
46 <member type="way" ref="35064038" role=""/>
47 <member type="way" ref="35065746" role=""/>
48 <member type="way" ref="48690404" role=""/>
49 <member type="way" ref="24221632" role=""/>
50 <tag k="name" v="Mt. Douglas Park Local Connector"/>
51 <tag k="network" v="rcn"/>
52 <tag k="route" v="bicycle"/>
53 <tag k="type" v="route"/>
54 </relation>
55 */
56
57 void
show_progress()58 OSMDocumentParserCallback::show_progress() {
59 #if 0
60 try {
61 if (m_line == 0) return;
62 assert(m_rDocument.lines());
63 if (m_rDocument.lines() == 0) return;
64 if (((++m_line) % (m_rDocument.lines() / 100)) == 0) {
65 print_progress(m_rDocument.lines(), m_line);
66 }
67 } catch(...) {
68 m_line = 1;
69 }
70 #endif
71 }
72
73
74 /**
75 Parser callback for OSMDocument files
76 */
77 void
StartElement(const char * name,const char ** atts)78 OSMDocumentParserCallback::StartElement(
79 const char *name,
80 const char** atts) {
81 show_progress();
82
83 if (strcmp(name, "osm") == 0) {
84 m_section = 1;
85 }
86
87 if ((m_section == 1 && (strcmp(name, "way") == 0))
88 || (m_section == 2 && (strcmp(name, "relation") == 0))) {
89 ++m_section;
90 }
91
92
93 if (m_section == 1) {
94 if (strcmp(name, "node") == 0) {
95 last_node = new Node(atts);
96 }
97 if (strcmp(name, "tag") == 0) {
98 auto tag = last_node->add_tag(Tag(atts));
99 m_rDocument.add_config(last_node, tag);
100 }
101 return;
102 }
103
104 if (m_section == 2) {
105 if (strcmp(name, "way") == 0) {
106 last_way = new Way(atts);
107 }
108 if (strcmp(name, "tag") == 0) {
109 auto tag = last_way->add_tag(Tag(atts));
110 m_rDocument.add_config(last_way, tag);
111 }
112
113 if (strcmp(name, "nd") == 0) {
114 m_rDocument.add_node(*last_way, atts);
115 }
116 return;
117 }
118
119 if (m_section == 3) {
120 /*
121 * START RELATIONS CODE
122 */
123 if (strcmp(name, "relation") == 0) {
124 last_relation = new Relation(atts);
125 return;
126 }
127
128 if (strcmp(name, "member") == 0) {
129 /*
130 <member type="node" ref="721818679" role="label"/>
131 <member type="way" ref="173424370" role=""/>
132 <member type="way" ref="48435091" role="link"/>
133 */
134 auto way_id = last_relation->add_member(atts);
135 if (way_id == -1) return;
136 assert(!last_relation->way_refs().empty());
137 if (m_rDocument.has_way(way_id)) {
138 Way* way_ptr = m_rDocument.FindWay(way_id);
139 way_ptr->insert_tags(last_relation->tags());
140 } else {
141 assert(!last_relation->way_refs().empty());
142 last_relation->way_refs().pop_back();
143 }
144
145 return;
146 }
147 if (strcmp(name, "tag") == 0) {
148 auto tag = last_relation->add_tag(Tag(atts));
149 m_rDocument.add_config(last_relation, tag);
150 }
151 }
152 if (strcmp(name, "osm") == 0) {
153 }
154 }
155
EndElement(const char * name)156 void OSMDocumentParserCallback::EndElement(const char* name) {
157 if (strcmp(name, "osm") == 0) {
158 m_rDocument.endOfFile();
159 show_progress();
160 return;
161 }
162
163 if (strcmp(name, "node") == 0) {
164 m_rDocument.AddNode(*last_node);
165 delete last_node;
166 return;
167 }
168 if (strcmp(name, "way") == 0) {
169 m_rDocument.AddWay(*last_way);
170 if (m_rDocument.config_has_tag(last_way->tag_config())) {
171
172 auto maxspeed = m_rDocument.maxspeed(last_way->tag_config());
173 if (last_way->maxspeed_forward() <= 0) {
174 last_way->maxspeed_forward(maxspeed);
175 }
176 if (last_way->maxspeed_backward() <= 0) {
177 last_way->maxspeed_backward(maxspeed);
178 }
179 }
180 delete last_way;
181 return;
182 }
183
184 if (strcmp(name, "relation") == 0) {
185 if (m_rDocument.config_has_tag(last_relation->tag_config())) {
186 for (auto it = last_relation->way_refs().begin(); it != last_relation->way_refs().end(); ++it) {
187 auto way_id = *it;
188 assert(m_rDocument.has_way(way_id));
189 if (m_rDocument.has_way(way_id)) {
190 Way* way_ptr = m_rDocument.FindWay(way_id);
191 way_ptr->tag_config(last_relation->tag_config());
192 auto newValue = m_rDocument.maxspeed(
193 last_relation->tag_config());
194 if (way_ptr->maxspeed_forward() <= 0) {
195 way_ptr->maxspeed_forward(newValue);
196 }
197 if (way_ptr->maxspeed_backward() <= 0) {
198 way_ptr->maxspeed_backward(newValue);
199 }
200 }
201 }
202 m_rDocument.AddRelation(*last_relation);
203 }
204 // TODO add all other relations
205 delete last_relation;
206 return;
207 }
208 }
209
210 } // end namespace osm2pgr
211