Path: blob/main/src/utils/gui/globjects/GUIPointOfInterest.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 GUIPointOfInterest.cpp14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date June 200618///19// The GUI-version of a point of interest20/****************************************************************************/2122#include <utils/common/StringTokenizer.h>23#include <utils/gui/div/GUIParameterTableWindow.h>24#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>25#include <utils/gui/div/GUIGlobalSelection.h>26#include <utils/gui/images/GUITextureSubSys.h>27#include <utils/gui/div/GLHelper.h>28#include <utils/gui/globjects/GLIncludes.h>2930#include "GUIPointOfInterest.h"313233// ===========================================================================34// method definitions35// ===========================================================================3637GUIPointOfInterest::GUIPointOfInterest(const std::string& id, const std::string& type, const RGBColor& color, const Position& pos,38bool geo, const std::string& lane, double posOverLane, bool friendlyPos, double posLat,39const std::string& icon, double layer, double angle, const std::string& imgFile,40double width, double height) :41PointOfInterest(id, type, color, pos, geo, lane, posOverLane, friendlyPos, posLat, icon, layer, angle, imgFile, width, height),42GUIGlObject_AbstractAdd(GLO_POI, id,43(lane.size() > 0) ? GUIIconSubSys::getIcon(GUIIcon::POILANE) : geo ? GUIIconSubSys::getIcon(GUIIcon::POIGEO) : GUIIconSubSys::getIcon(GUIIcon::POI)) {44}454647GUIPointOfInterest::~GUIPointOfInterest() {}484950GUIGLObjectPopupMenu*51GUIPointOfInterest::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {52GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);53// build shape header54buildShapePopupOptions(app, ret, getShapeType());55return ret;56}575859GUIParameterTableWindow*60GUIPointOfInterest::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {61GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);62// add items63ret->mkItem("type", false, getShapeType());64ret->mkItem("icon", false, getIconStr());65ret->mkItem("layer", false, getShapeLayer());66ret->closeBuilding(this);67return ret;68}697071double72GUIPointOfInterest::getExaggeration(const GUIVisualizationSettings& s) const {73return s.poiSize.getExaggeration(s, this);74}757677Boundary78GUIPointOfInterest::getCenteringBoundary() const {79Boundary b;80b.add(x(), y());81if (getShapeImgFile() != DEFAULT_IMG_FILE) {82b.growWidth(myHalfImgWidth);83b.growHeight(myHalfImgHeight);84} else {85b.grow(3);86}87return b;88}899091void92GUIPointOfInterest::drawGL(const GUIVisualizationSettings& s) const {93// check if POI can be drawn94if (checkDraw(s, this)) {95// push name (needed for getGUIGlObjectsUnderCursor(...)96GLHelper::pushName(getGlID());97// draw inner polygon98drawInnerPOI(s, this, this, false, s.poiUseCustomLayer ? s.poiCustomLayer : getShapeLayer(), getWidth(), getHeight());99// pop name100GLHelper::popName();101}102}103104105bool106GUIPointOfInterest::checkDraw(const GUIVisualizationSettings& s, const GUIGlObject* o) {107// only continue if scale is valid108if (s.scale * (1.3 / 3.0) * o->getExaggeration(s) < s.poiSize.minSize) {109return false;110}111return true;112}113114115void116GUIPointOfInterest::setColor(const GUIVisualizationSettings& s, const PointOfInterest* POI, const GUIGlObject* o, bool disableSelectionColor) {117const GUIColorer& c = s.poiColorer;118const int active = c.getActive();119if (s.netedit && active != 1 && gSelected.isSelected(o->getType(), o->getGlID()) && disableSelectionColor) {120// override with special colors (unless the color scheme is based on selection)121GLHelper::setColor(RGBColor(0, 0, 204));122} else if (active == 0) {123GLHelper::setColor(POI->getShapeColor());124} else if (active == 1) {125GLHelper::setColor(c.getScheme().getColor(gSelected.isSelected(o->getType(), o->getGlID())));126} else {127GLHelper::setColor(c.getScheme().getColor(0));128}129}130131132void133GUIPointOfInterest::drawInnerPOI(const GUIVisualizationSettings& s, const PointOfInterest* POI, const GUIGlObject* o,134const bool disableSelectionColor, const double layer, const double width, const double height) {135const double exaggeration = o->getExaggeration(s);136GLHelper::pushMatrix();137setColor(s, POI, o, disableSelectionColor);138// add extra offset z provided by icon to avoid overlapping139glTranslated(POI->x(), POI->y(), layer + (double)POI->getIcon());140glRotated(-POI->getShapeNaviDegree(), 0, 0, 1);141// check if has to be drawn as a circle or with an image142if (POI->getShapeImgFile() != DEFAULT_IMG_FILE) {143int textureID = GUITexturesHelper::getTextureID(POI->getShapeImgFile());144if (textureID > 0) {145GUITexturesHelper::drawTexturedBox(textureID,146width * -0.5 * exaggeration, height * -0.5 * exaggeration,147width * 0.5 * exaggeration, height * 0.5 * exaggeration);148}149} else {150// fallback if no image is defined151GLHelper::drawFilledCircle(width * 0.5 * exaggeration, s.poiDetail);152// check if draw polygon153if (POI->getIcon() != POIIcon::NONE) {154// translate155glTranslated(0, 0, 0.1);156// rotate157glRotated(180, 0, 0, 1);158// draw texture159GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getPOITexture(POI->getIcon()), exaggeration * 0.8);160}161}162GLHelper::popMatrix();163if (!s.drawForRectangleSelection) {164const Position namePos = *POI;165o->drawName(namePos, s.scale, s.poiName, s.angle);166if (s.poiType.show(o)) {167const Position p = namePos + Position(0, -0.6 * s.poiType.size / s.scale);168GLHelper::drawTextSettings(s.poiType, POI->getShapeType(), p, s.scale, s.angle);169}170if (s.poiText.show(o)) {171GLHelper::pushMatrix();172glTranslated(POI->x(), POI->y(), 0);173std::string value = POI->getParameter(s.poiTextParam, "");174if (value != "") {175auto lines = StringTokenizer(value, StringTokenizer::NEWLINE).getVector();176glRotated(-s.angle, 0, 0, 1);177glTranslated(0, 0.7 * s.poiText.scaledSize(s.scale) * (double)lines.size(), 0);178glRotated(s.angle, 0, 0, 1);179// FONS_ALIGN_LEFT = 1180// FONS_ALIGN_CENTER = 2181// FONS_ALIGN_MIDDLE = 16182const int align = (lines.size() > 1 ? 1 : 2) | 16;183for (std::string& line : lines) {184GLHelper::drawTextSettings(s.poiText, line, Position(0, 0), s.scale, s.angle, GLO_MAX, align);185glRotated(-s.angle, 0, 0, 1);186glTranslated(0, -0.7 * s.poiText.scaledSize(s.scale), 0);187glRotated(s.angle, 0, 0, 1);188}189}190GLHelper::popMatrix();191}192}193}194195196/****************************************************************************/197198199