Path: blob/main/src/netedit/elements/network/GNEWalkingArea.cpp
185790 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNEWalkingArea.cpp14/// @author Pablo Alvarez Lopez15/// @date Jun 202216///17// A class for visualizing and editing WalkingAreas18/****************************************************************************/1920#include <netedit/GNENet.h>21#include <netedit/GNETagProperties.h>22#include <netedit/changes/GNEChange_Attribute.h>23#include <utils/gui/div/GLHelper.h>24#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>25#include <utils/gui/windows/GUIAppEnum.h>26#include <utils/gui/div/GUIDesigns.h>2728#include "GNEWalkingArea.h"2930// ===========================================================================31// method definitions32// ===========================================================================3334GNEWalkingArea::GNEWalkingArea(GNEJunction* junction, const std::string& ID) :35GNENetworkElement(junction->getNet(), ID, SUMO_TAG_WALKINGAREA),36myTesselation(ID, "", RGBColor::GREY, junction->getNBNode()->getWalkingArea(ID).shape, false, true, 0) {37// set parent38setParent<GNEJunction*>(junction);39}404142GNEWalkingArea::~GNEWalkingArea() {43}444546GNEMoveElement*47GNEWalkingArea::getMoveElement() const {48return nullptr;49}505152Parameterised*53GNEWalkingArea::getParameters() {54return nullptr;55}565758const Parameterised*59GNEWalkingArea::getParameters() const {60return nullptr;61}626364void65GNEWalkingArea::updateGeometry() {66// Nothing to update67}686970Position71GNEWalkingArea::getPositionInView() const {72return getParentJunctions().front()->getPositionInView();73}747576bool77GNEWalkingArea::checkDrawFromContour() const {78return false;79}808182bool83GNEWalkingArea::checkDrawToContour() const {84return false;85}868788bool89GNEWalkingArea::checkDrawRelatedContour() const {90// check opened popup91if (myNet->getViewNet()->getPopup()) {92return myNet->getViewNet()->getPopup()->getGLObject() == this;93}94return false;95}969798bool99GNEWalkingArea::checkDrawOverContour() const {100return false;101}102103104bool105GNEWalkingArea::checkDrawDeleteContour() const {106// get edit modes107const auto& editModes = myNet->getViewNet()->getEditModes();108// check if we're in delete mode109if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {110return myNet->getViewNet()->checkOverLockedElement(this, mySelected);111} else {112return false;113}114}115116117bool118GNEWalkingArea::checkDrawDeleteContourSmall() const {119return false;120}121122123bool124GNEWalkingArea::checkDrawSelectContour() const {125// get edit modes126const auto& editModes = myNet->getViewNet()->getEditModes();127// check if we're in select mode128if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {129return myNet->getViewNet()->checkOverLockedElement(this, mySelected);130} else {131return false;132}133}134135136bool137GNEWalkingArea::checkDrawMoveContour() const {138return false;139}140141142NBNode::WalkingArea&143GNEWalkingArea::getNBWalkingArea() const {144return getParentJunctions().front()->getNBNode()->getWalkingArea(getMicrosimID());145}146147148void149GNEWalkingArea::drawGL(const GUIVisualizationSettings& s) const {150// declare variables151const double walkingAreaExaggeration = getExaggeration(s);152// get walking area shape153const auto& walkingAreaShape = getParentJunctions().front()->getNBNode()->getWalkingArea(getID()).shape;154// only continue if exaggeration is greater than 0 and junction's shape is greater than 4155if ((getParentJunctions().front()->getNBNode()->getShape().area() > 4) &&156(walkingAreaShape.size() > 0) && s.drawCrossingsAndWalkingareas) {157// don't draw this walking area if we're editing their junction parent158const GNENetworkElement* editedNetworkElement = myNet->getViewNet()->getEditNetworkElementShapes().getEditedNetworkElement();159if (!editedNetworkElement || (editedNetworkElement != getParentJunctions().front())) {160const auto contourMode = drawInContourMode();161// get detail level162const auto d = s.getDetailLevel(walkingAreaExaggeration);163// draw geometry only if we'rent in drawForObjectUnderCursor mode164if (!s.drawForViewObjectsHandler) {165// draw walking area166if (!contourMode) {167drawWalkingArea(s, d, walkingAreaShape, walkingAreaExaggeration);168}169// draw walkingArea name170if (s.cwaEdgeName.show(this)) {171drawName(walkingAreaShape.getCentroid(), s.scale, s.edgeName, 0, true);172}173// draw dotted contour174if (contourMode) {175myNetworkElementContour.drawDottedContour(s, GUIDottedGeometry::DottedContourType::WALKINGAREA, s.dottedContourSettings.segmentWidth, false);176} else {177myNetworkElementContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);178}179}180// draw dotted contour (except in contour mode) checking if junction parent was inserted with full boundary181myNetworkElementContour.calculateContourClosedShape(s, d, this, walkingAreaShape, getType(),182walkingAreaExaggeration, getParentJunctions().front(), !contourMode);183}184}185}186187188void189GNEWalkingArea::deleteGLObject() {190// currently WalkingAreas cannot be removed191}192193194void195GNEWalkingArea::updateGLObject() {196updateGeometry();197}198199200GUIGLObjectPopupMenu*201GNEWalkingArea::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {202// create popup203GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);204// build common options205buildPopUpMenuCommonOptions(ret, app, myNet->getViewNet(), myTagProperty->getTag(), mySelected);206// check if we're in supermode network207if (myNet->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {208// create menu commands209FXMenuCommand* mcCustomShape = GUIDesigns::buildFXMenuCommand(ret, "Set custom WalkingArea shape", nullptr, &parent, MID_GNE_WALKINGAREA_EDIT_SHAPE);210// check if menu commands has to be disabled211NetworkEditMode editMode = myNet->getViewNet()->getEditModes().networkEditMode;212if ((editMode == NetworkEditMode::NETWORK_CONNECT) || (editMode == NetworkEditMode::NETWORK_TLS) || (editMode == NetworkEditMode::NETWORK_CREATE_EDGE)) {213mcCustomShape->disable();214}215// disabled for release 1.15216mcCustomShape->disable();217}218return ret;219}220221222Boundary223GNEWalkingArea::getCenteringBoundary() const {224return myNetworkElementContour.getContourBoundary();225}226227228void229GNEWalkingArea::updateCenteringBoundary(const bool /*updateGrid*/) {230// nothing to update231}232233234std::string235GNEWalkingArea::getAttribute(SumoXMLAttr key) const {236if (key == SUMO_ATTR_ID) {237// for security purposes, avoid get WalkingArea if we want only the ID238return getMicrosimID();239}240const auto& walkingArea = getNBWalkingArea();241switch (key) {242case SUMO_ATTR_WIDTH:243return toString(walkingArea.width);244case SUMO_ATTR_LENGTH:245return toString(walkingArea.length);246case SUMO_ATTR_SHAPE:247return toString(walkingArea.shape);248default:249return getCommonAttribute(key);250}251}252253254double255GNEWalkingArea::getAttributeDouble(SumoXMLAttr key) const {256return getCommonAttributeDouble(key);257}258259260Position261GNEWalkingArea::getAttributePosition(SumoXMLAttr key) const {262return getCommonAttributePosition(key);263}264265266PositionVector267GNEWalkingArea::getAttributePositionVector(SumoXMLAttr key) const {268switch (key) {269case SUMO_ATTR_SHAPE:270return getNBWalkingArea().shape;271default:272return getCommonAttributePositionVector(key);273}274}275276277void278GNEWalkingArea::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {279if (value == getAttribute(key)) {280return; //avoid needless changes, later logic relies on the fact that attributes have changed281}282switch (key) {283case SUMO_ATTR_ID:284throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");285case SUMO_ATTR_WIDTH:286case SUMO_ATTR_LENGTH:287case SUMO_ATTR_SHAPE:288GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);289break;290default:291setCommonAttribute(key, value, undoList);292break;293}294}295296297bool298GNEWalkingArea::isAttributeEnabled(SumoXMLAttr key) const {299switch (key) {300case GNE_ATTR_SELECTED:301return true;302default:303return false;304}305}306307308bool309GNEWalkingArea::isValid(SumoXMLAttr key, const std::string& value) {310switch (key) {311case SUMO_ATTR_ID:312return false;313case SUMO_ATTR_WIDTH:314case SUMO_ATTR_LENGTH:315return canParse<double>(value) && (parse<double>(value) > 0);316case SUMO_ATTR_SHAPE:317if (canParse<PositionVector>(value)) {318return parse<PositionVector>(value).size() > 0;319} else {320return false;321}322default:323return isCommonAttributeValid(key, value);324}325}326327// ===========================================================================328// private329// ===========================================================================330331void332GNEWalkingArea::drawWalkingArea(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,333const PositionVector& shape, const double exaggeration) const {334// adjust shape to exaggeration335if (((exaggeration > 1) || (myExaggeration > 1)) && (exaggeration != myExaggeration)) {336myExaggeration = exaggeration;337myTesselation.setShape(shape);338myTesselation.getShapeRef().closePolygon();339myTesselation.getShapeRef().scaleRelative(exaggeration);340myTesselation.myTesselation.clear();341}342// push layer matrix343GLHelper::pushMatrix();344// translate to front345drawInLayer(GLO_WALKINGAREA, 0.1);346// set color347if (myShapeEdited) {348GLHelper::setColor(s.colorSettings.editShapeColor);349} else if (isAttributeCarrierSelected()) {350GLHelper::setColor(RGBColor::BLUE);351} else {352GLHelper::setColor(s.junctionColorer.getScheme().getColor(6));353}354// check if draw walking area tesselated or contour355if (drawInContourMode()) {356myInnenContour.drawInnenContourClosed(s, d, shape, exaggeration, s.dottedContourSettings.segmentWidth);357} else {358drawTesselatedWalkingArea(s, d);359}360// pop layer Matrix361GLHelper::popMatrix();362}363364365bool366GNEWalkingArea::drawInContourMode() const {367const auto& modes = myNet->getViewNet()->getEditModes();368// check modes369if (!modes.isCurrentSupermodeNetwork()) {370return true;371} else if (modes.networkEditMode == NetworkEditMode::NETWORK_MOVE) {372return true;373} else if (modes.networkEditMode == NetworkEditMode::NETWORK_DELETE) {374return true;375} else if (modes.networkEditMode == NetworkEditMode::NETWORK_CONNECT) {376return true;377} else {378return false;379}380}381382383void384GNEWalkingArea::drawTesselatedWalkingArea(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d) const {385// check if draw polygon or tesselation386if (d <= GUIVisualizationSettings::Detail::JunctionElementDetails) {387// draw shape with high detail388myTesselation.drawTesselation(myTesselation.getShape());389} else {390// draw shape391GLHelper::drawFilledPoly(myTesselation.getShape(), true);392}393// draw shape points only in Network supemode394if (myShapeEdited && s.drawMovingGeometryPoint(1, s.neteditSizeSettings.junctionGeometryPointRadius)) {395// draw geometry points396GUIGeometry::drawGeometryPoints(d, myTesselation.getShape(), GLHelper::getColor().changedBrightness(-32),397s.neteditSizeSettings.crossingGeometryPointRadius, 1,398myNet->getViewNet()->getNetworkViewOptions().editingElevation());399}400}401402403void404GNEWalkingArea::setAttribute(SumoXMLAttr key, const std::string& value) {405auto& walkingArea = getNBWalkingArea();406switch (key) {407case SUMO_ATTR_ID:408throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");409case SUMO_ATTR_WIDTH:410walkingArea.width = parse<double>(value);411break;412case SUMO_ATTR_LENGTH:413walkingArea.length = parse<double>(value);414break;415case SUMO_ATTR_SHAPE:416walkingArea.shape = parse<PositionVector>(value);417walkingArea.hasCustomShape = true;418break;419default:420setCommonAttribute(key, value);421break;422}423}424425/****************************************************************************/426427428