Path: blob/main/src/netedit/elements/additional/GNEInductionLoopDetector.cpp
169684 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 GNEInductionLoopDetector.cpp14/// @author Pablo Alvarez Lopez15/// @date Nov 201516///17//18/****************************************************************************/19#include <config.h>2021#include <netedit/GNENet.h>22#include <netedit/GNETagProperties.h>23#include <netedit/GNEUndoList.h>24#include <netedit/GNEViewNet.h>25#include <netedit/GNEViewParent.h>26#include <netedit/changes/GNEChange_Attribute.h>27#include <netedit/frames/network/GNETLSEditorFrame.h>28#include <utils/gui/div/GLHelper.h>29#include <utils/gui/div/GUIGlobalViewObjectsHandler.h>30#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>3132#include "GNEInductionLoopDetector.h"33#include "GNEAdditionalHandler.h"3435// ===========================================================================36// member method definitions37// ===========================================================================3839GNEInductionLoopDetector::GNEInductionLoopDetector(GNENet* net) :40GNEDetector(net, SUMO_TAG_INDUCTION_LOOP) {41}424344GNEInductionLoopDetector::GNEInductionLoopDetector(const std::string& id, GNENet* net, const std::string& filename, GNELane* lane,45const double pos, const SUMOTime freq, const std::string& outputFilename, const std::vector<std::string>& vehicleTypes,46const std::vector<std::string>& nextEdges, const std::string& detectPersons, const std::string& name, const bool friendlyPos,47const Parameterised::Map& parameters) :48GNEDetector(id, net, filename, SUMO_TAG_INDUCTION_LOOP, pos, freq, lane, outputFilename, vehicleTypes, nextEdges,49detectPersons, name, friendlyPos, parameters) {50// update centering boundary without updating grid51updateCenteringBoundary(false);52}535455GNEInductionLoopDetector::~GNEInductionLoopDetector() {56}575859void60GNEInductionLoopDetector::writeAdditional(OutputDevice& device) const {61device.openTag(getTagProperty()->getTag());62device.writeAttr(SUMO_ATTR_ID, getID());63device.writeAttr(SUMO_ATTR_LANE, getParentLanes().front()->getID());64device.writeAttr(SUMO_ATTR_POSITION, myPositionOverLane);65// write common parameters66writeDetectorValues(device);67// write parameters (Always after children to avoid problems with additionals.xsd)68writeParams(device);69device.closeTag();70}717273bool74GNEInductionLoopDetector::isAdditionalValid() const {75// with friendly position enabled position are "always fixed"76if (myFriendlyPosition) {77return true;78} else {79return fabs(myPositionOverLane) <= getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();80}81}828384std::string85GNEInductionLoopDetector::getAdditionalProblem() const {86// obtain final length87const double len = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();88// check if detector has a problem89if (GNEAdditionalHandler::checkLanePosition(myPositionOverLane, 0, len, myFriendlyPosition)) {90return "";91} else {92// declare variable for error position93std::string errorPosition;94// check positions over lane95if (myPositionOverLane < 0) {96errorPosition = (toString(SUMO_ATTR_POSITION) + " < 0");97}98if (myPositionOverLane > len) {99errorPosition = (toString(SUMO_ATTR_POSITION) + TL(" > lanes's length"));100}101return errorPosition;102}103}104105106void107GNEInductionLoopDetector::fixAdditionalProblem() {108// declare new position109double newPositionOverLane = myPositionOverLane;110// fix pos and length checkAndFixDetectorPosition111double length = 0;112GNEAdditionalHandler::fixLanePosition(newPositionOverLane, length, getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength());113// set new position114setAttribute(SUMO_ATTR_POSITION, toString(newPositionOverLane), myNet->getViewNet()->getUndoList());115}116117118void119GNEInductionLoopDetector::updateGeometry() {120// update geometry121myAdditionalGeometry.updateGeometry(getParentLanes().front()->getLaneShape(), getGeometryPositionOverLane(), myMoveElementLateralOffset);122// update centering boundary without updating grid123updateCenteringBoundary(false);124}125126127bool128GNEInductionLoopDetector::checkDrawRelatedContour() const {129// get TLS Attributes130const auto& TLSAttributes = myNet->getViewNet()->getViewParent()->getTLSEditorFrame()->getTLSAttributes();131// check detectors132if (myNet->getViewNet()->selectingDetectorsTLSMode() &&133(TLSAttributes->getE1Detectors().count(getParentLanes().front()->getID()) > 0) &&134(TLSAttributes->getE1Detectors().at(getParentLanes().front()->getID()) == getID())) {135return true;136}137// check opened popup138if (myNet->getViewNet()->getPopup()) {139return myNet->getViewNet()->getPopup()->getGLObject() == this;140}141return false;142}143144145void146GNEInductionLoopDetector::drawGL(const GUIVisualizationSettings& s) const {147// first check if additional has to be drawn148if (myNet->getViewNet()->getDataViewOptions().showAdditionals()) {149// Obtain exaggeration of the draw150const double E1Exaggeration = getExaggeration(s);151// get detail level152const auto d = s.getDetailLevel(E1Exaggeration);153// draw geometry only if we'rent in drawForObjectUnderCursor mode154if (s.checkDrawAdditional(d, isAttributeCarrierSelected())) {155// declare colors156RGBColor mainColor, secondColor, textColor;157// set color158if (drawUsingSelectColor()) {159mainColor = s.colorSettings.selectedAdditionalColor;160secondColor = mainColor.changedBrightness(-32);161textColor = mainColor.changedBrightness(32);162} else {163mainColor = s.detectorSettings.E1Color;164secondColor = RGBColor::WHITE;165textColor = RGBColor::BLACK;166}167// draw parent and child lines168drawParentChildLines(s, s.additionalSettings.connectionColor);169// push layer matrix170GLHelper::pushMatrix();171// translate to front172drawInLayer(GLO_E1DETECTOR);173// draw E1 shape174drawE1Shape(d, E1Exaggeration, mainColor, secondColor);175// draw E1 Logo176drawE1DetectorLogo(s, d, E1Exaggeration, "E1", textColor);177// pop layer matrix178GLHelper::popMatrix();179// draw lock icon180GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), myAdditionalGeometry.getShape().getCentroid(), E1Exaggeration);181// Draw additional ID182drawAdditionalID(s);183// draw additional name184drawAdditionalName(s);185// draw dotted contour186myAdditionalContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);187}188// calculate contour rectangle189myAdditionalContour.calculateContourRectangleShape(s, d, this, myAdditionalGeometry.getShape().front(), 2, 1, getType(), 0, 0,190myAdditionalGeometry.getShapeRotations().front(), E1Exaggeration, getParentLanes().front()->getParentEdge());191}192}193194195std::string196GNEInductionLoopDetector::getAttribute(SumoXMLAttr key) const {197return getDetectorAttribute(key);198}199200201double202GNEInductionLoopDetector::getAttributeDouble(SumoXMLAttr key) const {203return getDetectorAttributeDouble(key);204}205206207void208GNEInductionLoopDetector::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {209setDetectorAttribute(key, value, undoList);210}211212213bool214GNEInductionLoopDetector::isValid(SumoXMLAttr key, const std::string& value) {215return isDetectorValid(key, value);216}217218// ===========================================================================219// private220// ===========================================================================221222void223GNEInductionLoopDetector::setAttribute(SumoXMLAttr key, const std::string& value) {224setDetectorAttribute(key, value);225}226227228void229GNEInductionLoopDetector::setMoveShape(const GNEMoveResult& moveResult) {230// change position231myPositionOverLane = moveResult.newFirstPos;232// set lateral offset233myMoveElementLateralOffset = moveResult.firstLaneOffset;234// update geometry235updateGeometry();236}237238239void240GNEInductionLoopDetector::commitMoveShape(const GNEMoveResult& moveResult, GNEUndoList* undoList) {241// reset lateral offset242myMoveElementLateralOffset = 0;243// begin change attribute244undoList->begin(this, "position of " + getTagStr());245// set startPosition246setAttribute(SUMO_ATTR_POSITION, toString(moveResult.newFirstPos), undoList);247// check if lane has to be changed248if (moveResult.newFirstLane) {249// set new lane250setAttribute(SUMO_ATTR_LANE, moveResult.newFirstLane->getID(), undoList);251}252// end change attribute253undoList->end();254}255256/****************************************************************************/257258259