mapbox-maps-ios icon indicating copy to clipboard operation
mapbox-maps-ios copied to clipboard

CircleLayer.circleTranslate with circleTranslateAnchor === .viewport is not working as expected

Open zo0m opened this issue 1 year ago • 2 comments

Environment

  • Xcode version: Version 16.1 (16B40)
  • iOS version: 18.1
  • Devices affected: iPhone 13 Pro, Simulator iPhone 16 Pro
  • Maps SDK Version: 11.8.0

Observed behavior and steps to reproduce

circleTranslate with circleTranslateAnchor === .viewport is not working as expected. I expected (and it worked on 6.3.0) distance between 2 points the same on any zoom level But it looks like circleTranslate ignores circleTranslateAnchor, because point distance is different on different zoom levels

Expected behavior

circleTranslate should not be dependant on zoom level if circleTranslateAnchor === .viewport

Notes / preliminary analysis

Maybe circleTranslateAnchor is ignored

Additional links and references

Demo of my example (code below): https://www.loom.com/share/4db96bcaacfd4ed69cc271fe5bc7a2ee

Demo of my working app, where I'm dragging points: https://www.loom.com/share/a9ec12fda2b547c2bca889d9cb676144

import MapboxMaps
import UIKit


class ViewController: UIViewController {
    
    private var cancelables = Set<AnyCancelable>()
    private var fcMapEditors = Set<FCMapEditor>()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let centerCoordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0)
        let options = MapInitOptions(cameraOptions: CameraOptions(center: centerCoordinate, zoom: 2.4))
        
        let mapView = MapView(frame: view.bounds, mapInitOptions: options)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(mapView)
        
        mapView.mapboxMap.onNext(event: .mapLoaded) { _ in
            self.addCircleLayers(mapView: mapView)
        }
    }
    
    // Function to add circle layers to the map
    func addCircleLayers(mapView: MapView) {
        let pointCoordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0)
        
        var source = GeoJSONSource(id: "circle-source")
        source.data = .featureCollection(FeatureCollection(features: [Feature(
            geometry: .point(Point(pointCoordinate))
        )]))
        try? mapView.mapboxMap.addSource(source)
        
        // Define the red circle layer
        var redCircleLayer = CircleLayer(id: "red-circle", source: "circle-source")
        redCircleLayer.circleColor = .constant(StyleColor(.red))
        redCircleLayer.circleRadius = .constant(10.0)
        
        // Define the green circle layer with translation offset
        var greenCircleLayer = CircleLayer(id: "green-circle", source: "circle-source")
        greenCircleLayer.circleColor = .constant(StyleColor(.green))
        greenCircleLayer.circleRadius = .constant(10.0)
        greenCircleLayer.circleTranslateAnchor = .constant(.viewport)
        greenCircleLayer.circleTranslate = .constant([100.0, 0.0]) // Offset the green circle
        
        
        // Add layers to map
        try? mapView.mapboxMap.addLayer(redCircleLayer)
        try? mapView.mapboxMap.addLayer(greenCircleLayer)
    }
}

zo0m avatar Dec 30 '24 16:12 zo0m

Mapbox 6.3.0 works fine.

Demo: https://www.loom.com/share/988655a7b6a7436696573ad3517c97aa

Code:


import UIKit
import Mapbox

class ViewController: UIViewController, MGLMapViewDelegate {
    
    var mapView: MGLMapView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Initialize the map view with a frame
        mapView = MGLMapView(frame: view.bounds)
        
        // Set the map's center coordinate and zoom level
        mapView.setCenter(CLLocationCoordinate2D(latitude: 0, longitude: 0), zoomLevel: 2.4, animated: false)
        
        // Set the delegate to self
        mapView.delegate = self
        
        // Add the map view to the view hierarchy
        view.addSubview(mapView)
    }
    
    // MARK: - MGLMapViewDelegate
    
    func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
        addCircleLayers(to: mapView)
    }
    
    // Function to add circle layers to the map
    func addCircleLayers(to mapView: MGLMapView) {
        guard let style = mapView.style else {
            print("Style not loaded yet.")
            return
        }
        
        // 1. Create a GeoJSON source
        let point = MGLPointFeature()
        point.coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0)
        let geoJSON = MGLShapeCollectionFeature(shapes: [point])
        
        let source = MGLShapeSource(identifier: "circle-source", shape: geoJSON, options: nil)
        style.addSource(source)
        
        // 2. Create the red circle layer
        let redCircleLayer = MGLCircleStyleLayer(identifier: "red-circle", source: source)
        redCircleLayer.circleColor = NSExpression(forConstantValue: UIColor.red)
        redCircleLayer.circleRadius = NSExpression(forConstantValue: 10.0)
        style.addLayer(redCircleLayer)
        
        // 3. Create the green circle layer with translation offset
        let greenCircleLayer = MGLCircleStyleLayer(identifier: "green-circle", source: source)
        greenCircleLayer.circleColor = NSExpression(forConstantValue: UIColor.green)
        greenCircleLayer.circleRadius = NSExpression(forConstantValue: 10.0)
        greenCircleLayer.circleTranslation = NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: 100, dy: 0)))
        greenCircleLayer.circleTranslationAnchor = NSExpression(forConstantValue: "viewport")
        style.addLayer(greenCircleLayer)
    }
}

zo0m avatar Jan 02 '25 10:01 zo0m

https://jsfiddle.net/9kohupe0/6/

Mapbox GL has the same bug.

  • Open fiddle

  • zoom out

  • see that circles don't keep their distance and 'jumping'

  • change pitch and see that distance is not keeping the same

zo0m avatar Jan 02 '25 10:01 zo0m