1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2005-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    PointOfInterest.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Michael Behrisch
14 /// @author  Melanie Knocke
15 /// @date    2005-09-15
16 /// @version $Id$
17 ///
18 // A point-of-interest (2D)
19 /****************************************************************************/
20 #ifndef PointOfInterest_h
21 #define PointOfInterest_h
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28 
29 #include <utils/common/Parameterised.h>
30 #include <utils/common/StringUtils.h>
31 #include <utils/geom/GeoConvHelper.h>
32 #include <utils/geom/Position.h>
33 #include <utils/iodevices/OutputDevice.h>
34 #include "Shape.h"
35 
36 
37 // ===========================================================================
38 // class definitions
39 // ===========================================================================
40 /**
41  * @class PointOfInterest
42  * @brief A point-of-interest
43  */
44 class PointOfInterest : public Shape, public Position, public Parameterised {
45 public:
46     /** @brief Constructor
47      * @param[in] id The name of the POI
48      * @param[in] type The (abstract) type of the POI
49      * @param[in] color The color of the POI
50      * @param[in] pos The position of the POI
51      * @param[in[ geo use GEO coordinates (lon/lat)
52      * @param[in] lane The Lane in which this POI is placed
53      * @param[in] posOverLane The position over Lane
54      * @param[in] posLat The position lateral over Lane
55      * @param[in] layer The layer of the POI
56      * @param[in] angle The rotation of the POI
57      * @param[in] imgFile The raster image of the shape
58      * @param[in] relativePath set image file as relative path
59      * @param[in] width The width of the POI image
60      * @param[in] height The height of the POI image
61      */
62     PointOfInterest(const std::string& id, const std::string& type,
63                     const RGBColor& color, const Position& pos, bool geo,
64                     const std::string& lane, double posOverLane, double posLat,
65                     double layer = DEFAULT_LAYER,
66                     double angle = DEFAULT_ANGLE,
67                     const std::string& imgFile = DEFAULT_IMG_FILE,
68                     bool relativePath = DEFAULT_RELATIVEPATH,
69                     double width = DEFAULT_IMG_WIDTH,
70                     double height = DEFAULT_IMG_HEIGHT) :
Shape(id,type,color,layer,angle,imgFile,relativePath)71         Shape(id, type, color, layer, angle, imgFile, relativePath),
72         Position(pos),
73         myGeo(geo),
74         myLane(lane),
75         myPosOverLane(posOverLane),
76         myPosLat(posLat),
77         myHalfImgWidth(width / 2.0),
78         myHalfImgHeight(height / 2.0) {
79     }
80 
81 
82     /// @brief Destructor
~PointOfInterest()83     virtual ~PointOfInterest() { }
84 
85 
86     /// @name Getter
87     /// @{
88 
89     /// @brief Returns the image width of the POI
getWidth()90     inline double getWidth() const {
91         return myHalfImgWidth * 2.0;
92     }
93 
94     /// @brief Returns the image height of the POI
getHeight()95     inline double getHeight() const {
96         return myHalfImgHeight * 2.0;
97     }
98 
99     /// @brief Returns the image center of the POI
getCenter()100     Position getCenter() const {
101         return {x() + myHalfImgWidth, y() + myHalfImgHeight};
102     }
103     /// @}
104 
105 
106     /// @name Setter
107     /// @{
108 
109     /// @brief set the image width of the POI
setWidth(double width)110     inline void setWidth(double width) {
111         myHalfImgWidth = width / 2.0;
112     }
113 
114     /// @brief set the image height of the POI
setHeight(double height)115     inline void setHeight(double height) {
116         myHalfImgHeight = height / 2.0;
117     }
118     /// @}
119 
120 
121     /* @brief POI definition to the given device
122      * @param[in] geo  Whether to write the output in geo-coordinates
123      */
124     void writeXML(OutputDevice& out, const bool geo = false, const double zOffset = 0., const std::string laneID = "", const double pos = 0., const double posLat = 0.) {
125         out.openTag(SUMO_TAG_POI);
126         out.writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML(getID()));
127         if (getShapeType().size() > 0) {
128             out.writeAttr(SUMO_ATTR_TYPE, StringUtils::escapeXML(getShapeType()));
129         }
130         out.writeAttr(SUMO_ATTR_COLOR, getShapeColor());
131         out.writeAttr(SUMO_ATTR_LAYER, getShapeLayer() + zOffset);
132         if (laneID != "") {
133             out.writeAttr(SUMO_ATTR_LANE, laneID);
134             out.writeAttr(SUMO_ATTR_POSITION, pos);
135             if (posLat != 0) {
136                 out.writeAttr(SUMO_ATTR_POSITION_LAT, posLat);
137             }
138         } else {
139             if (geo) {
140                 Position POICartesianPos(*this);
141                 GeoConvHelper::getFinal().cartesian2geo(POICartesianPos);
142                 out.setPrecision(gPrecisionGeo);
143                 out.writeAttr(SUMO_ATTR_LON, POICartesianPos.x());
144                 out.writeAttr(SUMO_ATTR_LAT, POICartesianPos.y());
145                 out.setPrecision();
146             } else {
147                 out.writeAttr(SUMO_ATTR_X, x());
148                 out.writeAttr(SUMO_ATTR_Y, y());
149             }
150         }
151         if (getShapeNaviDegree() != Shape::DEFAULT_ANGLE) {
152             out.writeAttr(SUMO_ATTR_ANGLE, getShapeNaviDegree());
153         }
154         if (getShapeImgFile() != Shape::DEFAULT_IMG_FILE) {
155             if (getShapeRelativePath()) {
156                 // write only the file name, without file path
157                 std::string file = getShapeImgFile();
158                 file.erase(0, FileHelpers::getFilePath(getShapeImgFile()).size());
159                 out.writeAttr(SUMO_ATTR_IMGFILE, file);
160             } else {
161                 out.writeAttr(SUMO_ATTR_IMGFILE, getShapeImgFile());
162             }
163         }
164         if (getWidth() != Shape::DEFAULT_IMG_WIDTH) {
165             out.writeAttr(SUMO_ATTR_WIDTH, getWidth());
166         }
167         if (getHeight() != Shape::DEFAULT_IMG_HEIGHT) {
168             out.writeAttr(SUMO_ATTR_HEIGHT, getHeight());
169         }
170         writeParams(out);
171         out.closeTag();
172     }
173 
174 
175 protected:
176     /// @brief flag to check if POI was loaded as GEO Position (main used by netedit)
177     bool myGeo;
178 
179     /// @brief ID of lane in which this POI is placed (main used by netedit)
180     std::string myLane;
181 
182     /// @brief position over lane in which this POI is placed (main used by netedit)
183     double myPosOverLane;
184 
185     /// @brief latereal position over lane in which this POI is placed (main used by netedit)
186     double myPosLat;
187 
188     /// @brief The half width of the image when rendering this POI
189     double myHalfImgWidth;
190 
191     /// @brief The half height of the image when rendering this POI
192     double myHalfImgHeight;
193 
194 };
195 
196 
197 #endif
198 
199 /****************************************************************************/
200 
201