#include <config.h>
#ifdef HAVE_FFMPEG
#include <utils/gui/div/GUIVideoEncoder.h>
#endif
#include <iostream>
#include <utility>
#include <cmath>
#include <limits>
#include <foreign/rtree/SUMORTree.h>
#include <gui/GUIApplicationWindow.h>
#include <gui/GUIGlobals.h>
#include <guisim/GUIEdge.h>
#include <guisim/GUILane.h>
#include <guisim/GUINet.h>
#include <guisim/GUIVehicle.h>
#include <guisim/GUIVehicleControl.h>
#include <mesogui/GUIMEVehicle.h>
#include <mesogui/GUIMEVehicleControl.h>
#include <microsim/MSEdge.h>
#include <microsim/MSGlobals.h>
#include <microsim/MSJunctionControl.h>
#include <microsim/MSLane.h>
#include <microsim/MSStoppingPlace.h>
#include <microsim/traffic_lights/MSSimpleTrafficLightLogic.h>
#include <microsim/traffic_lights/MSTLLogicControl.h>
#include <utils/common/RGBColor.h>
#include <utils/foxtools/MFXButtonTooltip.h>
#include <utils/foxtools/MFXCheckableButton.h>
#include <utils/foxtools/MFXImageHelper.h>
#include <utils/geom/PositionVector.h>
#include <utils/gui/div/GLHelper.h>
#include <utils/gui/div/GUIDesigns.h>
#include <utils/gui/div/GUIGlobalSelection.h>
#include <utils/gui/globjects/GLIncludes.h>
#include <utils/gui/globjects/GUIGlObjectStorage.h>
#include <utils/gui/globjects/GUIShapeContainer.h>
#include <utils/gui/images/GUIIconSubSys.h>
#include <utils/gui/settings/GUICompleteSchemeStorage.h>
#include <utils/gui/windows/GUIAppEnum.h>
#include <utils/gui/windows/GUIDialog_ViewSettings.h>
#include <utils/gui/windows/GUIPerspectiveChanger.h>
#include <utils/gui/windows/GUISUMOAbstractView.h>
#include <utils/shapes/ShapeContainer.h>
#include "GUISUMOViewParent.h"
#include "GUIViewTraffic.h"
GUIViewTraffic::GUIViewTraffic(
FXComposite* p,
GUIMainWindow& app,
GUISUMOViewParent* parent,
GUINet& net, FXGLVisual* glVis,
FXGLCanvas* share) :
GUISUMOAbstractView(p, app, parent, net.getVisualisationSpeedUp(), glVis, share),
myTrackedID(GUIGlObject::INVALID_ID),
myTLSGame(OptionsCont::getOptions().getString("game.mode") == "tls")
#ifdef HAVE_FFMPEG
, myCurrentVideo(nullptr)
#endif
{}
GUIViewTraffic::~GUIViewTraffic() {
endSnapshot();
}
void
GUIViewTraffic::buildViewToolBars(GUIGlChildWindow* v) {
{
const std::vector<std::string>& names = gSchemeStorage.getNames();
for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
v->getColoringSchemesCombo()->appendIconItem(i->c_str());
if ((*i) == myVisualizationSettings->name) {
v->getColoringSchemesCombo()->setCurrentItem(v->getColoringSchemesCombo()->getNumItems() - 1);
}
}
}
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate Junctions") + std::string("\t") + TL("Locate a junction within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATEJUNCTION), v, MID_HOTKEY_SHIFT_J_LOCATEJUNCTION,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate Edges") + std::string("\t") + TL("Locate an edge within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATEEDGE), v, MID_HOTKEY_SHIFT_E_LOCATEEDGE,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate Vehicles") + std::string("\t") + TL("Locate a vehicle within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATEVEHICLE), v, MID_HOTKEY_SHIFT_V_LOCATEVEHICLE,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate Persons") + std::string("\t") + TL("Locate a person within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATEPERSON), v, MID_HOTKEY_SHIFT_P_LOCATEPERSON,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate Container") + std::string("\t") + TL("Locate a container within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATECONTAINER), v, MID_HOTKEY_SHIFT_C_LOCATECONTAINER,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate TLS") + std::string("\t") + TL("Locate a tls within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATETLS), v, MID_HOTKEY_SHIFT_T_LOCATETLS,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate Additional") + std::string("\t") + TL("Locate an additional structure within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATEADD), v, MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate PoI") + std::string("\t") + TL("Locate a PoI within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATEPOI), v, MID_HOTKEY_SHIFT_O_LOCATEPOI,
GUIDesignButtonPopup);
new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
(std::string("\t") + TL("Locate Polygon") + std::string("\t") + TL("Locate a Polygon within the network.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::LOCATEPOLY), v, MID_HOTKEY_SHIFT_L_LOCATEPOLY,
GUIDesignButtonPopup);
}
bool
GUIViewTraffic::setColorScheme(const std::string& name) {
if (!gSchemeStorage.contains(name)) {
return false;
}
if (myGUIDialogViewSettings != nullptr) {
if (myGUIDialogViewSettings->getCurrentScheme() != name) {
myGUIDialogViewSettings->setCurrentScheme(name);
}
}
myVisualizationSettings = &gSchemeStorage.get(name.c_str());
myVisualizationSettings->gaming = myApp->isGaming();
update();
return true;
}
void
GUIViewTraffic::buildColorRainbow(const GUIVisualizationSettings& s, GUIColorScheme& scheme, int active, GUIGlObjectType objectType,
const GUIVisualizationRainbowSettings& rs) {
assert(!scheme.isFixed());
double minValue = std::numeric_limits<double>::infinity();
double maxValue = -std::numeric_limits<double>::infinity();
bool hasMissingData = false;
if (objectType == GLO_LANE) {
if (active == 22) {
active = 21;
} else if (active == 24) {
active = 23;
}
const MSEdgeVector& edges = MSEdge::getAllEdges();
for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
if (MSGlobals::gUseMesoSim) {
const double val = static_cast<GUIEdge*>(*it)->getColorValue(s, active);
if (val == s.MISSING_DATA) {
hasMissingData = true;
continue;
}
minValue = MIN2(minValue, val);
maxValue = MAX2(maxValue, val);
} else {
const std::vector<MSLane*>& lanes = (*it)->getLanes();
for (std::vector<MSLane*>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); it_l++) {
const double val = static_cast<GUILane*>(*it_l)->getColorValue(s, active);
if (val == s.MISSING_DATA) {
hasMissingData = true;
continue;
}
minValue = MIN2(minValue, val);
maxValue = MAX2(maxValue, val);
}
}
}
} else if (objectType == GLO_VEHICLE) {
MSVehicleControl& c = MSNet::getInstance()->getVehicleControl();
for (MSVehicleControl::constVehIt it_v = c.loadedVehBegin(); it_v != c.loadedVehEnd(); ++it_v) {
const GUIGlObject* veh;
if (MSGlobals::gUseMesoSim) {
veh = static_cast<const GUIMEVehicle*>(it_v->second);
} else {
veh = static_cast<const GUIVehicle*>(it_v->second);
}
const double val = veh->getColorValue(s, active);
if (val == s.MISSING_DATA) {
hasMissingData = true;
continue;
}
minValue = MIN2(minValue, val);
maxValue = MAX2(maxValue, val);
}
} else if (objectType == GLO_JUNCTION) {
if (active == 3) {
std::set<const MSJunction*> junctions;
for (MSEdge* edge : MSEdge::getAllEdges()) {
junctions.insert(edge->getFromJunction());
junctions.insert(edge->getToJunction());
}
for (const MSJunction* junction : junctions) {
minValue = MIN2(minValue, junction->getPosition().z());
maxValue = MAX2(maxValue, junction->getPosition().z());
}
}
}
if (scheme.getName() == GUIVisualizationSettings::SCHEME_NAME_PERMISSION_CODE) {
scheme.clear();
std::set<SVCPermissions> codes;
for (MSEdge* edge : MSEdge::getAllEdges()) {
for (MSLane* lane : edge->getLanes()) {
codes.insert(lane->getPermissions());
}
}
int step = MAX2(1, 360 / (int)codes.size());
int hue = 0;
for (SVCPermissions p : codes) {
scheme.addColor(RGBColor::fromHSV(hue, 1, 1), (double)p);
hue = (hue + step) % 360;
}
return;
}
buildMinMaxRainbow(s, scheme, rs, minValue, maxValue, hasMissingData);
}
std::vector<std::string>
GUIViewTraffic::getEdgeDataAttrs() const {
if (GUINet::getGUIInstance() != nullptr) {
return GUINet::getGUIInstance()->getEdgeDataAttrs();
}
return std::vector<std::string>();
}
std::vector<std::string>
GUIViewTraffic::getMeanDataIDs() const {
if (GUINet::getGUIInstance() != nullptr) {
return GUINet::getGUIInstance()->getMeanDataIDs();
}
return std::vector<std::string>();
}
std::vector<std::string>
GUIViewTraffic::getMeanDataAttrs(const std::string& meanDataID) const {
if (GUINet::getGUIInstance() != nullptr) {
return GUINet::getGUIInstance()->getMeanDataAttrs(meanDataID);
}
return std::vector<std::string>();
}
std::vector<std::string>
GUIViewTraffic::getEdgeLaneParamKeys(bool edgeKeys) const {
std::set<std::string> keys;
for (const MSEdge* e : MSEdge::getAllEdges()) {
if (edgeKeys) {
for (const auto& item : e->getParametersMap()) {
keys.insert(item.first);
}
} else {
for (const auto lane : e->getLanes()) {
for (const auto& item : lane->getParametersMap()) {
keys.insert(item.first);
}
}
}
}
return std::vector<std::string>(keys.begin(), keys.end());
}
std::vector<std::string>
GUIViewTraffic::getVehicleParamKeys(bool ) const {
std::set<std::string> keys;
MSVehicleControl* vc = nullptr;
if (MSGlobals::gUseMesoSim) {
vc = GUINet::getGUIInstance()->getGUIMEVehicleControl();
} else {
vc = GUINet::getGUIInstance()->getGUIVehicleControl();
}
vc->secureVehicles();
for (auto vehIt = vc->loadedVehBegin(); vehIt != vc->loadedVehEnd(); ++vehIt) {
for (auto kv : vehIt->second->getParameter().getParametersMap()) {
keys.insert(kv.first);
}
}
vc->releaseVehicles();
return std::vector<std::string>(keys.begin(), keys.end());
}
std::vector<std::string>
GUIViewTraffic::getPOIParamKeys() const {
std::set<std::string> keys;
const ShapeContainer::POIs& pois = static_cast<ShapeContainer&>(GUINet::getInstance()->getShapeContainer()).getPOIs();
for (auto item : pois) {
for (auto kv : item.second->getParametersMap()) {
keys.insert(kv.first);
}
}
return std::vector<std::string>(keys.begin(), keys.end());
}
void
GUIViewTraffic::centerTo(GUIGlID id, bool applyZoom, double zoomDist) {
GUIGlobals::gSecondaryShape = myVisualizationSettings->secondaryShape;
GUISUMOAbstractView::centerTo(id, applyZoom, zoomDist);
GUIGlobals::gSecondaryShape = false;
}
int
GUIViewTraffic::doPaintGL(int mode, const Boundary& bound) {
glRenderMode(mode);
glMatrixMode(GL_MODELVIEW);
GLHelper::pushMatrix();
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
drawDecals();
myVisualizationSettings->scale = m2p(SUMO_const_laneWidth);
if (myVisualizationSettings->showGrid) {
paintGLGrid();
}
glLineWidth(1);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
const float minB[2] = { (float)bound.xmin(), (float)bound.ymin() };
const float maxB[2] = { (float)bound.xmax(), (float)bound.ymax() };
glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_POLYGON_OFFSET_LINE);
const SUMORTree& grid = GUINet::getGUIInstance()->getVisualisationSpeedUp(myVisualizationSettings->secondaryShape);
int hits2 = grid.Search(minB, maxB, *myVisualizationSettings);
GUIGlobals::gSecondaryShape = myVisualizationSettings->secondaryShape;
if (myAdditionallyDrawn.size() > 0) {
glTranslated(0, 0, -.01);
GUINet::getGUIInstance()->lock();
for (auto i : myAdditionallyDrawn) {
i.first->drawGLAdditional(this, *myVisualizationSettings);
}
GUINet::getGUIInstance()->unlock();
glTranslated(0, 0, .01);
}
GLHelper::popMatrix();
return hits2;
}
void
GUIViewTraffic::startTrack(int id) {
myTrackedID = id;
GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
if (o != nullptr) {
GUIBaseVehicle* v = dynamic_cast<GUIBaseVehicle*>(o);
if (v != nullptr) {
v->addActiveAddVisualisation(this, GUIBaseVehicle::VO_TRACK);
}
}
}
void
GUIViewTraffic::stopTrack() {
myTrackedID = GUIGlObject::INVALID_ID;
}
GUIGlID
GUIViewTraffic::getTrackedID() const {
return myTrackedID;
}
void
GUIViewTraffic::onGamingClick(Position pos) {
if (myTLSGame) {
MSTLLogicControl& tlsControl = MSNet::getInstance()->getTLSControl();
MSTrafficLightLogic* minTll = nullptr;
GUIGlObject* minRR = nullptr;
double minDist = std::numeric_limits<double>::infinity();
double minDistRR = std::numeric_limits<double>::infinity();
for (MSTrafficLightLogic* const tll : tlsControl.getAllLogics()) {
if (tlsControl.isActive(tll) && tll->getProgramID() != "off") {
const MSTrafficLightLogic::LaneVector& lanes = tll->getLanesAt(0);
if (lanes.size() > 0) {
const Position& endPos = lanes[0]->getShape().back();
if (endPos.distanceTo(pos) < minDist) {
minDist = endPos.distanceTo(pos);
minTll = tll;
}
}
}
}
if (makeCurrent()) {
for (GUIGlObject* o : getGUIGlObjectsAtPosition(getPositionInformation(), MIN2(minDist, 20.0))) {
if (o->getType() == GLO_REROUTER_EDGE) {
const double dist = o->getCenter().distanceTo2D(pos);
if (dist < minDistRR) {
minDistRR = dist;
minRR = o;
}
}
}
makeNonCurrent();
}
if (minDistRR < minDist && minRR != nullptr) {
minRR->onLeftBtnPress(nullptr);
update();
return;
}
if (minTll != nullptr) {
if (minTll->getPhaseNumber() == 0) {
return;
}
const int ci = minTll->getCurrentPhaseIndex();
const int n = minTll->getPhaseNumber();
int greenCount = 0;
for (auto& phase : minTll->getPhases()) {
if (phase->isGreenPhase()) {
greenCount++;
}
}
int nextPhase = (ci + 1) % n;
SUMOTime nextDuration = 0;
if (minTll->getCurrentPhaseDef().isGreenPhase() || (greenCount == 1 && minTll->getCurrentPhaseDef().isAllRedPhase())) {
nextDuration = minTll->getPhase(nextPhase).duration;
} else {
SUMOTime spentTransition = minTll->getSpentDuration();
for (int i = ci - 1; i != ci; i--) {
if (i < 0) {
i = n - 1;
}
if (minTll->getPhase(i).isGreenPhase()) {
break;
}
spentTransition += minTll->getPhase(i).duration;
}
int numGreen = 0;
int i = nextPhase;
for (; numGreen < 2; i = (i + 1) % n) {
if (minTll->getPhase(i).isGreenPhase()) {
numGreen++;
continue;
}
if (numGreen == 1) {
SUMOTime dur = minTll->getPhase(i).duration;
if (dur <= spentTransition) {
spentTransition -= dur;
} else {
nextPhase = i;
nextDuration = dur - spentTransition;
break;
}
}
}
}
minTll->changeStepAndDuration(tlsControl, MSNet::getInstance()->getCurrentTimeStep(), nextPhase, nextDuration);
update();
}
} else {
if (MSGlobals::gUseMesoSim) {
return;
}
const auto& sel = gSelected.getSelected(GLO_VEHICLE);
if (sel.size() == 0) {
double minDist = std::numeric_limits<double>::infinity();
GUIVehicle* closest = nullptr;
MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
MSVehicleControl::constVehIt it = vc.loadedVehBegin();
MSVehicleControl::constVehIt end = vc.loadedVehEnd();
for (it = vc.loadedVehBegin(); it != end; ++it) {
GUIVehicle* veh = dynamic_cast<GUIVehicle*>(it->second);
assert(veh != 0);
if (veh->getParameter().line != "") {
const double dist = veh->getPosition().distanceTo2D(pos);
if (dist < minDist) {
minDist = dist;
closest = veh;
}
}
}
if (closest != nullptr) {
gSelected.select(closest->getGlID());
closest->addActiveAddVisualisation(this, GUIBaseVehicle::VO_SHOW_FUTURE_ROUTE);
}
} else {
double minDist = std::numeric_limits<double>::infinity();
MSStoppingPlace* closestStop = nullptr;
const NamedObjectCont<MSStoppingPlace*>& stops = MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_BUS_STOP);
for (auto it = stops.begin(); it != stops.end(); ++it) {
MSStoppingPlace* stop = it->second;
const double dist = pos.distanceTo2D(stop->getLane().geometryPositionAtOffset(stop->getEndLanePosition()));
if (dist < minDist) {
minDist = dist;
closestStop = stop;
}
}
if (closestStop != 0) {
GUIGlID id = *sel.begin();
GUIVehicle* veh = dynamic_cast<GUIVehicle*>(GUIGlObjectStorage::gIDStorage.getObjectBlocking(id));
assert(veh != 0);
MSLane* lane = veh->getMutableLane();
lane->getVehiclesSecure();
veh->rerouteDRTStop(closestStop);
GUIGlObjectStorage::gIDStorage.unblockObject(id);
lane->releaseVehicles();
}
}
}
}
void
GUIViewTraffic::onGamingRightClick(Position ) {
const auto& sel = gSelected.getSelected(GLO_VEHICLE);
if (sel.size() > 0) {
GUIGlID id = *sel.begin();
GUIVehicle* veh = dynamic_cast<GUIVehicle*>(GUIGlObjectStorage::gIDStorage.getObjectBlocking(id));
if (veh != 0) {
veh->removeActiveAddVisualisation(this, GUIBaseVehicle::VO_SHOW_FUTURE_ROUTE);
}
GUIGlObjectStorage::gIDStorage.unblockObject(id);
}
gSelected.clear();
}
SUMOTime
GUIViewTraffic::getCurrentTimeStep() const {
return MSNet::getInstance()->getCurrentTimeStep();
}
long
GUIViewTraffic::onCmdCloseLane(FXObject*, FXSelector, void*) {
GUILane* lane = getLaneUnderCursor();
if (lane != nullptr) {
lane->closeTraffic();
GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
update();
}
return 1;
}
long
GUIViewTraffic::onCmdCloseEdge(FXObject*, FXSelector, void*) {
GUILane* lane = getLaneUnderCursor();
if (lane != nullptr) {
dynamic_cast<GUIEdge*>(&lane->getEdge())->closeTraffic(lane);
GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
update();
}
return 1;
}
long
GUIViewTraffic::onCmdAddRerouter(FXObject*, FXSelector, void*) {
GUILane* lane = getLaneUnderCursor();
if (lane != nullptr) {
dynamic_cast<GUIEdge*>(&lane->getEdge())->addRerouter();
GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
update();
}
return 1;
}
long
GUIViewTraffic::showLaneReachability(GUILane* lane, FXObject* menu, FXSelector) {
if (lane != nullptr) {
const double UNREACHED = INVALID_DOUBLE;
gSelected.clear();
for (const MSEdge* const e : MSEdge::getAllEdges()) {
for (MSLane* const l : e->getLanes()) {
GUILane* gLane = dynamic_cast<GUILane*>(l);
gLane->setReachability(UNREACHED);
}
}
FXMenuCommand* mc = dynamic_cast<FXMenuCommand*>(menu);
const SUMOVehicleClass svc = SumoVehicleClassStrings.get(mc->getText().text());
const double defaultMaxSpeed = SUMOVTypeParameter::VClassDefaultValues(svc).desiredMaxSpeed;
std::map<MSEdge*, double> reachableEdges;
reachableEdges[&lane->getEdge()] = 0;
MSEdgeVector check;
check.push_back(&lane->getEdge());
while (check.size() > 0) {
MSEdge* e = check.front();
check.erase(check.begin());
double traveltime = reachableEdges[e];
for (MSLane* const l : e->getLanes()) {
if (l->allowsVehicleClass(svc)) {
GUILane* gLane = dynamic_cast<GUILane*>(l);
gSelected.select(gLane->getGlID(), false);
gLane->setReachability(traveltime);
}
}
const double dt = e->getLength() / MIN2(e->getSpeedLimit(), defaultMaxSpeed);
traveltime += MAX2(dt, NUMERICAL_EPS);
for (MSEdge* const nextEdge : e->getSuccessors(svc)) {
if (reachableEdges.count(nextEdge) == 0 ||
reachableEdges[nextEdge] > traveltime) {
reachableEdges[nextEdge] = traveltime;
check.push_back(nextEdge);
}
}
if (svc == SVC_PEDESTRIAN) {
for (MSEdge* const prevEdge : e->getPredecessors()) {
if (prevEdge->allowedLanes(*e, svc) != nullptr &&
(reachableEdges.count(prevEdge) == 0 ||
reachableEdges[prevEdge] > traveltime)) {
reachableEdges[prevEdge] = traveltime;
check.push_back(prevEdge);
}
}
if (!MSNet::getInstance()->hasPedestrianNetwork()) {
for (const MSEdge* const in_const : e->getToJunction()->getIncoming()) {
MSEdge* in = const_cast<MSEdge*>(in_const);
if ((in->getPermissions() & svc) == svc &&
(reachableEdges.count(in) == 0 ||
reachableEdges[in] > traveltime)) {
reachableEdges[in] = traveltime;
check.push_back(in);
}
}
}
}
}
gSelected.notifyChanged();
}
return 1;
}
long
GUIViewTraffic::onCmdShowReachability(FXObject* menu, FXSelector selector, void*) {
GUILane* lane = getLaneUnderCursor();
if (lane != nullptr) {
showLaneReachability(lane, menu, selector);
if (myVisualizationSettings->laneColorer.getActive() != 36) {
myVisualizationSettings->laneColorer.setActive(1);
}
update();
}
return 1;
}
GUILane*
GUIViewTraffic::getLaneUnderCursor() {
if (makeCurrent()) {
int id = getObjectUnderCursor();
if (id != 0) {
GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
if (o != nullptr) {
return dynamic_cast<GUILane*>(o);
}
}
makeNonCurrent();
}
return nullptr;
}
long
GUIViewTraffic::onDoubleClicked(FXObject*, FXSelector, void*) {
if (myApp->isFullScreen()) {
myApp->onCmdFullScreen(nullptr, 0, nullptr);
} else {
stopTrack();
}
return 1;
}
void
GUIViewTraffic::saveFrame(const std::string& destFile, FXColor* buf) {
#ifdef HAVE_FFMPEG
if (myCurrentVideo == nullptr) {
myCurrentVideo = new GUIVideoEncoder(destFile.c_str(), getWidth(), getHeight(), myApp->getDelay());
}
myCurrentVideo->writeFrame((uint8_t*)buf);
#else
UNUSED_PARAMETER(destFile);
UNUSED_PARAMETER(buf);
#endif
}
void
GUIViewTraffic::endSnapshot() {
#ifdef HAVE_FFMPEG
if (myCurrentVideo != nullptr) {
delete myCurrentVideo;
myCurrentVideo = nullptr;
}
#endif
}
void
GUIViewTraffic::checkSnapshots() {
#ifdef HAVE_FFMPEG
if (myCurrentVideo != nullptr) {
addSnapshot(getCurrentTimeStep() - DELTA_T, "");
}
#endif
GUISUMOAbstractView::checkSnapshots();
}
const std::vector<SUMOTime>
GUIViewTraffic::retrieveBreakpoints() const {
return myApp->retrieveBreakpoints();
}
void
GUIViewTraffic::drawPedestrianNetwork(const GUIVisualizationSettings& s) const {
GUIShapeContainer& shapeContainer = dynamic_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer());
if (s.showPedestrianNetwork) {
shapeContainer.removeInactivePolygonTypes(std::set<std::string> {"jupedsim.pedestrian_network"});
} else {
shapeContainer.addInactivePolygonTypes(std::set<std::string> {"jupedsim.pedestrian_network"});
}
update();
}
void
GUIViewTraffic::changePedestrianNetworkColor(const GUIVisualizationSettings& s) const {
GUIShapeContainer& shapeContainer = dynamic_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer());
for (auto polygonwithID : shapeContainer.getPolygons()) {
if (polygonwithID.second->getShapeType() == "jupedsim.pedestrian_network") {
polygonwithID.second->setShapeColor(s.pedestrianNetworkColor);
}
}
update();
}