Path: blob/main/src/netedit/elements/additional/GNEBusStop.cpp
193674 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 GNEBusStop.cpp14/// @author Pablo Alvarez Lopez15/// @date Nov 201516///17// A lane area vehicles can halt at (GNE version)18/****************************************************************************/19#include <config.h>2021#include <netedit/changes/GNEChange_Attribute.h>22#include <netedit/GNENet.h>23#include <netedit/GNETagProperties.h>24#include <utils/gui/div/GLHelper.h>25#include <utils/options/OptionsCont.h>2627#include "GNEBusStop.h"2829// ===========================================================================30// method definitions31// ===========================================================================3233GNEBusStop*34GNEBusStop::buildBusStop(GNENet* net) {35return new GNEBusStop(SUMO_TAG_BUS_STOP, net);36}373839GNEBusStop*40GNEBusStop::buildTrainStop(GNENet* net) {41return new GNEBusStop(SUMO_TAG_TRAIN_STOP, net);42}434445GNEBusStop*46GNEBusStop::buildBusStop(const std::string& id, GNENet* net, FileBucket* fileBucket, GNELane* lane,47const double startPos, const double endPos, const std::string& name, const std::vector<std::string>& lines,48const int personCapacity, const double parkingLength, const RGBColor& color, const bool friendlyPosition,49const double angle, const Parameterised::Map& parameters) {50return new GNEBusStop(SUMO_TAG_BUS_STOP, id, net, fileBucket, lane, startPos, endPos, name, lines,51personCapacity, parkingLength, color, friendlyPosition, angle, parameters);52}535455GNEBusStop*56GNEBusStop::buildTrainStop(const std::string& id, GNENet* net, FileBucket* fileBucket, GNELane* lane,57const double startPos, const double endPos, const std::string& name, const std::vector<std::string>& lines,58const int personCapacity, const double parkingLength, const RGBColor& color, const bool friendlyPosition,59const double angle, const Parameterised::Map& parameters) {60return new GNEBusStop(SUMO_TAG_TRAIN_STOP, id, net, fileBucket, lane, startPos, endPos, name, lines,61personCapacity, parkingLength, color, friendlyPosition, angle, parameters);62}636465GNEBusStop::~GNEBusStop() {}666768void69GNEBusStop::writeAdditional(OutputDevice& device) const {70device.openTag(getTagProperty()->getTag());71// write common attributes72writeStoppingPlaceAttributes(device);73// write specific attributes74if (getAttribute(SUMO_ATTR_LINES) != myTagProperty->getDefaultStringValue(SUMO_ATTR_LINES)) {75device.writeAttr(SUMO_ATTR_LINES, toString(myLines));76}77if (myPersonCapacity != myTagProperty->getDefaultIntValue(SUMO_ATTR_PERSON_CAPACITY)) {78device.writeAttr(SUMO_ATTR_PERSON_CAPACITY, myPersonCapacity);79}80if (myParkingLength != myTagProperty->getDefaultDoubleValue(SUMO_ATTR_PARKING_LENGTH)) {81device.writeAttr(SUMO_ATTR_PARKING_LENGTH, myParkingLength);82}83// write all access84for (const auto& access : getChildAdditionals()) {85access->writeAdditional(device);86}87// write parameters (Always after children to avoid problems with additionals.xsd)88writeParams(device);89device.closeTag();90}919293void94GNEBusStop::updateGeometry() {95// Get value of option "lefthand"96double offsetSign = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;97// Update common geometry of stopping place98setStoppingPlaceGeometry(getParentLanes().front()->getParentEdge()->getNBEdge()->getLaneWidth(getParentLanes().front()->getIndex()) * 0.5);99// Obtain a copy of the shape100PositionVector tmpShape = myAdditionalGeometry.getShape();101// Move shape to side102tmpShape.move2side(myNet->getViewNet()->getVisualisationSettings().stoppingPlaceSettings.stoppingPlaceSignOffset * offsetSign);103// Get position of the sign104mySymbolPosition = tmpShape.getLineCenter();105// update demand element children106for (const auto& demandElement : getChildDemandElements()) {107demandElement->updateGeometry();108}109}110111112void113GNEBusStop::drawGL(const GUIVisualizationSettings& s) const {114// check if additional has to be drawn115if (myNet->getViewNet()->getDataViewOptions().showAdditionals()) {116// Obtain exaggeration of the draw117const double busStopExaggeration = getExaggeration(s);118// check if draw moving geometry points119const bool movingGeometryPoints = drawMovingGeometryPoints();120// get width121const double stopWidth = (myTagProperty->getTag() == SUMO_TAG_BUS_STOP) ? s.stoppingPlaceSettings.busStopWidth : s.stoppingPlaceSettings.trainStopWidth;122// get detail level123const auto d = s.getDetailLevel(busStopExaggeration);124// draw geometry only if we'rent in drawForObjectUnderCursor mode125if (s.checkDrawAdditional(d, isAttributeCarrierSelected())) {126// declare colors127RGBColor baseColor, signColor;128// set colors129if (mySpecialColor) {130baseColor = *mySpecialColor;131signColor = baseColor.changedBrightness(-32);132} else if (drawUsingSelectColor()) {133baseColor = s.colorSettings.selectedAdditionalColor;134signColor = baseColor.changedBrightness(-32);135} else if (myColor != RGBColor::INVISIBLE) {136baseColor = myColor;137signColor = s.colorSettings.busStopColorSign;138} else if (myTagProperty->getTag() == SUMO_TAG_TRAIN_STOP) {139baseColor = s.colorSettings.trainStopColor;140signColor = s.colorSettings.trainStopColorSign;141} else {142baseColor = s.colorSettings.busStopColor;143signColor = s.colorSettings.busStopColorSign;144}145// draw parent and child lines146drawParentChildLines(s, baseColor);147// Add layer matrix148GLHelper::pushMatrix();149// translate to front150drawInLayer(GLO_BUS_STOP);151// set base color152GLHelper::setColor(baseColor);153// Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration154GUIGeometry::drawGeometry(d, myAdditionalGeometry, stopWidth * MIN2(1.0, busStopExaggeration));155// draw lines156drawLines(d, myLines, baseColor);157// draw sign158drawSign(s, d, busStopExaggeration, baseColor, signColor, (myTagProperty->getTag() == SUMO_TAG_BUS_STOP) ? "H" : "T");159// draw geometry points160if (movingGeometryPoints && (myStartPosOverLane != INVALID_DOUBLE)) {161drawLeftGeometryPoint(s, d, myAdditionalGeometry.getShape().front(), myAdditionalGeometry.getShapeRotations().front(), baseColor);162}163if (movingGeometryPoints && (myEndPosPosOverLane != INVALID_DOUBLE)) {164drawRightGeometryPoint(s, d, myAdditionalGeometry.getShape().back(), myAdditionalGeometry.getShapeRotations().back(), baseColor);165}166// pop layer matrix167GLHelper::popMatrix();168// draw lock icon169if (myTagProperty->getTag() == SUMO_TAG_BUS_STOP) {170GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), myAdditionalGeometry.getShape().getCentroid(), busStopExaggeration, 0.5);171} else {172GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), myAdditionalGeometry.getShape().getCentroid(), busStopExaggeration, 0.25);173}174// Draw additional ID175drawAdditionalID(s);176// draw additional name177drawAdditionalName(s);178// draw dotted contours179if (movingGeometryPoints) {180myAdditionalContour.drawDottedContourGeometryPoints(s, d, this, myAdditionalGeometry.getShape(), s.neteditSizeSettings.additionalGeometryPointRadius,1811, s.dottedContourSettings.segmentWidthSmall);182} else {183myAdditionalContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);184mySymbolContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidthSmall, true);185}186}187// draw demand element children188drawDemandElementChildren(s);189// calculate contours190calculateStoppingPlaceContour(s, d, stopWidth, busStopExaggeration, movingGeometryPoints);191}192}193194195std::string196GNEBusStop::getAttribute(SumoXMLAttr key) const {197switch (key) {198case SUMO_ATTR_LINES:199return joinToString(myLines, " ");200case SUMO_ATTR_PERSON_CAPACITY:201return toString(myPersonCapacity);202case SUMO_ATTR_PARKING_LENGTH:203return toString(myParkingLength);204default:205return getStoppingPlaceAttribute(key);206}207}208209210double211GNEBusStop::getAttributeDouble(SumoXMLAttr key) const {212return getStoppingPlaceAttributeDouble(key);213}214215216void217GNEBusStop::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {218switch (key) {219case SUMO_ATTR_LINES:220case SUMO_ATTR_PERSON_CAPACITY:221case SUMO_ATTR_PARKING_LENGTH:222GNEChange_Attribute::changeAttribute(this, key, value, undoList);223break;224default:225setStoppingPlaceAttribute(key, value, undoList);226break;227}228}229230231bool232GNEBusStop::isValid(SumoXMLAttr key, const std::string& value) {233switch (key) {234case SUMO_ATTR_LINES:235return true;236case SUMO_ATTR_PERSON_CAPACITY:237return canParse<int>(value) && (parse<int>(value) > 0 || parse<int>(value) == -1);238case SUMO_ATTR_PARKING_LENGTH:239return canParse<double>(value) && (parse<double>(value) >= 0);240default:241return isStoppingPlaceValid(key, value);242}243}244245// ===========================================================================246// private247// ===========================================================================248249void250GNEBusStop::setAttribute(SumoXMLAttr key, const std::string& value) {251switch (key) {252case SUMO_ATTR_LINES:253myLines = GNEAttributeCarrier::parse<std::vector<std::string> >(value);254break;255case SUMO_ATTR_PERSON_CAPACITY:256myPersonCapacity = GNEAttributeCarrier::parse<int>(value);257break;258case SUMO_ATTR_PARKING_LENGTH:259myParkingLength = GNEAttributeCarrier::parse<double>(value);260break;261default:262setStoppingPlaceAttribute(key, value);263break;264}265}266267268GNEBusStop::GNEBusStop(SumoXMLTag tag, GNENet* net) :269GNEStoppingPlace(net, tag) {270}271272273GNEBusStop::GNEBusStop(SumoXMLTag tag, const std::string& id, GNENet* net, FileBucket* fileBucket,274GNELane* lane, const double startPos, const double endPos, const std::string& name,275const std::vector<std::string>& lines, const int personCapacity, const double parkingLength,276const RGBColor& color, const bool friendlyPosition, const double angle,277const Parameterised::Map& parameters) :278GNEStoppingPlace(id, net, fileBucket, tag, lane, startPos, endPos, name, friendlyPosition, color, angle, parameters),279myLines(lines),280myPersonCapacity(personCapacity),281myParkingLength(parkingLength) {282}283284/****************************************************************************/285286287