Eclipse SUMO - Simulation of Urban MObility
GNEAdditionalFrame.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-2022 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// The Widget for add additional elements
19/****************************************************************************/
20#include <config.h>
21
22#include <netedit/GNENet.h>
23#include <netedit/GNEViewNet.h>
25
26#include "GNEAdditionalFrame.h"
27
28
29// ===========================================================================
30// method definitions
31// ===========================================================================
32
34 GNEFrame(viewParent, viewNet, "Additionals"),
35 myBaseAdditional(nullptr) {
36
37 // create item Selector modul for additionals
38 myAdditionalTagSelector = new GNETagSelector(this, GNETagProperties::TagType::ADDITIONALELEMENT, SUMO_TAG_BUS_STOP);
39
40 // Create additional parameters
42
43 // Create Netedit parameter
45
46 // Create selector parent
48
49 // Create selector child edges
51
52 // Create selector child lanes
54
55 // Create list for E2Multilane lane selector
57}
58
59
61 // check if we have to delete base additional object
62 if (myBaseAdditional) {
63 delete myBaseAdditional;
64 }
65}
66
67
68void
70 // refresh tag selector
72 // reset last position
74 // show frame
76}
77
78
79bool
81 // first check that current selected additional is valid
83 myViewNet->setStatusBarText("Current selected additional isn't valid.");
84 return false;
85 }
86 // check if add or remove edge
87 if (myEdgesSelector->isShown() && objectsUnderCursor.getEdgeFront()) {
89 return true;
90 }
91 // check if add or remove lane
92 if (myLanesSelector->isShown() && objectsUnderCursor.getLaneFront()) {
94 return true;
95 }
96 // show warning dialogbox and stop check if input parameters are valid
99 return false;
100 }
101 // obtain tagproperty (only for improve code legibility)
102 const auto& tagProperties = myAdditionalTagSelector->getCurrentTemplateAC()->getTagProperty();
103 // create base additional
104 if (!createBaseAdditionalObject(tagProperties)) {
105 return false;
106 }
107 // obtain attributes and values
109 // fill netedit attributes
111 return false;
112 }
113 // If consecutive Lane Selector is enabled, it means that either we're selecting lanes or we're finished or we'rent started
114 if (tagProperties.hasAttribute(SUMO_ATTR_EDGE) || (tagProperties.getTag() == SUMO_TAG_VAPORIZER)) {
115 return buildAdditionalOverEdge(objectsUnderCursor.getLaneFront(), tagProperties);
116 } else if (tagProperties.hasAttribute(SUMO_ATTR_LANE)) {
117 return buildAdditionalOverLane(objectsUnderCursor.getLaneFront(), tagProperties);
118 } else if (tagProperties.getTag() == GNE_TAG_MULTI_LANE_AREA_DETECTOR) {
119 return myConsecutiveLaneSelector->addLane(objectsUnderCursor.getLaneFront());
120 } else {
121 return buildAdditionalOverView(tagProperties);
122 }
123}
124
125
128 return myEdgesSelector;
129}
130
131
134 return myLanesSelector;
135}
136
137
141}
142
143
144bool
145GNEAdditionalFrame::createPath(const bool /* useLastRoute */) {
146 // obtain tagproperty (only for improve code legibility)
147 const auto& tagProperty = myAdditionalTagSelector->getCurrentTemplateAC()->getTagProperty();
148 // first check that current tag is valid (currently only for E2 multilane detectors)
149 if (tagProperty.getTag() == GNE_TAG_MULTI_LANE_AREA_DETECTOR) {
150 // now check number of lanes
151 if (myConsecutiveLaneSelector->getLanePath().size() < 2) {
152 WRITE_WARNING(TL("E2 multilane detectors need at least two consecutive lanes"));
153 } else if (createBaseAdditionalObject(tagProperty)) {
154 // get attributes and values
156 // fill netedit attributes
158 // Check if ID has to be generated
161 }
162 // add lane IDs
164 // set positions
167 // parse common attributes
168 if (buildAdditionalCommonAttributes(tagProperty)) {
169 // show warning dialogbox and stop check if input parameters are valid
170 if (myAdditionalAttributes->areValuesValid() == false) {
172 } else {
173 // declare additional handler
174 GNEAdditionalHandler additionalHandler(getViewNet()->getNet(), true, false);
175 // build additional
176 additionalHandler.parseSumoBaseObject(myBaseAdditional);
177 // Refresh additional Parent Selector (For additionals that have a limited number of children)
179 // abort E2 creation
181 // refresh additional attributes
183 return true;
184 }
185 }
186 }
187 }
188 }
189 return false;
190}
191
192
193void
195 // get template AC
196 const auto templateAC = myAdditionalTagSelector->getCurrentTemplateAC();
197 if (templateAC) {
198 // show additional attributes modul
200 // show netedit attributes
202 // Show myAdditionalFrameParent if we're adding an slave element
203 if (templateAC->getTagProperty().isChild()) {
204 mySelectorAdditionalParent->showSelectorParentModule(templateAC->getTagProperty().getParentTags());
205 } else {
207 }
208 // Show EdgesSelector if we're adding an additional that own the attribute SUMO_ATTR_EDGES
209 if (templateAC->getTagProperty().hasAttribute(SUMO_ATTR_EDGES)) {
211 } else {
213 }
214 // check if we must show consecutive lane selector
215 if (templateAC->getTagProperty().getTag() == GNE_TAG_MULTI_LANE_AREA_DETECTOR) {
218 } else if (templateAC->getTagProperty().hasAttribute(SUMO_ATTR_LANES)) {
221 } else {
224 }
225 // reset last position
227 } else {
228 // hide all moduls if additional isn't valid
235 }
236}
237
238
239bool
241 // check if baseAdditional exist, and if yes, delete it
242 if (myBaseAdditional) {
243 // go to base additional root
246 }
247 // delete baseAdditional (and all children)
248 delete myBaseAdditional;
249 // reset baseAdditional
250 myBaseAdditional = nullptr;
251 }
252 // declare tag for base additional
253 SumoXMLTag baseAdditionalTag = tagProperty.getTag();
254 // check if baseAdditionalTag has to be updated
255 if (baseAdditionalTag == GNE_TAG_MULTI_LANE_AREA_DETECTOR) {
256 baseAdditionalTag = SUMO_TAG_LANE_AREA_DETECTOR;
257 } else if (baseAdditionalTag == GNE_TAG_CALIBRATOR_FLOW) {
258 baseAdditionalTag = SUMO_TAG_FLOW;
259 }
260 // check if additional is child
261 if (tagProperty.isChild()) {
262 // get additional under cursor
263 const GNEAdditional* additionalUnderCursor = myViewNet->getObjectsUnderCursor().getAdditionalFront();
264 // if user click over an additional element parent, mark int in ParentAdditionalSelector
265 if (additionalUnderCursor && (additionalUnderCursor->getTagProperty().getTag() == tagProperty.getParentTags().front())) {
266 // update parent additional selected
267 mySelectorAdditionalParent->setIDSelected(additionalUnderCursor->getID());
268 }
269 // stop if currently there isn't a valid selected parent
271 myAdditionalAttributes->showWarningMessage("A " + toString(tagProperty.getParentTags().front()) + " must be selected before insertion of " + myAdditionalTagSelector->getCurrentTemplateAC()->getTagProperty().getTagStr() + ".");
272 return false;
273 } else {
274 // create baseAdditional parent
276 // set parent tag
277 myBaseAdditional->setTag(tagProperty.getParentTags().front());
278 // add ID
280 // create baseAdditional again as child of current myBaseAdditional
282 }
283 } else {
284 // just create a base additional
286 }
287 // set baseAdditional tag
288 myBaseAdditional->setTag(baseAdditionalTag);
289 // BaseAdditional created, then return true
290 return true;
291}
292
293
294bool
296 // If additional has a interval defined by a begin or end, check that is valid
297 if (tagProperties.hasAttribute(SUMO_ATTR_STARTTIME) && tagProperties.hasAttribute(SUMO_ATTR_END)) {
300 if (begin > end) {
301 myAdditionalAttributes->showWarningMessage("Attribute '" + toString(SUMO_ATTR_STARTTIME) + "' cannot be greater than attribute '" + toString(SUMO_ATTR_END) + "'.");
302 return false;
303 }
304 }
305 // If additional own the attribute SUMO_ATTR_FILE but was't defined, will defined as <ID>.xml
308 // SUMO_ATTR_FILE is optional for calibrators and rerouters (fails to load in sumo when given and the file does not exist)
310 }
311 }
312 // check edge children
314 // obtain edge IDs
316 // check if attribute has at least one edge
318 myAdditionalAttributes->showWarningMessage("List of " + toString(SUMO_TAG_EDGE) + "s cannot be empty");
319 return false;
320 }
321 }
322 // check lane children
324 // obtain lane IDs
326 // check if attribute has at least one lane
328 myAdditionalAttributes->showWarningMessage("List of " + toString(SUMO_TAG_LANE) + "s cannot be empty");
329 return false;
330 }
331 }
332 // all ok, continue building additional
333 return true;
334}
335
336
337bool
339 // check that lane exist
340 if (lane) {
341 // Get attribute lane's edge
343 // Check if ID has to be generated
344 if (tagProperties.getTag() == SUMO_TAG_VAPORIZER) {
348 }
349 } else {
350 return false;
351 }
352 // parse common attributes
353 if (!buildAdditionalCommonAttributes(tagProperties)) {
354 return false;
355 }
356 // show warning dialogbox and stop check if input parameters are valid
359 return false;
360 } else {
361 // declare additional handler
362 GNEAdditionalHandler additionalHandler(myViewNet->getNet(), true, false);
363 // build additional
364 additionalHandler.parseSumoBaseObject(myBaseAdditional);
365 // Refresh additional Parent Selector (For additionals that have a limited number of children)
367 // clear selected eddges and lanes
368 myEdgesSelector->onCmdClearSelection(nullptr, 0, nullptr);
369 myLanesSelector->onCmdClearSelection(nullptr, 0, nullptr);
370 // refresh additional attributes
372 return true;
373 }
374}
375
376
377bool
379 // check that lane exist
380 if (lane != nullptr) {
381 // Get attribute lane
383 // Check if ID has to be generated
386 }
387 } else {
388 return false;
389 }
390 // Obtain position of the mouse over lane (limited over grid)
392 // set attribute position as mouse position over lane
394 // parse common attributes
395 if (!buildAdditionalCommonAttributes(tagProperties)) {
396 return false;
397 }
398 // show warning dialogbox and stop check if input parameters are valid
401 return false;
402 } else {
403 // declare additional handler
404 GNEAdditionalHandler additionalHandler(myViewNet->getNet(), true, false);
405 // build additional
406 additionalHandler.parseSumoBaseObject(myBaseAdditional);
407 // Refresh additional Parent Selector (For additionals that have a limited number of children)
409 // clear selected eddges and lanes
410 myEdgesSelector->onCmdClearSelection(nullptr, 0, nullptr);
411 myLanesSelector->onCmdClearSelection(nullptr, 0, nullptr);
412 // refresh additional attributes
414 return true;
415 }
416}
417
418
419bool
421 // disable intervals (temporal)
422 if ((tagProperties.getTag() == SUMO_TAG_INTERVAL) ||
423 (tagProperties.getTag() == SUMO_TAG_DEST_PROB_REROUTE) ||
424 (tagProperties.getTag() == SUMO_TAG_CLOSING_REROUTE) ||
425 (tagProperties.getTag() == SUMO_TAG_CLOSING_LANE_REROUTE) ||
426 (tagProperties.getTag() == SUMO_TAG_ROUTE_PROB_REROUTE) ||
427 (tagProperties.getTag() == SUMO_TAG_PARKING_AREA_REROUTE)) {
428 WRITE_WARNING(TL("Currently unsuported. Create rerouter elements using rerouter dialog"));
429 return false;
430 }
431 // disable steps (temporal)
432 if (tagProperties.getTag() == SUMO_TAG_STEP) {
433 WRITE_WARNING(TL("Currently unsuported. Create VSS steps using VSS dialog"));
434 return false;
435 }
436 // disable flows (temporal)
437 if (tagProperties.getTag() == GNE_TAG_CALIBRATOR_FLOW) {
438 WRITE_WARNING(TL("Currently unsuported. Create calibratorFlows using calibrator dialog"));
439 return false;
440 }
441 // Check if ID has to be generated
444 }
445 // Obtain position as the clicked position over view
447 // add position and X-Y-Z attributes
452 // parse common attributes
453 if (!buildAdditionalCommonAttributes(tagProperties)) {
454 return false;
455 }
456 // special case for VSS Steps
458 // get VSS parent
461 // get last step
462 GNEAdditional* step = nullptr;
463 for (const auto& additionalChild : VSSParent->getChildAdditionals()) {
464 if (!additionalChild->getTagProperty().isSymbol()) {
465 step = additionalChild;
466 }
467 }
468 // set time
469 if (step) {
471 } else {
473 }
474 }
475 // show warning dialogbox and stop check if input parameters are valid
476 if (myAdditionalAttributes->areValuesValid() == false) {
478 return false;
479 } else {
480 // declare additional handler
481 GNEAdditionalHandler additionalHandler(myViewNet->getNet(), true, false);
482 // build additional
483 additionalHandler.parseSumoBaseObject(myBaseAdditional);
484 // Refresh additional Parent Selector (For additionals that have a limited number of children)
486 // clear selected eddges and lanes
487 myEdgesSelector->onCmdClearSelection(nullptr, 0, nullptr);
488 myLanesSelector->onCmdClearSelection(nullptr, 0, nullptr);
489 // refresh additional attributes
491 return true;
492 }
493}
494
495/****************************************************************************/
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define TL(string)
Definition: MsgHandler.h:282
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_CLOSING_REROUTE
reroute of type closing
@ SUMO_TAG_REROUTER
A rerouter.
@ GNE_TAG_MULTI_LANE_AREA_DETECTOR
an e2 detector over multiple lanes (placed here due create Additional Frame)
@ SUMO_TAG_PARKING_AREA_REROUTE
entry for an alternative parking zone
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_STEP
trigger: a step description
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ SUMO_TAG_ROUTE_PROB_REROUTE
probability of route of a reroute
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ GNE_TAG_CALIBRATOR_FLOW
a flow definition within in Calibrator
@ SUMO_TAG_DEST_PROB_REROUTE
probability of destiny of a reroute
@ SUMO_TAG_VAPORIZER
vaporizer of vehicles
@ SUMO_TAG_LANE_AREA_DETECTOR
alternative tag for e2 detector
@ SUMO_TAG_CLOSING_LANE_REROUTE
lane of a reroute of type closing
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
@ SUMO_TAG_VSS
A variable speed sign.
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_LANE
@ SUMO_ATTR_FILE
@ SUMO_ATTR_Y
@ SUMO_ATTR_Z
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_X
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_LANES
@ SUMO_ATTR_STARTTIME
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_TIME
trigger: the time of the step
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void parseSumoBaseObject(CommonXMLStructure::SumoBaseObject *obj)
parse SumoBaseObject (it's called recursivelly)
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
void setTag(const SumoXMLTag tag)
set SumoBaseObject tag
SumoBaseObject * getParentSumoBaseObject() const
get pointer to mySumoBaseObjectParent SumoBaseObject (if is null, then is the root)
void addTimeAttribute(const SumoXMLAttr attr, const SUMOTime value)
add time attribute into current SumoBaseObject node
void addStringListAttribute(const SumoXMLAttr attr, const std::vector< std::string > &value)
add string list attribute into current SumoBaseObject node
void addDoubleAttribute(const SumoXMLAttr attr, const double value)
add double attribute into current SumoBaseObject node
void addPositionAttribute(const SumoXMLAttr attr, const Position &value)
add Position attribute into current SumoBaseObject node
void addStringAttribute(const SumoXMLAttr attr, const std::string &value)
double getDoubleAttribute(const SumoXMLAttr attr) const
get double attribute
const std::vector< std::string > & getStringListAttribute(const SumoXMLAttr attr) const
get string list attribute
bool hasStringListAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given string list attribute
const std::string & getStringAttribute(const SumoXMLAttr attr) const
get string attribute
GNESelectorParent * mySelectorAdditionalParent
Module for select a single parent additional.
bool buildAdditionalOverLane(GNELane *lane, const GNETagProperties &tagValues)
build additional over a single lane
GNEConsecutiveSelector * getConsecutiveLaneSelector() const
get consecutive lane selector
GNETagSelector * myAdditionalTagSelector
item selector
GNENetworkSelector * getLanesSelector() const
get edges selector
bool createPath(const bool useLastRoute)
create path
GNEAdditionalFrame(GNEViewParent *viewParent, GNEViewNet *viewNet)
Constructor.
GNENetworkSelector * getEdgesSelector() const
get edges selector
void tagSelected()
Tag selected in GNETagSelector.
GNENetworkSelector * myLanesSelector
Module for select lanes.
bool buildAdditionalOverView(const GNETagProperties &tagValues)
build additional over view
bool buildAdditionalCommonAttributes(const GNETagProperties &tagValues)
build common additional attributes
void show()
show Frame
GNEAttributesCreator * myAdditionalAttributes
internal additional attributes
~GNEAdditionalFrame()
Destructor.
GNENetworkSelector * myEdgesSelector
Module for select edges.
CommonXMLStructure::SumoBaseObject * myBaseAdditional
SumoBaseObject used for create additional.
bool addAdditional(const GNEViewNetHelper::ObjectsUnderCursor &objectsUnderCursor)
add additional element
bool createBaseAdditionalObject(const GNETagProperties &tagProperty)
GNENeteditAttributes * myNeteditAttributes
Netedit parameter.
bool buildAdditionalOverEdge(GNELane *lane, const GNETagProperties &tagValues)
build additional over an edge (parent of lane)
GNEConsecutiveSelector * myConsecutiveLaneSelector
Module for select consecutive lanes.
Builds additional objects for GNENet (busStops, chargingStations, detectors, etc.....
An Element which don't belong to GNENet but has influence in the simulation.
Definition: GNEAdditional.h:48
virtual std::string getAttribute(SumoXMLAttr key) const =0
const std::string getID() const
get ID (all Attribute Carriers have one)
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
void getAttributesAndValues(CommonXMLStructure::SumoBaseObject *baseObject, bool includeAll) const
get attributes and their values
bool areValuesValid() const
check if parameters of attributes are valid
void showAttributesCreatorModule(GNEAttributeCarrier *templateAC, const std::vector< SumoXMLAttr > &hiddenAttributes)
show GNEAttributesCreator modul
void hideAttributesCreatorModule()
hide group box
void showWarningMessage(std::string extra="") const
show warning message with information about non-valid attributes
void refreshAttributesCreator()
refresh attribute creator
bool addLane(GNELane *lane)
add lane
void abortPathCreation()
abort path creation
void showConsecutiveLaneSelectorModule()
show GNEConsecutiveSelector
const std::vector< std::pair< GNELane *, double > > & getLanePath() const
get vector with lanes and clicked positions
void hideConsecutiveLaneSelectorModule()
show GNEConsecutiveSelector
const std::vector< std::string > getLaneIDPath() const
get lane IDs
GNEViewNet * getViewNet() const
get view net
Definition: GNEFrame.cpp:150
GNEViewNet * myViewNet
FOX need this.
Definition: GNEFrame.h:117
virtual void show()
show Frame
Definition: GNEFrame.cpp:115
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
const PositionVector & getLaneShape() const
get elements shape
Definition: GNELane.cpp:142
double getLengthGeometryFactor() const
get length geometry factor
Definition: GNELane.cpp:1807
GNEEdge * getParentEdge() const
get parent edge
Definition: GNELane.cpp:124
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
std::string generateAdditionalID(SumoXMLTag type) const
generate additional id
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:132
void showNeteditAttributesModule(GNEAttributeCarrier *templateAC)
show Netedit attributes modul
void hideNeteditAttributesModule()
hide Netedit attributes modul
bool getNeteditAttributesAndValues(CommonXMLStructure::SumoBaseObject *baseObject, const GNELane *lane) const
fill valuesMap with netedit attributes
void hideNetworkElementsSelector()
hide GNENetworkSelector Module
bool toggleSelectedElement(const GNENetworkElement *networkElement)
toggle selected networkElement
bool isShown() const
return true if module is shown
long onCmdClearSelection(FXObject *, FXSelector, void *)
called when clear selection button is pressed
void showNetworkElementsSelector()
show GNENetworkSelector Module
std::vector< std::string > getSelectedIDs() const
get selected IDs
void setIDSelected(const std::string &id)
select manually a element of the list
void showSelectorParentModule(const std::vector< SumoXMLTag > &parentTags)
Show list of GNESelectorParent Module.
void refreshSelectorParentModule()
Refresh list of Additional Parents Module.
std::string getIdSelected() const
get currently parent additional selected
void hideSelectorParentModule()
hide GNESelectorParent Module
const std::vector< SumoXMLTag > & getParentTags() const
get parent tags
const std::string & getTagStr() const
get Tag vinculated with this attribute Property in String Format (used to avoid multiple calls to toS...
bool isChild() const
return true if tag correspond to an element child of another element (Example: E3->Entry/Exit)
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
void refreshTagSelector()
refresh tagSelector (used when frameParent is show)
GNEAttributeCarrier * getCurrentTemplateAC() const
get current templateAC
class used to group all variables related with objects under cursor after a click over view
GNELane * getLaneFront() const
get front lane or a pointer to nullptr
GNEAdditional * getAdditionalFront() const
get front additional element or a pointer to nullptr
GNEEdge * getEdgeFront() const
get front edge or a pointer to nullptr
GNENet * getNet() const
get the net object
void resetLastClickedPosition()
reset last clicked position
Definition: GNEViewNet.cpp:774
const GNEViewNetHelper::ObjectsUnderCursor & getObjectsUnderCursor() const
get objects under cursor
Definition: GNEViewNet.cpp:462
void setStatusBarText(const std::string &text)
set statusBar text
Definition: GNEViewNet.cpp:768
A single child window which contains a view of the simulation area.
Definition: GNEViewParent.h:84
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double x() const
Returns the x-position.
Definition: Position.h:55
double z() const
Returns the z-position.
Definition: Position.h:65
double y() const
Returns the y-position.
Definition: Position.h:60
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D