Path: blob/main/src/netedit/frames/demand/GNEVehicleFrame.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 GNEVehicleFrame.cpp14/// @author Pablo Alvarez Lopez15/// @date Jan 201816///17// The Widget for add Vehicles/Flows/Trips/etc. elements18/****************************************************************************/1920#include <netedit/GNEApplicationWindow.h>21#include <netedit/GNENet.h>22#include <netedit/GNEViewParent.h>23#include <netedit/elements/additional/GNETAZ.h>24#include <netedit/elements/demand/GNERouteHandler.h>25#include <netedit/frames/GNEAttributesEditor.h>26#include <netedit/frames/GNEDemandSelector.h>27#include <netedit/frames/GNEPathCreator.h>28#include <netedit/frames/GNEPathLegendModule.h>29#include <netedit/frames/GNETagSelector.h>30#include <utils/foxtools/MFXDynamicLabel.h>31#include <utils/gui/div/GUIDesigns.h>32#include <utils/vehicle/SUMOVehicleParserHelper.h>33#include <utils/xml/SUMOSAXAttributesImpl_Cached.h>3435#include "GNEVehicleFrame.h"3637// ===========================================================================38// method definitions39// ===========================================================================4041// ---------------------------------------------------------------------------42// GNEVehicleFrame::HelpCreation - methods43// ---------------------------------------------------------------------------4445GNEVehicleFrame::HelpCreation::HelpCreation(GNEVehicleFrame* vehicleFrameParent) :46MFXGroupBoxModule(vehicleFrameParent, TL("Help")),47myVehicleFrameParent(vehicleFrameParent) {48myInformationLabel = new MFXDynamicLabel(getCollapsableFrame(), "", 0, GUIDesignLabelFrameInformation);49}505152GNEVehicleFrame::HelpCreation::~HelpCreation() {}535455void56GNEVehicleFrame::HelpCreation::showHelpCreation() {57// first update help cration58updateHelpCreation();59// show modul60show();61}626364void65GNEVehicleFrame::HelpCreation::hideHelpCreation() {66hide();67}6869void70GNEVehicleFrame::HelpCreation::updateHelpCreation() {71// create information label72std::ostringstream information;73// set text depending of selected vehicle type74switch (myVehicleFrameParent->myVehicleTagSelector->getCurrentTemplateAC()->getTagProperty()->getTag()) {75// vehicles76case SUMO_TAG_VEHICLE:77information78<< "- " << TL("Click over a route to create a vehicle.");79break;80case SUMO_TAG_TRIP:81information82<< "- " << TL("Select two edges to create a trip.");83break;84case GNE_TAG_VEHICLE_WITHROUTE:85information86<< "- " << TL("Select two edges to create a vehicle with embedded route.");87break;88case GNE_TAG_TRIP_JUNCTIONS:89information90<< "- " << TL("Select two junctions to create a trip.");91break;92case GNE_TAG_TRIP_TAZS:93information94<< "- " << TL("Select two TAZS to create a trip.");95break;96// flows97case GNE_TAG_FLOW_ROUTE:98information99<< "- " << TL("Click over a route to create a routeFlow.");100break;101case SUMO_TAG_FLOW:102information103<< "- " << TL("Select two edges to create a flow.");104break;105case GNE_TAG_FLOW_WITHROUTE:106information107<< "- " << TL("Select two edges to create a flow with embedded route.");108break;109case GNE_TAG_FLOW_JUNCTIONS:110information111<< "- " << TL("Select two junctions to create a flow.");112break;113case GNE_TAG_FLOW_TAZS:114information115<< "- " << TL("Select two TAZs to create a flow.");116break;117default:118break;119}120// set information label121myInformationLabel->setText(information.str().c_str());122}123124// ---------------------------------------------------------------------------125// GNEVehicleFrame - methods126// ---------------------------------------------------------------------------127128GNEVehicleFrame::GNEVehicleFrame(GNEViewParent* viewParent, GNEViewNet* viewNet) :129GNEFrame(viewParent, viewNet, TL("Vehicles")),130myVehicleBaseObject(new CommonXMLStructure::SumoBaseObject(nullptr)) {131132// Create item Selector module for vehicles133myVehicleTagSelector = new GNETagSelector(this, GNETagProperties::Type::VEHICLE, SUMO_TAG_TRIP);134135// Create vehicle type selector and set DEFAULT_VTYPE_ID as default element136myTypeSelector = new GNEDemandElementSelector(this, SUMO_TAG_VTYPE, GNETagProperties::Type::VEHICLE);137138// Create attributes editor139myVehicleAttributesEditor = new GNEAttributesEditor(this, GNEAttributesEditorType::EditorType::CREATOR);140141// create GNEPathCreator Module142myPathCreator = new GNEPathCreator(this, viewNet->getNet()->getDemandPathManager());143144// Create Help Creation Module145myHelpCreation = new HelpCreation(this);146147// create legend label148myPathLegend = new GNEPathLegendModule(this);149}150151152GNEVehicleFrame::~GNEVehicleFrame() {153delete myVehicleBaseObject;154}155156157void158GNEVehicleFrame::show() {159// refresh tag selector160myVehicleTagSelector->refreshTagSelector();161// show frame162GNEFrame::show();163}164165166void167GNEVehicleFrame::hide() {168// reset edge candidates169for (const auto& edge : myViewNet->getNet()->getAttributeCarriers()->getEdges()) {170edge.second->resetCandidateFlags();171}172// reset junctioncandidates173for (const auto& junction : myViewNet->getNet()->getAttributeCarriers()->getJunctions()) {174junction.second->resetCandidateFlags();175}176// hide frame177GNEFrame::hide();178}179180181bool182GNEVehicleFrame::addVehicle(const GNEViewNetHelper::ViewObjectsSelector& viewObjects, const GNEViewNetHelper::MouseButtonKeyPressed& mouseButtonKeyPressed) {183// check template AC184if (myVehicleTagSelector->getCurrentTemplateAC() == nullptr) {185return false;186}187// begin cleaning vehicle base object188myVehicleBaseObject->clear();189// obtain tag (only for improve code legibility)190SumoXMLTag vehicleTag = myVehicleTagSelector->getCurrentTemplateAC()->getTagProperty()->getTag();191const bool addEdge = ((vehicleTag == SUMO_TAG_TRIP) || (vehicleTag == GNE_TAG_VEHICLE_WITHROUTE) || (vehicleTag == SUMO_TAG_FLOW) || (vehicleTag == GNE_TAG_FLOW_WITHROUTE));192const bool addJunction = ((vehicleTag == GNE_TAG_TRIP_JUNCTIONS) || (vehicleTag == GNE_TAG_FLOW_JUNCTIONS));193const bool addTAZ = ((vehicleTag == GNE_TAG_TRIP_TAZS) || (vehicleTag == GNE_TAG_FLOW_TAZS));194// first check that current selected vehicle is valid195if (vehicleTag == SUMO_TAG_NOTHING) {196myViewNet->setStatusBarText(TL("Current selected vehicle isn't valid."));197return false;198}199// now check if VType is valid200if (myTypeSelector->getCurrentDemandElement() == nullptr) {201myViewNet->setStatusBarText(TL("Current selected vehicle type isn't valid."));202return false;203}204// add VType205myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TYPE, myTypeSelector->getCurrentDemandElement()->getID());206// set route or edges depending of vehicle type207if (myVehicleTagSelector->getCurrentTemplateAC()->getTagProperty()->vehicleRoute()) {208return buildVehicleOverRoute(vehicleTag, viewObjects.getDemandElementFront());209} else if (addEdge && viewObjects.getEdgeFront()) {210// add clicked edge in GNEPathCreator211return myPathCreator->addEdge(viewObjects.getEdgeFront(), mouseButtonKeyPressed.shiftKeyPressed(), mouseButtonKeyPressed.controlKeyPressed());212} else if (addJunction && viewObjects.getJunctionFront()) {213// add clicked junction in GNEPathCreator214return myPathCreator->addJunction(viewObjects.getJunctionFront());215} else if (addTAZ && viewObjects.getTAZFront()) {216// add clicked TAZ in GNEPathCreator217return myPathCreator->addTAZ(viewObjects.getTAZFront());218} else {219return false;220}221}222223224GNETagSelector*225GNEVehicleFrame::getVehicleTagSelector() const {226return myVehicleTagSelector;227}228229230GNEDemandElementSelector*231GNEVehicleFrame::getTypeSelector() const {232return myTypeSelector;233}234235236GNEPathCreator*237GNEVehicleFrame::getPathCreator() const {238return myPathCreator;239}240241242GNEAttributesEditor*243GNEVehicleFrame::getVehicleAttributesEditor() const {244return myVehicleAttributesEditor;245}246247// ===========================================================================248// protected249// ===========================================================================250251void252GNEVehicleFrame::tagSelected() {253if (myVehicleTagSelector->getCurrentTemplateAC()) {254// show vehicle type selector modul255myTypeSelector->showDemandElementSelector();256// show path creator modul257myPathCreator->showPathCreatorModule(myVehicleTagSelector->getCurrentTemplateAC()->getTagProperty(), false);258// check if show path legend259if (myVehicleTagSelector->getCurrentTemplateAC()->getTagProperty()->vehicleRouteEmbedded()) {260myPathLegend->hidePathLegendModule();261} else {262myPathLegend->showPathLegendModule();263}264} else {265// hide all moduls if tag isn't valid266myTypeSelector->hideDemandElementSelector();267myVehicleAttributesEditor->hideAttributesEditor();268myPathCreator->hidePathCreatorModule();269myHelpCreation->hideHelpCreation();270myPathLegend->hidePathLegendModule();271}272}273274275void276GNEVehicleFrame::demandElementSelected() {277if (myTypeSelector->getCurrentDemandElement()) {278// show vehicle attributes modul279myVehicleAttributesEditor->showAttributesEditor(myVehicleTagSelector->getCurrentTemplateAC(), true);280// clear colors281myPathCreator->clearJunctionColors();282myPathCreator->clearEdgeColors();283// set current VTypeClass in pathCreator284myPathCreator->setVClass(myTypeSelector->getCurrentDemandElement()->getVClass());285// show path creator module286myPathCreator->showPathCreatorModule(myVehicleTagSelector->getCurrentTemplateAC()->getTagProperty(), false);287// show help creation288myHelpCreation->showHelpCreation();289} else {290// hide all moduls if selected item isn't valid291myVehicleAttributesEditor->hideAttributesEditor();292myPathCreator->hidePathCreatorModule();293myPathLegend->hidePathLegendModule();294myHelpCreation->hideHelpCreation();295}296}297298299bool300GNEVehicleFrame::createPath(const bool useLastRoute) {301// first check if parameters are valid302if (myVehicleAttributesEditor->checkAttributes(true) && myTypeSelector->getCurrentDemandElement()) {303// obtain tag (only for improve code legibility)304SumoXMLTag vehicleTag = myVehicleTagSelector->getCurrentTemplateAC()->getTagProperty()->getTag();305// begin cleaning vehicle base object306myVehicleBaseObject->clear();307// Updated myVehicleBaseObject308myVehicleAttributesEditor->fillSumoBaseObject(myVehicleBaseObject);309// add VType310myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TYPE, myTypeSelector->getCurrentDemandElement()->getID());311// declare route handler312GNERouteHandler routeHandler(myViewNet->getNet(), myVehicleBaseObject->hasStringAttribute(GNE_ATTR_DEMAND_FILE) ?313myVehicleBaseObject->getStringAttribute(GNE_ATTR_DEMAND_FILE) : "",314myViewNet->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed());315// check if use last route316if (useLastRoute) {317// build vehicle using last route318return buildVehicleOverRoute(vehicleTag, myViewNet->getLastCreatedRoute());319} else {320// extract via attribute321std::vector<std::string> viaEdges;322for (int i = 1; i < ((int)myPathCreator->getSelectedEdges().size() - 1); i++) {323viaEdges.push_back(myPathCreator->getSelectedEdges().at(i)->getID());324}325// continue depending of tag326if ((vehicleTag == SUMO_TAG_TRIP) && (myPathCreator->getSelectedEdges().size() > 0)) {327// set tag328myVehicleBaseObject->setTag(SUMO_TAG_TRIP);329// Add parameter departure330if (!myVehicleBaseObject->hasStringAttribute(SUMO_ATTR_DEPART) || myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPART).empty()) {331myVehicleBaseObject->addStringAttribute(SUMO_ATTR_DEPART, "0");332}333// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes334SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));335// obtain trip parameters336SUMOVehicleParameter* tripParameters = SUMOVehicleParserHelper::parseVehicleAttributes(vehicleTag, SUMOSAXAttrs, false);337tripParameters->setParameters(myVehicleBaseObject->getParameters());338// check trip parameters339if (tripParameters) {340myVehicleBaseObject->setVehicleParameter(tripParameters);341myVehicleBaseObject->addStringAttribute(SUMO_ATTR_FROM, myPathCreator->getSelectedEdges().front()->getID());342myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TO, myPathCreator->getSelectedEdges().back()->getID());343myVehicleBaseObject->addStringListAttribute(SUMO_ATTR_VIA, viaEdges);344// parse vehicle345routeHandler.parseSumoBaseObject(myVehicleBaseObject);346// delete tripParameters and base object347delete tripParameters;348}349} else if ((vehicleTag == GNE_TAG_VEHICLE_WITHROUTE) && (myPathCreator->getPath().size() > 0)) {350// set tag351myVehicleBaseObject->setTag(SUMO_TAG_VEHICLE);352// Add parameter departure353if (!myVehicleBaseObject->hasStringAttribute(SUMO_ATTR_DEPART) || myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPART).empty()) {354myVehicleBaseObject->addStringAttribute(SUMO_ATTR_DEPART, "0");355}356// get route edges357std::vector<std::string> routeEdges;358for (const auto& subPath : myPathCreator->getPath()) {359for (const auto& edge : subPath.getSubPath()) {360routeEdges.push_back(edge->getID());361}362}363// avoid consecutive duplicated edges364routeEdges.erase(std::unique(routeEdges.begin(), routeEdges.end()), routeEdges.end());365// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes366SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));367// obtain vehicle parameters368SUMOVehicleParameter* vehicleParameters = SUMOVehicleParserHelper::parseVehicleAttributes(vehicleTag, SUMOSAXAttrs, false);369vehicleParameters->setParameters(myVehicleBaseObject->getParameters());370// continue depending of vehicleParameters371if (vehicleParameters) {372myVehicleBaseObject->setVehicleParameter(vehicleParameters);373// create route base object374CommonXMLStructure::SumoBaseObject* embeddedRouteObject = new CommonXMLStructure::SumoBaseObject(myVehicleBaseObject);375embeddedRouteObject->setTag(SUMO_TAG_ROUTE);376embeddedRouteObject->addStringListAttribute(SUMO_ATTR_EDGES, routeEdges);377embeddedRouteObject->addColorAttribute(SUMO_ATTR_COLOR, RGBColor::INVISIBLE);378embeddedRouteObject->addIntAttribute(SUMO_ATTR_REPEAT, 0);379embeddedRouteObject->addTimeAttribute(SUMO_ATTR_CYCLETIME, 0);380embeddedRouteObject->addDoubleAttribute(SUMO_ATTR_PROB, 1.0);381// parse route382routeHandler.parseSumoBaseObject(myVehicleBaseObject);383// delete vehicleParamters384delete vehicleParameters;385}386} else if ((vehicleTag == SUMO_TAG_FLOW) && (myPathCreator->getSelectedEdges().size() > 0)) {387// set tag388myVehicleBaseObject->setTag(SUMO_TAG_FLOW);389// set flow attributes390updateFlowAttributes();391// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes392SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));393// obtain flow parameters394SUMOVehicleParameter* flowParameters = SUMOVehicleParserHelper::parseFlowAttributes(vehicleTag, SUMOSAXAttrs, false, true, 0, SUMOTime_MAX);395flowParameters->setParameters(myVehicleBaseObject->getParameters());396// check flowParameters397if (flowParameters) {398myVehicleBaseObject->setVehicleParameter(flowParameters);399myVehicleBaseObject->addStringAttribute(SUMO_ATTR_FROM, myPathCreator->getSelectedEdges().front()->getID());400myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TO, myPathCreator->getSelectedEdges().back()->getID());401myVehicleBaseObject->addStringListAttribute(SUMO_ATTR_VIA, viaEdges);402// parse vehicle403routeHandler.parseSumoBaseObject(myVehicleBaseObject);404// delete flowParameters and base object405delete flowParameters;406}407} else if ((vehicleTag == GNE_TAG_FLOW_WITHROUTE) && (myPathCreator->getPath().size() > 0)) {408// set tag409myVehicleBaseObject->setTag(SUMO_TAG_FLOW);410// set flow attributes411updateFlowAttributes();412// get route edges413std::vector<std::string> routeEdges;414for (const auto& subPath : myPathCreator->getPath()) {415for (const auto& edge : subPath.getSubPath()) {416routeEdges.push_back(edge->getID());417}418}419// avoid consecutive duplicated edges420routeEdges.erase(std::unique(routeEdges.begin(), routeEdges.end()), routeEdges.end());421// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes422SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));423// obtain flow parameters424SUMOVehicleParameter* flowParameters = SUMOVehicleParserHelper::parseFlowAttributes(vehicleTag, SUMOSAXAttrs, false, true, 0, SUMOTime_MAX);425flowParameters->setParameters(myVehicleBaseObject->getParameters());426// continue depending of vehicleParameters427if (flowParameters) {428myVehicleBaseObject->setVehicleParameter(flowParameters);429// create under base object430CommonXMLStructure::SumoBaseObject* embeddedRouteObject = new CommonXMLStructure::SumoBaseObject(myVehicleBaseObject);431embeddedRouteObject->setTag(SUMO_TAG_ROUTE);432embeddedRouteObject->addStringListAttribute(SUMO_ATTR_EDGES, routeEdges);433embeddedRouteObject->addColorAttribute(SUMO_ATTR_COLOR, RGBColor::INVISIBLE);434embeddedRouteObject->addIntAttribute(SUMO_ATTR_REPEAT, 0);435embeddedRouteObject->addTimeAttribute(SUMO_ATTR_CYCLETIME, 0);436embeddedRouteObject->addDoubleAttribute(SUMO_ATTR_PROB, 1.0);437// parse route438routeHandler.parseSumoBaseObject(myVehicleBaseObject);439// delete vehicleParamters440delete flowParameters;441}442} else if ((vehicleTag == GNE_TAG_TRIP_JUNCTIONS) && (myPathCreator->getSelectedJunctions().size() > 0)) {443// set tag444myVehicleBaseObject->setTag(SUMO_TAG_TRIP);445// Add parameter departure446if (!myVehicleBaseObject->hasStringAttribute(SUMO_ATTR_DEPART) || myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPART).empty()) {447myVehicleBaseObject->addStringAttribute(SUMO_ATTR_DEPART, "0");448}449// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes450SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));451// obtain trip parameters452SUMOVehicleParameter* tripParameters = SUMOVehicleParserHelper::parseVehicleAttributes(vehicleTag, SUMOSAXAttrs, false);453tripParameters->setParameters(myVehicleBaseObject->getParameters());454// check trip parameters455if (tripParameters) {456myVehicleBaseObject->setVehicleParameter(tripParameters);457myVehicleBaseObject->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, myPathCreator->getSelectedJunctions().front()->getID());458myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TO_JUNCTION, myPathCreator->getSelectedJunctions().back()->getID());459// parse vehicle460routeHandler.parseSumoBaseObject(myVehicleBaseObject);461// delete tripParameters and base object462delete tripParameters;463}464} else if ((vehicleTag == GNE_TAG_TRIP_TAZS) && (myPathCreator->getSelectedTAZs().size() > 0)) {465// set tag466myVehicleBaseObject->setTag(SUMO_TAG_TRIP);467// Add parameter departure468if (!myVehicleBaseObject->hasStringAttribute(SUMO_ATTR_DEPART) || myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPART).empty()) {469myVehicleBaseObject->addStringAttribute(SUMO_ATTR_DEPART, "0");470}471// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes472SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));473// obtain trip parameters474SUMOVehicleParameter* tripParameters = SUMOVehicleParserHelper::parseVehicleAttributes(vehicleTag, SUMOSAXAttrs, false);475tripParameters->setParameters(myVehicleBaseObject->getParameters());476// check trip parameters477if (tripParameters) {478myVehicleBaseObject->setVehicleParameter(tripParameters);479myVehicleBaseObject->addStringAttribute(SUMO_ATTR_FROM_TAZ, myPathCreator->getSelectedTAZs().front()->getID());480myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TO_TAZ, myPathCreator->getSelectedTAZs().back()->getID());481// parse vehicle482routeHandler.parseSumoBaseObject(myVehicleBaseObject);483// delete tripParameters and base object484delete tripParameters;485}486} else if ((vehicleTag == GNE_TAG_FLOW_JUNCTIONS) && (myPathCreator->getSelectedJunctions().size() > 0)) {487// set tag488myVehicleBaseObject->setTag(SUMO_TAG_FLOW);489// set flow attributes490updateFlowAttributes();491// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes492SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));493// obtain flow parameters494SUMOVehicleParameter* flowParameters = SUMOVehicleParserHelper::parseFlowAttributes(vehicleTag, SUMOSAXAttrs, false, true, 0, SUMOTime_MAX);495flowParameters->setParameters(myVehicleBaseObject->getParameters());496// check flowParameters497if (flowParameters) {498myVehicleBaseObject->setVehicleParameter(flowParameters);499myVehicleBaseObject->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, myPathCreator->getSelectedJunctions().front()->getID());500myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TO_JUNCTION, myPathCreator->getSelectedJunctions().back()->getID());501// parse vehicle502routeHandler.parseSumoBaseObject(myVehicleBaseObject);503// delete flowParameters and base object504delete flowParameters;505}506} else if ((vehicleTag == GNE_TAG_FLOW_TAZS) && (myPathCreator->getSelectedTAZs().size() > 0)) {507// set tag508myVehicleBaseObject->setTag(SUMO_TAG_FLOW);509// set flow attributes510updateFlowAttributes();511// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes512SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));513// obtain flow parameters514SUMOVehicleParameter* flowParameters = SUMOVehicleParserHelper::parseFlowAttributes(vehicleTag, SUMOSAXAttrs, false, true, 0, SUMOTime_MAX);515flowParameters->setParameters(myVehicleBaseObject->getParameters());516// check flowParameters517if (flowParameters) {518myVehicleBaseObject->setVehicleParameter(flowParameters);519myVehicleBaseObject->addStringAttribute(SUMO_ATTR_FROM_TAZ, myPathCreator->getSelectedTAZs().front()->getID());520myVehicleBaseObject->addStringAttribute(SUMO_ATTR_TO_TAZ, myPathCreator->getSelectedTAZs().back()->getID());521// parse vehicle522routeHandler.parseSumoBaseObject(myVehicleBaseObject);523// delete flowParameters and base object524delete flowParameters;525}526}527// abort path creation528myPathCreator->abortPathCreation();529// refresh attributes editor530myVehicleAttributesEditor->refreshAttributesEditor();531return true;532}533}534return false;535}536537538bool539GNEVehicleFrame::buildVehicleOverRoute(SumoXMLTag vehicleTag, GNEDemandElement* route) {540if (route && (route->getTagProperty()->isRoute())) {541// now check if parameters are valid542if (!myVehicleAttributesEditor->checkAttributes(true)) {543return false;544}545// get vehicle attributes546myVehicleAttributesEditor->fillSumoBaseObject(myVehicleBaseObject);547// declare route handler548GNERouteHandler routeHandler(myViewNet->getNet(), myVehicleBaseObject->hasStringAttribute(GNE_ATTR_DEMAND_FILE) ?549myVehicleBaseObject->getStringAttribute(GNE_ATTR_DEMAND_FILE) : "",550myViewNet->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed());551// check if departLane is valid552if ((route->getTagProperty()->getTag() == SUMO_TAG_ROUTE) && myVehicleBaseObject->hasStringAttribute(SUMO_ATTR_DEPARTLANE) &&553GNEAttributeCarrier::canParse<int>(myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPARTLANE))) {554const int departLane = GNEAttributeCarrier::parse<int>(myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPARTLANE));555if (departLane >= (int)route->getParentEdges().front()->getChildLanes().size()) {556myViewNet->setStatusBarText("Invalid " + toString(SUMO_ATTR_DEPARTLANE));557return false;558}559}560// check if departSpeed is valid561if (myVehicleBaseObject->hasStringAttribute(SUMO_ATTR_DEPARTSPEED) && GNEAttributeCarrier::canParse<double>(myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPARTSPEED))) {562double departSpeed = GNEAttributeCarrier::parse<double>(myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPARTSPEED));563if (departSpeed >= myTypeSelector->getCurrentDemandElement()->getAttributeDouble(SUMO_ATTR_MAXSPEED)) {564myViewNet->setStatusBarText("Invalid " + toString(SUMO_ATTR_DEPARTSPEED));565return false;566}567}568// check if we're creating a vehicle or a flow569if (vehicleTag == SUMO_TAG_VEHICLE) {570// set tag571myVehicleBaseObject->setTag(SUMO_TAG_VEHICLE);572// Add parameter departure573if (!myVehicleBaseObject->hasStringAttribute(SUMO_ATTR_DEPART) || myVehicleBaseObject->getStringAttribute(SUMO_ATTR_DEPART).empty()) {574myVehicleBaseObject->addStringAttribute(SUMO_ATTR_DEPART, "0");575}576// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes577SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));578// obtain vehicle parameters in vehicleParameters579SUMOVehicleParameter* vehicleParameters = SUMOVehicleParserHelper::parseVehicleAttributes(vehicleTag, SUMOSAXAttrs, false);580vehicleParameters->setParameters(myVehicleBaseObject->getParameters());581// check if vehicle was successfully created)582if (vehicleParameters) {583vehicleParameters->routeid = route->getID();584myVehicleBaseObject->setVehicleParameter(vehicleParameters);585// parse vehicle586routeHandler.parseSumoBaseObject(myVehicleBaseObject);587// delete vehicleParameters and sumoBaseObject588delete vehicleParameters;589}590} else {591// set tag592myVehicleBaseObject->setTag(SUMO_TAG_FLOW);593// set flow attributes594updateFlowAttributes();595// declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes596SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(myVehicleBaseObject->getAllAttributes(), getPredefinedTagsMML(), toString(vehicleTag));597// obtain routeFlow parameters in routeFlowParameters598SUMOVehicleParameter* routeFlowParameters = SUMOVehicleParserHelper::parseFlowAttributes(vehicleTag, SUMOSAXAttrs, false, true, 0, SUMOTime_MAX);599routeFlowParameters->setParameters(myVehicleBaseObject->getParameters());600// check if flow was successfully created)601if (routeFlowParameters) {602routeFlowParameters->routeid = route->getID();603myVehicleBaseObject->setVehicleParameter(routeFlowParameters);604// parse flow605routeHandler.parseSumoBaseObject(myVehicleBaseObject);606// delete vehicleParameters and sumoBaseObject607delete routeFlowParameters;608}609}610// center view after creation611const auto* vehicle = myViewNet->getNet()->getAttributeCarriers()->retrieveDemandElement(myVehicleBaseObject->getTag(), myVehicleBaseObject->getStringAttribute(SUMO_ATTR_ID), false);612if (vehicle && !myViewNet->getVisibleBoundary().around(vehicle->getPositionInView())) {613myViewNet->centerTo(vehicle->getPositionInView(), false);614}615// refresh attributes editor616myVehicleAttributesEditor->refreshAttributesEditor();617// all ok, then return true;618return true;619} else {620myViewNet->setStatusBarText(toString(vehicleTag) + " has to be placed within a route.");621return false;622}623}624625626void627GNEVehicleFrame::updateFlowAttributes() {628// adjust poisson value629if (myVehicleBaseObject->hasDoubleAttribute(GNE_ATTR_POISSON)) {630myVehicleBaseObject->addStringAttribute(SUMO_ATTR_PERIOD, "exp(" + toString(myVehicleBaseObject->getDoubleAttribute(GNE_ATTR_POISSON)) + ")");631}632}633634/****************************************************************************/635636637