GMSMapView-da jonlantirilgan polyline marshrutini qanday qilib olish kerak, xaritani ko'chirish bilan birga xaritada harakat qilish kerakmi?

Men CAShapeLayer kabi kodli kodni yaratdim, CAShapeLayer-ni GMSMapiew-ga sublayer sifatida qo'shdim, lekin agar xaritani ko'chirsam, qavat harakatlanmaydi. qatlamni qaerga qo'shishingiz mumkin, shunday qilib u xarita bilan birga harakatlanadimi?

   func layer(from path: GMSPath) -> CAShapeLayer {
        let breizerPath = UIBezierPath()
        let firstCoordinate: CLLocationCoordinate2D = path.coordinate(at: 0)
        breizerPath.move(to: self.mapView.projection.point(for: firstCoordinate))
        for i in 1 ..< Int((path.count())){
            print(path.coordinate(at: UInt(i)))
            let coordinate: CLLocationCoordinate2D = path.coordinate(at: UInt(i))
            breizerPath.addLine(to: self.mapView.projection.point(for: coordinate))
        }

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = breizerPath.reversing().cgPath
        shapeLayer.strokeColor = UIColor.green.cgColor
        shapeLayer.lineWidth = 4.0
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineJoin = kCALineJoinRound
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.cornerRadius = 5
        return shapeLayer
    }

    func animatePath(_ layer: CAShapeLayer) {
        let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
        pathAnimation.duration = 6
        //pathAnimation.delegate = self
        pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
        pathAnimation.fromValue = Int(0.0)
        pathAnimation.toValue = Int(1.0)
        pathAnimation.repeatCount = 100
        layer.add(pathAnimation, forKey: "strokeEnd")
    }

GoogleMapView tomonidan qo'shildi

    let shapelayer: CAShapeLayer = self.layer(from: path!)
    self.animatePath(shapelayer)
    self.mapView.layer.addSublayer(shapelayer)

I get the following output

14
bu qatorni UIViewController'ning ko'rinishidagi subview sifatida qo'shishga harakat qiling, GMSMapView
qo'shib qo'ydi muallif JuicyFruit, manba

6 javoblar

SWIFT

Deklaratsiya

var polyline = GMSPolyline()
var animationPolyline = GMSPolyline()
var path = GMSPath()
var animationPath = GMSMutablePath()
var i: UInt = 0
var timer: Timer!

Darw yo'nalishi bo'ylab

