Results 1 to 6 of 6

Thread: change in zoomLevelConfigurations only take effect after significant speed change

  1. #1
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123

    have a change in zoomLevelConfigurations take effect immediately

    While in navigation I have "autoZoom" enabled by setting the zoomLevelConfigurations of the SKNavSettings Property. Autozoom works fine.
    Now, I also want the user to change the zoom level manually, so I added zoom buttons.

    Upon tapping the zoom button I change the SKNavigationSettings zoomLevelConfigurations and call SKRoutingService.sharedInstance().changeNavigation Settings(self.navSettings)

    Also this works fine, but the map doesn't zoom in or out immediately after tapping a zoom button. It only changes after a significant (> 2km/hr) speed change was detected (this is at least what I found in my tests, could also be a significant location change, I don't know.).

    What I'd like to achieve is that when the user taps one of the zoom buttons, he sees the map zoom in or zoom out immediately, regardless if he's not moving or moving. I tried simulating a significant speed change right after changing the navSettings zoomLevelConfiguration (see commented out lines in code), but so far unsuccessful.

    Is there a way to have a change in the zoomLevelConfigurations have effect immediately, regardless of a speed change?

    Thanks & Regards,
    Guido

    Here is the code:

    Code:
        var maxZoomLevel: Float = 19
        var navSettings: SKNavigationsettings!
        var locManager: CLLocationManager //necessary to enable background navigation in iOS9 (as I'm still on 2.5.0)
    
        @IBAction func tappedZoomInButton(sender: AnyObject) {
            dispatch_async(dispatch_get_main_queue()) {
                self.maxZoomLevel = min(19, self.maxZoomLevel + 1)
                self.setZoomLevel()
                SKRoutingService.sharedInstance().changeNavigationSettings(self.navSettings)
    //            let curLocation = self.locManager.location!
    //            let simLocation = CLLocation(coordinate: curLocation.coordinate, altitude: curLocation.altitude, horizontalAccuracy: curLocation.horizontalAccuracy, verticalAccuracy: curLocation.verticalAccuracy, course: curLocation.course, speed: curLocation.speed + 3, timestamp: curLocation.timestamp)
    //            SKPositionerService.sharedInstance().positionerMode = .PositionSimulation
    //            SKPositionerService.sharedInstance().reportGPSLocation(simLocation)
    //            SKPositionerService.sharedInstance().positionerMode = .RealPositions
            }
    
        }
        
        @IBAction func tappedZoomOutButton(sender: AnyObject) {
            dispatch_async(dispatch_get_main_queue()) {
                guard self.maxZoomLevel > 7 else { return }
                self.maxZoomLevel = max(7, self.maxZoomLevel - 1)
                self.setZoomLevel()
                SKRoutingService.sharedInstance().changeNavigationSettings(self.navSettings)
    //            let curLocation = self.locManager.location!
    //            let simLocation = CLLocation(coordinate: curLocation.coordinate, altitude: curLocation.altitude, horizontalAccuracy: curLocation.horizontalAccuracy, verticalAccuracy: curLocation.verticalAccuracy, course: curLocation.course, speed: curLocation.speed + 3, timestamp: curLocation.timestamp)
    //            SKPositionerService.sharedInstance().positionerMode = .PositionSimulation
    //            SKPositionerService.sharedInstance().reportGPSLocation(simLocation)
    //            SKPositionerService.sharedInstance().positionerMode = .RealPositions
            }
        }
        
        func setZoomLevel() {
            let zoomLevel1 = SKZoomLevelConfiguration()
            zoomLevel1.speedInterval = SKSpeedInterval(minimumSpeed: 0, maximumSpeed: 10)
            zoomLevel1.zoomLevel = maxZoomLevel
            let zoomLevel2 = SKZoomLevelConfiguration()
            zoomLevel2.speedInterval = SKSpeedInterval(minimumSpeed: 10, maximumSpeed: 25)
            zoomLevel2.zoomLevel = maxZoomLevel - 1
            let zoomLevel3 = SKZoomLevelConfiguration()
            zoomLevel3.speedInterval = SKSpeedInterval(minimumSpeed: 25, maximumSpeed: 70)
            zoomLevel3.zoomLevel = maxZoomLevel - 2
            let zoomLevel4 = SKZoomLevelConfiguration()
            zoomLevel4.speedInterval = SKSpeedInterval(minimumSpeed: 70, maximumSpeed: 120)
            zoomLevel4.zoomLevel = maxZoomLevel - 4
            let zoomLevel5 = SKZoomLevelConfiguration()
            zoomLevel5.speedInterval = SKSpeedInterval(minimumSpeed: 120, maximumSpeed: 500)
            zoomLevel5.zoomLevel = maxZoomLevel - 6
            navSettings.zoomLevelConfigurations = [zoomLevel1, zoomLevel2, zoomLevel3, zoomLevel4, zoomLevel5]
        }
    Last edited by guidove; 13.04.2016 at 20:21.

  2. #2
    Oberskobbler
    Join Date
    22.07.2014
    Posts
    399
    The zoomLevelConfiguration is designed to properly work in navigation scenarios therefore it's connected to the movement speed (current implementation closely ties the zoomLevelConfiguration to the speed)
    Maybe you can achieve your intended effect by manipulating the 3dCameraSettings?
    See: http://developer.skobbler.com/docs/a...aSettings.html

  3. #3
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123
    Thanks for the reply Adela.
    I understand why it acts like it does. I guess the zoomLevelConfig is not meant to be changed during Navigation. I was just hoping there was a way to "trick" the framework to immediately apply the new zoomLevelConfiguration.

    The 3DCameraSettings is not an option for me because I'm allowing the user to switch between 2D and 3D.

    Is there no "trick" for the framework to apply the new zoomConfig immediately? I tried this by temporarily switching to "Simulation" mode and then sending a location that's different form the current location (see above commented out code), but that didn't seem to do the trick.

    Thanks and regards,
    Guido
    Oh, I'm on iOS, still using 2.5.0 btw Perhaps I'm gonna update to 2.5.1, but depends on when your next release is planned. Any news on that? Saw the thread on this, but it's been quite there for a little while.

  4. #4
    Oberskobbler
    Join Date
    22.07.2014
    Posts
    399
    Another trick: set zoomLevelConfig on nothing, force the zoom level you need (through visible region or something else) then set again the zoomLevelConfig - try this and let us know if this is a good solution for what you need.

    Reg the new update - should be available soon (this/ next month)- until then we can offer the beta build for testing if you send a request at dev@telenav.com

  5. #5
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123
    Hi Adela,

    Thanks for the suggestion. This actually seemed to work, however I ran into another issue: auto zoom is not working in 3D mode.
    I decided to implement my own zooming function (see below) and ran into another problem: animateToZoomlevel and animateToBearing seem to reset the positionerAlignment of SKNavigationSettings. I tried setting back the positionerAlignment right after animating, but that didn't work. As a workaround for this I used visibleRegion and the (deprecated) bearing property of SKMapView. This is not as nice as these don't animate, but it does the trick.

    Perhaps someone else is looking for the same so I'll share a bit of my code here. With this code you have autozoom and you can adjust the zoom level manually with zoomIn and zoomOut buttons. It works in 3D and 2D mode and in HeadingUp or NorthUp mode. It's just copy paste so if someone has questions about it, fire away.

    Code:
        @IBOutlet weak var zoomInButton: UIButton!
        @IBOutlet weak var zoomOutButton: UIButton!
        var maxZoomLevel: Float = 17
        var zoomLevelsForSpeedRanges: [(minSpeedMperS: Double, zoomLevel: Float)]!
        var currentSpeedRange: (minSpeedMperS: Double, maxSpeedMperS: Double) = (0,4)
    
        func routingService(routingService: SKRoutingService!, didChangeCurrentSpeed speed: Double) {
            //print("NAVDELEGATE: didChangeCurrentSpeed - \(speed)")
            self.navInfo.currentSpeed = speed
            maxSpeedMperS = max(maxSpeedMperS,speed)
            if speed < currentSpeedRange.minSpeedMperS || speed >= currentSpeedRange.maxSpeedMperS {
                self.zoomToNewZoomLevel()
            }
            if UIApplication.sharedApplication().applicationState == .Active {
                dispatch_async(dispatch_get_main_queue()) {(_) -> Void in
                    self.updateSpeedLabel()
                }
            }
        }
    
        @IBAction func tappedZoomInButton(sender: AnyObject) {
            dispatch_async(dispatch_get_main_queue()) {(_) -> Void in
                self.mapSettingsVisibilityTimer?.invalidate()
                self.mapSettingsVisibilityTimer = NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: #selector(NavViewController.hideMapSettingsView), userInfo: nil, repeats: false)
            }
            guard self.maxZoomLevel < 19 else { return }
            self.maxZoomLevel = min(19, self.maxZoomLevel + 0.5)
            self.setZoomLevelForRanges()
            self.zoomToNewZoomLevel()
        }
        
        @IBAction func tappedZoomOutButton(sender: AnyObject) {
            dispatch_async(dispatch_get_main_queue()) {(_) -> Void in
                self.mapSettingsVisibilityTimer?.invalidate()
                self.mapSettingsVisibilityTimer = NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: #selector(NavViewController.hideMapSettingsView), userInfo: nil, repeats: false)
            }
            guard self.maxZoomLevel > 7 else { return }
            self.maxZoomLevel = max(7, self.maxZoomLevel - 0.5)
            self.setZoomLevelForRanges()
            self.zoomToNewZoomLevel()
        }
    
        @IBAction func tapped3DButton(sender: AnyObject) {
            dispatch_async(dispatch_get_main_queue()) {
                self.mapSettingsVisibilityTimer?.invalidate()
                print("mapSettingsVisibilityTimer Timer Stopped")
                self.mapSettingsVisibilityTimer = NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: #selector(NavViewController.hideMapSettingsView), userInfo: nil, repeats: false)
                print("mapSettingsVisibilityTimer Timer Started")
            }
            if UD.mapIs2D! {
                UD.mapIs2D = false
                ThreeDButton.setImage(UIImage(named: "3D"), forState: .Normal)
                SKRoutingService.sharedInstance().mapView?.settings.displayMode = SKMapDisplayMode.Mode3D
            }
            else {
                UD.mapIs2D = true
                ThreeDButton.setImage(UIImage(named: "2D"), forState: .Normal)
                SKRoutingService.sharedInstance().mapView?.settings.displayMode = SKMapDisplayMode.Mode2D
            }
            zoomToNewZoomLevel()
        }
        
        @IBAction func tappedNorthUpButton(sender: AnyObject) {
            dispatch_async(dispatch_get_main_queue()) {
                self.mapSettingsVisibilityTimer?.invalidate()
                print("mapSettingsVisibilityTimer Timer Stopped")
                self.mapSettingsVisibilityTimer = NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: #selector(NavViewController.hideMapSettingsView), userInfo: nil, repeats: false)
                print("mapSettingsVisibilityTimer Timer Started")
            }
            let currentZoomLevel = SKRoutingService.sharedInstance().mapView!.visibleRegion.zoomLevel
            SKRoutingService.sharedInstance().mapView!.settings.zoomLimits = SKMapZoomLimits(mapZoomLimitMin: currentZoomLevel, mapZoomLimitMax: currentZoomLevel)
            if UD.mapNorthUp! {
                UD.mapNorthUp = false
                northUpButton.setImage(UIImage(named: "headingUp"), forState: .Normal)
                if let currentBearing = SKPositionerService.sharedInstance().currentHeading?.trueHeading {
                    SKRoutingService.sharedInstance().mapView!.bearing = Float(currentBearing)
                }
                SKRoutingService.sharedInstance().mapView!.centerOnCurrentPosition()
                SKRoutingService.sharedInstance().mapView!.settings.headingMode = SKHeadingMode.Route
                navSettings.positionerAlignment = SKPositionerAlignment(vertical: -0.25, horizontal: 0)
                SKRoutingService.sharedInstance().changeNavigationSettings(navSettings)
            }
            else {
                UD.mapNorthUp = true
                northUpButton.setImage(UIImage(named: "northUp"), forState: .Normal)
                SKRoutingService.sharedInstance().mapView!.settings.headingMode = SKHeadingMode.RotatingHeading
                navSettings.positionerAlignment = SKPositionerAlignment(vertical: -0.1, horizontal: 0)
                SKRoutingService.sharedInstance().changeNavigationSettings(navSettings)
                SKRoutingService.sharedInstance().mapView!.bearing = 0
            }
            SKRoutingService.sharedInstance().mapView!.settings.zoomLimits = SKMapZoomLimits(mapZoomLimitMin: 0, mapZoomLimitMax: 19)
            zoomToNewZoomLevel()
        }
        
        func setZoomLevelForRanges() {
            zoomLevelsForSpeedRanges = [
                (0, maxZoomLevel), // > 0 km/h
                (4, maxZoomLevel - 1), // > 14,4 km/h
                (9, maxZoomLevel - 2), // > 32,4 km/h
                (25, maxZoomLevel - 3), // > 90 km/h
                (40, maxZoomLevel - 3.5), // > 144 km/h
            ]
        }
        
        func zoomToNewZoomLevel() {
            var newZoom: Float!
            for (index, range) in zoomLevelsForSpeedRanges.enumerate().reverse() {
                if navInfo.currentSpeed >= range.minSpeedMperS {
                    newZoom = range.zoomLevel
                    currentSpeedRange = (range.minSpeedMperS, index == 4 ? 500 : zoomLevelsForSpeedRanges[index+1].minSpeedMperS)
                    print("New Speed Range: \(currentSpeedRange.minSpeedMperS) - \(currentSpeedRange.maxSpeedMperS)")
                    break
                }
            }
            dispatch_async(dispatch_get_main_queue()) {(_) -> Void in
                SKRoutingService.sharedInstance().mapView.visibleRegion = SKCoordinateRegion(center: SKRoutingService.sharedInstance().mapView.visibleRegion.center, zoomLevel: newZoom)
            }
        }
    Last edited by guidove; 21.04.2016 at 01:18.

  6. #6
    Oberskobbler
    Join Date
    22.07.2014
    Posts
    399
    Happy to hear you manage to make it work and thanks for sharing with us the tricks.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •