Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

lineWithForPolylineAnnotation delegate not changing line width #15773

Closed
Arrodl opened this issue Oct 7, 2019 · 12 comments
Closed

lineWithForPolylineAnnotation delegate not changing line width #15773

Arrodl opened this issue Oct 7, 2019 · 12 comments
Labels
annotations Annotations on iOS and macOS or markers on Android iOS Mapbox Maps SDK for iOS

Comments

@Arrodl
Copy link

Arrodl commented Oct 7, 2019

Using the delegates for MGLPolyline is not changing the style of the Feature

Screen Shot 2019-10-07 at 11 58 07 AM

Expected behavior

Line with should change sizes

Actual behavior

Line with is always same size, no matter the value given

Configuration

I´ve tried with the delegates, aswell as with style layers which results in mapView ignoring every kind of styles provided, even with the geojson and code provided in this example

https://docs.mapbox.com/ios/maps/examples/shape-collection/

Mapbox SDK versions: 5.4.0
iOS/macOS versions: 5.4.0
Device/simulator models: Physical devise iOS 13 iphone 7 32 GB
Xcode version: 11

@jmkiley jmkiley added annotations Annotations on iOS and macOS or markers on Android iOS Mapbox Maps SDK for iOS labels Oct 7, 2019
@jmkiley
Copy link
Contributor

jmkiley commented Oct 7, 2019

Hello -

Thank you for your report. I haven't been able to reproduce this issue with iOS SDK v5.4.0.

Can you confirm where you are setting the MGLMapViewDelegate?

Code I used
override func viewDidLoad() {
        super.viewDidLoad()

        let mapView = MGLMapView(frame: view.bounds)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        // Set the map’s center coordinate and zoom level.
        mapView.setCenter(CLLocationCoordinate2D(latitude: 59.31, longitude: 18.06), zoomLevel: 9, animated: false)
        view.addSubview(mapView)
        mapView.delegate = self

        let coordinates = [mapView.visibleCoordinateBounds.ne, mapView.visibleCoordinateBounds.sw]
        let annot = MGLPolyline(coordinates: coordinates, count: 2)
        mapView.add(annot)
    }

    func mapView(_ mapView: MGLMapView, lineWidthForPolylineAnnotation annotation: MGLPolyline) -> CGFloat {
        return 10
    }

    func mapView(_ mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor {
        return .white
    }

@Arrodl
Copy link
Author

Arrodl commented Oct 7, 2019

This is the code i used

class MEMMapController: UIViewController, MGLMapViewDelegate {

let minZoomForRegion : Double = 3.08
let center = CLLocationCoordinate2D(latitude: 19.432608, longitude: -99.133209)

@IBOutlet var mapView: MGLMapView!

override func viewDidLoad () {
    super.viewDidLoad()
    mapView.delegate = self

// mapView.maximumZoomLevel = minZoomForRegion
mapView.setCenter(center, zoomLevel: minZoomForRegion, animated: true)
}

private func drawMexicanPolyline () {
    DispatchQueue.global(qos: .background).async {
        let jsonPath = Bundle.main.path(forResource: "sistemainterconectadonacional", ofType: "geojson")
        let url = URL(fileURLWithPath: jsonPath!)
        do {
            let data = try Data(contentsOf: url)
            guard let shapeCollectionFeature = try MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as? MGLShapeCollectionFeature else {
                fatalError("Could not parse geojson file")
            }
            for shape in shapeCollectionFeature.shapes {
                if let feature = shape as? MGLPolygonFeature {
                    feature.title = feature.attribute(forKey: "name") as? String
                    let labelPoint = MGLPointAnnotation()
                    labelPoint.coordinate = feature.coordinate
                    labelPoint.title = feature.attribute(forKey: "name") as? String
                    DispatchQueue.main.async { [unowned self] in
                        self.mapView.addAnnotation(labelPoint)
                        self.mapView.addAnnotation(feature)
                    }
                }
            }
        } catch {
            print("GeoJSON parsing failed")
        }
    }
}

func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
    drawMexicanPolyline()
}

var mapTimer : Timer?

func mapView(_ mapView: MGLMapView, lineWidthForPolylineAnnotation annotation: MGLPolyline) -> CGFloat {
    return 0.98
}

func mapView(_ mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor {
    return .white
}

func mapView(_ mapView: MGLMapView, regionDidChangeWith reason: MGLCameraChangeReason, animated: Bool) {
    if reason != .programmatic {
        let centerCoordinate = CLLocation(latitude: self.center.latitude, longitude: self.center.longitude)
        let distance = centerCoordinate.distance(from: CLLocation(latitude: mapView.camera.centerCoordinate.latitude, longitude: mapView.camera.centerCoordinate.longitude))
        if distance > 1000000 {
            if mapTimer != nil {
                mapTimer!.invalidate()
            }
            mapTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { (_) in
                self.mapView.setCenter(self.center, zoomLevel: self.minZoomForRegion, animated: true)
            }
        }
    }
}

func mapView(_ mapView: MGLMapView, alphaForShapeAnnotation annotation: MGLShape) -> CGFloat {
    return 0.9
}

func mapView(_ mapView: MGLMapView, fillColorForPolygonAnnotation annotation: MGLPolygon) -> UIColor {
    return Constant.Color.darkGray
}

func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
    guard annotation is MGLPointAnnotation else {
        
        return nil
    }
    let reuseIdentifier = "\(annotation.coordinate.longitude)"
    var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
    if annotationView == nil {
        let title : String = annotation.title! ?? ""
        annotationView = RegionAnnotationView(reuseIdentifier: reuseIdentifier, title: title)
        annotationView!.bounds = CGRect(x: 0, y: 0, width: 10 + title.uppercased().width(withConstrainedHeight: 15, font: Constant.Font.smallFont!), height: 15)
        annotationView!.backgroundColor = .white
    }
    
    return annotationView
}

func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation) {
    let region = RegionManager.shared.findRegion(by: annotation.title!!)
    let alert = UIAlertController(title: annotation.title ?? "", message: "El id de la región es \(region?.id ?? 0)", preferredStyle: .actionSheet)
    alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
    self.present(alert, animated: true, completion: nil)
}

