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