Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/polyconvert/PCPolyContainer.cpp
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2005-2025 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 PCPolyContainer.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @author Melanie Knocke
19
/// @date Mon, 05 Dec 2005
20
///
21
// A storage for loaded polygons and pois
22
/****************************************************************************/
23
#include <config.h>
24
25
#include <string>
26
#include <algorithm>
27
#include <map>
28
#include <utils/common/MsgHandler.h>
29
#include <utils/common/ToString.h>
30
#include <utils/common/UtilExceptions.h>
31
#include <utils/common/StringUtils.h>
32
#include <utils/geom/GeoConvHelper.h>
33
#include <utils/shapes/SUMOPolygon.h>
34
#include <utils/iodevices/OutputDevice.h>
35
#include <utils/xml/SUMOSAXAttributes.h>
36
#include <utils/options/OptionsCont.h>
37
#include "PCPolyContainer.h"
38
39
40
// ===========================================================================
41
// method definitions
42
// ===========================================================================
43
PCPolyContainer::PCPolyContainer(bool prune,
44
const Boundary& pruningBoundary,
45
const std::vector<std::string>& removeByNames)
46
: myPruningBoundary(pruningBoundary), myDoPrune(prune),
47
myRemoveByNames(removeByNames) {}
48
49
50
PCPolyContainer::~PCPolyContainer() {
51
myPolygons.clear();
52
myPOIs.clear();
53
}
54
55
56
bool
57
PCPolyContainer::add(SUMOPolygon* poly, bool ignorePruning) {
58
// check whether the polygon lies within the wished area
59
// - if such an area was given
60
if (myDoPrune && !ignorePruning) {
61
Boundary b = poly->getShape().getBoxBoundary();
62
if (!b.partialWithin(myPruningBoundary)) {
63
delete poly;
64
return false;
65
}
66
}
67
// check whether the polygon was named to be a removed one
68
if (find(myRemoveByNames.begin(), myRemoveByNames.end(), poly->getID()) != myRemoveByNames.end()) {
69
delete poly;
70
return false;
71
}
72
return ShapeContainer::add(poly);
73
}
74
75
76
bool
77
PCPolyContainer::add(PointOfInterest* poi, bool ignorePruning) {
78
// check whether the poi lies within the wished area
79
// - if such an area was given
80
if (myDoPrune && !ignorePruning) {
81
if (!myPruningBoundary.around(*poi)) {
82
delete poi;
83
return false;
84
}
85
}
86
// check whether the polygon was named to be a removed one
87
if (find(myRemoveByNames.begin(), myRemoveByNames.end(), poi->getID()) != myRemoveByNames.end()) {
88
delete poi;
89
return false;
90
}
91
return ShapeContainer::add(poi);
92
}
93
94
95
void
96
PCPolyContainer::addLanePos(const std::string& poiID, const std::string& laneID, const double lanePos, const bool friendlyPos, const double lanePosLat) {
97
myLanePosPois[poiID] = LanePos(laneID, lanePos, friendlyPos, lanePosLat);
98
}
99
100
101
void
102
PCPolyContainer::save(const std::string& file, bool useGeo) {
103
const GeoConvHelper& gch = GeoConvHelper::getFinal();
104
if (useGeo && !gch.usingGeoProjection()) {
105
WRITE_WARNING(TL("Ignoring option \"proj.plain-geo\" because no geo-conversion has been defined"));
106
useGeo = false;
107
}
108
OutputDevice& out = OutputDevice::getDevice(file);
109
out.writeXMLHeader("additional", "additional_file.xsd");
110
if (useGeo) {
111
out.setPrecision(gPrecisionGeo);
112
} else if (gch.usingGeoProjection()) {
113
GeoConvHelper::writeLocation(out);
114
}
115
// write polygons
116
for (auto i : myPolygons) {
117
i.second->writeXML(out, useGeo);
118
}
119
// write pois
120
const double zOffset = OptionsCont::getOptions().getFloat("poi-layer-offset");
121
for (const auto& POI : myPOIs) {
122
std::map<std::string, LanePos>::const_iterator it = myLanePosPois.find(POI.first);
123
if (it == myLanePosPois.end()) {
124
POI.second->writeXML(out, useGeo, zOffset);
125
} else {
126
POI.second->writeXML(out, useGeo, zOffset, it->second.laneID, it->second.pos, it->second.friendlyPos, it->second.posLat);
127
}
128
}
129
out.close();
130
}
131
132
133
void PCPolyContainer::writeDlrTDPHeader(OutputDevice& device, const OptionsCont& oc) {
134
// XXX duplicate of NWWriter_DlrNavteq::writeHeader()
135
device << "# Format matches Extraction version: V6.5 \n";
136
std::stringstream tmp;
137
oc.writeConfiguration(tmp, true, false, false);
138
tmp.seekg(std::ios_base::beg);
139
std::string line;
140
while (!tmp.eof()) {
141
std::getline(tmp, line);
142
device << "# " << line << "\n";
143
}
144
device << "#\n";
145
}
146
147
148
void
149
PCPolyContainer::saveDlrTDP(const std::string& prefix) {
150
const OptionsCont& oc = OptionsCont::getOptions();
151
const GeoConvHelper& gch = GeoConvHelper::getFinal();
152
const bool haveGeo = gch.usingGeoProjection();
153
const double geoScale = pow(10.0f, haveGeo ? 5 : 2); // see NIImporter_DlrNavteq::GEO_SCALE
154
// write pois
155
OutputDevice& out = OutputDevice::getDevice(prefix + "_points_of_interest.txt");
156
out.setPrecision(0);
157
writeDlrTDPHeader(out, oc);
158
// write format specifier
159
out << "# ID\tCITY\tTYPE\tNAME\tgeo_x\tgeo_y\n";
160
int id = 0;
161
for (const auto& i : myPOIs) {
162
Position pos(*i.second);
163
gch.cartesian2geo(pos);
164
pos.mul(geoScale);
165
out << id << "\t";
166
out << "" << "\t";
167
out << i.second->getShapeType() << "\t";
168
out << i.first << "\t";
169
out << pos.x() << "\t";
170
out << pos.y() << "\t";
171
id++;
172
}
173
out.close();
174
// write polygons
175
OutputDevice& out2 = OutputDevice::getDevice(prefix + "_polygons.txt");
176
out2.setPrecision(0);
177
writeDlrTDPHeader(out2, oc);
178
// write format specifier
179
out2 << "# ID\tCITY\tTYPE\tNAME\tgeo_x1\tgeo_y1\t[geo_x2 geo_y2 ...]\n";
180
id = 0;
181
for (const auto& i : myPolygons) {
182
out2 << id << "\t";
183
out2 << "" << "\t";
184
out2 << i.second->getShapeType() << "\t";
185
out2 << i.first << "\t";
186
187
for (Position pos : i.second->getShape()) {
188
gch.cartesian2geo(pos);
189
pos.mul(geoScale);
190
out2 << pos.x() << "\t";
191
out2 << pos.y() << "\t";
192
}
193
id++;
194
}
195
out2.close();
196
}
197
198
199
int
200
PCPolyContainer::getEnumIDFor(const std::string& key) {
201
return myIDEnums[key]++;
202
}
203
204
205
PCPolyContainer::LanePos::LanePos() :
206
pos(0),
207
friendlyPos(false),
208
posLat(0) {
209
}
210
211
212
PCPolyContainer::LanePos::LanePos(const std::string& _laneID, double _pos, bool _friendlyPos, double _posLat) :
213
laneID(_laneID),
214
pos(_pos),
215
friendlyPos(_friendlyPos),
216
posLat(_posLat) {
217
}
218
219
/****************************************************************************/
220
221