SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-2015 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 #if GDAL_VERSION_MAJOR < 2
88  OGRRegisterAll();
89  OGRDataSource* poDS = OGRSFDriverRegistrar::Open(shpName.c_str(), FALSE);
90 #else
91  GDALAllRegister();
92  GDALDataset* poDS = (GDALDataset*) GDALOpen(shpName.c_str(), GA_ReadOnly);
93 #endif
94  if (poDS == NULL) {
95  throw ProcessError("Could not open shape description '" + shpName + "'.");
96  }
97 
98  // begin file parsing
99  OGRLayer* poLayer = poDS->GetLayer(0);
100  poLayer->ResetReading();
101 
102  // build coordinate transformation
103  OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
104  OGRSpatialReference destTransf;
105  // use wgs84 as destination
106  destTransf.SetWellKnownGeogCS("WGS84");
107  OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf);
108  if (poCT == NULL) {
109  if (oc.isSet("shapefile.guess-projection")) {
110  OGRSpatialReference origTransf2;
111  origTransf2.SetWellKnownGeogCS("WGS84");
112  poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
113  }
114  if (poCT == 0) {
115  WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed.");
116  }
117  }
118 
119  OGRFeature* poFeature;
120  poLayer->ResetReading();
121  unsigned int runningID = 0;
122  while ((poFeature = poLayer->GetNextFeature()) != NULL) {
123  std::vector<Parameterised*> parCont;
124  // read in edge attributes
125  std::string id = useRunningID ? toString(runningID) : poFeature->GetFieldAsString(idField.c_str());
126  ++runningID;
128  if (id == "") {
129  throw ProcessError("Missing id under '" + idField + "'");
130  }
131  id = prefix + id;
132  // read in the geometry
133  OGRGeometry* poGeometry = poFeature->GetGeometryRef();
134  if (poGeometry == 0) {
135  OGRFeature::DestroyFeature(poFeature);
136  continue;
137  }
138  // try transform to wgs84
139  poGeometry->transform(poCT);
140  OGRwkbGeometryType gtype = poGeometry->getGeometryType();
141  switch (gtype) {
142  case wkbPoint: {
143  OGRPoint* cgeom = (OGRPoint*) poGeometry;
144  Position pos((SUMOReal) cgeom->getX(), (SUMOReal) cgeom->getY());
145  if (!geoConvHelper.x2cartesian(pos)) {
146  WRITE_ERROR("Unable to project coordinates for POI '" + id + "'.");
147  }
148  PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer);
149  if (toFill.insert(id, poi, layer)) {
150  parCont.push_back(poi);
151  }
152  }
153  break;
154  case wkbLineString: {
155  OGRLineString* cgeom = (OGRLineString*) poGeometry;
156  PositionVector shape;
157  for (int j = 0; j < cgeom->getNumPoints(); j++) {
158  Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j));
159  if (!geoConvHelper.x2cartesian(pos)) {
160  WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
161  }
162  shape.push_back_noDoublePos(pos);
163  }
164  Polygon* poly = new Polygon(id, type, color, shape, false, (SUMOReal)layer);
165  if (toFill.insert(id, poly, layer)) {
166  parCont.push_back(poly);
167  }
168  }
169  break;
170  case wkbPolygon: {
171  OGRLinearRing* cgeom = ((OGRPolygon*) poGeometry)->getExteriorRing();
172  PositionVector shape;
173  for (int j = 0; j < cgeom->getNumPoints(); j++) {
174  Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j));
175  if (!geoConvHelper.x2cartesian(pos)) {
176  WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
177  }
178  shape.push_back_noDoublePos(pos);
179  }
180  Polygon* poly = new Polygon(id, type, color, shape, true, (SUMOReal)layer);
181  if (toFill.insert(id, poly, layer)) {
182  parCont.push_back(poly);
183  }
184  }
185  break;
186  case wkbMultiPoint: {
187  OGRMultiPoint* cgeom = (OGRMultiPoint*) poGeometry;
188  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
189  OGRPoint* cgeom2 = (OGRPoint*) cgeom->getGeometryRef(i);
190  Position pos((SUMOReal) cgeom2->getX(), (SUMOReal) cgeom2->getY());
191  std::string tid = id + "#" + toString(i);
192  if (!geoConvHelper.x2cartesian(pos)) {
193  WRITE_ERROR("Unable to project coordinates for POI '" + tid + "'.");
194  }
195  PointOfInterest* poi = new PointOfInterest(tid, type, color, pos, (SUMOReal)layer);
196  if (toFill.insert(tid, poi, layer)) {
197  parCont.push_back(poi);
198  }
199  }
200  }
201  break;
202  case wkbMultiLineString: {
203  OGRMultiLineString* cgeom = (OGRMultiLineString*) poGeometry;
204  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
205  OGRLineString* cgeom2 = (OGRLineString*) cgeom->getGeometryRef(i);
206  PositionVector shape;
207  std::string tid = id + "#" + toString(i);
208  for (int j = 0; j < cgeom2->getNumPoints(); j++) {
209  Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j));
210  if (!geoConvHelper.x2cartesian(pos)) {
211  WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
212  }
213  shape.push_back_noDoublePos(pos);
214  }
215  Polygon* poly = new Polygon(tid, type, color, shape, false, (SUMOReal)layer);
216  if (toFill.insert(tid, poly, layer)) {
217  parCont.push_back(poly);
218  }
219  }
220  }
221  break;
222  case wkbMultiPolygon: {
223  OGRMultiPolygon* cgeom = (OGRMultiPolygon*) poGeometry;
224  for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
225  OGRLinearRing* cgeom2 = ((OGRPolygon*) cgeom->getGeometryRef(i))->getExteriorRing();
226  PositionVector shape;
227  std::string tid = id + "#" + toString(i);
228  for (int j = 0; j < cgeom2->getNumPoints(); j++) {
229  Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j));
230  if (!geoConvHelper.x2cartesian(pos)) {
231  WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
232  }
233  shape.push_back_noDoublePos(pos);
234  }
235  Polygon* poly = new Polygon(tid, type, color, shape, true, (SUMOReal)layer);
236  if (toFill.insert(tid, poly, layer)) {
237  parCont.push_back(poly);
238  }
239  }
240  }
241  break;
242  default:
243  WRITE_WARNING("Unsupported shape type occured (id='" + id + "').");
244  break;
245  }
246  if (oc.getBool("shapefile.add-param")) {
247  for (std::vector<Parameterised*>::const_iterator it = parCont.begin(); it != parCont.end(); ++it) {
248  OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
249  for (int iField = 0; iField < poFDefn->GetFieldCount(); iField++) {
250  OGRFieldDefn* poFieldDefn = poFDefn->GetFieldDefn(iField);
251  if (poFieldDefn->GetNameRef() != idField) {
252  if (poFieldDefn->GetType() == OFTReal) {
253  (*it)->addParameter(poFieldDefn->GetNameRef(), toString(poFeature->GetFieldAsDouble(iField)));
254  } else {
255  (*it)->addParameter(poFieldDefn->GetNameRef(), StringUtils::latin1_to_utf8(poFeature->GetFieldAsString(iField)));
256  }
257  }
258  }
259  }
260  }
261  OGRFeature::DestroyFeature(poFeature);
262  }
264 #else
265  WRITE_ERROR("SUMO was compiled without GDAL support.");
266 #endif
267 }
268 
269 
270 /****************************************************************************/
271 
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:53
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
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:215
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.