Tuesday 26 July 2016

TrafficControl: MapQuest/OSM needs API Key

For the last time, I've been working experimenting with maps using QML and MapQuest/Open Street Maps. The application logic is still in C++ but the map handling is in QML, where the map is rendered. Unfortunately, API keys are needed for applications using OSM  since July 11th this year.

The consequence of this is that the map tiles applications get from OSM contains no useful map information:
Before, the center of Malmö was shown


The issue is also affecting the default Qt examples, and there is a bug report addressing this issue: https://bugreports.qt.io/browse/QTBUG-5459. Currently, it isn't clear how to add that API key in Qt/QML programs. For the Qt version 5.6, API keys aren't supported, but hopefully the Qt developers may provide a patch for that.

I assume that OSM has introduced this API key requirement to reduce traffic to the servers and to have some control of which software packages that can access the servers. Providing servers and storage for maps are very resource demanding.

For my program, I can still investigate the implementation, where I'm trying to figure out how to add tracks to QML dynamically when the program reads the KML file. I am considering some C++ model that is interacting with a QML view.

Update:
The lesson of this is that software depending on external parties needs to be revised on a regular basis, since there will be changes to external interfaces.

Saturday 9 July 2016

TrafficControl: Calculating Distances between Coordinates on the Surface of a Sphere

Distance calculations will be essential for the TrafficControl program. In a flat world, Pythagoras theorem would do just fine, but the calculations will be done on the surface of a sphere.

Starting from Paris, moving 2000 km north and after that 1000 km to the east, you will end up close to Rovaniemi, Finland. Moving 1000 km east from Paris and then 2000 km north, you will end up south of the national park of Sarek, 400 km off. This happens as the distance around the world along a certain latitude is smaller when moving away from the equator.

The Haversine formula takes all this into account. The implementation I use is:

def haversine(lon1, lat1, lon2, lat2):  #From rosettacode.org

  R = 6372.8 # Earth radius in kilometers
  dLat = radians(lat2 - lat1)
  dLon = radians(lon2 - lon1)
  lat1 = radians(lat1)
  lat2 = radians(lat2)

  a = sin(dLat/2)**2 + cos(lat1)*cos(lat2)*sin(dLon/2)**2
  c = 2*asin(sqrt(a))

  return R * c

Here, the distance between the coordinates (lon1, lat1) and (lon2, lat2) is R*c.

Keep in mind to check whether the coordinates are sent with longitude first and latitude last or the other way around. That will reduce the risk of tricky bugs.