SUMO - Simulation of Urban MObility
PCLoaderArcView.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // A reader of pois and polygons from shape files
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <string>
28 #include <utils/common/ToString.h>
31 #include <utils/geom/GeomHelper.h>
32 #include "PCLoaderArcView.h"
34 #include <utils/common/RGBColor.h>
36 
37 #ifdef HAVE_GDAL
38 #if __GNUC__ > 3
39 #pragma GCC diagnostic push
40 #pragma GCC diagnostic ignored "-Wpedantic"
41 #endif
42 #include <ogrsf_frmts.h>
43 #if __GNUC__ > 3
44 #pragma GCC diagnostic pop
45 #endif
46 #endif
47 
48 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
52 void
54  PCTypeMap& tm) {
55  if (!oc.isSet("shapefile-prefixes")) {
56  return;
57  }
58  // parse file(s)
59  std::vector<std::string> files = oc.getStringVector("shapefile-prefixes");
60  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
61  PROGRESS_BEGIN_MESSAGE("Parsing from shape-file '" + *file + "'");
62  load(*file, oc, toFill, tm);
64  }
65 }
66 
67 
68 
69 void
70 PCLoaderArcView::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill,
71  PCTypeMap&) {
72 #ifdef HAVE_GDAL
74  // get defaults
75  std::string prefix = oc.getString("prefix");
76  std::string type = oc.getString("type");
77  RGBColor color = RGBColor::parseColor(oc.getString("color"));
78  double layer = oc.getFloat("layer");
79  std::string idField = oc.getString("shapefile.id-column");
80  bool useRunningID = oc.getBool("shapefile.use-running-id") || idField == "";
81  // start parsing
82  std::string shpName = file + ".shp";
83  int fillType = -1;
84  if (oc.getString("shapefile.fill") == "true") {
85  fillType = 1;
86  } else if (oc.getString("shapefile.fill") == "false") {
87  fillType = 0;
88  }
89 #if GDAL_VERSION_MAJOR < 2
90  OGRRegisterAll();
91  OGRDataSource* poDS = OGRSFDriverRegistrar::Open(shpName.c_str(), FALSE);
92 #else
93  GDALAllRegister();
94  GDALDataset* poDS = (GDALDataset*) GDALOpenEx(shpName.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL);
95 #endif
96  if (poDS == NULL) {
97  throw ProcessError("Could not open shape description '" + shpName + "'.");
98  }
99 
100  // begin file parsing
101  OGRLayer* poLayer = poDS->GetLayer(0);
102  poLayer->ResetReading();
103 
104  // build coordinate transformation
105  OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
106  OGRSpatialReference destTransf;
107  // use wgs84 as destination
108  destTransf.SetWellKnownGeogCS("WGS84");
109  OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf);
110  if (poCT == NULL) {
111  if (oc.isSet("shapefile.guess-projection")) {
112  OGRSpatialReference origTransf2;
113  origTransf2.SetWellKnownGeogCS("WGS84");
114  poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
115  }
116  if (poCT == 0) {
117  WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed.");
118  }
119  }
120 
121  OGRFeature* poFeature;
122  poLayer->ResetReading();
123  int runningID = 0;
124  while ((poFeature = poLayer->GetNextFeature()) != NULL) {
125  std::vector<Parameterised*> parCont;
126  // read in edge attributes
127  std::string id = useRunningID ? toString(runningID) : poFeature->GetFieldAsString(idField.c_str());
128  ++runningID;
130  if (id == "") {
131  throw ProcessError("Missing id under '" + idField + "'");
132  }
133  id = prefix + id;
134  // read in the geometry
135  OGRGeometry* poGeometry = poFeature->GetGeometryRef();
136  if (poGeometry == 0) {
137  OGRFeature::DestroyFeature(poFeature);
138  continue;
139  }
140  // try transform to wgs84
141  poGeometry->transform(poCT);
142  OGRwkbGeometryType gtype = poGeometry->getGeometryType();
143  switch (gtype) {
144  case wkbPoint: {
145  OGRPoint* cgeom = (OGRPoint*) poGeometry;
146  Position pos((double) cgeom->getX(), (double) cgeom->getY());
147  if (!geoConvHelper.x2cartesian(pos)) {
148  WRITE_ERROR("Unable to project coordinates for POI '" + id + "'.");
149  }
150  PointOfInterest* poi = new PointOfInterest(id, type, color, pos, false, "", 0, 0, layer);
151  if (toFill.add(poi)) {
152  parCont.push_back(poi);
153  }
154  }
155  break;
156  case wkbLineString: {
157  bool fill = fillType < 0 ? false : (fillType == 1);
158  OGRLineString* cgeom = (OGRLineString*) poGeometry;
159  PositionVector shape;
160  for (int j = 0; j < cgeom->getNumPoints(); j++) {
161  Position pos((double) cgeom->getX(j), (double) cgeom->getY(j));
162  if (!geoConvHelper.x2cartesian(pos)) {
163  WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
164  }
165  shape.push_back_noDoublePos(pos);
166  }
167  SUMOPolygon* poly = new SUMOPolygon(id, type, color, shape, false, fill, 1, layer);
168  if (toFill.add(poly)) {
169  parCont.push_back(poly);
170  }
171  }
172  break;
173  case wkbPolygon: {
174  bool fill = fillType < 0 ? true : (fillType == 1);
175  OGRLinearRing* cgeom = ((OGRPolygon*) poGeometry)->getExteriorRing();
176  PositionVector shape;
177  for (int j = 0; j < cgeom->getNumPoints(); j++) {
178  Position pos((double) cgeom->getX(j), (double) cgeom->getY(j));
179  if (!geoConvHelper.x2cartesian(pos)) {
180  WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
181  }
182  shape.push_back_noDoublePos(pos);
183  }
184  SUMOPolygon* poly = new SUMOPolygon(id, type, color, shape, false, fill, 1, layer);
185  if (toFill.add(poly)) {
186  parCont.push_back(poly);
187  }
188  }
189  break;
190  case wkbMultiPoint: {
191  OGRMultiPoint* cgeom = (OGRMultiPoint*) poGeometry;
192  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
193  OGRPoint* cgeom2 = (OGRPoint*) cgeom->getGeometryRef(i);
194  Position pos((double) cgeom2->getX(), (double) cgeom2->getY());
195  std::string tid = id + "#" + toString(i);
196  if (!geoConvHelper.x2cartesian(pos)) {
197  WRITE_ERROR("Unable to project coordinates for POI '" + tid + "'.");
198  }
199  PointOfInterest* poi = new PointOfInterest(tid, type, color, pos, "", 0, 0, layer);
200  if (toFill.add(poi)) {
201  parCont.push_back(poi);
202  }
203  }
204  }
205  break;
206  case wkbMultiLineString: {
207  bool fill = fillType < 0 ? false : (fillType == 1);
208  OGRMultiLineString* cgeom = (OGRMultiLineString*) poGeometry;
209  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
210  OGRLineString* cgeom2 = (OGRLineString*) cgeom->getGeometryRef(i);
211  PositionVector shape;
212  std::string tid = id + "#" + toString(i);
213  for (int j = 0; j < cgeom2->getNumPoints(); j++) {
214  Position pos((double) cgeom2->getX(j), (double) cgeom2->getY(j));
215  if (!geoConvHelper.x2cartesian(pos)) {
216  WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
217  }
218  shape.push_back_noDoublePos(pos);
219  }
220  SUMOPolygon* poly = new SUMOPolygon(tid, type, color, shape, false, fill, 1, layer);
221  if (toFill.add(poly)) {
222  parCont.push_back(poly);
223  }
224  }
225  }
226  break;
227  case wkbMultiPolygon: {
228  bool fill = fillType < 0 ? true : (fillType == 1);
229  OGRMultiPolygon* cgeom = (OGRMultiPolygon*) poGeometry;
230  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
231  OGRLinearRing* cgeom2 = ((OGRPolygon*) cgeom->getGeometryRef(i))->getExteriorRing();
232  PositionVector shape;
233  std::string tid = id + "#" + toString(i);
234  for (int j = 0; j < cgeom2->getNumPoints(); j++) {
235  Position pos((double) cgeom2->getX(j), (double) cgeom2->getY(j));
236  if (!geoConvHelper.x2cartesian(pos)) {
237  WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
238  }
239  shape.push_back_noDoublePos(pos);
240  }
241  SUMOPolygon* poly = new SUMOPolygon(tid, type, color, shape, false, fill, 1, layer);
242  if (toFill.add(poly)) {
243  parCont.push_back(poly);
244  }
245  }
246  }
247  break;
248  default:
249  WRITE_WARNING("Unsupported shape type occurred (id='" + id + "').");
250  break;
251  }
252  if (oc.getBool("shapefile.add-param")) {
253  for (std::vector<Parameterised*>::const_iterator it = parCont.begin(); it != parCont.end(); ++it) {
254  OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
255  for (int iField = 0; iField < poFDefn->GetFieldCount(); iField++) {
256  OGRFieldDefn* poFieldDefn = poFDefn->GetFieldDefn(iField);
257  if (poFieldDefn->GetNameRef() != idField) {
258  if (poFieldDefn->GetType() == OFTReal) {
259  (*it)->setParameter(poFieldDefn->GetNameRef(), toString(poFeature->GetFieldAsDouble(iField)));
260  } else {
261  (*it)->setParameter(poFieldDefn->GetNameRef(), StringUtils::latin1_to_utf8(poFeature->GetFieldAsString(iField)));
262  }
263  }
264  }
265  }
266  }
267  OGRFeature::DestroyFeature(poFeature);
268  }
269 #if GDAL_VERSION_MAJOR < 2
270  OGRDataSource::DestroyDataSource(poDS);
271 #else
272  GDALClose(poDS);
273 #endif
275 #else
276  UNUSED_PARAMETER(file);
277  UNUSED_PARAMETER(oc);
278  UNUSED_PARAMETER(toFill);
279  WRITE_ERROR("SUMO was compiled without GDAL support.");
280 #endif
281 }
282 
283 
284 /****************************************************************************/
285 
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:177
bool add(SUMOPolygon *poly, bool ignorePruning=false)
Adds a polygon to the storage.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:84
bool x2cartesian(Position &from, bool includeInBoundary=true)
Converts the given coordinate into a cartesian and optionally update myConvBoundary.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
A storage for loaded polygons and pois.
static std::string latin1_to_utf8(std::string str)
Transfers from Latin 1 (ISO-8859-1) to UTF-8.
Definition: StringUtils.cpp:69
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
A storage for type mappings.
Definition: PCTypeMap.h:45
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:53
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
A list of positions.
static void loadIfSet(OptionsCont &oc, PCPolyContainer &toFill, PCTypeMap &tm)
Loads pois/polygons assumed to be stored as shape files-files.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
static void load(const std::string &file, OptionsCont &oc, PCPolyContainer &toFill, PCTypeMap &tm)
Parses pois/polys stored within the given file.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:243
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:247
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:47
A storage for options typed value containers)
Definition: OptionsCont.h:92
void push_back_noDoublePos(const Position &p)
insert in back a non double position
A point-of-interest.
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:244