zonas trazar studio rutas ruta poligonos poligono marcar google geocercas dibujar delimitar centro ios swift google-maps-sdk-ios gmsmapview google-maps-ios

ios - rutas - trazar ruta en google maps android studio



¿Cómo obtener una ruta de polilínea animada en GMSMapView, para que se mueva junto con el mapa cuando se mueve el mapa? (6)

He creado una polilínea animada como CAShapeLayer siguiendo el código, he agregado CAShapeLayer como subcapa a GMSMapiew pero, si muevo el mapa, la capa no se moverá. ¿Dónde agregar la capa, para que se mueva junto con el mapa?

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") }

Añadido a GoogleMapView por

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


Esta es una adaptación del código de Elangovan.

Los cambios que hice fueron eliminar la var de la clase para estar solo en la función y también quitar el #selector que ya no es necesario en 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() }


Mueva la capa siempre que el mapa se mueva implementando el delegado mapView:didChangeCameraPosition:


Necesitas usar GMSPolyline para esto. Cree una instancia de GMSPolyline , configure su instancia de GMSMapView para que sea su mapa principal.

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

Eso es todo. No necesita hacer nada adicional para que se mueva con el movimiento de la cámara del mapa. Lo hace automáticamente.


Puede crear una variable para shapeLayer y usar los métodos GMSMapViewDelegate mapView (_ mapView: GMSMapView, willMove gesto: Bool) y mapView (_ mapView: GMSMapView, idleAt position: GMSCameraPosition) para agregar y eliminar la capa del mapa. Este enfoque tiene dos inconvenientes, primero es que la capa no se anima cuando el mapa se está arrastrando (moviendo) y la segunda desventaja es que la capa siempre se encuentra encima de todos los demás elementos del mapa como marcadores, nombres de carreteras, PDI, etc. No pude encontrar una manera de agregar esta capa como subcapa directamente a la superposición del suelo. Puedes encontrar el código completo a continuación:

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() } }


Soy crear animación GMSPath con coordinate ruta.

C objetivo

interfaz

@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

implementación

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

Consigue un GMSPath y crea una polilínea azul.

-(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]; }]; }

Animar una polilínea verde

Añadiendo coordenadas a la ruta 2 y asignando al mapa

-(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; } } }); }


RÁPIDO

Declaración

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

A la ruta de darw

func drawRoute(routeDict: Dictionary<String, Any>) { let routesArray = routeDict ["routes"] as! NSArray if (routesArray.count > 0) { let routeDict = routesArray[0] as! Dictionary<String, Any> let routeOverviewPolyline = routeDict["overview_polyline"] as! Dictionary<String, Any> 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) } }

Animar camino

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 } }

No se olvide de detener el temporizador en la vista.

self.timer.invalidate()

Salida