Skip to content

Commit

Permalink
Load job segments and draw them
Browse files Browse the repository at this point in the history
JobLineGraph: moved from StationGraphObject to LineGraphScene
JobLineGraph: renamed to JobSegmentGraph
  • Loading branch information
gfgit committed Aug 26, 2021
1 parent 6e954c4 commit 757525c
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 33 deletions.
89 changes: 77 additions & 12 deletions src/graph/model/linegraphscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ static inline qreal timeToHourFraction(const QTime &t)
return ret;
}

static inline double stationPlatformPosition(const StationGraphObject& st, const db_id platfId, const double platfOffset)
{
double x = st.xPos;
for(const StationGraphObject::PlatformGraph& platf : st.platforms)
{
if(platf.platformId == platfId)
return x;
x += platfOffset;
}
return -1;
}

LineGraphScene::LineGraphScene(sqlite3pp::database &db, QObject *parent) :
QObject(parent),
mDb(db),
Expand Down Expand Up @@ -97,7 +109,7 @@ bool LineGraphScene::loadGraph(db_id objectId, LineGraphType type, bool force)
//Register a single station at start position
st.xPos = curPos;
stations.insert(st.stationId, st);
stationPositions = {{st.stationId, 0, st.xPos}};
stationPositions = {{st.stationId, 0, st.xPos, {}}};
graphObjectName = st.stationName;
}
else if(type == LineGraphType::RailwaySegment)
Expand Down Expand Up @@ -141,8 +153,8 @@ bool LineGraphScene::loadGraph(db_id objectId, LineGraphType type, bool force)
stations.insert(stA.stationId, stA);
stations.insert(stB.stationId, stB);

stationPositions = {{stA.stationId, objectId, stA.xPos},
{stB.stationId, 0, stB.xPos}};
stationPositions = {{stA.stationId, objectId, stA.xPos, {}},
{stB.stationId, 0, stB.xPos, {}}};
}
else if(type == LineGraphType::RailwayLine)
{
Expand Down Expand Up @@ -173,14 +185,16 @@ bool LineGraphScene::reloadJobs()
return false;

//TODO: maybe only load visible
//FIXME: also load job graph lines between stations

for(StationGraphObject& st : stations)
{
if(!loadStationJobStops(st))
return false;
}

//Save last station from previous iteration
auto lastSt = stations.constEnd();

for(int i = 0; i < stationPositions.size(); i++)
{
StationPosEntry& stPos = stationPositions[i];
Expand All @@ -195,15 +209,25 @@ bool LineGraphScene::reloadJobs()
if(!toStId)
break; //No next station

auto fromSt = stations.constFind(fromStId);
if(fromSt == stations.constEnd())
continue;
auto fromSt = lastSt;
if(fromSt == stations.constEnd() || fromSt->stationId != fromStId)
{
fromSt = stations.constFind(fromStId);
if(fromSt == stations.constEnd())
{
continue;
}
}

auto toSt = stations.constFind(toStId);
if(toSt == stations.constEnd())
continue;

if(!loadSegmentJobs(stPos, fromSt.value(), toSt.value()))
return false;

//Store last station
lastSt = toSt;
}

return true;
Expand All @@ -223,7 +247,7 @@ JobEntry LineGraphScene::getJobAt(const QPointF &pos, const double tolerance)
db_id prevStId = 0;
db_id nextStId = 0;

for(const StationPosEntry& stPos : stationPositions)
for(const StationPosEntry& stPos : qAsConst(stationPositions))
{
if(stPos.xPos <= pos.x())
prevStId = stPos.stationId;
Expand Down Expand Up @@ -435,7 +459,7 @@ bool LineGraphScene::loadFullLine(db_id lineId)

st.xPos = curPos;
stations.insert(st.stationId, st);
stationPositions.append({st.stationId, railwaySegmentId, st.xPos});
stationPositions.append({st.stationId, railwaySegmentId, st.xPos, {}});
curPos += st.platforms.count() * Session->platformOffset + Session->stationOffset;
}
else if(fromStationId != lastStationId)
Expand All @@ -454,7 +478,7 @@ bool LineGraphScene::loadFullLine(db_id lineId)
stations.insert(stB.stationId, stB);

stationPositions.last().segmentId = railwaySegmentId;
stationPositions.append({stB.stationId, 0, stB.xPos});
stationPositions.append({stB.stationId, 0, stB.xPos, {}});

curPos += stB.platforms.count() * Session->platformOffset + Session->stationOffset;
lastStationId = stB.stationId;
Expand Down Expand Up @@ -540,10 +564,18 @@ bool LineGraphScene::loadStationJobStops(StationGraphObject &st)
return true;
}