func drawRoute(routeDict: Dictionary) {

        let routesArray = routeDict ["routes"] as! NSArray

        if (routesArray.count > 0)
        {
            let routeDict = routesArray[0] as! Dictionary
            let routeOverviewPolyline = routeDict["overview_polyline"] as! Dictionary
            let points = routeOverviewPolyline["points"]
            self.path = GMSPath.init(fromEncodedPath: points as! String)!

            self.polyline.path = path
            self.polyline.strokeColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
            self.polyline.strokeWidth = 3.0
            self.polyline.map = self.mapView

            self.timer = Timer.scheduledTimer(timeInterval: 0.003, target: self, selector: #selector(animatePolylinePath), userInfo: nil, repeats: true)
        }
    }

Yo'lda turish

func animatePolylinePath() {
        if (self.i < self.path.count()) {
            self.animationPath.add(self.path.coordinate(at: self.i))
            self.animationPolyline.path = self.animationPath
            self.animationPolyline.strokeColor = UIColor.black
            self.animationPolyline.strokeWidth = 3
            self.animationPolyline.map = self.mapView
            self.i += 1
        }
        else {
            self.i = 0
            self.animationPath = GMSMutablePath()
            self.animationPolyline.map = nil
        }
    }

Taymerni to'xtatishni unutmangVillDisappear

self.timer.invalidate()

Chiqish

enter image description here

17
qo'shib qo'ydi
Tx tez aylantirish uchun
qo'shib qo'ydi muallif Harshal Valanda, manba
XI versiyasi 10.3.1 (iPhone 5) uning ishlashi mukammal emas. ba'zi hollarda qurilmada sekin va tezkor ishlaydi. IPhone 6-da 10.3.1 operatsion tizimida ishlayotgan bo'lsa, u 10.0.1 ga oshib ketadi.
qo'shib qo'ydi muallif Nisha, manba
Tez o'tkazish uchun juda ko'p narsa!
qo'shib qo'ydi muallif Bishan, manba
Ilova fon timerida ishlayotgan va dastur xotirani sarflash bilan tugatilishiga olib keladigan xotira muammolarini keltirib chiqaradi
qo'shib qo'ydi muallif JeeVan TiWari, manba

I am create GMSPath animation with path coordinate

enter image description here

maqsadi C

interfeys

@interface MapWithTracking() 

@property (weak, nonatomic) IBOutlet GMSMapView *mapView;

@property (nonatomic,strong) GMSMutablePath *path2;

@property (nonatomic,strong)NSMutableArray *arrayPolylineGreen;

@property (nonatomic,strong) GMSPolyline *polylineBlue;

@property (nonatomic,strong) GMSPolyline *polylineGreen;

@end

amalga oshirish

-(void)viewDidLoad {
    _arrayPolylineGreen = [[NSMutableArray alloc] init];
    _path2 = [[GMSMutablePath alloc]init];
}

GMSPath ni oling va ko'k rangli poliniyani yarating.

-(void)createBluePolyline(GMSPath *path) {

      //Here create a blue poly line
      _polylineBlue = [GMSPolyline polylineWithPath:path];
      _polylineBlue.strokeColor = [UIColor blueColor];
      _polylineBlue.strokeWidth = 3;
      _polylineBlue.map = _mapView;

      //animate green path with timer
       [NSTimer scheduledTimerWithTimeInterval:0.003 repeats:true block:^(NSTimer * _Nonnull timer) {
             [self animate:path];
       }];

}

Yashil chiziq bilan harakatlaning

2 yo'lga koordinatalar qo'shish va xaritaga topshirish

-(void)animate:(GMSPath *)path {

    dispatch_async(dispatch_get_main_queue(), ^{
        if (i < path.count) {
            [_path2 addCoordinate:[path coordinateAtIndex:i]];
            _polylineGreen = [GMSPolyline polylineWithPath:_path2];
            _polylineGreen.strokeColor = [UIColor greenColor];
            _polylineGreen.strokeWidth = 3;
            _polylineGreen.map = _mapView;
            [arrayPolylineGreen addObject:_polylineGreen];
            i++;
        }
        else {
            i = 0;
            _path2 = [[GMSMutablePath alloc] init];

            for (GMSPolyline *line in arrayPolylineGreen) {
                line.map = nil;
            }

        }
    });
}
16
qo'shib qo'ydi
Shuningdek, biz 30 km dan ortiq yo'lni chizib qo'ysak, yo'lni tekshirib chiqdim va yo'l oldinga cho'zilmadi, keyin u ko'proq vaqtni oladi.
qo'shib qo'ydi muallif Bhavin Chauhan, manba
Sizning kodingizni tekshirib chiqdim, o'qish juda oson. Ammo bir savolim bor: Polyline har doim 3 millisekunddan keyin chiziladi? Demak, agar kenglik va uzunlik murakkab tuzilma bo'lsa, unda yo'lni chizish uchun vaqt kerak bo'ladi. (asosiy oqim yukiga bog'liq)
qo'shib qo'ydi muallif Bhavin Chauhan, manba
Ha, men bir xil kodni ishlatganman, va siz ham xuddi shunday operatsiyani talab qildim. Lekin muammo shundaki, aylana va yo'l kabi yuvarlatilgan yo'l bor bo'lsa (masalan, qaynoq yo'l), unda animatsiya to'g'ri emas, shuningdek, polyline vaqtni 3 millisekundga, hatto uni 3 milisaniyalik vaqtga o'rnatadi. Iltimos, meni taklif qila olasizmi?
qo'shib qo'ydi muallif Bhavin Chauhan, manba
Ha, bu animatsiyani 3 millisekund bilan ishlatsam, unda u barcha qurilmalarda bir xil animatsiya emas. Ushbu operatsiyani bajarish uchun DispatchQueue foydalanganman. Yaxshimi yoki nsTimerdan foydalanishim kerakmi? Iltimos, menga maslahat bera olasizmi?
qo'shib qo'ydi muallif Bhavin Chauhan, manba
@kemdo o'rnatish taymerini NSTimer * myTimer = [NSTimer scheduledTimerWithTimeInterval: 110.0 maqsad: o'z-ni tanlang: @selector (targetMethod :) userInfo: nil takrorlaydi: YES]; Stop timer [myTimer invalidate];
qo'shib qo'ydi muallif Harshal Valanda, manba
yuqorida ko'rsatilgan misolda ham ko'rishingiz mumkinki, agar yo'l to'siq bo'lsa, keyin yo'nalish tez yursa, yumaloq yo'l va masofa ham aylanadigan yo'lni oshiradi
qo'shib qo'ydi muallif Harshal Valanda, manba
Ha, bu ko'proq vaqtni oladi, chunki yo'l yo'lga qaraganda dumaloqroq bo'lsa, u holda koordinat yanada kengayadi. yo'lni chizish uchun bitta koordinatani o'tkazib ko'rishga harakat qilishingiz mumkin, bu faqat bitta usul.
qo'shib qo'ydi muallif Harshal Valanda, manba
xarita ichiga yangi nuqta va Polyline qo'shib, raqobatdan keyin olib tashlashni xohlayman. kam xotiradan foydalanish va ishlashni yaxshilash uchun faqat bitta polyline usulini ishlatish mumkin. Yuqoridagi holatda i poliney qatorini qo'llaydilar.
qo'shib qo'ydi muallif Harshal Valanda, manba
Yuqoridagi holatda men taymerdan foydalanaman, chunki har bir 0,003 soniyada yangi yo'nalish koordinatasini qo'shdim va u barcha qurilmalarda ishlaydi. Vaqt mening nuqtai nazarimdan foydalanish, bunday operatsiyani ishlatishning oson yo'li.
qo'shib qo'ydi muallif Harshal Valanda, manba
O'z ehtiyojlaringizga ko'ra ikkinchi darajani belgilashingiz mumkin. Agar yo'lning murakkab tuzilishi bo'lsa, unda u jozibasi kabi ishlaydi, chunki asosiy ipda murakkab operatsiya qilmaymiz. Shuningdek, u fon yorug'ini ham bajarishi mumkin, lekin animatsiya joziba kabi ishlamaydi.
qo'shib qo'ydi muallif Harshal Valanda, manba
taymerni qanday qilib to'xtatish mumkin?
qo'shib qo'ydi muallif kemdo, manba

