Skip to content

Commit 732e0ab

Browse files
authored
SVG support (#36)
* Initial pass at SVG supported, generated with Claude Sonnet 4 * Test if we have Testing Plus Zed's auto formatting * Coordinate system should depend on output, not on OS * Convert all tests to Swift Testing
1 parent 99de9f3 commit 732e0ab

File tree

12 files changed

+870
-184
lines changed

12 files changed

+870
-184
lines changed

.github/workflows/swift.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
runs-on: ubuntu-latest
2121
strategy:
2222
matrix:
23-
swift: ["6.0", "5.10", "5.9"]
23+
swift: ["6.0", "5.10"]
2424
container:
2525
image: swift:${{ matrix.swift }}
2626
steps:

Package.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,11 @@ let package = Package(
4141
"GeoProjector",
4242
.product(name: "Algorithms", package: "swift-algorithms"),
4343
]),
44+
.testTarget(
45+
name: "GeoDrawerTests",
46+
dependencies: [
47+
"GeoDrawer",
48+
"GeoProjector",
49+
]),
4450
]
4551
)

Sources/GeoDrawer/GeoDrawer+CoreGraphics.swift

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,29 @@ import GeoProjector
1818

1919
extension GeoDrawer {
2020

21+
private var coordinateSystem: CoordinateSystem {
22+
#if os(macOS)
23+
.bottomLeft
24+
#else
25+
.topLeft
26+
#endif
27+
}
28+
2129
/// Draws the line into the current context
2230
public func draw(_ line: GeoJSON.LineString, strokeColor: CGColor, strokeWidth: Double = 2, in context: CGContext) {
23-
for line in project(line) {
31+
for line in project(line, coordinateSystem: coordinateSystem) {
2432
draw(line, strokeColor: strokeColor, strokeWidth: strokeWidth, in: context)
2533
}
2634
}
2735

2836
public func draw(_ polygon: GeoJSON.Polygon, fillColor: CGColor? = nil, strokeColor: CGColor? = nil, strokeWidth: Double = 2, frame: CGRect, in context: CGContext) {
29-
for polygon in project(polygon) {
37+
for polygon in project(polygon, coordinateSystem: coordinateSystem) {
3038
draw(polygon, fillColor: fillColor, strokeColor: strokeColor, strokeWidth: strokeWidth, frame: frame, in: context)
3139
}
3240
}
3341

3442
func drawCircle(_ position: GeoJSON.Position, radius: CGFloat, fillColor: CGColor, strokeColor: CGColor? = nil, strokeWidth: Double = 2, in context: CGContext) {
35-
guard let center = converter(position)?.0 else { return }
43+
guard let center = converter(position, coordinateSystem)?.0 else { return }
3644
drawCircle(center, radius: radius, fillColor: fillColor, strokeColor: strokeColor, strokeWidth: strokeWidth, in: context)
3745
}
3846

@@ -141,25 +149,25 @@ extension GeoDrawer {
141149

142150
switch bounds {
143151
case .ellipse:
144-
let min = projection.translate(.init(x: -1 * projection.projectionSize.width / 2, y: projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets)
145-
let max = projection.translate(.init(x: projection.projectionSize.width / 2, y: -1 * projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets)
152+
let min = projection.translate(.init(x: -1 * projection.projectionSize.width / 2, y: projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets, coordinateSystem: coordinateSystem)
153+
let max = projection.translate(.init(x: projection.projectionSize.width / 2, y: -1 * projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets, coordinateSystem: coordinateSystem)
146154

147155
path = CGPath(ellipseIn: .init(
148156
origin: min.cgPoint,
149157
size: .init(width: max.x - min.x, height: max.y - min.y)
150158
), transform: nil)
151159

152160
case .rectangle:
153-
let min = projection.translate(.init(x: -1 * projection.projectionSize.width / 2, y: projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets)
154-
let max = projection.translate(.init(x: projection.projectionSize.width / 2, y: -1 * projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets)
161+
let min = projection.translate(.init(x: -1 * projection.projectionSize.width / 2, y: projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets, coordinateSystem: coordinateSystem)
162+
let max = projection.translate(.init(x: projection.projectionSize.width / 2, y: -1 * projection.projectionSize.height / 2), to: size, zoomTo: zoomTo, insets: insets, coordinateSystem: coordinateSystem)
155163

156164
path = CGPath(rect: .init(
157165
origin: min.cgPoint,
158166
size: .init(width: max.x - min.x, height: max.y - min.y)
159167
), transform: nil)
160168

161169
case .bezier(let array):
162-
let points = array.map { projection.translate($0, to: size, zoomTo: zoomTo, insets: insets) }
170+
let points = array.map { projection.translate($0, to: size, zoomTo: zoomTo, insets: insets, coordinateSystem: coordinateSystem) }
163171
let mutable = CGMutablePath()
164172
mutable.move(to: points[0].cgPoint)
165173
for point in points[1...] {
@@ -189,7 +197,7 @@ extension GeoDrawer {
189197
extension GeoDrawer {
190198

191199
public func draw(_ contents: [Content], mapBackground: CGColor? = nil, mapOutline: CGColor? = nil, mapBackdrop: CGColor? = nil, in context: CGContext) {
192-
let projected = contents.compactMap(project)
200+
let projected = contents.compactMap { project($0, coordinateSystem: coordinateSystem) }
193201
draw(projected, mapBackground: mapBackground, mapOutline: mapOutline, mapBackdrop: mapBackdrop, in: context)
194202
}
195203

0 commit comments

Comments
 (0)