maparoni/geoprojector
This is a Swift-only library to calculate and draw map projections.
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:
- GeoJSONKit, a light-weight GeoJSON
framework.
- GeoJSONKit-Turf, a fork of
turf-swift with GeoJSONKit's GeoJSON enums used for the basic data models.
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
)?.0Note 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.
Package Metadata
Repository: maparoni/geoprojector
Default branch: main
README: README.md