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