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-2017 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 #if __GNUC__ > 3
46 #pragma GCC diagnostic push
47 #pragma GCC diagnostic ignored "-Wpedantic"
48 #endif
49 #include <ogrsf_frmts.h>
50 #if __GNUC__ > 3
51 #pragma GCC diagnostic pop
52 #endif
53 #endif
54 
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
59 void
61  PCTypeMap& tm) {
62  if (!oc.isSet("shapefile-prefixes")) {
63  return;
64  }
65  // parse file(s)
66  std::vector<std::string> files = oc.getStringVector("shapefile-prefixes");
67  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
68  PROGRESS_BEGIN_MESSAGE("Parsing from shape-file '" + *file + "'");
69  load(*file, oc, toFill, tm);
71  }
72 }
73 
74 
75 
76 void
77 PCLoaderArcView::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill,
78  PCTypeMap&) {
79 #ifdef HAVE_GDAL
81  // get defaults
82  std::string prefix = oc.getString("prefix");
83  std::string type = oc.getString("type");
84  RGBColor color = RGBColor::parseColor(oc.getString("color"));
85  double layer = oc.getFloat("layer");
86  std::string idField = oc.getString("shapefile.id-column");
87  bool useRunningID = oc.getBool("shapefile.use-running-id");
88  // start parsing
89  std::string shpName = file + ".shp";
90  int fillType = -1;
91  if (oc.getString("shapefile.fill") == "true") {
92  fillType = 1;
93  } else if (oc.getString("shapefile.fill") == "false") {
94  fillType = 0;
95  }
96 #if GDAL_VERSION_MAJOR < 2
97  OGRRegisterAll();
98  OGRDataSource* poDS = OGRSFDriverRegistrar::Open(shpName.c_str(), FALSE);
99 #else
100  GDALAllRegister();
101  GDALDataset* poDS = (GDALDataset*) GDALOpenEx(shpName.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL);
102 #endif
103  if (poDS == NULL) {
104  throw ProcessError("Could not open shape description '" + shpName + "'.");
105  }
106 
107  // begin file parsing
108  OGRLayer* poLayer = poDS->GetLayer(0);
109  poLayer->ResetReading();
110 
111  // build coordinate transformation
112  OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
113  OGRSpatialReference destTransf;
114  // use wgs84 as destination
115  destTransf.SetWellKnownGeogCS("WGS84");
116  OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf);
117  if (poCT == NULL) {
118  if (oc.isSet("shapefile.guess-projection")) {
119  OGRSpatialReference origTransf2;
120  origTransf2.SetWellKnownGeogCS("WGS84");
121  poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
122  }
123  if (poCT == 0) {
124  WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed.");
125  }
126  }
127 
128  OGRFeature* poFeature;
129  poLayer->ResetReading();
130  int runningID = 0;
131  while ((poFeature = poLayer->GetNextFeature()) != NULL) {
132  std::vector<Parameterised*> parCont;
133  // read in edge attributes
134  std::string id = useRunningID ? toString(runningID) : poFeature->GetFieldAsString(idField.c_str());
135  ++runningID;
137  if (id == "") {
138  throw ProcessError("Missing id under '" + idField + "'");
139  }
140  id = prefix + id;
141  // read in the geometry
142  OGRGeometry* poGeometry = poFeature->GetGeometryRef();
143  if (poGeometry == 0) {
144  OGRFeature::DestroyFeature(poFeature);
145  continue;
146  }
147  // try transform to wgs84
148  poGeometry->transform(poCT);
149  OGRwkbGeometryType gtype = poGeometry->getGeometryType();
150  switch (gtype) {
151  case wkbPoint: {
152  OGRPoint* cgeom = (OGRPoint*) poGeometry;
153  Position pos((double) cgeom->getX(), (double) cgeom->getY());
154  if (!geoConvHelper.x2cartesian(pos)) {
155  WRITE_ERROR("Unable to project coordinates for POI '" + id + "'.");
156  }
157  PointOfInterest* poi = new PointOfInterest(id, type, color, pos, layer);
158  if (toFill.add(poi)) {
159  parCont.push_back(poi);
160  }
161  }
162  break;
163  case wkbLineString: {
164  bool fill = fillType < 0 ? false : (fillType == 1);
165  OGRLineString* cgeom = (OGRLineString*) poGeometry;
166  PositionVector shape;
167  for (int j = 0; j < cgeom->getNumPoints(); j++) {
168  Position pos((double) cgeom->getX(j), (double) cgeom->getY(j));
169  if (!geoConvHelper.x2cartesian(pos)) {
170  WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
171  }
172  shape.push_back_noDoublePos(pos);
173  }
174  SUMO::Polygon* poly = new SUMO::Polygon(id, type, color, shape, fill, layer);
175  if (toFill.add(poly)) {
176  parCont.push_back(poly);
177  }
178  }
179  break;
180  case wkbPolygon: {
181  bool fill = fillType < 0 ? true : (fillType == 1);
182  OGRLinearRing* cgeom = ((OGRPolygon*) poGeometry)->getExteriorRing();
183  PositionVector shape;
184  for (int j = 0; j < cgeom->getNumPoints(); j++) {
185  Position pos((double) cgeom->getX(j), (double) cgeom->getY(j));
186  if (!geoConvHelper.x2cartesian(pos)) {
187  WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
188  }
189  shape.push_back_noDoublePos(pos);
190  }
191  SUMO::Polygon* poly = new SUMO::Polygon(id, type, color, shape, fill, layer);
192  if (toFill.add(poly)) {
193  parCont.push_back(poly);
194  }
195  }
196  break;
197  case wkbMultiPoint: {
198  OGRMultiPoint* cgeom = (OGRMultiPoint*) poGeometry;
199  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
200  OGRPoint* cgeom2 = (OGRPoint*) cgeom->getGeometryRef(i);
201  Position pos((double) cgeom2->getX(), (double) cgeom2->getY());
202  std::string tid = id + "#" + toString(i);
203  if (!geoConvHelper.x2cartesian(pos)) {
204  WRITE_ERROR("Unable to project coordinates for POI '" + tid + "'.");
205  }
206  PointOfInterest* poi = new PointOfInterest(tid, type, color, pos, layer);
207  if (toFill.add(poi)) {
208  parCont.push_back(poi);
209  }
210  }
211  }
212  break;
213  case wkbMultiLineString: {
214  bool fill = fillType < 0 ? false : (fillType == 1);
215  OGRMultiLineString* cgeom = (OGRMultiLineString*) poGeometry;
216  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
217  OGRLineString* cgeom2 = (OGRLineString*) cgeom->getGeometryRef(i);
218  PositionVector shape;
219  std::string tid = id + "#" + toString(i);
220  for (int j = 0; j < cgeom2->getNumPoints(); j++) {
221  Position pos((double) cgeom2->getX(j), (double) cgeom2->getY(j));
222  if (!geoConvHelper.x2cartesian(pos)) {
223  WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
224  }
225  shape.push_back_noDoublePos(pos);
226  }
227  SUMO::Polygon* poly = new SUMO::Polygon(tid, type, color, shape, fill, layer);
228  if (toFill.add(poly)) {
229  parCont.push_back(poly);
230  }
231  }
232  }
233  break;
234  case wkbMultiPolygon: {
235  bool fill = fillType < 0 ? true : (fillType == 1);
236  OGRMultiPolygon* cgeom = (OGRMultiPolygon*) poGeometry;
237  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
238  OGRLinearRing* cgeom2 = ((OGRPolygon*) cgeom->getGeometryRef(i))->getExteriorRing();
239  PositionVector shape;
240  std::string tid = id + "#" + toString(i);
241  for (int j = 0; j < cgeom2->getNumPoints(); j++) {
242  Position pos((double) cgeom2->getX(j), (double) cgeom2->getY(j));
243  if (!geoConvHelper.x2cartesian(pos)) {
244  WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
245  }
246  shape.push_back_noDoublePos(pos);
247  }
248  SUMO::Polygon* poly = new SUMO::Polygon(tid, type, color, shape, fill, layer);
249  if (toFill.add(poly)) {
250  parCont.push_back(poly);
251  }
252  }
253  }
254  break;
255  default:
256  WRITE_WARNING("Unsupported shape type occured (id='" + id + "').");
257  break;
258  }
259  if (oc.getBool("shapefile.add-param")) {
260  for (std::vector<Parameterised*>::const_iterator it = parCont.begin(); it != parCont.end(); ++it) {
261  OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
262  for (int iField = 0; iField < poFDefn->GetFieldCount(); iField++) {
263  OGRFieldDefn* poFieldDefn = poFDefn->GetFieldDefn(iField);
264  if (poFieldDefn->GetNameRef() != idField) {
265  if (poFieldDefn->GetType() == OFTReal) {
266  (*it)->addParameter(poFieldDefn->GetNameRef(), toString(poFeature->GetFieldAsDouble(iField)));
267  } else {
268  (*it)->addParameter(poFieldDefn->GetNameRef(), StringUtils::latin1_to_utf8(poFeature->GetFieldAsString(iField)));
269  }
270  }
271  }
272  }
273  }
274  OGRFeature::DestroyFeature(poFeature);
275  }
276 #if GDAL_VERSION_MAJOR < 2
277  OGRDataSource::DestroyDataSource(poDS);
278 #else
279  GDALClose(poDS);
280 #endif
282 #else
283  WRITE_ERROR("SUMO was compiled without GDAL support.");
284 #endif
285 }
286 
287 
288 /****************************************************************************/
289 
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:168
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)
#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:74
A 2D- or 3D-polygon.
Definition: Polygon.h:57
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:52
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:60
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
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.
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:202
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool add(SUMO::Polygon *poly, bool ignorePruning=false)
Adds a polygon to the storage.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:52
A storage for options typed value containers)
Definition: OptionsCont.h:99
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:203