mkmapviewmapkitmkoverlaymkpolyline

How to use MKMapKit to generate polyline for Continental United States Boundary?


Note: If this question requires more information, please add a comment.

Details:

I would like to generate a boundary line around the continental United States on an MKMapView. The idea is to begin drawing overlays on the area outside of the country outline (I need to de-emphasize external areas and just have the US be the primary focal point; I am considering a blur effect but would be open to suggestions on implementation or other methods to achieve the objective).

Background:

I need to blur out (or de-emphasize) the other countries that appear in the default MKMapView other than the Continental US.

My Initial Approach:

  1. Identify the contiguous country boundary box using polylines (similar to how a bus route is represented on the map; I note there seems to be some default line ~ any method to access those coordinates?)
  2. Identify a method to mask the map using a UIVisualEffectView with blur (or any other possibility to dim that portion of the map not inside the boundary)

I don't necessarily need a code solution (though if posted, I'll try it). I am wondering if someone experienced in this area could provide pseudo code or just some pointers as to the best approach to take on this process.

Other Research:

I have reviewed other sources, including the MapKit documentation and this overlay tutorial.


Solution

  • You would need to draw a polygon around all your MKMapView with an inner polygon that would be the area you don't want to blur out. Here is my solution:

    First you need the coordinates to cover every bit of the map:

    struct WorldCoordinates {
        static let values = [
            CLLocationCoordinate2D(latitude: 90, longitude: 0),
            CLLocationCoordinate2D(latitude: 90, longitude: 180),
            CLLocationCoordinate2D(latitude: -90, longitude: 180),
            CLLocationCoordinate2D(latitude: -90, longitude: 0),
            CLLocationCoordinate2D(latitude: -90, longitude: -180),
            CLLocationCoordinate2D(latitude: 90, longitude: -180)
        ]
    }
    

    Then use a method like this one to add your inner and outer polygons: Please note that I use "City" as an example of a struct with boundigCoordinatesArray being an array of the bounding coordinates of the area you don't want to blur.

    func addCityBoundingPolygon(in mapView: MKMapView, with city: City) {
        // Declare your inner polygon
        let innerPolygon = MKPolygon(coordinates: city.boundingCoordinatesArray, count: city.boundingCoordinatesArray.count)
        innerPolygon.title = "\(city.id)"
            
        // Declare your outer polygon with previously created inner polygon
        let outerPolygon = MKPolygon(coordinates: WorldCoordinates.values, count: WorldCoordinates.values.count, interiorPolygons: [innerPolygon])
            
        mapView.addOverlay(outerPolygon)    
    }
    

    Finally add the color of your outer polygon on your MKMapViewDelegate like this:

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        if let polygon = overlay as? MKPolygon {
            let renderer = MKPolygonRenderer(polygon: polygon)
            renderer.fillColor = UIColor.outOfCityBounds().withAlphaComponent(0.1)
            renderer.strokeColor = UIColor.outOfCityBounds().withAlphaComponent(0.4)
            renderer.lineWidth = 1
            return renderer
        }
    
        return MKOverlayRenderer()
    }
    

    With this approach you will be able to recreate something like this: Urbvan App