Limit map visibility to its overlay - ios

I want to place an image over my map and limit the map visibility to the image overlay, so that the user can only see my image and not the map behind it. I tried to used the solution offered by Google Maps API with the GMSGroundOverlay, like so:
let southWest = CLLocationCoordinate2D(latitude: 40.712216, longitude: 32.22655)
let northEast = CLLocationCoordinate2D(latitude: 40.773941, longitude: 23.12544)
let overlayBounds = GMSCoordinateBounds(coordinate: southWest, coordinate: northEast)
let icon = UIImage(named: “someImg”)
let overlay = GMSGroundOverlay(bounds: overlayBounds, icon: icon)
overlay.bearing = 0
overlay.map = mapView
Also, I set the cameraTarget of the map to the bounding box:
mapView.cameraTargetBounds = overlayBounds
This does limit the user from scrolling the map infinitely, but I expected these limits to go as far as the overlay goes. Now the image looks like a sticker on the map, as I can still see the map around the image.
I am not sure I fully understand the way GMSCoordinateBounds and GMSGroundOverlay work..so I'm asking here if anyone can give me some hints on the adjustments that I can make to get what I want.

Related

How to get a reliable rect of the whole mapview (not just visible) with Mapbox?

So I've been struggling with this for some time. I wish to know the CGRect of the whole map. The issue I am facing right now is that due to the wrapping of the map, the x of the top-left coordinate keeps switching between a negative and a positive value as I move around the map. This results in the width of the map also changing.
I tried restricting the camera bounds to prevent wrapping and it does that job perfectly, but it still doesn't help with x switching between positive/negative as I move around the map.
let extremeBounds = CoordinateBounds(
southwest: CLLocationCoordinate2D(latitude: -62.59334083012023, longitude: -141.328125),
northeast: CLLocationCoordinate2D(latitude: 82.85338229176081, longitude: 167.34375)
)
try? view.mapboxMap.setCameraBounds(with: CameraBoundsOptions(bounds: extremeBounds))
This is how I am calculating the rect on cameraChange:
mapView.mapboxMap.rect(for: self.extremeBounds)
Is there an official way of disabling the wrapping of the map so that the northwest coordinate always appears at the top left side of the map? Or maybe my approach is incorrect and there's an easier way of finding out the rect of the map?
you can try setting ConstrainModeto widthAndHeight, by default this value is heightOnly-> only y axis is constrained.
let mapInitOptions = MapInitOptions(mapOptions: MapOptions(constrainMode: .widthAndHeight))
let mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions)

iOS 12 won't display .svg file as an overlay Google Maps iOS API

So basically I want to use an SVG file I drew as an overlay for the Google Maps iOS API 3. Whenever I use a .jpg file it seems to work fine. I'm using iOS 12
I've tried switching file names and it still only seems to work with JPEGS, not sure about PNGS.
This is my code:
let camera = GMSCameraPosition.camera(withLatitude: 47.457925, longitude: 8.548466, zoom: 16.0)
let southWest = CLLocationCoordinate2D(latitude: 47.444561, longitude: 8.534752)
let northEast = CLLocationCoordinate2D(latitude: 47.483037, longitude: 8.575470)
let overlayBounds = GMSCoordinateBounds(coordinate: southWest, coordinate: northEast)
let icon = UIImage(named: "lszh-int-lv-main.svg")
let overlay = GMSGroundOverlay(bounds: overlayBounds, icon: icon)
overlay.bearing = 0
overlay.map = mapView
mapView.camera = camera
mapView.animate(to: camera)
I'm not getting any error messages with the SVG, it's just not showing up. Is it impossible to even show SVGs as overlays? Thank you for your help!
Preserve Vector Data
Xcode 9 changes this situation by allowing you to choose to treat the image as a vector at runtime. This means the image can smoothly
scale to arbitrary sizes. The only change you need to make is to tick
Preserve Vector Data for the PDF image in the asset catalog.
You need to export your vector as an pdf and add it into asset catalog. For more info :
Link 1 Link 2

Get google map currently rotated angle by user in iOS

