Path: blob/main/src/netedit/elements/additional/GNEInstantInductionLoopDetector.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 GNEInstantInductionLoopDetector.cpp14/// @author Pablo Alvarez Lopez15/// @date Jun 201816///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>3031#include "GNEInstantInductionLoopDetector.h"32#include "GNEAdditionalHandler.h"3334// ===========================================================================35// member method definitions36// ===========================================================================3738GNEInstantInductionLoopDetector::GNEInstantInductionLoopDetector(GNENet* net) :39GNEDetector(net, SUMO_TAG_INSTANT_INDUCTION_LOOP) {40}414243GNEInstantInductionLoopDetector::GNEInstantInductionLoopDetector(const std::string& id, GNENet* net, const std::string& filename, GNELane* lane,44const double pos, const std::string& outputFilename, const std::vector<std::string>& vehicleTypes, const std::vector<std::string>& nextEdges,45const std::string& detectPersons, const std::string& name, const bool friendlyPos, const Parameterised::Map& parameters) :46GNEDetector(id, net, filename, SUMO_TAG_INSTANT_INDUCTION_LOOP, pos, 0, lane, outputFilename,47vehicleTypes, nextEdges, detectPersons, name, friendlyPos, parameters) {48// update centering boundary without updating grid49updateCenteringBoundary(false);50}515253GNEInstantInductionLoopDetector::~GNEInstantInductionLoopDetector() {54}555657void58GNEInstantInductionLoopDetector::writeAdditional(OutputDevice& device) const {59device.openTag(getTagProperty()->getTag());60device.writeAttr(SUMO_ATTR_ID, getID());61device.writeAttr(SUMO_ATTR_LANE, getParentLanes().front()->getID());62device.writeAttr(SUMO_ATTR_POSITION, myPositionOverLane);63// write common detector parameters64writeDetectorValues(device);65// write parameters (Always after children to avoid problems with additionals.xsd)66writeParams(device);67device.closeTag();68}697071bool72GNEInstantInductionLoopDetector::isAdditionalValid() const {73// with friendly position enabled position are "always fixed"74if (myFriendlyPosition) {75return true;76} else {77return fabs(myPositionOverLane) <= getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();78}79}808182std::string83GNEInstantInductionLoopDetector::getAdditionalProblem() const {84// obtain final length85const double len = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();86// check if detector has a problem87if (GNEAdditionalHandler::checkLanePosition(myPositionOverLane, 0, len, myFriendlyPosition)) {88return "";89} else {90// declare variable for error position91std::string errorPosition;92// check positions over lane93if (myPositionOverLane < 0) {94errorPosition = (toString(SUMO_ATTR_POSITION) + " < 0");95}96if (myPositionOverLane > len) {97errorPosition = (toString(SUMO_ATTR_POSITION) + TL(" > lanes's length"));98}99return errorPosition;100}101}102103104void105GNEInstantInductionLoopDetector::fixAdditionalProblem() {106// declare new position107double newPositionOverLane = myPositionOverLane;108// fix pos and length checkAndFixDetectorPosition109double length = 0;110GNEAdditionalHandler::fixLanePosition(newPositionOverLane, length, getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength());111// set new position112setAttribute(SUMO_ATTR_POSITION, toString(newPositionOverLane), myNet->getViewNet()->getUndoList());113}114115116void117GNEInstantInductionLoopDetector::updateGeometry() {118// update geometry119myAdditionalGeometry.updateGeometry(getParentLanes().front()->getLaneShape(), getGeometryPositionOverLane(), myMoveElementLateralOffset);120// update centering boundary without updating grid121updateCenteringBoundary(false);122}123124125void126GNEInstantInductionLoopDetector::drawGL(const GUIVisualizationSettings& s) const {127// check if additional has to be drawn128if (myNet->getViewNet()->getDataViewOptions().showAdditionals() &&129!myNet->getViewNet()->selectingDetectorsTLSMode()) {130// Obtain exaggeration of the draw131const double E1InstantExaggeration = getExaggeration(s);132// get detail level133const auto d = s.getDetailLevel(E1InstantExaggeration);134// draw geometry only if we'rent in drawForObjectUnderCursor mode135if (s.checkDrawAdditional(d, isAttributeCarrierSelected())) {136// declare colors137RGBColor mainColor, secondColor, textColor;138// set color139if (drawUsingSelectColor()) {140mainColor = s.colorSettings.selectedAdditionalColor;141secondColor = mainColor.changedBrightness(-32);142textColor = mainColor.changedBrightness(32);143} else {144mainColor = s.detectorSettings.E1InstantColor;145secondColor = RGBColor::WHITE;146textColor = RGBColor::BLACK;147}148// draw parent and child lines149drawParentChildLines(s, s.additionalSettings.connectionColor);150// push layer matrix151GLHelper::pushMatrix();152// translate to front153drawInLayer(GLO_E1DETECTOR_INSTANT);154// draw E1Instant shape155drawE1Shape(d, E1InstantExaggeration, mainColor, secondColor);156// draw E1 Logo157drawE1DetectorLogo(s, d, E1InstantExaggeration, "E1", textColor);158// pop layer matrix159GLHelper::popMatrix();160// draw lock icon161GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), myAdditionalGeometry.getShape().getCentroid(),162E1InstantExaggeration);163// Draw additional ID164drawAdditionalID(s);165// draw additional name166drawAdditionalName(s);167// draw dotted contour168myAdditionalContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);169}170// draw dotted contour171myAdditionalContour.calculateContourRectangleShape(s, d, this, myAdditionalGeometry.getShape().front(), 2, 1, getType(), 0, 0,172myAdditionalGeometry.getShapeRotations().front(), E1InstantExaggeration, getParentLanes().front()->getParentEdge());173}174}175176177std::string178GNEInstantInductionLoopDetector::getAttribute(SumoXMLAttr key) const {179return getDetectorAttribute(key);180}181182183double184GNEInstantInductionLoopDetector::getAttributeDouble(SumoXMLAttr key) const {185return getDetectorAttributeDouble(key);186}187188189void190GNEInstantInductionLoopDetector::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {191setDetectorAttribute(key, value, undoList);192}193194195bool196GNEInstantInductionLoopDetector::isValid(SumoXMLAttr key, const std::string& value) {197return isDetectorValid(key, value);198}199200// ===========================================================================201// private202// ===========================================================================203204void205GNEInstantInductionLoopDetector::setAttribute(SumoXMLAttr key, const std::string& value) {206setDetectorAttribute(key, value);207}208209210void211GNEInstantInductionLoopDetector::setMoveShape(const GNEMoveResult& moveResult) {212// change position213myPositionOverLane = moveResult.newFirstPos;214// set lateral offset215myMoveElementLateralOffset = moveResult.firstLaneOffset;216// update geometry217updateGeometry();218}219220221void222GNEInstantInductionLoopDetector::commitMoveShape(const GNEMoveResult& moveResult, GNEUndoList* undoList) {223// reset lateral offset224myMoveElementLateralOffset = 0;225// begin change attribute226undoList->begin(this, "position of " + getTagStr());227// set startPosition228setAttribute(SUMO_ATTR_POSITION, toString(moveResult.newFirstPos), undoList);229// check if lane has to be changed230if (moveResult.newFirstLane) {231// set new lane232setAttribute(SUMO_ATTR_LANE, moveResult.newFirstLane->getID(), undoList);233}234// end change attribute235undoList->end();236}237238/****************************************************************************/239240241