Path: blob/main/src/netedit/elements/additional/GNEEntryExitDetector.cpp
193728 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 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 GNEEntryExitDetector.cpp14/// @author Pablo Alvarez Lopez15/// @date Nov 201516///17//18/****************************************************************************/19#include <config.h>2021#include <netedit/changes/GNEChange_Attribute.h>22#include <netedit/elements/moving/GNEMoveElementLaneSingle.h>23#include <netedit/GNENet.h>24#include <netedit/GNETagProperties.h>25#include <utils/gui/div/GLHelper.h>2627#include "GNEEntryExitDetector.h"2829// ===========================================================================30// member method definitions31// ===========================================================================3233GNEEntryExitDetector::GNEEntryExitDetector(SumoXMLTag entryExitTag, GNENet* net) :34GNEDetector(net, entryExitTag),35myMoveElementLaneSingle(new GNEMoveElementLaneSingle(this, SUMO_ATTR_POSITION, myPosOverLane, myFriendlyPos,36GNEMoveElementLaneSingle::PositionType::SINGLE)) {37}383940GNEEntryExitDetector::GNEEntryExitDetector(SumoXMLTag entryExitTag, GNEAdditional* parent, GNELane* lane, const double pos,41const bool friendlyPos, const Parameterised::Map& parameters) :42GNEDetector(parent, entryExitTag, 0, "", "", parameters),43myPosOverLane(pos),44myFriendlyPos(friendlyPos),45myMoveElementLaneSingle(new GNEMoveElementLaneSingle(this, SUMO_ATTR_POSITION, myPosOverLane, myFriendlyPos,46GNEMoveElementLaneSingle::PositionType::SINGLE)) {47// set parents48setParent<GNELane*>(lane);49// update centering boundary without updating grid50updateCenteringBoundary(false);51}525354GNEEntryExitDetector::~GNEEntryExitDetector() {55delete myMoveElementLaneSingle;56}575859GNEMoveElement*60GNEEntryExitDetector::getMoveElement() const {61return myMoveElementLaneSingle;62}636465void66GNEEntryExitDetector::writeAdditional(OutputDevice& device) const {67device.openTag(getTagProperty()->getTag());68// write common additional attributes69writeAdditionalAttributes(device);70// write move attributes71myMoveElementLaneSingle->writeMoveAttributes(device);72// write common detector parameters73writeDetectorValues(device);74// write parameters75writeParams(device);76device.closeTag();77}787980bool81GNEEntryExitDetector::isAdditionalValid() const {82// only movement problems83return myMoveElementLaneSingle->isMoveElementValid();84}858687std::string88GNEEntryExitDetector::getAdditionalProblem() const {89// only movement problems90return myMoveElementLaneSingle->getMovingProblem();91}929394void95GNEEntryExitDetector::fixAdditionalProblem() {96// only movement problems97myMoveElementLaneSingle->fixMovingProblem();98}99100101void102GNEEntryExitDetector::updateGeometry() {103// update geometry104myAdditionalGeometry.updateGeometry(getParentLanes().front()->getLaneShape(), myMoveElementLaneSingle->getFixedPositionOverLane(true), myMoveElementLaneSingle->myMovingLateralOffset);105// update centering boundary without updating grid106updateCenteringBoundary(false);107}108109110void111GNEEntryExitDetector::drawGL(const GUIVisualizationSettings& s) const {112// first check if additional has to be drawn113if (myNet->getViewNet()->getDataViewOptions().showAdditionals() &&114!myNet->getViewNet()->selectingDetectorsTLSMode()) {115// Set initial values116const double entryExitExaggeration = getExaggeration(s);117// get detail level118const auto d = s.getDetailLevel(entryExitExaggeration);119// draw geometry only if we'rent in drawForObjectUnderCursor mode120if (s.checkDrawAdditional(d, isAttributeCarrierSelected())) {121// draw parent and child lines122drawParentChildLines(s, s.additionalSettings.connectionColor);123// Push layer matrix124GLHelper::pushMatrix();125// translate to front126drawInLayer(GLO_DET_ENTRY);127// Set color128RGBColor color;129if (drawUsingSelectColor()) {130color = s.colorSettings.selectedAdditionalColor;131} else if (myTagProperty->getTag() == SUMO_TAG_DET_ENTRY) {132color = s.detectorSettings.E3EntryColor;133} else if (myTagProperty->getTag() == SUMO_TAG_DET_EXIT) {134color = s.detectorSettings.E3ExitColor;135}136// draw parts137drawBody(d, color, entryExitExaggeration);138drawEntryLogo(d, color, entryExitExaggeration);139drawE3Logo(d, color, entryExitExaggeration);140// pop layer matrix141GLHelper::popMatrix();142// draw additional name143drawAdditionalName(s);144// draw lock icon145GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), myAdditionalGeometry.getShape().getCentroid(),146entryExitExaggeration);147// draw dotted contour148myAdditionalContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);149}150// calculate contour151myAdditionalContour.calculateContourRectangleShape(s, d, this, myAdditionalGeometry.getShape().front(), 2.7, 1.6,152getType(), 2, 0, myAdditionalGeometry.getShapeRotations().front(), entryExitExaggeration,153getParentLanes().front()->getParentEdge());154}155}156157158std::string159GNEEntryExitDetector::getAttribute(SumoXMLAttr key) const {160switch (key) {161case GNE_ATTR_PARENT:162return getParentAdditionals().at(0)->getID();163default:164return getDetectorAttribute(key);165}166}167168169double170GNEEntryExitDetector::getAttributeDouble(SumoXMLAttr key) const {171return getDetectorAttributeDouble(key);172}173174175Position176GNEEntryExitDetector::getAttributePosition(SumoXMLAttr key) const {177return getDetectorAttributePosition(key);178}179180181void182GNEEntryExitDetector::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {183switch (key) {184case GNE_ATTR_PARENT:185GNEChange_Attribute::changeAttribute(this, key, value, undoList);186break;187default:188setDetectorAttribute(key, value, undoList);189break;190}191}192193194bool195GNEEntryExitDetector::isValid(SumoXMLAttr key, const std::string& value) {196switch (key) {197case GNE_ATTR_PARENT:198return (myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_ENTRY_EXIT_DETECTOR, value, false) != nullptr);199default:200return isDetectorValid(key, value);201}202}203204205void206GNEEntryExitDetector::drawBody(const GUIVisualizationSettings::Detail d,207const RGBColor& color, const double exaggeration) const {208// check detail level209if (d <= GUIVisualizationSettings::Detail::Additionals) {210// Push polygon matrix211GLHelper::pushMatrix();212// set color213GLHelper::setColor(color);214// set polygon mode215glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);216// move to position217glTranslated(myAdditionalGeometry.getShape().front().x(), myAdditionalGeometry.getShape().front().y(), 0);218// rotate over lane219GUIGeometry::rotateOverLane(myAdditionalGeometry.getShapeRotations().front() + 90);220// scale221glScaled(exaggeration, exaggeration, 1);222// check detail level223if (d <= GUIVisualizationSettings::Detail::AdditionalDetails) {224// Draw polygon225glBegin(GL_LINES);226glVertex2d(1.7, 0);227glVertex2d(-1.7, 0);228glEnd();229glBegin(GL_QUADS);230glVertex2d(-1.7, .5);231glVertex2d(-1.7, -.5);232glVertex2d(1.7, -.5);233glVertex2d(1.7, .5);234glEnd();235// first Arrow236glTranslated(1.5, 0, 0);237GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);238GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);239// second Arrow240glTranslated(-3, 0, 0);241GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);242GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);243} else {244// Draw square in drawy for selecting mode245glBegin(GL_QUADS);246glVertex2d(-1.7, 4.3);247glVertex2d(-1.7, -.5);248glVertex2d(1.7, -.5);249glVertex2d(1.7, 4.3);250glEnd();251}252// Pop polygon matrix253GLHelper::popMatrix();254}255}256257258void259GNEEntryExitDetector::drawEntryLogo(const GUIVisualizationSettings::Detail d,260const RGBColor& color, const double exaggeration) const {261// check detail level262if (d <= GUIVisualizationSettings::Detail::AdditionalDetails) {263// Push matrix264GLHelper::pushMatrix();265// set color266GLHelper::setColor(color);267// Traslate to center of detector268glTranslated(myAdditionalGeometry.getShape().front().x(), myAdditionalGeometry.getShape().front().y(), getType() + 0.1);269// rotate over lane270GUIGeometry::rotateOverLane(myAdditionalGeometry.getShapeRotations().front());271//move to logo position272glTranslated(1.9, 0, 0);273// scale274glScaled(exaggeration, exaggeration, 1);275//move to logo position276glTranslated(1.7, 0, 0);277// rotate 90 degrees lane278glRotated(90, 0, 0, 1);279// draw Entry or Exit text if isn't being drawn for selecting280if (d <= GUIVisualizationSettings::Detail::Text) {281if (myTagProperty->getTag() == SUMO_TAG_DET_ENTRY) {282GLHelper::drawText("Entry", Position(), .1, 1, color, 180);283} else if (myTagProperty->getTag() == SUMO_TAG_DET_EXIT) {284GLHelper::drawText("Exit", Position(), .1, 1, color, 180);285}286} else {287GLHelper::drawBoxLine(Position(0, 1), 0, 2, 1);288}289// pop matrix290GLHelper::popMatrix();291}292}293294295void296GNEEntryExitDetector::drawE3Logo(const GUIVisualizationSettings::Detail d,297const RGBColor& color, const double exaggeration) const {298// check detail level299if (d <= GUIVisualizationSettings::Detail::Text) {300// Push matrix301GLHelper::pushMatrix();302// set color303GLHelper::setColor(color);304// Traslate to center of detector305glTranslated(myAdditionalGeometry.getShape().front().x(), myAdditionalGeometry.getShape().front().y(), getType() + 0.1);306// rotate over lane307GUIGeometry::rotateOverLane(myAdditionalGeometry.getShapeRotations().front());308//move to logo position309glTranslated(1.9, 0, 0);310// scale311glScaled(exaggeration, exaggeration, 1);312// draw E3 logo313GLHelper::drawText("E3", Position(0, 0), .1, 2.8, color);314// pop matrix315GLHelper::popMatrix();316}317}318319320void321GNEEntryExitDetector::setAttribute(SumoXMLAttr key, const std::string& value) {322switch (key) {323case SUMO_ATTR_LANE:324// set hier because GNEHierarchicalElement is a template325replaceAdditionalParentLanes(value);326break;327case GNE_ATTR_PARENT:328replaceAdditionalParent(SUMO_TAG_ENTRY_EXIT_DETECTOR, value, 0);329break;330default:331setDetectorAttribute(key, value);332break;333}334}335336/****************************************************************************/337338339