Skip to content

Commit 71d5b34

Browse files
authored
Fix line burning and test rasterize against GDAL (#330)
* fix line burning * bugfix * bump DD compat to 0.23
1 parent 03f4eb1 commit 71d5b34

File tree

15 files changed

+321
-130
lines changed

15 files changed

+321
-130
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ ArchGDAL = "0.9"
3535
ColorTypes = "0.10, 0.11"
3636
ConstructionBase = "1"
3737
CoordinateTransformations = "0.6.2"
38-
DimensionalData = "0.22"
38+
DimensionalData = "0.23"
3939
DiskArrays = "^0.3.3"
4040
Extents = "0.1"
4141
FillArrays = "0.12, 0.13"
@@ -60,8 +60,9 @@ CFTime = "179af706-886a-5703-950a-314cd64e0468"
6060
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
6161
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
6262
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
63+
Shapefile = "8e980c4a-a4fe-5da2-b3a7-4b4b0353a2f4"
6364
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
6465
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6566

6667
[targets]
67-
test = ["Aqua", "CFTime", "DataFrames", "Plots", "SafeTestsets", "Statistics", "Test"]
68+
test = ["Aqua", "CFTime", "DataFrames", "Plots", "SafeTestsets", "Shapefile", "Statistics", "Test"]

docs/src/index.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ with an `Array`. `view` is always lazy, and reads from disk are deferred until
1414
way to subset an object, making use of the objects index to find values at
1515
e.g. certain X/Y coordinates. The available selectors are listed here:
1616

17-
| | |
18-
| :------------------- | :----------------------------------------------------------------- |
19-
| `At(x)` | get the index exactly matching the passed in value(s) |
20-
| `Near(x)` | get the closest index to the passed in value(s) |
21-
| `Where(f::Function)` | filter the array axis by a function of the dimension index values. |
22-
| `Between(a, b)` | get all indices between two values, excluding the high value. |
23-
| `Contains(x)` | get indices where the value x falls within an interval |
17+
| | |
18+
| :--------------------- | :----------------------------------------------------------------- |
19+
| `At(x)` | get the index exactly matching the passed in value(s) |
20+
| `Near(x)` | get the closest index to the passed in value(s) |
21+
| `Where(f::Function)` | filter the array axis by a function of the dimension index values. |
22+
| `a..b`/`Between(a, b)` | get all indices between two values, excluding the high value. |
23+
| `Contains(x)` | get indices where the value x falls within an interval |
2424

2525

26-
Use the `Between` selector to take a `view` of madagascar:
26+
Use the `..` selector to take a `view` of madagascar:
2727

2828
```@example
2929
using Rasters, Plots
@@ -209,9 +209,7 @@ to index it with `Near`.
209209

210210
```@example nc
211211
using CFTime
212-
A[Ti=Near(DateTime360Day(2001, 01, 17)),
213-
Y=Between(-60.0, 90.0),
214-
X=Between(190.0, 345.0)] |> plot
212+
A[Ti=Near(DateTime360Day(2001, 01, 17)), Y=-60.0..90.0), X=190.0..45.0)] |> plot
215213
```
216214

217215
Now get the mean over the timespan, then save it to disk, and plot it as a

src/methods/crop_extend.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
2727
rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
2828
2929
# Roughly cut out New Zealand from the evenness raster
30-
nz_bounds = X(Between(165, 180)), Y(Between(-32, -50))
30+
nz_bounds = X(165..180), Y(-32..-50)
3131
nz_evenness = evenness[nz_bounds...]
3232
3333
# Crop range to match evenness
@@ -125,7 +125,7 @@ evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
125125
rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
126126
127127
# Roughly cut out South America
128-
sa_bounds = X(Between(-88, -32)), Y(Between(-57, 13))
128+
sa_bounds = X(-88..-32), Y(-57..13)
129129
sa_evenness = evenness[sa_bounds...]
130130
131131
# Extend range to match the whole-world raster

src/methods/inpolygon.jl

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,15 @@ function _inpolygon(::GI.AbstractPointTrait, points, ::GI.AbstractGeometryTrait,
5151
return first(inpoly2([(GI.x(points), GI.y(points))], nodes, edges; kw...))
5252
end
5353

54+
55+
using PolygonInbounds: vertex, edgecount, flipio!, edgeindex, searchfirst
56+
5457
# Copied from PolygonInbounds, to add extra keyword arguments.
5558
# PR to include these when this has solidified
5659
function inpoly2(vert, node, edge=zeros(Int);
5760
atol::T=0.0, rtol::T=NaN, iyperm=nothing,
5861
vmin=nothing, vmax=nothing, pmin=nothing, pmax=nothing
62+
5963
) where T<:AbstractFloat
6064
rtol = !isnan(rtol) ? rtol : iszero(atol) ? eps(T)^0.85 : zero(T)
6165
poly = PolygonInbounds.PolygonMesh(node, edge)
@@ -70,7 +74,8 @@ function inpoly2(vert, node, edge=zeros(Int);
7074
tol = max(abs(rtol * lbar), abs(atol))
7175

7276
ac = PolygonInbounds.areacount(poly)
73-
stat = ac > 1 ? falses(length(points), 2, ac) : falses(length(points), 2)
77+
# stat = ac > 1 ? fill(false, length(points), 1, ac) :
78+
stat = fill(false, length(points), 2)
7479
# flip coordinates so expected effort is minimal
7580
dvert = vmax .- vmin
7681
if isnothing(iyperm)
@@ -83,3 +88,80 @@ function inpoly2(vert, node, edge=zeros(Int);
8388
PolygonInbounds.inpoly2!(points, iyperm, poly, ix, tol, stat)
8489
return stat
8590
end
91+
92+
function inpoly2!(points, iyperm, poly, ix::Integer, veps::T, stat::S) where {N,T<:AbstractFloat,S<:AbstractArray{Bool,N}}
93+
nvrt = length(points) # number of points to be checked
94+
nedg = edgecount(poly) # number of edges of the polygon mesh
95+
vepsx = vepsy = veps
96+
iy = 3 - ix
97+
98+
#----------------------------------- loop over polygon edges
99+
for epos = 1:nedg
100+
101+
inod = edgeindex(poly, epos, 1) # from
102+
jnod = edgeindex(poly, epos, 2) # to
103+
# swap order of vertices
104+
if vertex(poly, inod, iy) > vertex(poly, jnod, iy)
105+
inod, jnod = jnod, inod
106+
end
107+
108+
#------------------------------- calc. edge bounding-box
109+
xone = vertex(poly, inod, ix)
110+
yone = vertex(poly, inod, iy)
111+
xtwo = vertex(poly, jnod, ix)
112+
ytwo = vertex(poly, jnod, iy)
113+
114+
xmin0 = min(xone, xtwo)
115+
xmax0 = max(xone, xtwo)
116+
xmin = xmin0 - vepsx
117+
xmax = xmax0 + vepsx
118+
ymin = yone - vepsy
119+
ymax = ytwo + vepsy
120+
121+
ydel = ytwo - yone
122+
xdel = xtwo - xone
123+
xysq = xdel^2 + ydel^2
124+
feps = sqrt(xysq) * veps
125+
126+
# find top points[:,iy] < ymin by binary search
127+
ilow = searchfirst(points, iy, iyperm, ymin)
128+
#------------------------------- calc. edge-intersection
129+
# loop over all points with y ∈ [ymin,ymax)
130+
for jpos = ilow:nvrt
131+
jorig = iyperm[jpos]
132+
ypos = vertex(points, jorig, iy)
133+
ypos > ymax && break
134+
xpos = vertex(points, jorig, ix)
135+
136+
if xpos >= xmin
137+
if xpos <= xmax
138+
#--------- inside extended bounding box of edge
139+
mul1 = ydel * (xpos - xone)
140+
mul2 = xdel * (ypos - yone)
141+
# if abs(mul2 - mul1) <= feps
142+
#------- distance from line through edge less veps
143+
# mul3 = xdel * (2xpos-xone-xtwo) + ydel * (2ypos-yone-ytwo)
144+
# if abs(mul3) <= xysq ||
145+
# hypot(xpos- xone, ypos - yone) <= veps ||
146+
# hypot(xpos- xtwo, ypos - ytwo) <= veps
147+
# # ---- round boundaries around endpoints of edge
148+
# setonbounds!(poly, stat, jorig, epos)
149+
# end
150+
#----- left of line && ypos exact to avoid multiple counting
151+
# end
152+
if mul1 < mul2 && yone <= ypos < ytwo
153+
elseif mul1 < mul2 && yone <= ypos < ytwo
154+
#----- left of line && ypos exact to avoid multiple counting
155+
flipio!(poly, stat, jorig, epos)
156+
end
157+
end
158+
else # xpos < xmin - left of bounding box
159+
if yone <= ypos < ytwo
160+
#----- ypos exact to avoid multiple counting
161+
flipio!(poly, stat, jorig, epos)
162+
end
163+
end
164+
end
165+
end
166+
stat
167+
end

src/methods/mask.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ function boolmask!(dest::AbstractRaster, src::AbstractRaster;
257257
broadcast!(a -> !isequal(a, missingval), dest, src)
258258
end
259259
function boolmask!(dest::AbstractRaster, geom; kw...)
260-
_fill_geometry!(dest, geom; fill=true, kw...)
260+
fill_geometry!(dest, geom; fill=true, kw...)
261261
return dest
262262
end
263263

src/methods/mosaic.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ Here we cut out australia and africa from a stack, and join them with `mosaic`.
2929
using Rasters, Plots
3030
st = RasterStack(WorldClim{Climate}; month=1);
3131
32-
africa = st[X(Between(-20.0, 60.0)), Y(Between(35.0, -40.0))]
32+
africa = st[X=-20.0..60.0, Y=35.0..(-40.0)]
3333
a = plot(africa)
3434
35-
aus = st[X(Between(100.0, 160.0)), Y(Between(-10.0, -50.0))]
35+
aus = st[X=100.0..160.0), Y=-10.0..(-50.0)]
3636
b = plot(aus)
3737
3838
# Combine with mosaic
@@ -118,8 +118,8 @@ into a single stack.
118118
```jldoctest
119119
using Rasters, Statistics, Plots
120120
st = read(RasterStack(WorldClim{Climate}; month=1))
121-
aus = st[X(Between(100.0, 160.0)), Y(Between(-10.0, -50.0))]
122-
africa = st[X(Between(-20.0, 60.0)), Y(Between(35.0, -40.0))]
121+
aus = st[X=100.0..160.0, Y=-10.0..(-50.0)]
122+
africa = st[X=-20.0..60.0, Y=35.0..(-40.0)]
123123
mosaic!(first, st, aus, africa)
124124
plot(st)
125125
savefig("build/mosaic_bang_example.png")

0 commit comments

Comments
 (0)