Skip to content

Commit 11ed3c2

Browse files
authored
add GeoInterfaceMakie (#71)
* add GeoInterfaceMakie * fix * fix * fix * fix * fix * fix * fix * fix * fix tests * fix * fix * fix * replace Makie by MakieCore where possible * drop Makie dependency * make Makie a test only dependency
1 parent 2ab9320 commit 11ed3c2

File tree

8 files changed

+285
-2
lines changed

8 files changed

+285
-2
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: GeoInterfaceMakie CI
2+
on:
3+
pull_request:
4+
paths-ignore:
5+
- 'docs/**'
6+
- '*.md'
7+
branches:
8+
- main
9+
- breaking-release
10+
push:
11+
paths-ignore:
12+
- 'docs/**'
13+
- '*.md'
14+
branches:
15+
- main
16+
- breaking-release
17+
tags: '*'
18+
19+
concurrency:
20+
group: makie-${{ github.ref }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
test:
25+
name: GeoInterfaceMakie Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
26+
runs-on: ${{ matrix.os }}
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
version:
31+
- '1.6'
32+
- '1' # automatically expands to the latest stable 1.x release of Julia
33+
os:
34+
- ubuntu-latest
35+
arch:
36+
- x64
37+
steps:
38+
- name: Checkout
39+
uses: actions/checkout@v2
40+
- uses: julia-actions/setup-julia@v1
41+
with:
42+
version: ${{ matrix.version }}
43+
arch: ${{ matrix.arch }}
44+
- uses: julia-actions/cache@v1
45+
- name: Install Julia dependencies
46+
shell: julia --project=monorepo {0}
47+
run: |
48+
using Pkg;
49+
# dev mono repo versions
50+
pkg"dev . ./GeoInterfaceMakie"
51+
- name: Run the tests
52+
continue-on-error: true
53+
run: >
54+
julia --color=yes --project=monorepo -e 'using Pkg; Pkg.test("GeoInterfaceMakie", coverage=true)'
55+
&& echo "TESTS_SUCCESSFUL=true" >> $GITHUB_ENV
56+
- name: Exit if tests failed
57+
if: ${{ env.TESTS_SUCCESSFUL != 'true' }}
58+
run: exit 1
59+
- uses: julia-actions/julia-processcoverage@v1
60+
- uses: codecov/codecov-action@v1
61+
with:
62+
file: lcov.info

.github/workflows/recipes.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ on:
55
- 'docs/**'
66
- '*.md'
77
branches:
8-
- master
8+
- main
99
- breaking-release
1010
push:
1111
paths-ignore:
1212
- 'docs/**'
1313
- '*.md'
1414
branches:
15-
- master
15+
- main
1616
- breaking-release
1717
tags: '*'
1818

GeoInterfaceMakie/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/Manifest.toml
2+
/docs/build/

GeoInterfaceMakie/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Jan Weidner <[email protected]> and contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

GeoInterfaceMakie/Project.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name = "GeoInterfaceMakie"
2+
uuid = "0edc0954-3250-4c18-859d-ec71c1660c08"
3+
authors = ["JuliaGeo and contributors"]
4+
version = "0.1.0"
5+
6+
[deps]
7+
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
8+
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
9+
MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b"
10+
11+
[compat]
12+
GeoInterface = "1"
13+
GeometryBasics = "0.4.4"
14+
MakieCore = "0.5.1"
15+
julia = "1.6"
16+
17+
[extras]
18+
LibGEOS = "a90b1aa1-3769-5649-ba7e-abc5a9d163eb"
19+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
20+
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
21+
22+
[targets]
23+
test = ["Test", "LibGEOS", "Makie"]

GeoInterfaceMakie/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# GeoInterfaceMakie
2+
3+
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://jw3126.github.io/GeoInterfaceMakie.jl/stable/)
4+
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://jw3126.github.io/GeoInterfaceMakie.jl/dev/)
5+
[![Build Status](https://github.com/jw3126/GeoInterfaceMakie.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/jw3126/GeoInterfaceMakie.jl/actions/workflows/CI.yml?query=branch%3Amain)
6+
7+
Makie support for any geometry that implements [GeoInterface](https://github.com/JuliaGeo/GeoInterface.jl).
8+
9+
# Usage
10+
Add Makie support to a type that implements GeoInterface:
11+
```julia
12+
struct MyGeometry
13+
...
14+
end
15+
# overload GeoInterface methods
16+
...
17+
import GeoInterfaceMakie
18+
GeoInterfaceMakie.@enable MyGeometry
19+
```
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
module GeoInterfaceMakie
2+
3+
using GeoInterface
4+
import MakieCore as MC
5+
import GeometryBasics as GB
6+
import GeoInterface as GI
7+
8+
9+
function _plottype(geom)
10+
plottype_from_geomtrait(GI.geomtrait(geom))
11+
end
12+
function plottype_from_geomtrait(::Union{GI.LineStringTrait, GI.MultiLineStringTrait})
13+
MC.Lines
14+
end
15+
function plottype_from_geomtrait(::Union{GI.PointTrait, GI.MultiPointTrait})
16+
MC.Scatter
17+
end
18+
function plottype_from_geomtrait(::Union{GI.PolygonTrait,GI.MultiPolygonTrait, GI.LinearRingTrait})
19+
MC.Poly
20+
end
21+
function pttype(geom)
22+
if GI.is3d(geom)
23+
GB.Point3f
24+
else
25+
GB.Point2f
26+
end
27+
end
28+
function points(geom)::Union{Vector{GB.Point2f}, Vector{GB.Point3f}}
29+
Pt = pttype(geom)
30+
out = Pt[]
31+
points!(out, GI.geomtrait(geom), geom)
32+
end
33+
@noinline function points!(out, ::GI.AbstractTrait, geom)
34+
for pt in GI.getpoint(geom)
35+
push!(out, _convert(eltype(out), pt))
36+
end
37+
out
38+
end
39+
@noinline function points!(out, ::GI.PointTrait, pt)
40+
push!(out, _convert(eltype(out), pt))
41+
out
42+
end
43+
function _convert(::Type{GB.Point2f}, pt)
44+
x,y = GI.getcoord(pt)
45+
GB.Point2f(x,y)
46+
end
47+
function _convert(::Type{GB.Point3f}, pt)
48+
x,y,z = GI.getcoord(pt)
49+
GB.Point3f(x,y,z)
50+
end
51+
52+
function basicsgeom(geom)
53+
t = GI.geomtrait(geom)
54+
T = basicsgeomtype(t)
55+
GI.convert(T, t, geom)
56+
end
57+
58+
basicsgeomtype(::GI.PointTrait) = GB.Point
59+
basicsgeomtype(::GI.MultiPointTrait) = GB.MultiPoint
60+
basicsgeomtype(::GI.PolygonTrait) = GB.Polygon
61+
basicsgeomtype(::GI.MultiPolygonTrait) = GB.MultiPolygon
62+
basicsgeomtype(::GI.LineStringTrait) = GB.LineString
63+
basicsgeomtype(::GI.MultiLineStringTrait) = GB.MultiLineString
64+
65+
function _convert_arguments(::Type{<:MC.Poly}, geom)::Tuple
66+
geob = basicsgeom(geom)::Union{GB.Polygon, GB.MultiPolygon}
67+
(geob,)
68+
end
69+
function _convert_arguments(::MC.PointBased, geom)::Tuple
70+
pts = points(geom)
71+
(pts,)
72+
end
73+
74+
function expr_enable(Geom)
75+
quote
76+
function $MC.plottype(geom::$Geom)
77+
$_plottype(geom)
78+
end
79+
function $MC.convert_arguments(p::Type{<:$MC.Poly}, geom::$Geom)
80+
$_convert_arguments(p,geom)
81+
end
82+
function $MC.convert_arguments(p::$MC.PointBased, geom::$Geom)
83+
$_convert_arguments(p,geom)
84+
end
85+
end
86+
end
87+
88+
"""
89+
90+
@enable(Geom)
91+
92+
Enable Makie based plotting for a type `Geom` that implements the geometry interface
93+
defined in `GeoInterface`.
94+
95+
# Usage
96+
```julia
97+
struct MyGeometry
98+
...
99+
end
100+
# overload GeoInterface for MyGeometry
101+
...
102+
103+
@enable MyGeometry
104+
```
105+
"""
106+
macro enable(Geom)
107+
esc(expr_enable(Geom))
108+
end
109+
110+
# TODO
111+
# Features and Feature collections
112+
# https://github.com/JuliaGeo/GeoInterface.jl/pull/72#issue-1406325596
113+
114+
end

GeoInterfaceMakie/test/runtests.jl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import GeoInterfaceMakie
2+
using Test
3+
import LibGEOS
4+
using LibGEOS
5+
import GeoInterface as GI
6+
using Makie
7+
8+
GeoInterfaceMakie.@enable(LibGEOS.AbstractGeometry)
9+
10+
@testset "points" begin
11+
points = GeoInterfaceMakie.points
12+
pt = LibGEOS.Point(1,2,3)
13+
@test points(pt) == [Point3f(1,2,3)]
14+
15+
unitsquare = readgeom("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))")
16+
@test points(unitsquare) == [
17+
Point2f(0.0, 0.0),
18+
Point2f(0.0, 1.0),
19+
Point2f(1.0, 1.0),
20+
Point2f(1.0, 0.0),
21+
Point2f(0.0, 0.0),
22+
]
23+
end
24+
25+
@testset "smoketest 2d" begin
26+
unitsquare = readgeom("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))")
27+
bigsquare = readgeom("POLYGON((0 0, 11 0, 11 11, 0 11, 0 0))")
28+
smallsquare = readgeom("POLYGON((5 5, 8 5, 8 8, 5 8, 5 5))")
29+
fig = Figure()
30+
geoms = [
31+
unitsquare,
32+
GI.difference(bigsquare, smallsquare),
33+
boundary(unitsquare),
34+
GI.union(smallsquare, unitsquare),
35+
readgeom("POINT(1 0)"),
36+
readgeom("MULTIPOINT(1 2, 2 3, 3 4)"),
37+
]
38+
for (i,geom) in enumerate(geoms)
39+
Makie.plot!(Axis(fig[i,1], title="$(GI.geomtrait(geom))"), geom)
40+
end
41+
fig
42+
end

0 commit comments

Comments
 (0)