Xaritani delegatni mapView: didChangeCameraPosition: amalga oshirish orqali harakatlantirganda qatlamni harakatlantiring.

1
qo'shib qo'ydi
Koordinatadan nuqta-ga va GMSMapView-da proyektsiya xususiyatidan foydalanib, bir nuqtadan koordinatsiya qilishingiz mumkin. noreferrer"> developers.google.com/maps/documentation/ios-sdk/reference saytiga qarang/& hellip;
qo'shib qo'ydi muallif Jon Rose, manba
GISPath koordinatalaridan breisepath yo'lini yaratdim va CAShapeLayerni breisepathdan yaratdim. Qanday qavat rejimini cameraPosition-ga o'zgartirish mumkin? @Jon
qo'shib qo'ydi muallif Elangovan, manba

Bu Elangovan kodining moslashtirilishi

The changes that I did was to remove the var from the class to be just in the function and also removed the #selector that is no longer need in iOS >= 10.

var timerAnimation: Timer!
var mapView:GMSMapView?



    func drawRoute(encodedString: String, animated: Bool) {

        if let path = GMSMutablePath(fromEncodedPath: encodedString) {

            let polyline = GMSPolyline(path: path)
            polyline.strokeWidth = 3.0
            polyline.strokeColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
            polyline.map = Singleton.shared.getMapView()

            if(animated){
                self.animatePolylinePath(path: path)
            }
        }
    }

    func animatePolylinePath(path: GMSMutablePath) {

        var pos: UInt = 0
        var animationPath = GMSMutablePath()
        let animationPolyline = GMSPolyline()
        self.timerAnimation = Timer.scheduledTimer(withTimeInterval: 0.003, repeats: true) { timer in

            pos += 1
            if(pos >= path.count()){
                pos = 0
                animationPath = GMSMutablePath()
                animationPolyline.map = nil
            }
            animationPath.add(path.coordinate(at: pos))
            animationPolyline.path = animationPath
            animationPolyline.strokeColor = UIColor.yellow
            animationPolyline.strokeWidth = 3
            animationPolyline.map = self.mapView
        }
    }


    func stopAnimatePolylinePath() {

        self.timerAnimation.invalidate()
    }
0
qo'shib qo'ydi

Buning uchun GMSPolyline dan foydalanishingiz kerak. GMSPolyline misolini yarating, uning kodi GMSMapView o'rnating.

GMSPolyline* routeOverlay =//config
routeOverlay.map =//my GMSMapView instance

Hammasi shu. Siz xarita kamerasi harakati bilan harakat qilish uchun qo'shimcha hech narsa qilishingiz shart emas. Bu avtomatik ravishda amalga oshiriladi.

