Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file PCLoaderDlrNavteq.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Christoph Sommer
18 : /// @author Michael Behrisch
19 : /// @date Thu, 02.11.2006
20 : ///
21 : // A reader of pois and polygons stored in DLR-Navteq (Elmar)-format
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <string>
26 : #include <map>
27 : #include <fstream>
28 : #include <sstream>
29 : #include <iostream>
30 : #include <utils/common/UtilExceptions.h>
31 : #include <utils/common/MsgHandler.h>
32 : #include <utils/common/StringUtils.h>
33 : #include <utils/common/StringUtils.h>
34 : #include <utils/common/ToString.h>
35 : #include <utils/common/StringTokenizer.h>
36 : #include <utils/common/FileHelpers.h>
37 : #include <utils/importio/LineReader.h>
38 : #include <utils/options/OptionsCont.h>
39 : #include <utils/options/Option.h>
40 : #include <utils/common/StdDefs.h>
41 : #include <polyconvert/PCPolyContainer.h>
42 : #include "PCLoaderDlrNavteq.h"
43 : #include <utils/common/RGBColor.h>
44 : #include <utils/geom/GeomHelper.h>
45 : #include <utils/geom/Boundary.h>
46 : #include <utils/geom/Position.h>
47 : #include <utils/geom/GeoConvHelper.h>
48 :
49 :
50 : // ===========================================================================
51 : // method definitions
52 : // ===========================================================================
53 : void
54 41 : PCLoaderDlrNavteq::loadIfSet(OptionsCont& oc, PCPolyContainer& toFill,
55 : PCTypeMap& tm) {
56 82 : if (oc.isSet("dlr-navteq-poly-files")) {
57 4 : loadPolyFiles(oc, toFill, tm);
58 : }
59 82 : if (oc.isSet("dlr-navteq-poi-files")) {
60 2 : loadPOIFiles(oc, toFill, tm);
61 : }
62 41 : }
63 :
64 :
65 : void
66 2 : PCLoaderDlrNavteq::loadPOIFiles(OptionsCont& oc, PCPolyContainer& toFill,
67 : PCTypeMap& tm) {
68 4 : std::vector<std::string> files = oc.getStringVector("dlr-navteq-poi-files");
69 4 : for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
70 4 : if (!FileHelpers::isReadable(*file)) {
71 0 : throw ProcessError(TLF("Could not open dlr-navteq-poi-file '%'.", *file));
72 : }
73 6 : PROGRESS_BEGIN_MESSAGE("Parsing pois from dlr-navteq-poi-file '" + *file + "'");
74 2 : loadPOIFile(*file, oc, toFill, tm);
75 2 : PROGRESS_DONE_MESSAGE();
76 : }
77 2 : }
78 :
79 :
80 : void
81 4 : PCLoaderDlrNavteq::loadPolyFiles(OptionsCont& oc, PCPolyContainer& toFill,
82 : PCTypeMap& tm) {
83 8 : std::vector<std::string> files = oc.getStringVector("dlr-navteq-poly-files");
84 8 : for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
85 8 : if (!FileHelpers::isReadable(*file)) {
86 0 : throw ProcessError(TLF("Could not open dlr-navteq-poly-file '%'.", *file));
87 : }
88 12 : PROGRESS_BEGIN_MESSAGE("Parsing pois from dlr-navteq-poly-file '" + *file + "'");
89 4 : loadPolyFile(*file, oc, toFill, tm);
90 4 : PROGRESS_DONE_MESSAGE();
91 : }
92 4 : }
93 :
94 :
95 : void
96 2 : PCLoaderDlrNavteq::loadPOIFile(const std::string& file,
97 : OptionsCont& oc, PCPolyContainer& toFill,
98 : PCTypeMap& tm) {
99 : // get the defaults
100 2 : RGBColor c = RGBColor::parseColor(oc.getString("color"));
101 : // parse
102 2 : int l = 0;
103 2 : LineReader lr(file);
104 10 : while (lr.hasMore()) {
105 8 : std::string line = lr.readLine();
106 8 : ++l;
107 : // skip invalid/empty lines
108 16 : if (line.length() == 0 || line.find("#") != std::string::npos) {
109 4 : continue;
110 : }
111 4 : if (StringUtils::prune(line) == "") {
112 0 : continue;
113 : }
114 : // parse the poi
115 4 : std::istringstream stream(line);
116 : // attributes of the poi
117 : std::string name, skip, type, desc;
118 4 : std::getline(stream, name, '\t');
119 4 : std::getline(stream, skip, '\t');
120 4 : std::getline(stream, type, '\t');
121 4 : std::getline(stream, desc, '\t');
122 4 : if (stream.fail()) {
123 0 : throw ProcessError("Invalid dlr-navteq-poi in line " + toString(l) + ":\n" + line);
124 : }
125 : double x, y;
126 : stream >> x;
127 4 : if (stream.fail()) {
128 0 : throw ProcessError(TLF("Invalid x coordinate for POI '%'.", name));
129 : }
130 : stream >> y;
131 4 : if (stream.fail()) {
132 0 : throw ProcessError(TLF("Invalid y coordinate for POI '%'.", name));
133 : }
134 4 : Position pos(x, y);
135 : // check the poi
136 4 : if (name == "") {
137 0 : throw ProcessError(TL("The name of a POI is missing."));
138 : }
139 4 : if (!GeoConvHelper::getProcessing().x2cartesian(pos, true)) {
140 0 : throw ProcessError(TLF("Unable to project coordinates for POI '%'.", name));
141 : }
142 :
143 : // patch the values
144 4 : bool discard = oc.getBool("discard");
145 4 : std::string icon = oc.getString("icon");
146 4 : double layer = oc.getFloat("layer");
147 4 : RGBColor color;
148 4 : if (tm.has(type)) {
149 0 : const PCTypeMap::TypeDef& def = tm.get(type);
150 0 : name = def.prefix + name;
151 0 : type = def.id;
152 0 : color = def.color;
153 0 : discard = def.discard;
154 0 : icon = def.icon;
155 0 : layer = def.layer;
156 : } else {
157 8 : name = oc.getString("prefix") + name;
158 4 : type = oc.getString("type");
159 4 : color = c;
160 : }
161 4 : if (!discard) {
162 4 : PointOfInterest* poi = new PointOfInterest(name, type, color, pos, false, "", 0, false, 0, icon, layer);
163 8 : toFill.add(poi, OptionsCont::getOptions().isInStringVector("prune.keep-list", name));
164 : }
165 4 : }
166 2 : }
167 :
168 :
169 : void
170 4 : PCLoaderDlrNavteq::loadPolyFile(const std::string& file,
171 : OptionsCont& oc, PCPolyContainer& toFill,
172 : PCTypeMap& tm) {
173 : // get the defaults
174 4 : RGBColor c = RGBColor::parseColor(oc.getString("color"));
175 : // attributes of the poly
176 : // parse
177 4 : LineReader lr(file);
178 19 : while (lr.hasMore()) {
179 15 : std::string line = lr.readLine();
180 : // skip invalid/empty lines
181 30 : if (line.length() == 0 || line.find("#") != std::string::npos) {
182 8 : continue;
183 : }
184 7 : if (StringUtils::prune(line) == "") {
185 0 : continue;
186 : }
187 : // parse the poi
188 21 : StringTokenizer st(line, "\t");
189 7 : std::vector<std::string> values = st.getVector();
190 7 : if (values.size() < 6 || values.size() % 2 != 0) {
191 0 : throw ProcessError(TLF("Invalid dlr-navteq-polygon - line: '%'.", line));
192 : }
193 : std::string id = values[0];
194 : std::string ort = values[1];
195 : std::string type = values[2];
196 : std::string name = values[3];
197 7 : PositionVector vec;
198 : int index = 4;
199 : // now collect the positions
200 116 : while ((int)values.size() > index) {
201 109 : std::string xpos = values[index];
202 109 : std::string ypos = values[index + 1];
203 109 : index += 2;
204 109 : double x = StringUtils::toDouble(xpos);
205 109 : double y = StringUtils::toDouble(ypos);
206 : Position pos(x, y);
207 109 : if (!GeoConvHelper::getProcessing().x2cartesian(pos)) {
208 0 : WRITE_WARNINGF(TL("Unable to project coordinates for polygon '%'."), id);
209 : }
210 109 : vec.push_back(pos);
211 : }
212 :
213 7 : name = StringUtils::convertUmlaute(name);
214 7 : if (name == "noname" || toFill.getPolygons().get(name) != 0) {
215 14 : name = name + "#" + toString(toFill.getEnumIDFor(name));
216 : }
217 :
218 : // check the polygon
219 7 : if (vec.size() == 0) {
220 0 : WRITE_WARNINGF(TL("The polygon '%' is empty."), id);
221 0 : continue;
222 : }
223 7 : if (id == "") {
224 0 : WRITE_WARNING(TL("The name of a polygon is missing; it will be discarded."));
225 0 : continue;
226 : }
227 :
228 : // patch the values
229 : bool fill = vec.front() == vec.back();
230 7 : bool discard = oc.getBool("discard");
231 7 : std::string icon = oc.getString("icon");
232 7 : double layer = oc.getFloat("layer");
233 7 : RGBColor color;
234 7 : if (tm.has(type)) {
235 0 : const PCTypeMap::TypeDef& def = tm.get(type);
236 0 : name = def.prefix + name;
237 0 : type = def.id;
238 0 : color = def.color;
239 0 : fill = fill && def.allowFill != PCTypeMap::Filltype::NOFILL;
240 0 : discard = def.discard;
241 0 : icon = def.icon;
242 0 : layer = def.layer;
243 : } else {
244 14 : name = oc.getString("prefix") + name;
245 7 : type = oc.getString("type");
246 7 : color = c;
247 : }
248 7 : if (!discard) {
249 7 : SUMOPolygon* poly = new SUMOPolygon(name, type, color, vec, false, fill, 1, layer);
250 7 : toFill.add(poly);
251 : }
252 : vec.clear();
253 14 : }
254 4 : }
255 :
256 :
257 : /****************************************************************************/
|