Path: blob/main/src/utils/gui/globjects/GUIShapeContainer.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 GUIShapeContainer.cpp14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date 08.10.200918///19// Storage for geometrical objects extended by mutexes20/****************************************************************************/21#include <config.h>2223#include "GUIShapeContainer.h"24#include <utils/common/MsgHandler.h>25#include <utils/shapes/PolygonDynamics.h>26#include <foreign/rtree/SUMORTree.h>27#include <utils/gui/globjects/GUIPolygon.h>28#include <utils/gui/globjects/GUIPointOfInterest.h>293031// ===========================================================================32// method definitions33// ===========================================================================34GUIShapeContainer::GUIShapeContainer(SUMORTree& vis) :35myVis(vis),36myAllowReplacement(false) {37}383940GUIShapeContainer::~GUIShapeContainer() {}414243bool44GUIShapeContainer::addPOI(const std::string& id, const std::string& type, const RGBColor& color, const Position& pos, bool geo,45const std::string& lane, double posOverLane, bool friendlyPos, double posLat, const std::string& icon,46double layer, double angle, const std::string& imgFile, double width, double height,47bool /* ignorePruning */) {48GUIPointOfInterest* p = new GUIPointOfInterest(id, type, color, pos, geo, lane, posOverLane, friendlyPos, posLat, icon,49layer, angle, imgFile, width, height);50FXMutexLock locker(myLock);51if (!myPOIs.add(id, p)) {52if (myAllowReplacement) {53GUIPointOfInterest* oldP = dynamic_cast<GUIPointOfInterest*>(myPOIs.get(id));54myVis.removeAdditionalGLObject(oldP);55myPOIs.remove(id);56myPOIs.add(id, p);57WRITE_WARNINGF(TL("Replacing POI '%'"), id);58} else {59delete p;60return false;61}62}63myVis.addAdditionalGLObject(p);64return true;65}666768bool69GUIShapeContainer::addPolygon(const std::string& id, const std::string& type, const RGBColor& color, double layer,70double angle, const std::string& imgFile, const PositionVector& shape, bool geo, bool fill,71double lineWidth, bool /* ignorePruning */, const std::string& name) {72GUIPolygon* p = new GUIPolygon(id, type, color, shape, geo, fill, lineWidth, layer, angle, imgFile, name);73FXMutexLock locker(myLock);74if (!myPolygons.add(id, p)) {75if (myAllowReplacement) {76GUIPolygon* oldP = dynamic_cast<GUIPolygon*>(myPolygons.get(id));77myVis.removeAdditionalGLObject(oldP);78myPolygons.remove(id);79myPolygons.add(id, p);80WRITE_WARNINGF(TL("Replacing polygon '%'"), id);81} else {82delete p;83return false;84}85}86bool state = myInactivePolygonTypes.empty() || (std::find(myInactivePolygonTypes.begin(), myInactivePolygonTypes.end(), type) == myInactivePolygonTypes.end());87p->activate(state);88myVis.addAdditionalGLObject(p);89return true;90}919293PolygonDynamics*94GUIShapeContainer::addPolygonDynamics(double simtime,95std::string polyID,96SUMOTrafficObject* trackedObject,97const std::vector<double>& timeSpan,98const std::vector<double>& alphaSpan,99bool looped,100bool rotate) {101PolygonDynamics* pd = ShapeContainer::addPolygonDynamics(simtime, polyID, trackedObject, timeSpan, alphaSpan, looped, rotate);102if (pd != nullptr) {103pd->setRTree(&myVis);104}105return pd;106}107108109SUMOTime110GUIShapeContainer::polygonDynamicsUpdate(SUMOTime t, PolygonDynamics* pd) {111FXMutexLock locker(myLock);112GUIPolygon* p = dynamic_cast<GUIPolygon*>(pd->getPolygon());113assert(p != nullptr);114myVis.removeAdditionalGLObject(p);115SUMOTime next = ShapeContainer::polygonDynamicsUpdate(t, pd);116if (next != 0) {117// Update polygon position in RTree118myVis.addAdditionalGLObject(p);119}120return next;121}122123124bool125GUIShapeContainer::removePolygon(const std::string& id, bool useLock) {126GUIPolygon* p = dynamic_cast<GUIPolygon*>(myPolygons.get(id));127if (p == nullptr) {128return false;129}130FXMutexLock* locker = nullptr;131if (useLock) {132locker = new FXMutexLock(myLock);133}134myVis.removeAdditionalGLObject(p);135bool succ = ShapeContainer::removePolygon(id);136delete locker;137return succ;138}139140141bool142GUIShapeContainer::removePOI(const std::string& id) {143FXMutexLock locker(myLock);144GUIPointOfInterest* p = dynamic_cast<GUIPointOfInterest*>(myPOIs.get(id));145if (p == nullptr) {146return false;147}148myVis.removeAdditionalGLObject(p);149return myPOIs.remove(id);150}151152153void154GUIShapeContainer::movePOI(const std::string& id, const Position& pos) {155FXMutexLock locker(myLock);156GUIPointOfInterest* p = dynamic_cast<GUIPointOfInterest*>(myPOIs.get(id));157if (p != nullptr) {158myVis.removeAdditionalGLObject(p);159static_cast<Position*>(p)->set(pos);160myVis.addAdditionalGLObject(p);161}162}163164165void166GUIShapeContainer::reshapePolygon(const std::string& id, const PositionVector& shape) {167FXMutexLock locker(myLock);168GUIPolygon* p = dynamic_cast<GUIPolygon*>(myPolygons.get(id));169if (p != nullptr) {170myVis.removeAdditionalGLObject(p);171p->setShape(shape);172myVis.addAdditionalGLObject(p);173}174}175176177178std::vector<GUIGlID>179GUIShapeContainer::getPOIIds() const {180FXMutexLock locker(myLock);181std::vector<GUIGlID> ret;182for (const auto& poi : getPOIs()) {183ret.push_back(static_cast<GUIPointOfInterest*>(poi.second)->getGlID());184}185return ret;186}187188189std::vector<GUIGlID>190GUIShapeContainer::getPolygonIDs() const {191FXMutexLock locker(myLock);192std::vector<GUIGlID> ret;193for (const auto& poly : getPolygons()) {194ret.push_back(static_cast<GUIPolygon*>(poly.second)->getGlID());195}196return ret;197}198199200void201GUIShapeContainer::allowReplacement() {202myAllowReplacement = true;203}204205206void207GUIShapeContainer::setInactivePolygonTypes(std::set<std::string> inactivePolygonTypes) {208myInactivePolygonTypes = inactivePolygonTypes;209computeActivePolygons();210}211212213void214GUIShapeContainer::addInactivePolygonTypes(std::set<std::string> inactivePolygonTypes) {215myInactivePolygonTypes.insert(inactivePolygonTypes.begin(), inactivePolygonTypes.end());216computeActivePolygons();217}218219220void221GUIShapeContainer::removeInactivePolygonTypes(std::set<std::string> inactivePolygonTypes) {222for (std::string type : inactivePolygonTypes) {223myInactivePolygonTypes.erase(type);224}225computeActivePolygons();226}227228229void230GUIShapeContainer::computeActivePolygons(void) {231for (auto polygonWithID : myPolygons) {232GUIPolygon* polygon = (GUIPolygon*)polygonWithID.second;233bool state = std::find(myInactivePolygonTypes.begin(), myInactivePolygonTypes.end(), polygon->getShapeType()) == myInactivePolygonTypes.end();234polygon->activate(state);235}236}237238/****************************************************************************/239240241