bool LineGraphScene::loadSegmentJobs(LineGraphScene::StationPosEntry& stPos, const StationGraphObject& fromStm, const StationGraphObject& toSt)
bool LineGraphScene::loadSegmentJobs(LineGraphScene::StationPosEntry& stPos, const StationGraphObject& fromSt, const StationGraphObject& toSt)
{
//Reset previous job segment graph
stPos.nextSegmentJobGraphs.clear();

const double vertOffset = Session->vertOffset;
const double hourOffset = Session->hourOffset;
const double platfOffset = Session->platformOffset;

sqlite3pp::query q(mDb, "SELECT sub.*, jobs.category, g_out.track_id, g_in.track_id FROM ("
" SELECT stops.id AS cur_stop_id, lead(stops.id, 1) OVER win AS next_stop_id, stops.station_id,"
" SELECT stops.id AS cur_stop_id, lead(stops.id, 1) OVER win AS next_stop_id,"
" stops.station_id,"
" stops.job_id,"
" stops.departure, lead(stops.arrival, 1) OVER win AS next_stop_arrival,"
" stops.out_gate_conn,"
Expand All @@ -562,6 +594,39 @@ bool LineGraphScene::loadSegmentJobs(LineGraphScene::StationPosEntry& stPos, con
for(auto stop : q)
{
//TODO: store line in stPos
JobSegmentGraph job;
job.fromStopId = stop.get<db_id>(0);
job.toStopId = stop.get<db_id>(1);
db_id stId = stop.get<db_id>(2);
job.jobId = stop.get<db_id>(3);
QTime departure = stop.get<QTime>(4);
QTime arrival = stop.get<QTime>(5);
//6 - out gate connection
//7 - in gate connection
//8 - segment_id
job.category = JobCategory(stop.get<int>(9));
job.fromPlatfId = stop.get<db_id>(11);
job.toPlatfId = stop.get<db_id>(12);

if(toSt.stationId == stId)
{
//Job goes in opposite direction, reverse stops
qSwap(job.fromStopId, job.toStopId);
qSwap(job.fromPlatfId, job.toPlatfId);
qSwap(departure, arrival);
}

//Calculate coordinates
job.fromDeparture.rx() = stationPlatformPosition(fromSt, job.fromPlatfId, platfOffset);
job.fromDeparture.ry() = vertOffset + timeToHourFraction(departure) * hourOffset;

job.toArrival.rx() = stationPlatformPosition(toSt, job.toPlatfId, platfOffset);
job.toArrival.ry() = vertOffset + timeToHourFraction(arrival) * hourOffset;

if(job.fromDeparture.x() < 0 || job.toArrival.x() < 0)
continue; //Skip, couldn't find platform

stPos.nextSegmentJobGraphs.append(job);
}

return true;
Expand Down
32 changes: 31 additions & 1 deletion src/graph/model/linegraphscene.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,41 @@ public slots:

private:

/*!
* \brief Graph of the job while is moving
*
* Contains informations to draw job line between two adjacent stations
*/
typedef struct
{
db_id jobId;
JobCategory category;

db_id fromStopId;
db_id fromPlatfId;
QPointF fromDeparture;

db_id toStopId;
db_id toPlatfId;
QPointF toArrival;
} JobSegmentGraph;

/*!
* \brief Station entry on scene
*
* Represents a station item placeholder in an ordered list of scene
*/
typedef struct
{
db_id stationId;
db_id segmentId;
double xPos;

QVector<JobSegmentGraph> nextSegmentJobGraphs;
/*!<
* Stores job graph of the next segment
* Which means jobs departing from this staation and going to next one
*/
} StationPosEntry;

private:
Expand All @@ -89,7 +119,7 @@ public slots:
bool loadFullLine(db_id lineId);

bool loadStationJobStops(StationGraphObject &st);
bool loadSegmentJobs(StationPosEntry &stPos, const StationGraphObject &fromStm, const StationGraphObject &toSt);
bool loadSegmentJobs(StationPosEntry &stPos, const StationGraphObject &fromSt, const StationGraphObject &toSt);

private:
friend class BackgroundHelper;
Expand Down
21 changes: 1 addition & 20 deletions src/graph/model/stationgraphobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* \brief Graph of a railway station
*
* Contains informations to draw station name, platforms and jobs
*
* \sa PlatformGraph
*/
class StationGraphObject
Expand All @@ -38,31 +39,11 @@ class StationGraphObject
double departureY;
} JobStopGraph;

/*!
* \brief Graph of the job while is moving
*
* Contains informations to draw job line between two adjacent stations
*/
typedef struct
{
db_id jobId;
JobCategory category;

db_id fromStopId;
db_id fromPlatfId;
double fromDepartureY;

db_id toStopId;
db_id toPlatfId;
double toArrivalY;
} JobLineGraph;

/*!
* \brief Graph of a station track (platform)
*
* Contains informations to draw platform line and header name
* \sa JobStopGraph
* \sa JobLineGraph
*/
typedef struct
{
Expand Down
44 changes: 44 additions & 0 deletions src/graph/view/backgroundhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ void BackgroundHelper::drawJobStops(QPainter *painter, LineGraphScene *scene, co
{
for(const StationGraphObject::JobStopGraph& jobStop : platf.jobStops)
{
//NOTE: departure comes AFTER arrival in time, opposite than job segment
if(jobStop.arrivalY > rect.bottom() || jobStop.departureY < rect.top())
continue; //Skip, job not visible

Expand All @@ -237,3 +238,46 @@ void BackgroundHelper::drawJobStops(QPainter *painter, LineGraphScene *scene, co
}
}
}

void BackgroundHelper::drawJobSegments(QPainter *painter, LineGraphScene *scene, const QRectF &rect)
{
const double stationOffset = Session->stationOffset;

QPen jobPen;
jobPen.setWidth(AppSettings.getJobLineWidth());

//Iterate until one but last
//This way we can always acces next station
for(int i = 0; i < scene->stationPositions.size() - 1; i++)
{
const LineGraphScene::StationPosEntry& stPos = scene->stationPositions.at(i);

const double left = stPos.xPos;
double right = 0;

if(i < scene->stationPositions.size() - 2)
{
const LineGraphScene::StationPosEntry& afterNextPos = scene->stationPositions.at(i + 2);
right = afterNextPos.xPos - stationOffset;
}
else
{
right = rect.right(); //Last station, use all space on right side
}

if(left > rect.right() || right < rect.left())
continue; //Skip station, it's not visible

for(const LineGraphScene::JobSegmentGraph& job : stPos.nextSegmentJobGraphs)
{
//NOTE: departure comes BEFORE arrival in time, opposite than job stop
if(job.fromDeparture.y() > rect.bottom() || job.toArrival.y() < rect.top())
continue; //Skip, job not visible

jobPen.setColor(Session->colorForCat(job.category));
painter->setPen(jobPen);

painter->drawLine(job.fromDeparture, job.toArrival);
}
}
}
2 changes: 2 additions & 0 deletions src/graph/view/backgroundhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class BackgroundHelper
static void drawStations(QPainter *painter, LineGraphScene *scene, const QRectF& rect);

static void drawJobStops(QPainter *painter, LineGraphScene *scene, const QRectF& rect);

static void drawJobSegments(QPainter *painter, LineGraphScene *scene, const QRectF &rect);
};

#endif // BACKGROUNDHELPER_H
1 change: 1 addition & 0 deletions src/graph/view/linegraphview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ void LineGraphView::paintEvent(QPaintEvent *e)

BackgroundHelper::drawStations(&painter, m_scene, exposedRect);
BackgroundHelper::drawJobStops(&painter, m_scene, exposedRect);
BackgroundHelper::drawJobSegments(&painter, m_scene, exposedRect);
}

void LineGraphView::resizeEvent(QResizeEvent *)
Expand Down

0 comments on commit 757525c

Please sign in to comment.