I'm using GoogleMaps for iOS platform, Swift language.
I draw the path according to the Google Maps documentation:
let path = GMSMutablePath()
path.add(previousLocation)
path.add(currentLocation)
let line = GMSPolyline(path: path)
line.strokeWidth = 5
line.strokeColor = .blue
line.map = mapView
My client complains that the route lines intersections must be smoothly rounded. How can I implement this? Some suggestions?
Thanks!
I found the solution.
My problem was that I was always drawing only the last two points:
let path = GMSMutablePath()
path.add(previousLocation)
path.add(currentLocation)
Now, every time when a new location comes, I clear the map and redraw again the entire route:
mapView.clear()
let path = GMSMutablePath()
for location in locationsArray {
path.add(location)
}
let line = GMSPolyline(path: path)
line.strokeWidth = 5
line.strokeColor = .blue
line.map = mapView
Seems that in this way Google Maps draws the route correctly.
Have a look at SwiftSimplify. It is a library that reduces the number of geopoints in the polyline to make it more smooth and efficient.
This library also smooth out the route. I am using this atm. IVBezierPathRenderer
Related
is it possible to animate my marker rotation using MGLSymbolStyleLayer's iconRotation property ? or is there any other way to rotate my marker smoothly ?
I just want to rotate my marker smoothly , as of now the rotation is fine but it is quite snappy. Also i get different bearing for different markers from the server, is there any way i can rotate my marker using MGLPointAnnotation only ?. My use case is that i want different degree rotation for different markers (each of same icon)
let point = MGLPointAnnotation()
point.coordinate = CLLocationCoordinate2D(latitude: 30.699335, longitude: 76.836422)
let shapeSource = MGLShapeSource(identifier: "marker-source", shape: point, options: nil)
shapeLayer = MGLSymbolStyleLayer(identifier: "marker-style", source: shapeSource)
if let image = UIImage(named: "auto") {
mapView.style?.setImage(image, forName: "auto")
}
shapeLayer?.iconImageName = NSExpression(forConstantValue: "auto")
CATransaction.begin()
CATransaction.setAnimationDuration(3.0)
self.shapeLayer?.iconRotation = NSExpression(forConstantValue: 120.0)
CATransaction.commit()
You can animate an MGLSymbolStyleLayer using the add live data example. You would need to set your #objc function to layer.iconRotation and have that value change every time the function is executed. You can also do the same using an MGLPointFeature or MGLPointAnnotation as a source for an MGLSymbolStyleLayer. Please take a look at the Mapbox Add markers and shapes documentation here to see the different features that are supported.
I have used GMSCoordinateBounds. But it zooms in too much. My marker doesn't show on the road because of the zoom level. My marker shows a little bit away from the road. I have used the below code:
let path = GMSMutablePath()
path.add(CLLocationCoordinate2DMake(23.740424444444443, 90.41102222222223))
let bounds = GMSCoordinateBounds(path: path)
self.googleMap.animate(with: GMSCameraUpdate.fit(bounds, withPadding:10.0)
I have solve the problem like bellow
let path = GMSMutablePath()
path.add(CLLocationCoordinate2DMake(23.740424444444443, 90.41102222222223))
let bounds = GMSCoordinateBounds(path: path)
self.googleMap.animate(with: GMSCameraUpdate.fit(bounds))
self.googleMap.setMinZoom(8, maxZoom: 14)
I have a slight problem, I am unable to remove the previous polyline created from the previous search.
I have looked at google documentation but i am unable to find the right answers.
let routes = json["routes"].arrayValue
for route in routes
{
let routeOverviewPolyline = route["overview_polyline"].dictionary
print("routesOVER:",routeOverviewPolyline)
let points = routeOverviewPolyline?["points"]?.stringValue
let path = GMSPath.init(fromEncodedPath: points!)
let polyline = GMSPolyline(path: path)
if polyline != nil {
print(polyline)
polyline.strokeColor = .black
polyline.strokeWidth = 10.0
polyline.map = self.googleMaps
}
}
}
catch let error as NSError {
print(error)
}
in the google maps, 2 polylines are shown. 1 from the previous search and another from the current search
Google Maps Image
You can clear the mapView before drawing to new polyline on the map.
self.googleMaps.clear()
But above code will clear pins on the map as well. your have to redraw your pins on the map as well
Im building an app with google maps, and i would like to show a route between 2 static points
I was folling this tutorial but i can't make it yet, for some reason it dont show the route.
I dont want to make an dinamic route i just want it from two point that i´ve define
here's some code
GMSServices.provideAPIKey("MY API KEY")
let camera = GMSCameraPosition.camera(withLatitude: 19.0660043, longitude: -98.12050499999998, zoom: 18.0)
mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
view = mapView
var source = CLLocationCoordinate2DMake(19.060914, -98.125935)
var destination = CLLocationCoordinate2DMake(19.1660043, -98.13000)
plx help
You need to create a path first and then use that path to create a polyline
let path = GMSMutablePath()
path.add(source)
path.add(destination)
let polyline = GMSPolyline(path: path)
polyline.strokeColor = UIColor.red
polyline.strokeWidth = 3.0
polyline.map = self.map
In iOS 11, I have a PDFView controller implementation that allows to annotate a PDF, and one of those annotation if free-form drawing using PDFAnnotationSubtypeInk
let page : PDFPage = ...
let points : [CGPoint] = ...
let path = UIBezierPath()
for x in 0..<points.count {
let point = self.pdfView.convert(points[x], to: page)
if x == 0 {
path.move(to: point)
}else{
path.addLine(to: point)
}
}
let border = PDFBorder()
border.style = .solid
border.lineWidth = 2.0
let drawAnnotation = PDFAnnotation(bounds: page.bounds(for: .mediaBox), forType: .ink, withProperties: nil)
drawAnnotation.backgroundColor = .yellow
drawAnnotation.interiorColor = .yellow
drawAnnotation.fontColor = .yellow
drawAnnotation.color = .yellow
drawAnnotation.border = border
drawAnnotation.add(path)
page.addAnnotation(drawAnnotation)
When I call the persistence code
if let path = self.pdfDocumentPath, let document = self.pdfDocument {
if !document.write(toFile: path){
NSLog("Failed to save PDF")
}
}
Everything works in theory, the PDF is saved to disk... But on the next-reload from disk, my annotation is nowhere to be seen. Other types of annotations are saved correctly (i.e. Text and Highlight)
It looks like the UIBezierPaths never makes it back from Disk. No UIBezierPath is to be found in the reloaded PDFAnnotation
Am I doing something wrong? Am I missing something?
PS: I am sorry for Ruby devs that are looking for questions/answers on the Ruby Package known as PDFKit... iOS also have a package named PDFKit since iOS 11... Sorry for any confusion.
I hacked my way around the problem. The annotation get saved, but the UIBezierPath does not (and all it's points)
So when I write the PDF back to disk, I go through all the pages, and all annotations, and find those with UIBezierPath, and serialize the CGPoints into JSON into the PDFAnnotation content property.
When reloading the same PDF, I do the exact same thing, which is go through all the pages, and find .ink annotation, deserialize the points, and add the UIBezierPath back on the annotation.
Apple fixed this bug in iOS 12. PDFAnnotation.paths is filled correctly.
Starting with some version between 11.2 - 11.4 (I do not have the opportunity to verify, but it does not work exactly in 11.1 and works in 11.4+) you can use PDFAnnotation method drawWithBox:inContext: for rendering ink annotation correctly.
Attention, in iOS 12.0 Apple broke PDFAnnotation.color (alpha is always equal 1 after save-reload PDFDocument from disk). Can be repaired by drawing an annotation through the context with method above.