View Full Version : Get notified when map has been loaded?

24.02.2015, 23:48
Is there a way to be notified when the map data/tiles have been loaded for the visible map region/boundingbox? Looked through the framework and the documentation, but can't seem to find a delegate method or property to check this.

I'm asking because routeCalculation fails if the map has not been completely loaded yet, so I would like to start route calculation after the map has finished loading. (Calculation fails for various reasons: InvalidStartCoordinate, InvalidDestinationCoordinate, CannotBeCalculated, SameStartAndDestinationCoordinate and when I try again after the map is loaded it calculates fine)

I could use renderMapImageInBoundingBox and listen to the mapViewDidFinishRenderingImageInBoundingBox callback, but that seems a bit overkill as I don't need an image of the map.

I could also keep retrying the calculation until it succeeds by initiating a retry from the didFailWithErrorCode callback, but then it will keep trying even if there is a real error.

Is there a notification like this, or perhaps another way of approaching this?

02.03.2015, 16:50
This is an interesting behaviour.

The online routing service by default connects to the online router when data is not available locally (cache or as an offline map) - the only error message that would make sense would be "Cannot be calculated" (i.e. it may be that you are experiencing connectivity issues and you cannot connect to the routing server).

The other error messages: InvalidStartCoordinate, InvalidDestinationCoordinate, SameStartAndDestinationCoordinate are connected to the input data you are using.

Could you attach the code you are using when calling the routing server?

Waiting for the map data to load is not the way to go - as we are using vector data, we are loading different "layers" asynchronously (this way you never see "white" tiles on the map, but data seems to appear on the map as time passes) and, if the data is not available locally, the route should be calculated on the server.

Again, please attach the code you are using (can you illustrate this behaviour by modifying the demo project?) and we'll look into it.

21.04.2015, 18:13
Sorry for my (very) late reply. Was tackling some other problems.

The situation is as follows:
I run my app on my iPhone for the first time (app is installed and there are no cached map regions etc.)
I then calculate a route (the route has 48 via points). The result is the following screenshot.
The blue line is a polygone line, connecting all the via point.
The red line is the calculated line.
During calculation (and also some 10-20 seconds after) I see the network activity indicator spinning. I image that's SKMaps downloading the map data and/or connecting the routing service????

