Path: blob/main/src/netedit/elements/additional/GNEChargingStation.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 GNEChargingStation.cpp14/// @author Pablo Alvarez Lopez15/// @date Nov 201516///17// A class for visualizing chargingStation geometry (adapted from GUILaneWrapper)18/****************************************************************************/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/options/OptionsCont.h>2526#include "GNEChargingStation.h"2728// ===========================================================================29// member method definitions30// ===========================================================================3132GNEChargingStation::GNEChargingStation(GNENet* net) :33GNEStoppingPlace(net, SUMO_TAG_CHARGING_STATION) {34}353637GNEChargingStation::GNEChargingStation(const std::string& id, GNENet* net, const std::string& filename, GNELane* lane,38const double startPos, const double endPos, const std::string& name, const double chargingPower,39const double efficiency, const bool chargeInTransit, const SUMOTime chargeDelay,40const std::string& chargeType, const SUMOTime waitingTime, const std::string& parkingAreaID,41const bool friendlyPosition, const Parameterised::Map& parameters) :42GNEStoppingPlace(id, net, filename, SUMO_TAG_CHARGING_STATION, lane, startPos, endPos, name, friendlyPosition, RGBColor::INVISIBLE, 0, parameters),43myChargingPower(chargingPower),44myEfficiency(efficiency),45myChargeInTransit(chargeInTransit),46myChargeDelay(chargeDelay),47myChargeType(chargeType),48myWaitingTime(waitingTime),49myParkingAreaID(parkingAreaID) {50// update centering boundary without updating grid51updateCenteringBoundary(false);52}535455GNEChargingStation::~GNEChargingStation() {}565758void59GNEChargingStation::writeAdditional(OutputDevice& device) const {60device.openTag(getTagProperty()->getTag());61// write common attributes62writeStoppingPlaceAttributes(device);63// write specific attributes64if (myChargingPower != myTagProperty->getDefaultDoubleValue(SUMO_ATTR_CHARGINGPOWER)) {65device.writeAttr(SUMO_ATTR_CHARGINGPOWER, toString(myChargingPower));66}67if (myEfficiency != myTagProperty->getDefaultDoubleValue(SUMO_ATTR_EFFICIENCY)) {68device.writeAttr(SUMO_ATTR_EFFICIENCY, myEfficiency);69}70if (myChargeInTransit != myTagProperty->getDefaultBoolValue(SUMO_ATTR_CHARGEINTRANSIT)) {71device.writeAttr(SUMO_ATTR_CHARGEINTRANSIT, myChargeInTransit);72}73if (myChargeDelay != myTagProperty->getDefaultTimeValue(SUMO_ATTR_CHARGEDELAY)) {74device.writeAttr(SUMO_ATTR_CHARGEDELAY, time2string(myChargeDelay));75}76if (myChargeType != myTagProperty->getDefaultStringValue(SUMO_ATTR_CHARGETYPE)) {77device.writeAttr(SUMO_ATTR_CHARGETYPE, myChargeType);78}79if (myWaitingTime != myTagProperty->getDefaultTimeValue(SUMO_ATTR_WAITINGTIME)) {80device.writeAttr(SUMO_ATTR_WAITINGTIME, time2string(myWaitingTime));81}82if (myParkingAreaID != myTagProperty->getDefaultStringValue(SUMO_ATTR_PARKING_AREA)) {83device.writeAttr(SUMO_ATTR_PARKING_AREA, myParkingAreaID);84}85// write parameters (Always after children to avoid problems with additionals.xsd)86writeParams(device);87device.closeTag();88}899091void92GNEChargingStation::updateGeometry() {93// Get value of option "lefthand"94const double offsetSign = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;9596// Update common geometry of stopping place97setStoppingPlaceGeometry(0);9899// Obtain a copy of the shape100PositionVector tmpShape = myAdditionalGeometry.getShape();101102// Move shape to side103tmpShape.move2side(myNet->getViewNet()->getVisualisationSettings().stoppingPlaceSettings.stoppingPlaceSignOffset * offsetSign);104105// Get position of the sign106mySymbolPosition = tmpShape.getLineCenter();107}108109110void111GNEChargingStation::drawGL(const GUIVisualizationSettings& s) const {112// first check if additional has to be drawn113if (myNet->getViewNet()->getDataViewOptions().showAdditionals()) {114// Obtain exaggeration of the draw115const double chargingStationExaggeration = getExaggeration(s);116// check if draw moving geometry points117const bool movingGeometryPoints = drawMovingGeometryPoints(false);118// get detail level119const auto d = s.getDetailLevel(chargingStationExaggeration);120// draw geometry only if we'rent in drawForObjectUnderCursor mode121if (s.checkDrawAdditional(d, isAttributeCarrierSelected())) {122// declare colors123RGBColor baseColor, signColor;124// set colors125if (mySpecialColor) {126baseColor = *mySpecialColor;127signColor = baseColor.changedBrightness(-32);128} else if (drawUsingSelectColor()) {129baseColor = s.colorSettings.selectedAdditionalColor;130signColor = baseColor.changedBrightness(-32);131} else {132baseColor = s.colorSettings.chargingStationColor;133signColor = s.colorSettings.chargingStationColorSign;134}135// draw parent and child lines136drawParentChildLines(s, s.additionalSettings.connectionColor);137// Add a layer matrix138GLHelper::pushMatrix();139// translate to front140drawInLayer(GLO_CHARGING_STATION);141// set base color142GLHelper::setColor(baseColor);143// Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration144GUIGeometry::drawGeometry(d, myAdditionalGeometry, s.stoppingPlaceSettings.chargingStationWidth * MIN2(1.0, chargingStationExaggeration));145// draw charging power and efficiency146drawLines(d, {toString(myChargingPower)}, baseColor);147// draw sign148drawSign(s, d, chargingStationExaggeration, baseColor, signColor, "C");149// draw geometry points150if (movingGeometryPoints && (myStartPosition != INVALID_DOUBLE)) {151drawLeftGeometryPoint(s, d, myAdditionalGeometry.getShape().front(), myAdditionalGeometry.getShapeRotations().front(), baseColor);152}153if (movingGeometryPoints && (myEndPosition != INVALID_DOUBLE)) {154drawRightGeometryPoint(s, d, myAdditionalGeometry.getShape().back(), myAdditionalGeometry.getShapeRotations().back(), baseColor);155}156// pop layer matrix157GLHelper::popMatrix();158// draw lock icon159GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), myAdditionalGeometry.getShape().getCentroid(), chargingStationExaggeration);160// Draw additional ID161drawAdditionalID(s);162// draw additional name163drawAdditionalName(s);164// draw dotted contours165if (movingGeometryPoints) {166myAdditionalContour.drawDottedContourGeometryPoints(s, d, this, myAdditionalGeometry.getShape(), s.neteditSizeSettings.additionalGeometryPointRadius,1671, s.dottedContourSettings.segmentWidthSmall);168} else {169myAdditionalContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);170mySymbolContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidthSmall, true);171}172}173// draw demand element children174drawDemandElementChildren(s);175// calculate contours176calculateStoppingPlaceContour(s, d, s.stoppingPlaceSettings.chargingStationWidth, chargingStationExaggeration, movingGeometryPoints);177}178}179180181std::string182GNEChargingStation::getAttribute(SumoXMLAttr key) const {183switch (key) {184case SUMO_ATTR_CHARGINGPOWER:185return toString(myChargingPower);186case SUMO_ATTR_EFFICIENCY:187return toString(myEfficiency);188case SUMO_ATTR_CHARGEINTRANSIT:189return toString(myChargeInTransit);190case SUMO_ATTR_CHARGEDELAY:191return time2string(myChargeDelay);192case SUMO_ATTR_CHARGETYPE:193return myChargeType;194case SUMO_ATTR_WAITINGTIME:195return time2string(myWaitingTime);196case SUMO_ATTR_PARKING_AREA:197return myParkingAreaID;198default:199return getStoppingPlaceAttribute(this, key);200}201}202203204double205GNEChargingStation::getAttributeDouble(SumoXMLAttr key) const {206switch (key) {207case SUMO_ATTR_CHARGINGPOWER:208return myChargingPower;209case SUMO_ATTR_EFFICIENCY:210return myEfficiency;211default:212return getStoppingPlaceAttributeDouble(key);213}214}215216217void218GNEChargingStation::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {219switch (key) {220case SUMO_ATTR_CHARGINGPOWER:221case SUMO_ATTR_EFFICIENCY:222case SUMO_ATTR_CHARGEINTRANSIT:223case SUMO_ATTR_CHARGEDELAY:224case SUMO_ATTR_CHARGETYPE:225case SUMO_ATTR_WAITINGTIME:226case SUMO_ATTR_PARKING_AREA:227GNEChange_Attribute::changeAttribute(this, key, value, undoList);228break;229default:230setStoppingPlaceAttribute(key, value, undoList);231break;232}233}234235236bool237GNEChargingStation::isValid(SumoXMLAttr key, const std::string& value) {238switch (key) {239case SUMO_ATTR_CHARGINGPOWER:240return (canParse<double>(value) && parse<double>(value) >= 0);241case SUMO_ATTR_EFFICIENCY:242if (canParse<double>(value)) {243const double efficiency = parse<double>(value);244return (efficiency >= 0) && (efficiency <= 1);245} else {246return false;247}248case SUMO_ATTR_CHARGEINTRANSIT:249return canParse<bool>(value);250case SUMO_ATTR_CHARGEDELAY:251return canParse<SUMOTime>(value) && parse<SUMOTime>(value) >= 0;252case SUMO_ATTR_CHARGETYPE: {253return SUMOXMLDefinitions::ChargeTypes.hasString(value);254}255case SUMO_ATTR_WAITINGTIME:256return canParse<SUMOTime>(value) && parse<SUMOTime>(value) >= 0;257case SUMO_ATTR_PARKING_AREA:258return isValidAdditionalID(value);259default:260return isStoppingPlaceValid(key, value);261}262}263264// ===========================================================================265// private266// ===========================================================================267268void269GNEChargingStation::setAttribute(SumoXMLAttr key, const std::string& value) {270switch (key) {271case SUMO_ATTR_CHARGINGPOWER:272myChargingPower = parse<double>(value);273break;274case SUMO_ATTR_EFFICIENCY:275myEfficiency = parse<double>(value);276break;277case SUMO_ATTR_CHARGEINTRANSIT:278myChargeInTransit = parse<bool>(value);279break;280case SUMO_ATTR_CHARGEDELAY:281myChargeDelay = parse<SUMOTime>(value);282break;283case SUMO_ATTR_CHARGETYPE:284myChargeType = value;285break;286case SUMO_ATTR_WAITINGTIME:287myWaitingTime = parse<SUMOTime>(value);288break;289case SUMO_ATTR_PARKING_AREA:290myParkingAreaID = value;291break;292default:293setStoppingPlaceAttribute(this, key, value);294break;295}296}297298299/****************************************************************************/300301302