Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEShapeFrame.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2023 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 polygons
19/****************************************************************************/
20#include <config.h>
21
28#include <netedit/GNENet.h>
29#include <netedit/GNEViewNet.h>
30
31#include "GNEShapeFrame.h"
32
33
34// ===========================================================================
35// FOX callback mapping
36// ===========================================================================
37
43
44// Object implementation
45FXIMPLEMENT(GNEShapeFrame::GEOPOICreator, MFXGroupBoxModule, GEOPOICreatorMap, ARRAYNUMBER(GEOPOICreatorMap))
46
47
48// ===========================================================================
49// method definitions
50// ===========================================================================
51
52// ---------------------------------------------------------------------------
53// GNEShapeFrame::GEOPOICreator - methods
54// ---------------------------------------------------------------------------
55
57 MFXGroupBoxModule(polygonFrameParent, TL("GEO POI Creator")),
58 myShapeFrameParent(polygonFrameParent) {
59 // create RadioButtons for formats
60 myLonLatRadioButton = new FXRadioButton(getCollapsableFrame(), TL("Format: Lon-Lat"), this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);
61 myLatLonRadioButton = new FXRadioButton(getCollapsableFrame(), TL("Format: Lat-Lon"), this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);
62 // set lat-lon as default
63 myLatLonRadioButton->setCheck(TRUE);
64 // create text field for coordinates
65 myCoordinatesTextField = new FXTextField(getCollapsableFrame(), GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
66 // create checkBox
67 myCenterViewAfterCreationCheckButton = new FXCheckButton(getCollapsableFrame(), TL("Center View after creation"), this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
68 // create button for create GEO POIs
69 myCreateGEOPOIButton = new FXButton(getCollapsableFrame(), TL("Create GEO POI (clipboard)"), nullptr, this, MID_GNE_CREATE, GUIDesignButton);
70 // create information label
71 myLabelCartesianPosition = new MFXDynamicLabel(getCollapsableFrame(),
72 (TL("Cartesian equivalence:") + std::string("\n") +
73 TL("- X = give valid longitude") + std::string("\n") +
74 TL("- Y = give valid latitude")).c_str(),
76}
77
78
80
81
82void
84 // check if there is an GEO Proj string is defined
85 if (GeoConvHelper::getFinal().getProjString() != "!") {
86 myCoordinatesTextField->enable();
87 myCoordinatesTextField->setText("");
88 myCoordinatesTextField->enable();
89 myCreateGEOPOIButton->enable();
90 } else {
91 myCoordinatesTextField->setText(TL("No geo-conversion defined"));
92 myCoordinatesTextField->disable();
93 myCreateGEOPOIButton->disable();
94 }
95 show();
96}
97
98
99void
103
104
105long
107 // check if input contains spaces
108 std::string input = myCoordinatesTextField->getText().text();
109 std::string inputWithoutSpaces;
110 for (const auto& i : input) {
111 if (i != ' ') {
112 inputWithoutSpaces.push_back(i);
113 }
114 }
115 // if input contains spaces, call this function again, and in other case set red text color
116 if (input.size() != inputWithoutSpaces.size()) {
117 myCoordinatesTextField->setText(inputWithoutSpaces.c_str());
118 }
119 if (inputWithoutSpaces.size() > 0) {
120 myCreateGEOPOIButton->setText(TL("Create GEO POI"));
121 } else {
122 myCreateGEOPOIButton->setText(TL("Create GEO POI (clipboard)"));
123 }
124 // simply check if given value can be parsed to Position
125 if (GNEAttributeCarrier::canParse<Position>(myCoordinatesTextField->getText().text())) {
126 myCoordinatesTextField->setTextColor(FXRGB(0, 0, 0));
127 myCoordinatesTextField->killFocus();
128 // convert coordinates into lon-lat
129 Position geoPos = GNEAttributeCarrier::parse<Position>(myCoordinatesTextField->getText().text());
130 if (myLatLonRadioButton->getCheck() == TRUE) {
131 geoPos.swapXY();
132 }
134 // check if GEO Position has to be swapped
135 // update myLabelCartesianPosition
136 myLabelCartesianPosition->setText(
137 (TL("Cartesian equivalence:") + std::string("\n- X = ") + toString(geoPos.x()) + std::string("\n- Y = ") + toString(geoPos.y())).c_str());
138 } else {
139 myCoordinatesTextField->setTextColor(FXRGB(255, 0, 0));
140 myLabelCartesianPosition->setText(
141 (TL("Cartesian equivalence:") + std::string("\n") +
142 TL("- X = give valid longitude") + std::string("\n") +
143 TL("- Y = give valid latitude")).c_str());
144 };
145 return 1;
146}
147
148
149long
150GNEShapeFrame::GEOPOICreator::onCmdSetFormat(FXObject* obj, FXSelector, void*) {
151 //disable other radio button depending of selected option
152 if (obj == myLonLatRadioButton) {
153 myLonLatRadioButton->setCheck(TRUE);
154 myLatLonRadioButton->setCheck(FALSE);
155 } else if (obj == myLatLonRadioButton) {
156 myLonLatRadioButton->setCheck(FALSE);
157 myLatLonRadioButton->setCheck(TRUE);
158 }
159 // in both cases call onCmdSetCoordinates(0,0,0) to set new cartesian equivalence
160 onCmdSetCoordinates(0, 0, 0);
161 return 1;
162}
163
164
165long
167 // first check if current GEO Position is valid
168 if (myShapeFrameParent->myShapeAttributes->areValuesValid()) {
169 std::string geoPosStr = myCoordinatesTextField->getText().text();
170 if (geoPosStr.empty()) {
171 // use clipboard
172 WRITE_WARNING(TL("Using clipboard"));
173 geoPosStr = GUIUserIO::copyFromClipboard(*getApp());
174 myCoordinatesTextField->setText(geoPosStr.c_str());
175 // remove spaces, update cartesian value
176 onCmdSetCoordinates(0, 0, 0);
177 geoPosStr = myCoordinatesTextField->getText().text();
178 myCoordinatesTextField->setText("");
179 myCreateGEOPOIButton->setText(TL("Create GEO POI (clipboard)"));
180 }
181 if (GNEAttributeCarrier::canParse<Position>(geoPosStr)) {
182 // create baseShape object
183 myShapeFrameParent->createBaseShapeObject(SUMO_TAG_POI);
184 // obtain shape attributes and values
185 myShapeFrameParent->myShapeAttributes->getAttributesAndValues(myShapeFrameParent->myBaseShape, true);
186 // obtain netedit attributes and values
187 myShapeFrameParent->myNeteditAttributes->getNeteditAttributesAndValues(myShapeFrameParent->myBaseShape, nullptr);
188 // Check if ID has to be generated
189 if (!myShapeFrameParent->myBaseShape->hasStringAttribute(SUMO_ATTR_ID)) {
190 myShapeFrameParent->myBaseShape->addStringAttribute(SUMO_ATTR_ID, myShapeFrameParent->myViewNet->getNet()->getAttributeCarriers()->generateAdditionalID(SUMO_TAG_POI));
191 }
192 // force GEO attribute to true and obain position
193 myShapeFrameParent->myBaseShape->addBoolAttribute(SUMO_ATTR_GEO, true);
194 Position geoPos = GNEAttributeCarrier::parse<Position>(geoPosStr);
195 // convert coordinates into lon-lat
196 if (myLatLonRadioButton->getCheck() == TRUE) {
197 geoPos.swapXY();
198 }
200 // add lon/lat
201 myShapeFrameParent->myBaseShape->addDoubleAttribute(SUMO_ATTR_LON, geoPos.x());
202 myShapeFrameParent->myBaseShape->addDoubleAttribute(SUMO_ATTR_LAT, geoPos.y());
203 // set GEO Position as true
204 myShapeFrameParent->myBaseShape->addBoolAttribute(SUMO_ATTR_GEO, true);
205 // add shape
206 myShapeFrameParent->addShape();
207 // check if view has to be centered over created GEO POI
208 if (myCenterViewAfterCreationCheckButton->getCheck() == TRUE) {
209 // create a boundary over given GEO Position and center view over it
210 Boundary centerPosition;
211 centerPosition.add(geoPos);
212 centerPosition = centerPosition.grow(10);
213 myShapeFrameParent->myViewNet->getViewParent()->getView()->centerTo(centerPosition);
214 }
215 }
216 // refresh shape attributes
217 myShapeFrameParent->myShapeAttributes->refreshAttributesCreator();
218 }
219 return 1;
220}
221
222
223// ---------------------------------------------------------------------------
224// GNEShapeFrame - methods
225// ---------------------------------------------------------------------------
226
228 GNEFrame(viewParent, viewNet, TL("Shapes")),
229 myBaseShape(nullptr) {
230
231 // create item Selector modul for shapes
233
234 // Create shape parameters
236
237 // Create Netedit parameter
239
240 // Create drawing controls
242
244 myGEOPOICreator = new GEOPOICreator(this);
245}
246
247
249 // check if we have to delete base additional object
250 if (myBaseShape) {
251 delete myBaseShape;
252 }
253}
254
255
256void
258 // refresh tag selector
260 // show frame
262}
263
264
265bool
266GNEShapeFrame::processClick(const Position& clickedPosition, const GNEViewNetHelper::ObjectsUnderCursor& objectsUnderCursor, bool& updateTemporalShape) {
267 // reset updateTemporalShape
268 updateTemporalShape = false;
269 // check if current selected shape is valid
270 if (myShapeTagSelector->getCurrentTemplateAC() != nullptr) {
272 // show warning dialogbox and stop if input parameters are invalid
273 if (myShapeAttributes->areValuesValid() == false) {
275 return false;
276 }
277 // create baseShape object
279 // obtain shape attributes and values
281 // obtain netedit attributes and values
283 // Check if ID has to be generated
286 }
287 // add X-Y
288 myBaseShape->addDoubleAttribute(SUMO_ATTR_X, clickedPosition.x());
289 myBaseShape->addDoubleAttribute(SUMO_ATTR_Y, clickedPosition.y());
290 // set GEO Position as false (because we have created POI clicking over View
292 // add shape
293 addShape();
294 // refresh shape attributes
296 // shape added, then return true
297 return true;
299 // show warning dialogbox and stop if input parameters are invalid
300 if (myShapeAttributes->areValuesValid() == false) {
302 return false;
303 }
304 // create baseShape object
306 // obtain shape attributes and values
308 // obtain netedit attributes and values
310 // Check if ID has to be generated
313 }
314 // convert position to cartesian
315 Position GEOPos = clickedPosition;
317 // add X-Y in geo format
320 // set GEO Position as false (because we have created POI clicking over View
322 // add shape
323 addShape();
324 // refresh shape attributes
326 // shape added, then return true
327 return true;
329 // abort if lane is nullptr
330 if (objectsUnderCursor.getLaneFront() == nullptr) {
331 WRITE_WARNING(TL("POILane can be only placed over lanes"));
332 return false;
333 }
334 // show warning dialogbox and stop if input parameters are invalid
335 if (myShapeAttributes->areValuesValid() == false) {
337 return false;
338 }
339 // create baseShape object
341 // obtain shape attributes and values
343 // obtain netedit attributes and values
345 // Check if ID has to be generated
348 }
349 // obtain Lane
351 // obtain position over lane
353 // add shape
354 addShape();
355 // refresh shape attributes
357 // shape added, then return true
358 return true;
360 if (myDrawingShape->isDrawing()) {
361 // add or delete a new point depending of flag "delete last created point"
364 } else {
365 myDrawingShape->addNewPoint(clickedPosition);
366 }
367 // set temporal shape
368 updateTemporalShape = true;
369 return true;
370 } else {
371 return false;
372 }
373 }
374 }
375 myViewNet->setStatusBarText(TL("Current selected shape isn't valid."));
376 return false;
377}
378
379
380std::string
381GNEShapeFrame::getIdsSelected(const FXList* list) {
382 // Obtain Id's of list
383 std::string vectorOfIds;
384 for (int i = 0; i < list->getNumItems(); i++) {
385 if (list->isItemSelected(i)) {
386 if (vectorOfIds.size() > 0) {
387 vectorOfIds += " ";
388 }
389 vectorOfIds += (list->getItem(i)->getText()).text();
390 }
391 }
392 return vectorOfIds;
393}
394
395
400
401
402void
404 // check if baseShape exist, and if yes, delete it
405 if (myBaseShape) {
406 // delete baseShape (and all children)
407 delete myBaseShape;
408 }
409 // just create a base shape
411 // set tag
412 myBaseShape->setTag(shapeTag);
413}
414
415
416bool
418 // show warning dialogbox and stop check if input parameters are valid
421 return false;
422 } else if (myDrawingShape->getTemporalShape().size() == 0) {
423 WRITE_WARNING(TL("Polygon shape cannot be empty"));
424 return false;
425 } else {
426 // create baseShape object
428 // obtain shape attributes and values
430 // obtain netedit attributes and values
432 // Check if ID has to be generated
435 }
436 // obtain shape and check if has to be closed
439 temporalShape.closePolygon();
440 }
442 // obtain geo (by default false)
444 // add shape
445 addShape();
446 // refresh shape attributes
448 // shape added, then return true;
449 return true;
450 }
451}
452
453
454void
457 // if there are parmeters, show and Recalc groupBox
459 // show netedit attributes
461 // Check if drawing mode has to be shown
464 } else {
466 }
467 // Check if GEO POI Creator has to be shown
470 } else {
472 }
473 } else {
474 // hide all widgets
479 }
480}
481
482
483void
485 // declare additional handler
486 GNEAdditionalHandler additionalHandler(myViewNet->getNet(), true, false);
487 // build shape
488 additionalHandler.parseSumoBaseObject(myBaseShape);
489}
490
491/****************************************************************************/
FXDEFMAP(GNEShapeFrame::GEOPOICreator) GEOPOICreatorMap[]
@ MID_GNE_SET_ATTRIBUTE
attribute edited
Definition GUIAppEnum.h:907
@ MID_CHOOSEN_OPERATION
set type of selection
Definition GUIAppEnum.h:590
@ MID_GNE_CREATE
create element
Definition GUIAppEnum.h:909
#define GUIDesignButton
Definition GUIDesigns.h:74
#define GUIDesignTextField
Definition GUIDesigns.h:51
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition GUIDesigns.h:66
#define GUIDesignCheckButton
checkButton placed in left position
Definition GUIDesigns.h:187
#define GUIDesignRadioButton
Definition GUIDesigns.h:224
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition GUIDesigns.h:274
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define TL(string)
Definition MsgHandler.h:287
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_POI
begin/end of the description of a Point of interest
@ GNE_TAG_POIGEO
Point of interest over view with GEO attributes.
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ GNE_TAG_POILANE
Point of interest over Lane.
@ SUMO_ATTR_LANE
@ SUMO_ATTR_LON
@ SUMO_ATTR_Y
@ SUMO_ATTR_X
@ SUMO_ATTR_GEO
@ GNE_ATTR_CLOSE_SHAPE
Close shape of a polygon (Used by GNEPolys)
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_LAT
@ SUMO_ATTR_ID
@ SUMO_ATTR_POSITION
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)
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:78
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:300
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
void setTag(const SumoXMLTag tag)
set SumoBaseObject tag
void addPositionVectorAttribute(const SumoXMLAttr attr, const PositionVector &value)
add PositionVector attribute into current SumoBaseObject node
void addBoolAttribute(const SumoXMLAttr attr, const bool value)
add bool attribute into current SumoBaseObject node
void addDoubleAttribute(const SumoXMLAttr attr, const double value)
add double attribute into current SumoBaseObject node
bool getBoolAttribute(const SumoXMLAttr attr) const
get bool attribute
void addStringAttribute(const SumoXMLAttr attr, const std::string &value)
Builds additional objects for GNENet (busStops, chargingStations, detectors, etc.....
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 isDrawing() const
return true if currently a shape is drawed
void addNewPoint(const Position &P)
add new point to temporal shape
bool getDeleteLastCreatedPoint()
get flag delete last created point
void removeLastPoint()
remove last added point
void showDrawingShape()
show Drawing mode
void hideDrawingShape()
hide Drawing mode
const PositionVector & getTemporalShape() const
get Temporal shape
GNEViewNet * myViewNet
FOX need this.
Definition GNEFrame.h:117
virtual void show()
show Frame
Definition GNEFrame.cpp:115
virtual void hide()
hide Frame
Definition GNEFrame.cpp:124
const PositionVector & getLaneShape() const
get elements shape
Definition GNELane.cpp:136
std::string generateAdditionalID(SumoXMLTag type) const
generate additional id
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:120
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
long onCmdSetFormat(FXObject *, FXSelector, void *)
called when user select a format radio button
void hideGEOPOICreatorModule()
hide GEOPOICreator Module
long onCmdSetCoordinates(FXObject *, FXSelector, void *)
void showGEOPOICreatorModule()
Show list of GEOPOICreator Module.
long onCmdCreateGEOPOI(FXObject *, FXSelector, void *)
called when user type in search box
void tagSelected()
Tag selected in GNETagSelector.
void show()
show Frame
GNEDrawingShape * getDrawingShapeModule() const
get drawing mode editor
GNEAttributesCreator * myShapeAttributes
shape internal attributes
void addShape()
add shape (using base shape)
void createBaseShapeObject(const SumoXMLTag shapeTag)
GNEDrawingShape * myDrawingShape
Drawing shape.
CommonXMLStructure::SumoBaseObject * myBaseShape
SumoBaseObject used for create shape.
GEOPOICreator * myGEOPOICreator
GEOPOICreator.
~GNEShapeFrame()
Destructor.
GNENeteditAttributes * myNeteditAttributes
Netedit parameter.
bool processClick(const Position &clickedPosition, const GNEViewNetHelper::ObjectsUnderCursor &objectsUnderCursor, bool &updateTemporalShape)
process click over Viewnet
static std::string getIdsSelected(const FXList *list)
get list of selecte id's in string format
GNEShapeFrame(GNEViewParent *viewParent, GNEViewNet *viewNet)
Constructor.
bool shapeDrawed()
build a shaped element using the drawed shape return true if was successfully created
GNETagSelector * myShapeTagSelector
shape tag selector
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
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
GNENet * getNet() const
get the net object
void setStatusBarText(const std::string &text)
set statusBar text
A single child window which contains a view of the simulation area.
static std::string copyFromClipboard(const FXApp &app)
Copies text from the clipboard.
Definition GUIUserIO.cpp:44
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation.
A list item which allows for custom coloring.
MFXGroupBoxModule (based on FXGroupBox)
C++ TraCI client API implementation.
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
void swapXY()
swap position X and Y
Definition Position.h:290
double y() const
Returns the y-position.
Definition Position.h:60
A list of positions.
void closePolygon()
ensures that the last position equals the first
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D