I am using google map in the application. When I do not rotate map everything works fine. But when I rotate map I am getting problem as shown in image. To solve that I need to get the google map currently rotated angle by the user. I need to get this so that I can place the marker back on the map at the same angle. Currently my map angle after rotation and my overlay seems to be different after placing plan image on map even when I am getting correct top left & bottom right corner coordinates.
My code
let topCoordinate = CLLocationCoordinate2D(latitude: topLattitude, longitude: topLongitude)//top
let bottomCoordinate = CLLocationCoordinate2D(latitude: bottomLattitude, longitude: bottomLongitude)//bottom
overlayBounds = GMSCoordinateBounds(coordinate: topCoordinate, coordinate:
bottomCoordinate)
let overlay = GMSGroundOverlay(bounds: overlayBounds, icon: planImage)
overlay.map = mapView
GMSMapViewDelegate
Bearing of the camera, in degrees clockwise from true north.
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
print(position.bearing)
}
I have solved my problem by changing the overlay method as
let zoomLevel = (object["image_zoom_level"] as? NSString)?.doubleValue
let overlay = GMSGroundOverlay(position: centreCoordinate, icon: planImage, zoomLevel: CGFloat(zoomLevel!))
overlay.map = mapView
if let angle = (object["rotation_angle"] as? NSString)?.doubleValue{
overlay.bearing = angle
}
Instead of using Overlay bounds I have just used center coordinate and placed overlay image using image zoom level and rotation angle. By this, my image is placing in proper angle and at a proper place. This works fine if the Image size is correct as you want place and the center point is accurate and precise.

how to fix boundaries to show limited google map area in Swift 4 (iOS)

I am able to set limited area to show at google map for user. After setting below code google map is not moving outside of this area defined with below code in Android: -
final LatLngBounds ADELAIDE = new LatLngBounds(
new LatLng(25.27, 93.46), new LatLng(27.05, 95.19));
// Constrain the camera target to the Adelaide bounds.
mMap.setMinZoomPreference(6.0f);
mMap.setLatLngBoundsForCameraTarget(ADELAIDE);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(26.05839, 94.45399), 6.0f));
Now I am trying to implement same feature to restrict user for google map area in Swift but there is no method like setLatLngBoundsForCameraTarget.
I have tried below code: -
let southWest = CLLocationCoordinate2DMake(25.27,93.46)
let northEast = CLLocationCoordinate2DMake(27.05,95.19)
let bounds = GMSCoordinateBounds(coordinate: northEast, coordinate: southWest)
let cameraBounds = googleMapView.camera(for: bounds, insets: UIEdgeInsets.zero)
googleMapView.camera = cameraBounds!
but this is not working. User still can move outside of this bounds.
Please help. Thanks in advance.

Swift mkmapview get zoom level, width or radius of visible map area from latitude longitude delta

I am in a confusion, on how to get a zoom level and radius of a visible area of the map (using mapkit mapview).
Here is what I am looking for (either of them or both, as needed) -
Zoom level, is to see at what level of the map is being shown to the users and with that information, I want to display the custom pins in the visible area. If zoom level is high, I need to show the actual logos of some commerce stores as pins. If zoom level is low, I need to show colored dots instead of logos.
As of now, I am using let updatedRadius = (mapView.camera.altitude)/1000 to get altitude of the camera, and if the updatedRadius value is > 25.0, I am showing colored dots. Below 25.0, I show the logos. I am doing this in regionDidChanged
Is this approach correct?
Radius, is to send it as a parameter to my REST API to fetch the list of places within that radius. When user zooms out on the map, visible area increases and so the REST API needs bigger radius to return the places covered in that area.
Ultimately, what should happen is, whenever user zooms out, then the radius changes. I need to send this changed radius to my REST to get an updated list.
What are latitude longtitude deltas, can we get radius/width of visible area using these values?
let latitudeDeltaVal = mapView.region.span.latitudeDelta
let longitudeDeltaVal = mapView.region.span.longitudeDelta
Can someone throw some light on what needs to be done please?
Since you need to call the api when the region changes you need to calculate the radius in mapView's delegate function, RegionDidChange.
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
let centralLocation = CLLocation(latitude: mapView.centerCoordinate.latitude, longitude: mapView.centerCoordinate.longitude)
self.centralLocationCoordinate = mapView.centerCoordinate
print("Radius - \(self.getRadius(centralLocation))")
}
func getRadius(centralLocation: CLLocation) -> Double{
let topCentralLat:Double = centralLocation.coordinate.latitude - mapView.region.span.latitudeDelta/2
let topCentralLocation = CLLocation(latitude: topCentralLat, longitude: centralLocation.coordinate.longitude)
let radius = centralLocation.distanceFromLocation(topCentralLocation)
return radius / 1000.0 // to convert radius to meters
}
To account for both landscape and portrait orientations, and/or situations where the map orientation is close to Northeast, Northwest, Southwest, Southeast, and to enclose the full screen up to the corners, one should consider both latitudeDelta and longitudeDelta:
func getRadius() -> Double{
let centralLocation = CLLocation(latitude: mapView.region.center.latitude, longitude: mapView.region.center.longitude)
let cornerOfMap = CLLocation(latitude: centralLocation.coordinate.latitude + mapView.region.span.latitudeDelta , longitude: centralLocation.coordinate.longitude + mapView.region.span.longitudeDelta)
let radius = centralLocation.distance(from: cornerOfMap)
return radius / 1000.0 // to convert radius to meters
}

Resources