0
qo'shib qo'ydi
Savol bu GMSPolyline bilan qila olmayman deb o'ylamagan yo'lni jonlantirish usulini so'raydi
qo'shib qo'ydi muallif Jon Rose, manba
Siz bu yo'lni jonlantira olasizmi?
qo'shib qo'ydi muallif Jon Rose, manba
zo'r fikr. Keling, siz animatsiyaning doimiy ravishda takrorlanishini xohlaysiz, demak u har doim ekranda. Xarita harakatlanayotganda shapaynerni qanday harakat qilish mumkin?
qo'shib qo'ydi muallif Jon Rose, manba
Bunday foydalanish holatlariga duch kelmadim. Savol bu haqda ham gapirmadi. Biroq, bunday holatda, biz shakllashdagi yo'l xaritasini harakat qilishimiz kerak.
qo'shib qo'ydi muallif Tarun Tyagi, manba
@JonRose Animatsiya GMSPolyline mumkin emas. Vaqtinchalik echim animatsiya chizish uchun CAShapeLayer'dan foydalanish va animatsiya tugallangach haqiqiy GMSPolyline dan foydalaning. Malumot - stackoverflow.com/questions/38221641/…
qo'shib qo'ydi muallif Tarun Tyagi, manba
@JonRose Siz GMSPath misoli bilan GMSPolyline misol yaratishingiz mumkin. Ikkita joy o'rtasida marshrutni topish uchun Google Places API-laridan olingan kodlanganPath magazini bilan GMSPath yaratishingiz mumkin. Elangovan allaqachon ushbu sozlamani ishlatgan deb o'ylayman.
qo'shib qo'ydi muallif Tarun Tyagi, manba

FormLayer uchun o'zgaruvchini yaratishingiz va GMSMapViewDelegate usullaridan foydalanishingiz mumkin mapView (_ mapView: GMSMapView, willMove harakati: Bool) va mapView (_ mapView: GMSMapView, bo'sh joy: GMSCameraPosition) qatlamni xaritadan qo'shish va olib tashlash. Ushbu yondashuvga ikkita nuqta qo'yiladi: birinchi navbatda, xarita ko'chirilganda (qatlam) ko'chirilganda qatlam jonlantirilmaydi va ikkinchi salbiy tomondan qatlam har doim markerlar, yo'l nomlari, POI va boshqalar kabi barcha xarita elementlarining tepasida o'tiradi. Bu qatlamni er osti qatlamiga to'g'ridan-to'g'ri pastki qatlam sifatida qo'shishning yo'lini topolmadim. Quyidagi to'liq kodni topishingiz mumkin:

var polyLineShapeLayer:CAShapeLayer?

 var layerAdded = false

 var path = GMSPath()

 var polyLine:GMSPolyline!



// Add regular polyline to the map 

func addPolyLineWithEncodedStringInMap(_ encodedString:String) {
        self.polyLine = GMSPolyline(path: self.path)
        polyLine.strokeWidth = 3.8
        self.polyLine.strokeColor = .black
        polyLine.map = googleMapView

        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
            self.addPolyLineShapeLayerToMapView()
            self.layerAdded = true
        }

    }


// Add CAshapeLayer to map 

  func layer(from path: GMSPath) -> CAShapeLayer {
        let breizerPath = UIBezierPath()
        let firstCoordinate: CLLocationCoordinate2D = path.coordinate(at: 0)
        breizerPath.move(to: self.googleMapView.projection.point(for: firstCoordinate))
        for i in 1 ..< Int((path.count())){
            print(path.coordinate(at: UInt(i)))
            let coordinate: CLLocationCoordinate2D = path.coordinate(at: UInt(i))
            breizerPath.addLine(to: self.googleMapView.projection.point(for: coordinate))
        }

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = breizerPath.cgPath
        shapeLayer.strokeColor = UIColor.lightGray.withAlphaComponent(0.8).cgColor
        shapeLayer.lineWidth = 4.0
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineJoin = kCALineJoinRound
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.cornerRadius = 5
        return shapeLayer
    }

    func animatePath(_ layer: CAShapeLayer) {
        let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
        pathAnimation.duration = 2
        pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        pathAnimation.fromValue = Int(0.0)
        pathAnimation.toValue = Int(1.0)
        pathAnimation.repeatCount = 200
        layer.add(pathAnimation, forKey: "strokeEnd")
    }

    func addPolyLineShapeLayerToMapView(){

        polyLineShapeLayer = self.layer(from: self.path)

        if let polyLineShapeLayer = polyLineShapeLayer{
            self.animatePath(polyLineShapeLayer)
            self.googleMapView.layer.addSublayer(polyLineShapeLayer)
            polyLineShapeLayer.zPosition = 0

        }

    }


// Delegate methods to control the polyline 


// whenever map is about to move, if layer is already added, remove the layer from superLayer 

    func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
        if layerAdded{
            DispatchQueue.main.async {
                self.polyLineShapeLayer?.removeFromSuperlayer()
                self.polyLineShapeLayer = nil
            }
        }
    }

// when map is idle again(var layerAdded:bool ensures that additional layer is not added initially when the delegate method is fired) add new instance of polylineShapeLayer to the map with current projected coordinates. 

    func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
        if self.layerAdded{
            self.addPolyLineShapeLayerToMapView()
        }

    }
0
qo'shib qo'ydi