func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
    return false
}

}

@Arrodl
Copy link
Author

Arrodl commented Oct 7, 2019

But is not that the line does not appear, it does, but no way to change it`s width, i no longer have the code for the line style implementation but i does not work

@jmkiley
Copy link
Contributor

jmkiley commented Oct 8, 2019

Thank you for the sample code @Arrodl. I see where you are adding an MGLPolygonFeature, but I don't see where an MGLPolylineFeature is being added. Are you trying to style the stroke width on the MGLPolygonFeature?

@Arrodl
Copy link
Author

Arrodl commented Oct 9, 2019

Yes

@Arrodl
Copy link
Author

Arrodl commented Oct 9, 2019

This would be the implementation using the MGLPolylineFeature

if let geometry = shape.geoJSONDictionary()["geometry"] as? [String : Any],
                            let baseCoordinates = geometry["coordinates"] as? [[[Double]]],
                            let coordinateCollection = baseCoordinates.first {
                            let collection = coordinateCollection.map({ CLLocationCoordinate2D(latitude: $0.first!, longitude: $0.last!) })
                            let pairs = stride(from: 0, to: collection.endIndex, by: 2).map {
                                (collection[$0], $0 < collection.index(before: collection.endIndex) ? collection[$0.advanced(by: 1)] : collection.first)
                            }
                            for pair in pairs {
                                let sourceName = "\(indexIdentifer)helper-source"
                                let styleName = "\(indexIdentifer)helper-style"
                                let polyline = MGLPolylineFeature(coordinates: [pair.0, pair.1!], count: 2)
                                if let source = self.mapView.style?.source(withIdentifier: sourceName) as? MGLShapeSource {
                                    source.shape = polyline
                                } else {
                                    let color = UIColor.white
                                    let source = MGLShapeSource(identifier: sourceName, features: [polyline], options: nil)
                                    let lineStyle = MGLLineStyleLayer(identifier: styleName, source: source)
                                    lineStyle.lineWidth = NSExpression(forConstantValue: 8)
                                    lineStyle.lineColor = NSExpression(forConstantValue: color)
                                    DispatchQueue.main.async {
                                        self.mapView.style?.addSource(source)
                                        self.mapView.style?.addLayer(lineStyle)
                                    }
                                }
                                indexIdentifer += 1
                            }
                        }

@Arrodl
Copy link
Author

Arrodl commented Oct 9, 2019

This does not work and has performance issues so i have to remove it, however this works when drawing limited amounts of lines as seen here:

IMG_5049

@Arrodl
Copy link
Author

Arrodl commented Oct 24, 2019

?

@jmkiley
Copy link
Contributor

jmkiley commented Oct 24, 2019

Hello -

Could you clarify whether you are using both #15773 (comment) and #15773 (comment) in the same implementation, or separately?

@Arrodl
Copy link
Author

Arrodl commented Oct 24, 2019

Same implementation

@jmkiley
Copy link
Contributor

jmkiley commented Oct 24, 2019

Thank you for the additional information! [MGLMapViewDelegate lineWidthForPolylineAnnotation] does not work for MGLLineStyleLayer objects because they are not rendered as annotations, even if they have an MGLAnnotation subclass as a source. Instead, update the lineWidth property on the MGLLineStyleLayer. You may also want to check the order of your style's layers in order to ensure that the MGLLineStyleLayer is above your annotations, as well as to confirm that you are creating and adding the source and layer after the style has finished loading.

If you would prefer to use [MGLMapViewDelegate lineWidthForPolylineAnnotation], create a MGLPolylineFeature instead of the style layer and add it to your map view as an annotation.

If you continue to see this issue, a minimal test case that reproduces the issue would help us to troubleshoot.

@julianrex
Copy link
Contributor

Closing as answered.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
annotations Annotations on iOS and macOS or markers on Android iOS Mapbox Maps SDK for iOS
Projects
None yet
Development

No branches or pull requests

3 participants