Skip to content

Commit

Permalink
add implementation of shapecoords for AbstractGeometry
Browse files Browse the repository at this point in the history
this is for packages implementing GeoInterface at the level of
AbstractGeometry, rather than the subtypes
AbstractPoint…AbstractMultiPolygon. They just need to define
`geotype(::AbstractGeometry)` in order for this package to identify
which geometry type it is, and return the corresponding coordinates.

We first define methods (`pointcoords()`,…,`multipolygoncoords()`) on
AbstractGeometry that returns the coordinates for different geometry
types. We can then have a `shapecoords(geom::AbstractGeometry)` that
uses `geotype(geom)` to look up the corresponding method to call
  • Loading branch information
yeesian authored and visr committed Jan 28, 2018
1 parent 9b73cf2 commit 5151e04
Showing 1 changed file with 92 additions and 33 deletions.
125 changes: 92 additions & 33 deletions src/plotrecipes.jl
Original file line number Diff line number Diff line change
@@ -1,86 +1,145 @@
shapecoords(geom::AbstractPoint) = [tuple(coordinates(geom)...)]
function pointcoords(geom::AbstractGeometry)
@assert geotype(geom) == :Point
[tuple(coordinates(geom)...)]
end

function multipointcoords(geom::AbstractGeometry)
@assert geotype(geom) == :MultiPoint
coords = coordinates(geom)
first.(coords), last.(coords)
end

function linestringcoords(geom::AbstractGeometry)
@assert geotype(geom) == :LineString
coords = coordinates(geom)
first.(coords), last.(coords)
end

function multilinestringcoords(geom::AbstractGeometry)
@assert geotype(geom) == :MultiLineString
x, y = Float64[], Float64[]
for line in coordinates(geom)
append!(x, first.(line)); push!(x, NaN)
append!(y, last.(line)); push!(y, NaN)
end
x, y
end

function polygoncoords(geom::AbstractGeometry)
@assert geotype(geom) == :Polygon
ring = first(coordinates(geom)) # currently doesn't plot holes
first.(ring), last.(ring)
end

function multipolygoncoords(geom::AbstractGeometry)
@assert geotype(geom) == :MultiPolygon
x, y = Float64[], Float64[]
for poly in coordinates(geom)
ring = first(coordinates(poly)) # currently doesn't plot holes
append!(x, first.(ring)); push!(x, NaN)
append!(y, last.(ring)); push!(y, NaN)
end
x, y
end

shapecoords(geom::AbstractPoint) = pointcoords(geom)
shapecoords(geom::AbstractMultiPoint) = multipointcoords(geom)
shapecoords(geom::AbstractLineString) = linestringcoords(geom)
shapecoords(geom::AbstractMultiLineString) = multilinestringcoords(geom)
shapecoords(geom::AbstractPolygon) = polygoncoords(geom)
shapecoords(geom::AbstractMultiPolygon) = multipolygoncoords(geom)

function shapecoords(geom::AbstractGeometry)
gtype = geotype(geom)
if gtype == :Point
return pointcoords(geom)
elseif gtype == :MultiPoint
return multipointcoords(geom)
elseif gtype == :LineString
return linestringcoords(geom)
elseif gtype == :MultiLineString
return multilinestringcoords(geom)
elseif gtype == :Polygon
return polygoncoords(geom)
elseif gtype == :MultiPolygon
return multipolygoncoords(geom)
else
warn("unknown geometry type: $gtype")
end
end

RecipesBase.@recipe f(geom::AbstractPoint) = (
aspect_ratio := 1;
seriestype --> :scatter;
legend --> :false;
shapecoords(geom)
)

function shapecoords(geom::AbstractMultiPoint)
coords = coordinates(geom)
first.(coords), last.(coords)
end
RecipesBase.@recipe f(geom::AbstractMultiPoint) = (
aspect_ratio := 1;
seriestype --> :scatter;
legend --> :false;
shapecoords(geom)
)

function shapecoords(geom::AbstractLineString)
coords = coordinates(geom)
first.(coords), last.(coords)
end
RecipesBase.@recipe f(geom::AbstractLineString) = (
aspect_ratio := 1;
seriestype --> :path;
legend --> :false;
shapecoords(geom)
)

function shapecoords(geom::AbstractMultiLineString)
x, y = Float64[], Float64[]
for line in coordinates(geom)
append!(x, first.(line)); push!(x, NaN)
append!(y, last.(line)); push!(y, NaN)
end
x, y
end
RecipesBase.@recipe f(geom::AbstractMultiLineString) = (
aspect_ratio := 1;
seriestype --> :path;
legend --> :false;
shapecoords(geom)
)

function shapecoords(geom::AbstractPolygon)
ring = first(coordinates(geom)) # currently doesn't plot holes
first.(ring), last.(ring)
end
RecipesBase.@recipe f(geom::AbstractPolygon) = (
aspect_ratio := 1;
seriestype --> :shape;
legend --> :false;
shapecoords(geom)
)

function shapecoords(geom::AbstractMultiPolygon)
x, y = Float64[], Float64[]
for poly in coordinates(geom)
ring = first(coordinates(poly)) # currently doesn't plot holes
append!(x, first.(ring)); push!(x, NaN)
append!(y, last.(ring)); push!(y, NaN)
end
x, y
end
RecipesBase.@recipe f(geom::AbstractMultiPolygon) = (
aspect_ratio := 1;
seriestype --> :shape;
legend --> :false;
shapecoords(geom)
)

RecipesBase.@recipe function f(geom::AbstractGeometry)
aspect_ratio := 1
legend --> :false
gtype = geotype(geom)
if gtype == :Point || gtype == :MultiPoint
seriestype := :scatter
elseif gtype == :LineString || gtype == :MultiLineString
seriestype := :path
elseif gtype == :Polygon || gtype == :MultiPolygon
seriestype := :shape
else
warn("unknown geometry type: $gtype")
end
shapecoords(geom)
end

RecipesBase.@recipe function f(geom::Vector{<:AbstractGeometry})
aspect_ratio := 1
legend --> :false
for g in geom
@series begin
if g isa AbstractPoint || g isa AbstractMultiPoint
gtype = geotype(g)
if gtype == :Point || gtype == :MultiPoint
seriestype := :scatter
elseif g isa AbstractLineString || g isa AbstractMultiLineString
elseif gtype == :LineString || gtype == :MultiLineString
seriestype := :path
elseif g isa AbstractPolygon || g isa AbstractMultiPolygon
elseif gtype == :Polygon || gtype == :MultiPolygon
seriestype := :shape
else
warn("unknown geometry type: $gtype")
end
shapecoords(g)
end
Expand Down

0 comments on commit 5151e04

Please sign in to comment.