Then I close the app and run it for a 2nd time. (It's already installed by now and it has cached map data)
I calculate the same route again and now it looks like the screenshot below.
I don't see the network activity indicator spinning at all during and after calculation.

The code I'm using to calculate the route is as follows:

func calculateAndDrawTrack() {
routingSettings = SKRouteSettings()
SKRoutingService.sharedInstance().mapView = self.mapView
SKRoutingService.sharedInstance().routingDelegate = self
SKRoutingService.sharedInstance().clearCurrentRout es()
routingSettings.shouldBeRendered = true
let routeRestriction = SKRouteRestrictions(avoidTollRoads: false, avoidHighways: false, avoidFerryLines: false, avoidBicycleWalk: true, avoidBicycleCarry: true)
routingSettings.routeRestrictions = routeRestriction
routingSettings.waitForCorridorDownload = true
routingSettings.routeMode = SKRouteMode.CarEfficient

routingSettings.startCoordinate = simplifiedRoutePoints.first!.coordinate
routingSettings.destinationCoordinate = simplifiedRoutePoints.last!.coordinate
println("start: \(routingSettings.startCoordinate.latitude):\(rout ingSettings.startCoordinate.longitude)")
println("desti: \(routingSettings.destinationCoordinate.latitude): \(routingSettings.destinationCoordinate.longitude)")

var viaPointArray = [SKViaPoint]()
for var i = 1; i < simplifiedRoutePoints.count - 1; ++i {
let viaPoint = SKViaPoint((Int32(i-1)), withCoordinate: simplifiedRoutePoints[i].coordinate)
if !viaPointArray.isEmpty && viaPointArray.count > 0 {
routingSettings.viaPoints = viaPointArray
SKRoutingService.sharedInstance().calculateRoute(r outingSettings)

This code is called by user action (so not in viewDidLoad or something). By the time the user action occurs the map is visible on screen, but on first launch I guess not all routing and map info is loaded yet since the network activity indicator is still spinning.

Below is an extract of the GPX file that I'm using to create the start, end and viaPoints (the forum editor did not take the full xml as attachment nor could I paste the full xml here). Let me know if you want that for testing and I'll send it to you by email.

lat="52.3836708" lon="4.7554064"
lat="52.3860138" lon="4.7339398"
lat="52.3944855" lon="4.7683827"
lat="52.430706" lon="4.7249365"
lat="52.405858" lon="4.6564436"
lat="52.3863316" lon="4.6469593"
lat="52.3920393" lon="4.609623"
lat="52.4092913" lon="4.6054602"
lat="52.4077463" lon="4.6143007"
lat="52.4490309" lon="4.6384192"
lat="52.4617338" lon="4.6331406"
lat="52.4645662" lon="4.5904827"
lat="52.4668407" lon="4.6054173"
lat="52.4716473" lon="4.6026278"
lat="52.4705744" lon="4.625845"
lat="52.4780753" lon="4.6442801"
lat="52.473278" lon="4.6555853"
lat="52.479372" lon="4.6635675"
lat="52.4735355" lon="4.6723223"
lat="52.4647067" lon="4.6681091"
lat="52.4357271" lon="4.726181"
lat="52.4404478" lon="4.7088003"
lat="52.4655104" lon="4.6992731"
lat="52.4922895" lon="4.7140789"
lat="52.5123239" lon="4.7489847"
lat="52.5213618" lon="4.7470019"
lat="52.5288105" lon="4.715538"
lat="52.5479507" lon="4.7209024"
lat="52.5704813" lon="4.7451496"
lat="52.5411701" lon="4.82862"
lat="52.525034" lon="4.8474169"
lat="52.5103569" lon="4.9447489"
lat="52.4686432" lon="4.9473667"
lat="52.4592876" lon="4.9566793"
lat="52.4576998" lon="4.9729872"
lat="52.4706602" lon="5.0101519"
lat="52.4641371" lon="5.0316525"
lat="52.4554381" lon="5.0294647"
lat="52.4552965" lon="5.0461578"
lat="52.4402332" lon="5.0477457"
lat="52.4248695" lon="5.0326395"
lat="52.4201059" lon="5.0717354"
lat="52.4136686" lon="5.0669718"
lat="52.4144411" lon="5.0550413"
lat="52.4010944" lon="5.031352"
lat="52.3880911" lon="5.0245714"
lat="52.3813105" lon="5.0024271"
lat="52.38994" lon="5.0018247"
lat="52.380717" lon="4.9722101"
lat="52.3774052" lon="4.9886513"

Thanks for your help. I really hope this is because I did something stupid in my code :-)

11.05.2015, 12:45
Sorry for the late reply.
Let me check with the dev team- I'll get back to you when I have an answer

24.07.2015, 11:18
Sorry for the late reply.
Let me check with the dev team- I'll get back to you when I have an answer

any follow up on this? Is there callback when tiles / map is completely loaded?

03.08.2015, 12:12
For longer routes you will receive 2 callbacks on route calculation:
- one as soon as the route is available and you have the data for the first part of the route (initial segments) - this way you can already display it on the map & start navigation
- a second one once all the route data is downloaded (including the buffer corridor) - since this takes longer, by default it is decoupled from the initial callback (for a better experience). You can override this behaviour by setting the "downloadRouteCorridor" (http://developer.skobbler.com/docs/android/2.5.0/com/skobbler/ngx/routing/SKRouteSettings.html#setDownloadRouteCorridor(bool ean)) flag

The second time you trigger the calculation the information is already available locally (cached) so it will be reused (no network calls).

Now, from your screenshots I don't understand the first picture where the red line (polyline) is different from the blue line - do you draw the red line based on the route? Can you include the code where you draw the polyline?

As for your request "Is there callback when tiles / map is completely loaded?" - it's hard to define what "completely" load means with an online connection. If you want full offline/on-board support then you have to download the map package as an on-board (offline) package - this way there will be no network calls.
When operating in "online" mode only the needed data is downloaded - when you zoom in, pan & calculate routes new data will be requested from the server (as expected).

Let me know if the above is of use to you or I there is something that I misunderstood or that I should further explain.

05.11.2015, 18:05
Hi dandronic, sorry for the late reply, but I've recently picked up the code where I left of. The problem remains. In my above example, didFinishRouteCalculation is only called once and the routeCorridor is downloaded (I check that).
The way my app works:
- I have a gpx track with many points.
- I run a "smart" coordinate-reducing algorithm on the track coordinates so that I end up with no more than 50 coordinates.
- I put those 50 coordinates to routingSettings.startCoordinate, routingSettings.viaPoints and routingSettings.destinationCoordinate
- I calculate the route and let it render on the map by routingSettings.shouldBeRendered = true...that's the RED line (i changed the default color)
- The BLUE line is a polyline of the original GPX track with the many points.

I did some more analyses. I wanted to check if it was a route calculation problem or a route rendering problem, so I drew another polyline based on the points in SKRoutingSettings.sharedInstance().routeCoordinate sForRouteWithId. This polyline follows the RED line exactly, so, it's not a rendering problem, it's a calculation problem.

I've now managed to implement a workaround, but it's not working great, it's heavy on performance and network activity and it's not really reliable. The workaround is:
In didFinishRouteCalculationWithInfo I check for UIApplication.sharedApplication().networkActivityI ndicatorVisible which tells me if Map Data is still being downloaded (even thought the route calculation finished). If it is I clear the routeCache and try re-calculate the route 2 seconds later. So, basically I disregard the calculated route while the network activity indicator is still running. If it's not running after route calculation finished I know the route is correct.

This of course is a very unstable and unreliable workaround. The networkActivityIndicator could also be spinning for another reason than MapData being downloaded. So I was hoping there would be another way to check if MapData is still being downloaded or a completely other way to do this. Am I the only one reporting this problem btw?

09.11.2015, 12:20
1 . Are you targeting only 1 specific geography? (i.e. Netherlands) - if yes, then you can make the map available as an offline map (either download on demand, or prebundle (http://sdkblog.skobbler.com/creating-an-app-with-a-pre-bundled-map/) within the app) - this should take the "map data missing" problem off the table.

2. Use the calculateRouteFromPoints API - this is the API that is designed to convert GPX tracks to routes - see http://sdkblog.skobbler.com/creating-routes-from-gps-points-gpx-track-navigation/ and http://forum.skobbler.com/showthread.php/7257-SIGSEGV-error-in-calculateRouteWithPoints() before you start

09.11.2015, 14:21
Hi Dragos,
Thanks for your reply. Unfortunately those 2 possibilities are not an option for me. 1. Yes, targeting multiple geografies and also want to make the offline maps a paid feature in my app. 2. We had a call about this a couple of months back. What I understood this is an enterprise plan feature (not an option for me at this time) so I implemented the workaround where I reduce the route points and calculate a route with viaPoints

No other way to do this? Or a better way (better than checking the networkactivityindicator) to check if map data is still being downloaded?


21.02.2016, 17:55
Hi Dragos,

Will this issue be addressed in the next release?
I'm still experiencing this issue. Even though I check for corridor downloaded (and that value is true) the calculated route is calculated wrong (i.e. using only main roads). When I give the map (or road data in the map area?) a bit more time to download it does calculate correctly.

Thanks & Regards,

28.03.2016, 16:17
hi guidove,

Unfortunately won't be available in the next SDK. What you could try is when calculating the route, to force the connectivity mode to Online.