Mapbox + Swiftui / Measure tool on map

47 Views Asked by At

I am using Mapbox API in a Swiftui project.

I would like a button on my map to start a function that allow users to tap two points and get the distance in between them (a simple straight line, not a route).

  • Tap button
  • create a black point on the map where the user make the first tap
  • create another point on the map where the user makes the second tap
  • Create a black polyline in between the two points
  • Display the distance in meters in the text box

See my attempt below :

What doesnt work here:

  • Cant get that PolylineAnnotation to work. What am I doing wrong ?
  • Can´t get that CoreLocation distance function to compile as well. What am I misunderstanding here ?
import SwiftUI
@_spi(Experimental) import MapboxMaps
import CoreLocation


struct testmap: View {
    @State private var isMeasuring = false
    @State private var startLocation: CLLocationCoordinate2D?
    @State private var measuredDistance: String?
    
    //    MEASUREMENT
    @State var isMeasureOn : Bool = false
    @State var touchPoint1:CLLocationCoordinate2D? = nil
    @State var touchPoint2:CLLocationCoordinate2D? = nil
    
    @State var distanceTwoPoints = touchPoint1.distance(from: touchPoint2)


    var lineArray: [CLLocationCoordinate2D?] {
        [touchPoint1, touchPoint2]
    }
    
    
    
    var body: some View {
        ZStack{
            Map(initialViewport: .camera(center: CLLocationCoordinate2D(latitude: 55.681, longitude: 12.59), zoom: 12)){
                
                // MEASURE
                if isMeasureOn {
                    if let point1 = touchPoint1 {
                        CircleAnnotation(centerCoordinate: point1)
                            .circleRadius(5)
                            .circleColor(StyleColor(.black))
                            .circleOpacity(1)
                    }
                    
                    if let point2 = touchPoint2 {
                        CircleAnnotation(centerCoordinate: point2)
                            .circleRadius(5)
                            .circleColor(StyleColor(.black))
                            .circleOpacity(1)
                    }
                    
                    // DRAW THE LINE IN BETWEEN THE TWO POINTS
                    PolylineAnnotation(lineCoordinates: lineArray?)
                }
                

            }
            
            // GET TAP COORDINATES
            .onMapTapGesture{ context in
                if touchPoint1 == nil {
                    touchPoint1 = context.coordinate
                    
                } else {
                    touchPoint2 = context.coordinate
                    
                }
                
            }
            
            
            VStack{
                Button {
                    isMeasureOn.toggle()
                    
                } label: {
                    if !isMeasureOn {
                        Image("ICO-RULER")
                            .font(.custom("Merriweather-Regular", size: 17))
                            .foregroundStyle(.black)
                            .padding(10)
                            .frame(maxWidth: 50, maxHeight:50, alignment:.center)
                            .background(Color.white
                                .shadow(color: Color.black.opacity(0.15), radius: 0, x: 4.0, y: 4.0))
                    } else {
                        Image("ICO-RULER")
                            .font(.custom("Merriweather-Regular", size: 17))
                            .foregroundStyle(.white)
                            .padding(10)
                            .frame(maxWidth: 50, maxHeight:50, alignment:.center)
                            .background(Color("CPHColor")
                                .shadow(color: Color.black.opacity(0.15), radius: 0, x: 4.0, y: 4.0))
                    }
                    
                    if isMeasureOn {
                        Text (distanceTwoPoints)
                            .background(Color.white)
                            .padding(10)
                    }
                    
                }
            }
            
        }
        
    }
}

Thanks a lot for your help. Sorry if the post doesnt comply with rules, I couldn´t understand why my first one was closed.

0

There are 0 best solutions below