Skip to content

maparoni/GeoProjector

Repository files navigation

GitHub License CI

GeoProjector

This is a Swift-only library to calculate and draw map projections.

This is in early days, has some glitches, and is not yet stable.

  • GeoProjector: Map projections, turning coordinates into projected coordinates and into screen coordinates.
  • GeoDrawer: Draw GeoJSON using whichever projection you choose.

Goals of this library

  • Support a selection of map projections, but not an exhaustive list
  • Provide methods for drawing those projections, draw GeoJSON content on top, and drawing just a section of the resulting map
  • Provide methods for getting coordinates of projected map points
  • Compatibility with Apple platforms and Linux

Dependencies

This library is part of the Maparoni suite of mapping related Swift libraries and depends on:

Usage

Installation

As noted above, this library is not yet stable!

To install GeoProjector using the Swift Package Manager, add the following package to the dependencies in your Package.swift file or in Xcode:

.package(
  name: "GeoProjector", url: "https://github.com/maparoni/geoprojector", 
  branch: "main" // no tagged versions yet 
)

Projections

Projections are defined using the Projection protocol, which defines the expected project method, but also some additional information, such as the shape of the map bounds of the projection.

The projections themselves are available through the Projections namespace (i.e., a caseless enum) which provides implementations of different projections. Note that the implementations are based on radians, but there are various helper methods to work with GeoJSON and coordinates in degrees.

Example usage:

import GeoProjector

let projection = Projections.Orthographic(
  reference: GeoJSON.Position(latitude: 0, longitude: 100)
)
let sydney = GeoJSON.Position(latitude: -33.8, longitude: 151.3)
let projected = projection.point(
  for: sydney, 
  size: .init(width: 100, height: 100) // the maximum size of the canvas
)?.0

Note that projected points align with what's common on the platform, so macOS has (x: 0, y: 0) for the bottom left map coordinate (latitude: -180, longitude: -90) while other platforms have it in the top left map coordinate (latitude: -180, longitude: 90).

Maps (AppKit)

The GeoDrawer library includes an NSView called GeoMapView and a corresponding SwiftUI view called GeoMap. You can use these to get a map view to draw content on.

import SwiftUI
import GeoDrawer

struct MyMap: View {

  var body: some View {
    GeoMap(
      contents: try! GeoDrawer.Content.world(),
      projection: Projections.Cassini()
    )
  }
  
}

Credits

The code in this repo is all written by myself, Adrian Schönig, but it wouldn't have been able to do this so smoothly without the help of these precious resources:

  • Justin Kunimune's jkunimune/Map-Projections, which is comprehensive suite of map projections implemented in Java, including some projections of his own making.
  • The comprehensive description of map projections on Wikipedia.

License

This library is available under the MIT License. Use it as you please according to those terms.

The examples are public domain and can be adapted freely.