Path: blob/main/src/netedit/elements/data/GNEEdgeRelData.cpp
193735 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 GNEEdgeRelData.cpp14/// @author Pablo Alvarez Lopez15/// @date Jan 202016///17// class for edge relation data18/****************************************************************************/1920#include <netedit/GNENet.h>21#include <netedit/GNETagProperties.h>22#include <netedit/GNESegment.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/data/GNEEdgeRelDataFrame.h>28#include <utils/gui/div/GLHelper.h>29#include <utils/gui/globjects/GLIncludes.h>3031#include "GNEEdgeRelData.h"32#include "GNEDataInterval.h"3334// ===========================================================================35// member method definitions36// ===========================================================================3738GNEEdgeRelData::GNEEdgeRelData(GNENet* net) :39GNEGenericData(SUMO_TAG_EDGEREL, net) {40}414243GNEEdgeRelData::GNEEdgeRelData(GNEDataInterval* dataIntervalParent, GNEEdge* fromEdge, GNEEdge* toEdge,44const Parameterised::Map& parameters) :45GNEGenericData(SUMO_TAG_EDGEREL, dataIntervalParent, parameters) {46// set parents47setParents<GNEEdge*>({fromEdge, toEdge});48}495051GNEEdgeRelData::~GNEEdgeRelData() {}525354RGBColor55GNEEdgeRelData::setColor(const GUIVisualizationSettings& s) const {56// set default color57RGBColor col = RGBColor::GREEN;58if (isAttributeCarrierSelected()) {59col = s.colorSettings.selectedEdgeDataColor;60} else if (s.dataColorer.getScheme().getName() == GUIVisualizationSettings::SCHEME_NAME_DATA_ATTRIBUTE_NUMERICAL) {61// user defined rainbow62double val = getColorValue(s, s.dataColorer.getActive());63col = s.dataColorer.getScheme().getColor(val);64} else if (myNet->getViewNet()->getEditModes().dataEditMode == DataEditMode::DATA_EDGERELDATA) {65// get selected data interval and filtered attribute66const GNEDataInterval* dataInterval = myNet->getViewParent()->getEdgeRelDataFrame()->getIntervalSelector()->getDataInterval();67const std::string filteredAttribute = myNet->getViewParent()->getEdgeRelDataFrame()->getAttributeSelector()->getFilteredAttribute();68// continue if there is a selected data interval and filtered attribute69if (dataInterval && (filteredAttribute.size() > 0)) {70// obtain minimum and maximum value71const double minValue = dataInterval->getSpecificAttributeColors().at(myTagProperty->getTag()).getMinValue(filteredAttribute);72const double maxValue = dataInterval->getSpecificAttributeColors().at(myTagProperty->getTag()).getMaxValue(filteredAttribute);73// get value74const double value = parse<double>(getParameter(filteredAttribute, "0"));75col = GNEViewNetHelper::getRainbowScaledColor(minValue, maxValue, value);76}77}78return col;79}808182double83GNEEdgeRelData::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {84switch (activeScheme) {85case 0:86return 0;87case 1:88return isAttributeCarrierSelected();89case 2:90return 0; // setfunctional color const GNEAdditional* TAZA = getParentAdditionals().front();91case 3:92return 0; // setfunctional color const GNEAdditional* TAZA = getParentAdditionals().back();93case 4:94// by numerical attribute value95try {96if (hasParameter(s.relDataAttr)) {97return StringUtils::toDouble(getParameter(s.relDataAttr, "-1"));98} else {99return GUIVisualizationSettings::MISSING_DATA;100}101} catch (NumberFormatException&) {102return GUIVisualizationSettings::MISSING_DATA;103}104default:105return 0;106}107}108109110bool111GNEEdgeRelData::isGenericDataVisible() const {112// obtain pointer to edge data frame (only for code legibly)113const GNEEdgeRelDataFrame* edgeRelDataFrame = myNet->getViewParent()->getEdgeRelDataFrame();114// get current data edit mode115DataEditMode dataMode = myNet->getViewNet()->getEditModes().dataEditMode;116// check if we have to filter generic data117if ((dataMode == DataEditMode::DATA_INSPECT) || (dataMode == DataEditMode::DATA_DELETE) || (dataMode == DataEditMode::DATA_SELECT)) {118return isVisibleInspectDeleteSelect();119} else if (edgeRelDataFrame->shown()) {120// check interval121if ((edgeRelDataFrame->getIntervalSelector()->getDataInterval() != nullptr) &&122(edgeRelDataFrame->getIntervalSelector()->getDataInterval() != myDataIntervalParent)) {123return false;124}125// check attribute126if ((edgeRelDataFrame->getAttributeSelector()->getFilteredAttribute().size() > 0) &&127(getParametersMap().count(edgeRelDataFrame->getAttributeSelector()->getFilteredAttribute()) == 0)) {128return false;129}130// all checks ok, then return true131return true;132} else {133// GNEEdgeRelDataFrame hidden, then return false134return false;135}136}137138139void140GNEEdgeRelData::updateGeometry() {141// just compute path142computePathElement();143}144145146void147GNEEdgeRelData::drawGL(const GUIVisualizationSettings& /*s*/) const {148// Nothing to draw149}150151152void153GNEEdgeRelData::computePathElement() {154// calculate path155myNet->getDataPathManager()->calculateConsecutivePathEdges(this, SVC_IGNORING, getParentEdges());156}157158159void160GNEEdgeRelData::drawLanePartialGL(const GUIVisualizationSettings& s, const GNESegment* segment, const double offsetFront) const {161// get color162const auto color = setColor(s);163if (segment->getLane() && (color.alpha() != 0) && myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {164// get detail level165const auto d = s.getDetailLevel(1);166// draw over all edge's lanes167for (const auto& laneEdge : segment->getLane()->getParentEdge()->getChildLanes()) {168// get lane width169const double laneWidth = s.addSize.getExaggeration(s, laneEdge) * s.edgeRelWidthExaggeration *170(laneEdge->getParentEdge()->getNBEdge()->getLaneWidth(laneEdge->getIndex()) * 0.5);171// Add a draw matrix172GLHelper::pushMatrix();173// Start with the drawing of the area translating matrix to origin174drawInLayer(GLO_EDGERELDATA, offsetFront);175GLHelper::setColor(RGBColor::BLACK);176// draw box lines177178179GLHelper::drawBoxLines(laneEdge->getLaneShape(), laneEdge->getShapeRotations(),180laneEdge->getShapeLengths(), laneWidth);181// translate to top182glTranslated(0, 0, 0.01);183GLHelper::setColor(color);184// draw internal box lines185GLHelper::drawBoxLines(laneEdge->getLaneShape(), laneEdge->getShapeRotations(),186laneEdge->getShapeLengths(), (laneWidth - 0.1));187// Pop last matrix188GLHelper::popMatrix();189// draw lock icon190GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), getPositionInView(), 1);191// draw filtered attribute192if (getParentEdges().front()->getChildLanes().front() == laneEdge) {193drawFilteredAttribute(s, laneEdge->getLaneShape(),194myNet->getViewParent()->getEdgeRelDataFrame()->getAttributeSelector()->getFilteredAttribute(),195myNet->getViewParent()->getEdgeRelDataFrame()->getIntervalSelector()->getDataInterval());196}197// draw dotted contour198segment->getContour()->drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);199}200// draw dotted contour201if (getParentEdges().front() == segment->getLane()->getParentEdge()) {202segment->getContour()->calculateContourEdge(s, d, getParentEdges().front(), this, getType(), true, false);203}204if (getParentEdges().back() == segment->getLane()->getParentEdge()) {205segment->getContour()->calculateContourEdge(s, d, getParentEdges().back(), this, getType(), false, true);206}207// check if add this path element to redraw buffer208if (!gViewObjectsHandler.isPathElementMarkForRedraw(this) && segment->getContour()->checkDrawPathContour(s, d, this)) {209gViewObjectsHandler.addToRedrawPathElements(this);210}211212}213}214215216void217GNEEdgeRelData::drawJunctionPartialGL(const GUIVisualizationSettings& s, const GNESegment* segment, const double /*offsetFront*/) const {218// get color219const auto color = setColor(s);220if ((color.alpha() != 0) && myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {221// get detail level222const auto d = s.getDetailLevel(1);223// get flag for only draw contour224225// finish226227// draw dotted contour228if (segment->getPreviousLane() && segment->getNextLane()) {229segment->getContour()->calculateContourEdges(s, d, segment->getPreviousLane()->getParentEdge(), segment->getNextLane()->getParentEdge());230}231// check if add this path element to redraw buffer232if (!gViewObjectsHandler.isPathElementMarkForRedraw(this) && segment->getContour()->checkDrawPathContour(s, d, this)) {233gViewObjectsHandler.addToRedrawPathElements(this);234}235}236}237238239GNELane*240GNEEdgeRelData::getFirstPathLane() const {241/* temporal */242return nullptr;243}244245246GNELane*247GNEEdgeRelData::getLastPathLane() const {248/* temporal */249return nullptr;250}251252253Position254GNEEdgeRelData::getPositionInView() const {255return getParentEdges().front()->getPositionInView();256}257258259void260GNEEdgeRelData::writeGenericData(OutputDevice& device) const {261// open device262device.openTag(SUMO_TAG_EDGEREL);263// write from264device.writeAttr(SUMO_ATTR_FROM, getParentEdges().front()->getID());265// write to266device.writeAttr(SUMO_ATTR_TO, getParentEdges().back()->getID());267// iterate over attributes268for (const auto& attribute : getParametersMap()) {269// write attribute (don't use writeParams)270device.writeAttr(attribute.first, attribute.second);271}272// close device273device.closeTag();274}275276277bool278GNEEdgeRelData::isGenericDataValid() const {279return true;280}281282283std::string284GNEEdgeRelData::getGenericDataProblem() const {285return "";286}287288289void290GNEEdgeRelData::fixGenericDataProblem() {291throw InvalidArgument(getTagStr() + " cannot fix any problem");292}293294295Boundary296GNEEdgeRelData::getCenteringBoundary() const {297return getParentEdges().front()->getCenteringBoundary();298}299300301std::string302GNEEdgeRelData::getAttribute(SumoXMLAttr key) const {303switch (key) {304case SUMO_ATTR_ID:305return getPartialID() + getParentEdges().front()->getID();306case SUMO_ATTR_FROM:307return getParentEdges().front()->getID();308case SUMO_ATTR_TO:309return getParentEdges().back()->getID();310case GNE_ATTR_DATASET:311return myDataIntervalParent->getDataSetParent()->getID();312case SUMO_ATTR_BEGIN:313return myDataIntervalParent->getAttribute(SUMO_ATTR_BEGIN);314case SUMO_ATTR_END:315return myDataIntervalParent->getAttribute(SUMO_ATTR_END);316default:317return getCommonAttribute(key);318}319}320321322double323GNEEdgeRelData::getAttributeDouble(SumoXMLAttr key) const {324return getCommonAttributeDouble(key);325}326327328void329GNEEdgeRelData::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {330if (value == getAttribute(key)) {331return; //avoid needless changes, later logic relies on the fact that attributes have changed332}333switch (key) {334case SUMO_ATTR_FROM:335case SUMO_ATTR_TO:336GNEChange_Attribute::changeAttribute(this, key, value, undoList);337break;338default:339setCommonAttribute(key, value, undoList);340break;341}342}343344345bool346GNEEdgeRelData::isValid(SumoXMLAttr key, const std::string& value) {347switch (key) {348case SUMO_ATTR_FROM:349return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) != nullptr) &&350(value != getParentEdges().back()->getID());351case SUMO_ATTR_TO:352return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) != nullptr) &&353(value != getParentEdges().front()->getID());354default:355return isCommonAttributeValid(key, value);356}357}358359360bool GNEEdgeRelData::isAttributeEnabled(SumoXMLAttr key) const {361switch (key) {362case SUMO_ATTR_ID:363return false;364default:365return true;366}367}368369370std::string371GNEEdgeRelData::getPopUpID() const {372return getTagStr();373}374375376std::string377GNEEdgeRelData::getHierarchyName() const {378return getTagStr() + ": " + getParentEdges().front()->getID() + "->" + getParentEdges().back()->getID();379}380381382void383GNEEdgeRelData::setAttribute(SumoXMLAttr key, const std::string& value) {384switch (key) {385case SUMO_ATTR_FROM: {386// change first edge387replaceFirstParentEdge(value);388break;389}390case SUMO_ATTR_TO: {391// change last edge392replaceLastParentEdge(value);393break;394}395default:396setCommonAttribute(key, value);397if (!isTemplate()) {398myDataIntervalParent->getDataSetParent()->updateAttributeColors();399}400break;401}402// mark interval toolbar for update403if (!isTemplate()) {404myNet->getViewNet()->getIntervalBar().markForUpdate();405}406}407408/****************************************************************************/409410411