RouteMapKit

main

Dross52/ParallelRouteMapKit

🗺️ RouteMapKit

A Swift package for advanced, customizable, and dynamic route rendering on MapKit. RouteMapKit makes it easy to display multi-route polylines, intelligently offset overlapping segments, and add dynamic text annotations along the routes.

🚀 Features

✅ Dynamic route polylines with automatic offset for overlapping segments ✅ Zoom-scale adaptive line thickness ✅ Smooth annotation rendering using SwiftUI views on top of MapKit ✅ Supports both iOS and macOS platforms ✅ Easy to integrate with your existing MKMapView

🏗️ Architecture Overview

🔹 RoutePolyline

Represents an entire route, containing: • id, name, color • One or more RouteSegments • Distance intervals for annotation placement • Optional zoom threshold

🔹 RouteSegment

Represents a polyline segment of a route, with: • Coordinates • Optional name & color • List of route IDs (used to offset overlapping segments)

🔹 RouteAnnotationViewModel

Holds data for text annotations: • Coordinate, angle, zoom threshold • Optional text & color override

🔹 RouteAnnotationView

A SwiftUI View to render an annotation’s text label at a specific angle with an optional stroke outline.

🔹 RoutePolylineRenderer

Custom MKPolylineRenderer that: • Offsets overlapping segments based on route order • Adjusts line thickness dynamically based on zoom • Smoothly draws each route with rounded corners

📸 Screenshots


Dark Mode Annotation

Light Mode Annotation

Parallel Routes Example 1

Parallel Routes Example 2

🧩 How It Works • Add RoutePolyline overlays to your MKMapView. • Call RouteAnnotationViewModel.updateAnnotations() to add annotations. • The renderer automatically draws overlapping routes with offset. • The annotation view auto-rotates text to stay upright even when the map is rotated.

📄 Example Usage

import RouteMapKit

let mapView = MKMapView()

// Create your routes
let segments = [
    RouteSegment(coordinates: [...], routeIDs: ["Route1"], name: "Segment 1"),
    RouteSegment(coordinates: [...], routeIDs: ["Route1"])
]
let route = RoutePolyline(
    id: "Route1",
    name: "Route 1",
    color: .systemBlue,
    segments: segments,
    distanceInterval: 1000
)

// Add overlay
mapView.addOverlay(route.mkOverlay)

// Add annotations
await RouteAnnotationViewModel.updateAnnotations(
    on: mapView,
    using: [route],
    target: .segment
)

🎯 Annotation Targets

enum AnnotationTarget {
    case line      // Places annotations evenly along the entire polyline
    case segment   // Places annotations at each segment with optional names/colors
}

🌙 Dark Mode Support

Annotation text uses .oppositePrimary(colorScheme) to automatically select white or black stroke based on system appearance.

💻 Platform Support

Platform Minimum Version iOS 13.0+ macOS 10.15+

🔥 Future Improvements (Optional) • Add tap handlers for annotations • Animated annotation appearance • Integration with MKClusterAnnotation • Unit tests

📝 License

MIT License

Description

  • Swift Tools 5.7.0
View More Packages from this Author

Dependencies

  • None
Last updated: Tue May 13 2025 12:08:45 GMT-0900 (Hawaii-Aleutian Daylight Time)