Thursday 29 June 2017

TrafficControl: QML Station Visualisation of Available Platforms

The first step for visualisation of stations will be an indicator of available platform.

The border for the station QML elements will have different colors, depending on the state:

  • Green indicates that all platforms are available,
  • Yellow indicates that at least one platform is occupied and at least one platform is available,
  • Red inidcates that all platforms are occupied


A test run of TrafficControl is shown in the video below. Three trains are dispatched on the map at Hjärup, Gunnesbo and Lund. Their locations are shown in the tables to the left.

More visibility on the map will be added during the summer.

Saturday 24 June 2017

TrafficControl: Graphical Representation of a Station

Now when I know that I can mofidy the look of a station QML item from trafficControl/tcStation, I need to decide what info to visualize and how.

Some of the information I want to visualise for the stations are:
  • Number of waiting passengers
  • Number of people in the surrounding area
  • A metric for the delay
  • Status of occupied platforms on station: All platforms available/Some of the platforms are available/No Platforms available
The station is represented by a MapCircle QML type, which has the following members:
  • border.color
  • border.width
  • center - given by the station's coordinates
  • color 
  • radius
  • opacity - it should be possible to see through the item.

In this example, the border color is black and the width is is 30 pixels. 

The MapCircle can also be hidden by setting the property visible=false.

For future studies:
  • If neccessary, one can also add internal QML items inside the mapItem.
  • Maybe I can have some more detailed information to show on the station, either by
    • clicking/toggling the QML item, or 
    • presenting information related to the QML item that is currently highlited.

Tuesday 20 June 2017

TrafficControl: QML MapCircle Element Exploratory Testing and Design proposals

In this blog post, I'll explore how the QML Map Circle behaves to understand what I can do with it.

First step is to define a green circle with radius 500 m, opacity 0.3, and a black border of 30 pixels:
The border  is centered on the edge of the circle, consists of several overlapping rectangles.
When zooming out, the border is bigger compared to the green circle, since it is defined in terms of pixels.


Conclusion: The border shouldn't be too big, since that will block the inner circle. The border opacity is similar as the circle.

  • The opacity should be at least 0.3 and at most 0.7.
  • The border width can be from 0 to 4 pixels.
  • As stations will typically have distances of at least 2000 meters, so a maximum radius of 1000 should be sufficient.
  • White circles with black borders should be avoided since that might be confused with towns.

For now, I'll use the following coding:

  • border.width: 3 (always)
  • border.color: Green (all platforms available), yellow (at least one platform taken and at least one platform available), red (all platforms are taken). For now, I'll use only Green and Red since the number of platforms are currently not available. 
  • radius: number of waiting passengers [100-1000 m, default: 100 m]. Mapping of waiting passengers to radius will come later (to be implemented later).
  • color: A metric of the delays (to be implemented later).
  • opacity: 0.4 (not defined what to visualize)
This means that I'll also need to implement a list of  trains currently located at each station. When a train arrives or departs, the border.color may change.

Friday 16 June 2017

TrafficControl: Modifying Existing Station QML Items from C++ (continued)

In the previous blog post, I was able to send a signal from C++ to the QML part of the program. This is necessary to be able to update the QML map when the trains, stations and tracks change.

There are two ways to update the QML parts:
  • Either change the QML object properties directly from C++ (this is generally recommended). However, this approach requires the C++ part to know about the internal structure of the QML part, which will make future updates of QML structure very risky. http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html 
  • Use signal-slot to invoke a QML Javascript where the QML object properties are changed. I'll follow this approach for now.
I have a signal/slot relation between C++ and QML part

When the train arrives to the station, tcStation:trainArrival will emit that signal to the QML part:

The slot part in QML will iterate through the QML objects until it finds the corresponding station. 
I followed the example on https://stackoverflow.com/questions/13187439/qml-element-id-access-from-c
When it finds those stations, it will modify them, in this case changing the color to red and the radius to 1000 m.





Now, I need to think through the graphical design of the map elements (tracks, trains and stations), so that they will reflect the relevant information. I'll cover that in future blog posts.

Some notes:
To be able to send data to a QML/JS slot, the parameters must be of the type QVariant (a QVariant acts like a union of the most common Qt data types).

There will be a need for future optimizations in this approach. I may need to save the address/index to the QML items in the C part so that I won't need to iterate through all QML items every time I'm updating any QML item.

I later renamed the slot to qmlStationOccupancySlot

Sunday 11 June 2017

TrafficControl: Modifying Existing Station QML Items from C++

The blog posts has been scarse, due to positive news in my closest family. I'll be a busy family man for the coming decades but I'll keep writing on this blog.

When something happens to a station in the C++ part of the program, the corresponding QML item shall be modified. I got inspiration from a post on Andrew Jones' blog, regarding QML/C++ interactions using signals/slots.

Train::move() will trigger signal that will be caught by the QML part and update the map.
  • A train enters a station
  • A signal is trigged by train::move(), containing the station name, the train name and a description of the event
  • A slot in the QML part recieves the signal and extracts the information.
  • The corresponding QML item is updated
The new signal is called stationChangedSignal, and will contain three qVariants:
  1. The first will always contain the name of the station that is changing
  2. The second parameter will define what has happened (in this case: "train arrival")
  3. The third parameter will define any other items/objects (in this case, the train name)
In this case, I'll let the train::runningToOpeningState() emit a signal:
stationChangedSignal("LundC", "train arrival",  "Hedy_Lamarr")

This signal will tell the QML part that a train named "Hedy_Lamarr" has arrived to the station LundC".

The current commit, 1c198ff, has introduced a signal without any parameters. I still have some problems parsing a signal containing qVariant data to the QML javascript. More about that in the next blog post.