Skip to content

Commit

Permalink
Fix polygonize (#141)
Browse files Browse the repository at this point in the history
* start improving and testing bools

* add turf boolean tests

* more fixes

* fix polygonize

* fix polygonize and tweak performance

* optimise geometry processes with extent checks

* cleanup

* more cleanup

* handle over_allow and cross_allow

* only simple optimisations for now

* clean up example

* fix methods

* add multiple value handling

* dict

* faster with dict

* update disjoint optimisation logic

* get size down to an 8 multiple

* remove bools.jl

* cleanup

* test and allow multi value functions

* more tests

* fix extents for performance

* fix docs

* as/polygonize_docs (#142)

* Try to fix Literate not detecting the text properly

* Add testing packages to extras

* Return edge vectors with the same axis semantics as `axes(A)`

* Propagate CRS

* Propagate extend to returned MultiPolygon for the Bool case

* Add exotic array tests for polygonize

With the changes from the last commit, even Rasters work with roundtripped CRS.  The only thing remaining to be done is to figure out how to generate edge vectors for interval sampling, which would probably be an extension on Rasters in GeometryOps, since we're overriding an internal GO method.

* Remove unnecessary `crs` passthrough to temporary geometries

Co-authored-by: Rafael Schouten <rafaelschouten@gmail.com>

* Use mapreduce instead of reduce for extent unioning

Co-authored-by: Rafael Schouten <rafaelschouten@gmail.com>

* Add extent and CRS to features and featurecollections in polygonize

* dont add nodes in straight lines

* clean up and dict performance tweaks

---------

Co-authored-by: Anshul Singhvi <anshulsinghvi@gmail.com>
  • Loading branch information
rafaqz and asinghvi17 authored May 16, 2024
1 parent 3322900 commit 0321d26
Show file tree
Hide file tree
Showing 5 changed files with 443 additions and 144 deletions.
5 changes: 4 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,19 @@ julia = "1.9"
ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3"
CoordinateTransformations = "150eb455-5306-5404-9cee-2592286d6298"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DimensionalData = "0703355e-b756-11e9-17c0-8b28908087d0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FlexiJoins = "e37f2e79-19fa-4eb7-8510-b63b51fe0a37"
GeoFormatTypes = "68eda718-8dee-11e9-39e7-89f7f65f511f"
GeoJSON = "61d90e0f-e114-555e-ac52-39dfb47a3ef9"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
LibGEOS = "a90b1aa1-3769-5649-ba7e-abc5a9d163eb"
Rasters = "a3a2b9e3-a471-40c9-b274-f788e487c689"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
Proj = "c94c279d-25a6-4763-9509-64d165bea63e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Shapefile = "8e980c4a-a4fe-5da2-b3a7-4b4b0353a2f4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["ArchGDAL", "CoordinateTransformations", "DataFrames", "Distributions", "FlexiJoins", "GeoFormatTypes", "GeoJSON", "Proj", "JLD2", "LibGEOS", "Random", "Shapefile", "Test"]
test = ["ArchGDAL", "CoordinateTransformations", "DataFrames", "Distributions", "DimensionalData", "FlexiJoins", "GeoFormatTypes", "GeoJSON", "Proj", "JLD2", "LibGEOS", "Random", "Rasters", "OffsetArrays", "Shapefile", "Test"]
2 changes: 1 addition & 1 deletion src/methods/geom_relations/coveredby.jl
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,4 @@ function _coveredby(
!coveredby(sub_g1, g2) && return false
end
return true
end
end
58 changes: 53 additions & 5 deletions src/methods/geom_relations/geom_geom_processors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,18 @@ Else, return false.
If closed_line is true, line is treated as a closed line where the first and
last point are connected by a segment. Same with closed_curve.
=#
function _line_curve_process(
@inline function _line_curve_process(line, curve;
over_allow, cross_allow, kw...
)
skip, returnval = _maybe_skip_disjoint_extents(line, curve;
in_allow=(over_allow | cross_allow), kw...
)
skip && return returnval

return _inner_line_curve_process(line, curve; over_allow, cross_allow, kw...)
end

function _inner_line_curve_process(
line, curve;
over_allow, cross_allow, on_allow, out_allow,
in_require, on_require, out_require,
Expand Down Expand Up @@ -246,11 +257,17 @@ Else, return false.
If closed_line is true, line is treated as a closed line where the first and
last point are connected by a segment.
=#
function _line_polygon_process(
@inline function _line_polygon_process(line, polygon; kw...)
skip, returnval = _maybe_skip_disjoint_extents(line, polygon; kw...)
skip && return returnval
return _inner_line_polygon_process(line, polygon; kw...)
end

function _inner_line_polygon_process(
line, polygon;
closed_line=false,
in_allow, on_allow, out_allow,
in_require, on_require, out_require,
closed_line = false,
)
in_req_met = !in_require
on_req_met = !on_require
Expand Down Expand Up @@ -315,7 +332,13 @@ If out_require is true, the first polygon must have at least one interior point
If the point is in an "allowed" location and meets all requirments, return true.
Else, return false.
=#
function _polygon_polygon_process(
@inline function _polygon_polygon_process(poly1, poly2; kw...)
skip, returnval = _maybe_skip_disjoint_extents(poly1, poly2; kw...)
skip && return returnval
return _inner_polygon_polygon_process(poly1, poly2; kw...)
end

function _inner_polygon_polygon_process(
poly1, poly2;
in_allow, on_allow, out_allow,
in_require, on_require, out_require,
Expand Down Expand Up @@ -641,6 +664,7 @@ function _line_polygon_interactions(
line, polygon;
closed_line = false,
)

in_poly, on_poly, out_poly = _line_filled_curve_interactions(
line, GI.getexterior(polygon);
closed_line = closed_line,
Expand Down Expand Up @@ -669,4 +693,28 @@ end
function _point_in_extent(p, extent::Extents.Extent)
(x1, x2), (y1, y2) = extent.X, extent.Y
return x1 GI.x(p) x2 && y1 GI.y(p) y2
end
end

# Disjoint extent optimisation: skip work based on geom extent intersection
# returns Tuple{Bool, Bool} for (skip, returnval)
@inline function _maybe_skip_disjoint_extents(a, b;
in_allow, on_allow, out_allow,
in_require, on_require, out_require,
kw...
)
ext_disjoint = Extents.disjoint(GI.extent(a), GI.extent(b))
skip, returnval = if !ext_disjoint
# can't tell anything about this case
false, false
elseif out_allow # && ext_disjoint
if in_require || on_require
true, false
else
true, true
end
else # !out_allow && ext_disjoint
# points not allowed in exterior, but geoms are disjoint
true, false
end
return skip, returnval
end
Loading

0 comments on commit 0321d26

Please sign in to comment.