1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-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    GNETAZSourceSink.cpp
11 /// @author  Pablo Alvarez Lopez
12 /// @date    Apr 2017
13 /// @version $Id$
14 ///
15 //
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22 
23 #include <netedit/netelements/GNEEdge.h>
24 #include <netedit/changes/GNEChange_Attribute.h>
25 #include <netedit/GNEUndoList.h>
26 #include <netedit/GNEViewNet.h>
27 
28 #include "GNETAZSourceSink.h"
29 
30 
31 // ===========================================================================
32 // member method definitions
33 // ===========================================================================
34 
GNETAZSourceSink(SumoXMLTag sourceSinkTag,GNEAdditional * TAZParent,GNEEdge * edge,double departWeight)35 GNETAZSourceSink::GNETAZSourceSink(SumoXMLTag sourceSinkTag, GNEAdditional* TAZParent, GNEEdge* edge, double departWeight) :
36     GNEAdditional(TAZParent, TAZParent->getViewNet(), GLO_TAZ, sourceSinkTag, "", false, {
37     edge
38 }, {}, {}, {TAZParent}, {}, {}, {}, {}, {}, {}),
39 myDepartWeight(departWeight) {
40     //check that this is a TAZ Source OR a TAZ Sink
41     if ((sourceSinkTag != SUMO_TAG_TAZSOURCE) && (sourceSinkTag != SUMO_TAG_TAZSINK)) {
42         throw InvalidArgument("Invalid TAZ Child Tag");
43     }
44 }
45 
46 
~GNETAZSourceSink()47 GNETAZSourceSink::~GNETAZSourceSink() {}
48 
49 
50 double
getDepartWeight() const51 GNETAZSourceSink::getDepartWeight() const {
52     return myDepartWeight;
53 }
54 
55 
56 void
moveGeometry(const Position &)57 GNETAZSourceSink::moveGeometry(const Position&) {
58     // This additional cannot be moved
59 }
60 
61 
62 void
commitGeometryMoving(GNEUndoList *)63 GNETAZSourceSink::commitGeometryMoving(GNEUndoList*) {
64     // This additional cannot be moved
65 }
66 
67 
68 void
updateGeometry(bool)69 GNETAZSourceSink::updateGeometry(bool /*updateGrid*/) {
70     // Currently this additional doesn't own a Geometry
71 }
72 
73 
74 Position
getPositionInView() const75 GNETAZSourceSink::getPositionInView() const {
76     return getAdditionalParents().at(0)->getPositionInView();
77 }
78 
79 
80 std::string
getParentName() const81 GNETAZSourceSink::getParentName() const {
82     return getAdditionalParents().at(0)->getID();
83 }
84 
85 
86 void
drawGL(const GUIVisualizationSettings &) const87 GNETAZSourceSink::drawGL(const GUIVisualizationSettings&) const {
88     // Currently This additional isn't drawn
89 }
90 
91 
92 std::string
getAttribute(SumoXMLAttr key) const93 GNETAZSourceSink::getAttribute(SumoXMLAttr key) const {
94     switch (key) {
95         case SUMO_ATTR_ID:
96             return getAdditionalID();
97         case SUMO_ATTR_EDGE:
98             return getEdgeParents().front()->getID();
99         case SUMO_ATTR_WEIGHT:
100             return toString(myDepartWeight);
101         case GNE_ATTR_PARENT:
102             return getAdditionalParents().at(0)->getID();
103         case GNE_ATTR_GENERIC:
104             return getGenericParametersStr();
105         case GNE_ATTR_TAZCOLOR: {
106             // obtain max and min weight source
107             double maxWeightSource = parse<double>(getAdditionalParents().at(0)->getAttribute(GNE_ATTR_MAX_SOURCE));
108             double minWeightSource = parse<double>(getAdditionalParents().at(0)->getAttribute(GNE_ATTR_MIN_SOURCE));
109             // avoid division between zero
110             if ((maxWeightSource - minWeightSource) == 0) {
111                 return "0";
112             } else {
113                 // calculate percentage relative to the max and min weight
114                 double percentage = (myDepartWeight - minWeightSource) / (maxWeightSource - minWeightSource);
115                 // convert percentage to a value between [0-9] (because we have only 10 colors)
116                 if (percentage >= 1) {
117                     return "9";
118                 } else if (percentage < 0) {
119                     return "0";
120                 } else {
121                     return toString((int)(percentage * 10));
122                 }
123             }
124         }
125         default:
126             throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
127     }
128 }
129 
130 
131 void
setAttribute(SumoXMLAttr key,const std::string & value,GNEUndoList * undoList)132 GNETAZSourceSink::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
133     // this additional is the only that can edit a variable directly, see GNEAdditionalHandler::buildTAZEdge(...)
134     if (undoList == nullptr) {
135         setAttribute(key, value);
136     } else {
137         if (value == getAttribute(key)) {
138             return; //avoid needless changes, later logic relies on the fact that attributes have changed
139         }
140         switch (key) {
141             case SUMO_ATTR_ID:
142             case SUMO_ATTR_WEIGHT:
143             case GNE_ATTR_GENERIC:
144                 undoList->p_add(new GNEChange_Attribute(this, myViewNet->getNet(), key, value));
145                 break;
146             default:
147                 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
148         }
149     }
150 }
151 
152 
153 bool
isValid(SumoXMLAttr key,const std::string & value)154 GNETAZSourceSink::isValid(SumoXMLAttr key, const std::string& value) {
155     switch (key) {
156         case SUMO_ATTR_ID:
157             return isValidAdditionalID(value);
158         case SUMO_ATTR_WEIGHT:
159             return canParse<double>(value) && (parse<double>(value) >= 0);
160         case GNE_ATTR_GENERIC:
161             return isGenericParametersValid(value);
162         default:
163             throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
164     }
165 }
166 
167 
168 std::string
getPopUpID() const169 GNETAZSourceSink::getPopUpID() const {
170     return getTagStr();
171 }
172 
173 
174 std::string
getHierarchyName() const175 GNETAZSourceSink::getHierarchyName() const {
176     return getTagStr() + ": " + getAttribute(SUMO_ATTR_WEIGHT);
177 }
178 
179 Boundary
getCenteringBoundary() const180 GNETAZSourceSink::getCenteringBoundary() const {
181     return getEdgeParents().front()->getNBEdge()->getGeometry().getBoxBoundary();
182 }
183 
184 // ===========================================================================
185 // private
186 // ===========================================================================
187 
188 void
setAttribute(SumoXMLAttr key,const std::string & value)189 GNETAZSourceSink::setAttribute(SumoXMLAttr key, const std::string& value) {
190     switch (key) {
191         case SUMO_ATTR_ID:
192             changeAdditionalID(value);
193             break;
194         case SUMO_ATTR_WEIGHT:
195             myDepartWeight = parse<double>(value);
196             // update statictis of TAZ parent
197             getAdditionalParents().at(0)->updateAdditionalParent();
198             break;
199         case GNE_ATTR_GENERIC:
200             setGenericParametersStr(value);
201             break;
202         default:
203             throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
204     }
205     // check if updated attribute requieres update geometry
206     if (myTagProperty.hasAttribute(key) && myTagProperty.getAttributeProperties(key).requiereUpdateGeometry()) {
207         updateGeometry(true);
208     }
209 }
210 
211 
212 /****************************************************************************/
213