SUMO - Simulation of Urban MObility
ShapeHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // The XML-Handler for network loading
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #ifdef _MSC_VER
24 #include <windows_config.h>
25 #else
26 #include <config.h>
27 #endif
28 
29 #include <string>
32 #include <utils/xml/XMLSubSys.h>
36 #include <utils/common/RGBColor.h>
42 #include "Shape.h"
43 #include "ShapeContainer.h"
44 #include "ShapeHandler.h"
45 
46 
47 // ===========================================================================
48 // method definitions
49 // ===========================================================================
50 ShapeHandler::ShapeHandler(const std::string& file, ShapeContainer& sc) :
51  SUMOSAXHandler(file), myShapeContainer(sc),
52  myPrefix(""), myDefaultColor(RGBColor::RED), myDefaultLayer(), myDefaultFill(false),
53  myLastParameterised(0) {
54 }
55 
56 
58 
59 
60 void
61 ShapeHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
62  try {
63  switch (element) {
64  case SUMO_TAG_POLY:
66  addPoly(attrs, false, false);
67  break;
68  case SUMO_TAG_POI:
69  myDefaultLayer = (double)GLO_POI;
70  addPOI(attrs, false, false);
71  break;
72  case SUMO_TAG_PARAM:
73  if (myLastParameterised != 0) {
74  bool ok = true;
75  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, 0, ok);
76  // circumventing empty string test
77  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
79  }
80  default:
81  break;
82  }
83  } catch (InvalidArgument& e) {
84  WRITE_ERROR(e.what());
85  }
86 }
87 
88 
89 void
91  if (element != SUMO_TAG_PARAM) {
93  }
94 }
95 
96 void
97 ShapeHandler::addPOI(const SUMOSAXAttributes& attrs, const bool ignorePruning, const bool useProcessing) {
98  bool ok = true;
99  const double INVALID_POSITION(-1000000);
100  const std::string id = myPrefix + attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
101  double x = attrs.getOpt<double>(SUMO_ATTR_X, id.c_str(), ok, INVALID_POSITION);
102  const double y = attrs.getOpt<double>(SUMO_ATTR_Y, id.c_str(), ok, INVALID_POSITION);
103  double lon = attrs.getOpt<double>(SUMO_ATTR_LON, id.c_str(), ok, INVALID_POSITION);
104  double lat = attrs.getOpt<double>(SUMO_ATTR_LAT, id.c_str(), ok, INVALID_POSITION);
105  const double lanePos = attrs.getOpt<double>(SUMO_ATTR_POSITION, id.c_str(), ok, 0);
106  const double lanePosLat = attrs.getOpt<double>(SUMO_ATTR_POSITION_LAT, id.c_str(), ok, 0);
107  const double layer = attrs.getOpt<double>(SUMO_ATTR_LAYER, id.c_str(), ok, myDefaultLayer);
108  const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
109  const std::string laneID = attrs.getOpt<std::string>(SUMO_ATTR_LANE, id.c_str(), ok, "");
110  const RGBColor color = attrs.hasAttribute(SUMO_ATTR_COLOR) ? attrs.get<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok) : myDefaultColor;
111  const double angle = attrs.getOpt<double>(SUMO_ATTR_ANGLE, id.c_str(), ok, Shape::DEFAULT_ANGLE);
112  std::string imgFile = attrs.getOpt<std::string>(SUMO_ATTR_IMGFILE, id.c_str(), ok, Shape::DEFAULT_IMG_FILE);
113  if (imgFile != "" && !FileHelpers::isAbsolute(imgFile)) {
115  }
116  const double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, Shape::DEFAULT_IMG_WIDTH);
117  const double height = attrs.getOpt<double>(SUMO_ATTR_HEIGHT, id.c_str(), ok, Shape::DEFAULT_IMG_HEIGHT);
118  if (!ok) {
119  return;
120  }
121  const GeoConvHelper& gch = useProcessing ? GeoConvHelper::getProcessing() : GeoConvHelper::getFinal();
122  if (useProcessing && gch.usingGeoProjection()) {
123  if (lat == INVALID_POSITION || lon == INVALID_POSITION) {
124  lon = x;
125  lat = y;
126  x = INVALID_POSITION;
127  }
128  }
129  Position pos(x, y);
130  if (x == INVALID_POSITION || y == INVALID_POSITION) {
131  // try computing x,y from lane,pos
132  if (laneID != "") {
133  pos = getLanePos(id, laneID, lanePos, lanePosLat);
134  } else {
135  // try computing x,y from lon,lat
136  if (lat == INVALID_POSITION || lon == INVALID_POSITION) {
137  WRITE_ERROR("Either (x, y), (lon, lat) or (lane, pos) must be specified for PoI '" + id + "'.");
138  return;
139  } else if (!gch.usingGeoProjection()) {
140  WRITE_ERROR("(lon, lat) is specified for PoI '" + id + "' but no geo-conversion is specified for the network.");
141  return;
142  }
143  pos.set(lon, lat);
144  bool success = true;
145  if (useProcessing) {
146  success = GeoConvHelper::getProcessing().x2cartesian(pos);
147  } else {
149  }
150  if (!success) {
151  WRITE_ERROR("Unable to project coordinates for PoI '" + id + "'.");
152  return;
153  }
154  }
155  }
156  if (!myShapeContainer.addPOI(id, type, color, layer, angle, imgFile, pos, width, height, ignorePruning)) {
157  WRITE_ERROR("PoI '" + id + "' already exists.");
158  }
160  if (laneID != "" && addLanePosParams()) {
161  myLastParameterised->addParameter(toString(SUMO_ATTR_LANE), laneID);
162  myLastParameterised->addParameter(toString(SUMO_ATTR_POSITION), toString(lanePos));
163  myLastParameterised->addParameter(toString(SUMO_ATTR_POSITION_LAT), toString(lanePosLat));
164  }
165 }
166 
167 
168 void
169 ShapeHandler::addPoly(const SUMOSAXAttributes& attrs, const bool ignorePruning, const bool useProcessing) {
170  bool ok = true;
171  const std::string id = myPrefix + attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
172  // get the id, report an error if not given or empty...
173  if (!ok) {
174  return;
175  }
176  const double layer = attrs.getOpt<double>(SUMO_ATTR_LAYER, id.c_str(), ok, myDefaultLayer);
177  const bool fill = attrs.getOpt<bool>(SUMO_ATTR_FILL, id.c_str(), ok, myDefaultFill);
178  const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, Shape::DEFAULT_TYPE);
179  const RGBColor color = attrs.hasAttribute(SUMO_ATTR_COLOR) ? attrs.get<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok) : myDefaultColor;
180  PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
181  if (attrs.getOpt<bool>(SUMO_ATTR_GEO, id.c_str(), ok, false)) {
182  bool success = true;
183  for (int i = 0; i < (int)shape.size(); i++) {
184  if (useProcessing) {
185  success &= GeoConvHelper::getProcessing().x2cartesian(shape[i]);
186  } else {
187  success &= GeoConvHelper::getFinal().x2cartesian_const(shape[i]);
188  }
189  }
190  if (!success) {
191  WRITE_WARNING("Unable to project coordinates for polygon '" + id + "'.");
192  return;
193  }
194  }
195  const double angle = attrs.getOpt<double>(SUMO_ATTR_ANGLE, id.c_str(), ok, Shape::DEFAULT_ANGLE);
196  std::string imgFile = attrs.getOpt<std::string>(SUMO_ATTR_IMGFILE, id.c_str(), ok, Shape::DEFAULT_IMG_FILE);
197  if (imgFile != "" && !FileHelpers::isAbsolute(imgFile)) {
199  }
200  // check that shape's size is valid
201  if(shape.size() == 0) {
202  WRITE_ERROR("Polygon's shape cannot be empty.");
203  return;
204  }
205  if (!myShapeContainer.addPolygon(id, type, color, layer, angle, imgFile, shape, fill, ignorePruning)) {
206  WRITE_ERROR("Polygon '" + id + "' already exists.");
207  }
209 }
210 
211 
212 
213 bool
214 ShapeHandler::loadFiles(const std::vector<std::string>& files, ShapeHandler& sh) {
215  for (auto fileIt : files) {
216  if (!XMLSubSys::runParser(sh, fileIt, false)) {
217  WRITE_MESSAGE("Loading of shapes from " + fileIt + " failed.");
218  return false;
219  }
220  }
221  return true;
222 }
223 
224 
225 void
226 ShapeHandler::setDefaults(const std::string& prefix, const RGBColor& color, const double layer, const bool fill) {
227  myPrefix = prefix;
228  myDefaultColor = color;
229  myDefaultLayer = layer;
230  myDefaultFill = fill;
231 }
232 
233 
234 
235 /****************************************************************************/
double myDefaultLayer
The default layer to use.
Definition: ShapeHandler.h:127
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
Definition: FileHelpers.cpp:82
ShapeHandler(const std::string &file, ShapeContainer &sc)
Constructor.
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation. ...
static const std::string DEFAULT_IMG_FILE
Definition: Shape.h:152
void setDefaults(const std::string &prefix, const RGBColor &color, const double layer, const bool fill=false)
set default values
virtual void myEndElement(int element)
Called when a closing tag occurs.
virtual Position getLanePos(const std::string &poiID, const std::string &laneID, double lanePos, double lanePosLat)=0
get position for a given laneID
A layer number.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:98
static bool loadFiles(const std::vector< std::string > &files, ShapeHandler &sh)
loads all of the given files
bool x2cartesian(Position &from, bool includeInBoundary=true)
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static const double DEFAULT_IMG_HEIGHT
Definition: Shape.h:154
Storage for geometrical objects.
begin/end of the description of a polygon
RGBColor myDefaultColor
The default color to use.
Definition: ShapeHandler.h:124
Parameterised * myLastParameterised
element to receive parameters
Definition: ShapeHandler.h:136
void set(double x, double y)
set positions x and y
Definition: Position.h:93
SAX-handler base for SUMO-files.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything&#39;s ok.
Definition: XMLSubSys.cpp:110
static const std::string DEFAULT_TYPE
Definition: Shape.h:149
std::string myPrefix
The prefix to use.
Definition: ShapeHandler.h:121
const Polygons & getPolygons() const
Returns all polygons.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The XML-Handler for network loading.
Definition: ShapeHandler.h:56
T get(const std::string &id) const
Retrieves an item.
const std::string & getFileName() const
returns the current file name
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
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
Encapsulated SAX-Attributes.
virtual bool addLanePosParams()
Whether some input attributes shall be automatically added as params.
Definition: ShapeHandler.h:102
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
Definition: FileHelpers.cpp:97
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
parameter associated to a certain key
A list of positions.
virtual bool addPolygon(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, const PositionVector &shape, bool fill, bool ignorePruning=false)
Builds a polygon using the given values and adds it to the container.
void addPOI(const SUMOSAXAttributes &attrs, const bool ignorePruning, const bool useProcessing)
adds a POI
bool myDefaultFill
Information whether polygons should be filled.
Definition: ShapeHandler.h:130
edge: the shape in xml-definition
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
const POIs & getPOIs() const
Returns all pois.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
void addPoly(const SUMOSAXAttributes &attrs, const bool ignorePruning, const bool useProcessing)
adds a polygon
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
void addParameter(const std::string &key, const std::string &value)
Adds a parameter.
virtual ~ShapeHandler()
Destructor.
ShapeContainer & myShapeContainer
Definition: ShapeHandler.h:117
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
#define INVALID_POSITION
static const double DEFAULT_IMG_WIDTH
Definition: Shape.h:153
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool addPOI(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, const Position &pos, double width, double height, bool ignorePruning=false)
Builds a POI using the given values and adds it to the container.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
A color information.
Fill the polygon.
static const double DEFAULT_ANGLE
Definition: Shape.h:151
begin/end of the description of a polygon
static const double DEFAULT_LAYER
Definition: Shape.h:150