Skip to content

Commit

Permalink
Make logic to skip entries smarter for nested geoms
Browse files Browse the repository at this point in the history
  • Loading branch information
BenCurran98 committed Nov 4, 2024
1 parent 5dde309 commit 640bfca
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 40 deletions.
54 changes: 33 additions & 21 deletions src/wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,10 @@ for (geomtype, trait, childtype, child_trait, length_check, nesting) in (
# But not if geom is already a WrapperGeometry
convert(::Type{$geomtype}, ::$trait, geom::$geomtype) = geom

function Base.show(io::IO, ::MIME"text/plain", geom::$geomtype{Z, M, T, E, C}; show_mz::Bool = true) where {Z, M, T, E <: Union{Nothing,Extents.Extent}, C}
function Base.show(io::IO, ::MIME"text/plain", geom::$geomtype{Z, M, T, E, C}; show_mz::Bool = true, screen_ncols::Int = displaysize(io)[2]) where {Z, M, T, E <: Union{Nothing,Extents.Extent}, C}
compact = get(io, :compact, false)
spacing = compact ? "" : " "
show_mz &= !compact
screen_nrows, screen_ncols = displaysize(io)

extent_str = ""
crs_str = ""
Expand All @@ -195,35 +194,47 @@ for (geomtype, trait, childtype, child_trait, length_check, nesting) in (
end
str *= "("
this_geom = getgeom(trait(geom), geom)
# keep track of how much space we've used + make sure we give this info to any child geoms so they don't go over the limit
currently_used_space = textwidth(str) + textwidth(extent_str) + textwidth(crs_str)
if this_geom isa AbstractVector
# check here if we have enough room to display the whole object or if we need to condense the string
str *= "["
currently_used_space = textwidth(str) + textwidth(extent_str) + textwidth(crs_str) + 2 # +2 for brackets
length_of_one_object_in_chars = textwidth(_nice_geom_str(this_geom[1], false, compact))
num_objects_to_show = min(length(this_geom), floor(Int, (screen_ncols - currently_used_space - 1 #=triple dot character =#) / length_of_one_object_in_chars))
currently_used_space += 2 # +2 for brackets
available_space = screen_ncols - currently_used_space

space_per_object = floor(Int, available_space / length(this_geom))

length_of_one_object_in_chars = textwidth(_nice_geom_str(this_geom[1], false, compact, space_per_object))

# this makes sure that if we have 1 or 2 geometries here, we show both, but any more and we skip them
num_objects_to_show = min(length(this_geom), max(2, floor(Int, (available_space - 1 #=triple dot character =#) / length_of_one_object_in_chars)))

# separately track how many objects to show to the left and right of the ...()...
num_objects_left = num_objects_to_show == 1 ? 0 : ceil(Int, num_objects_to_show/2)
num_objects_right = max(1, floor(Int, num_objects_to_show/2))

num_shown_each_side = ceil(Int, num_objects_to_show/2)
num_missing = length(this_geom) - num_objects_to_show
# how many objects are we skipping?
num_missing = length(this_geom) - (num_objects_left + num_objects_right)

for i 1:num_shown_each_side
str *= "$(_nice_geom_str(this_geom[i], false, compact)),$(spacing)"
for i 1:num_objects_left
str *= "$(_nice_geom_str(this_geom[i], false, compact, space_per_object)),$(spacing)"
end

if num_missing > 0
# report how many geometries aren't shown here
str *= " … ($(num_missing))"
str *= "$(spacing)($(num_missing))$(spacing)$(spacing),$(spacing)"
end

for i 1:num_shown_each_side
str *= _nice_geom_str(this_geom[end - num_shown_each_side + i], false, compact)
if i != num_shown_each_side
for i 1:num_objects_right
str *= _nice_geom_str(this_geom[end - num_objects_right + i], false, compact, space_per_object)
if i != num_objects_right
str *= ",$(spacing)"
end
end

str *= "]"
else
str *= _nice_geom_str(g, false, compact)
str *= _nice_geom_str(g, false, compact, screen_ncols - currently_used_space)

Check warning on line 237 in src/wrappers.jl

View check run for this annotation

Codecov / codecov/patch

src/wrappers.jl#L237

Added line #L237 was not covered by tests
end

str *= extent_str
Expand Down Expand Up @@ -290,29 +301,30 @@ for (geomtype, trait, childtype, child_trait, length_check, nesting) in (
end
end

function _nice_geom_str(geom, ::Bool, ::Bool)
function _nice_geom_str(geom, ::Bool, ::Bool, ::Int)
io = IOBuffer()
show(io, MIME("text/plain"), geom)
return String(take!(io))
end

# need a work around to pass the show_mz variable through - put string to a temp IOBuffer then read it
function _nice_geom_str(geom::WrapperGeometry, show_mz::Bool, ::Bool)
io = IOBuffer()
show(io, MIME("text/plain"), geom; show_mz = show_mz)
return String(take!(io))
function _nice_geom_str(geom::WrapperGeometry, show_mz::Bool, compact::Bool, screen_ncols::Int)
buf = IOBuffer()
io = IOContext(IOContext(buf, :compact => compact))
show(io, MIME("text/plain"), geom; show_mz = show_mz, screen_ncols = screen_ncols)

Check warning on line 314 in src/wrappers.jl

View check run for this annotation

Codecov / codecov/patch

src/wrappers.jl#L311-L314

Added lines #L311 - L314 were not covered by tests
return String(take!(buf))
end

# handle tuples/vectors explicitly
function _nice_geom_str(geom::AbstractVector, ::Bool, compact::Bool)
function _nice_geom_str(geom::AbstractVector, ::Bool, compact::Bool, ::Int)
spacing = compact ? "" : " "
str = "["
str *= _add_elements_with_spacing(geom, spacing)
str *= "]"
return str
end

function _nice_geom_str(geom::Tuple, ::Bool, compact::Bool)
function _nice_geom_str(geom::Tuple, ::Bool, compact::Bool, ::Int)
spacing = compact ? "" : " "
str = "("
str *= _add_elements_with_spacing(geom, spacing)
Expand Down
38 changes: 19 additions & 19 deletions test/test_wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ polygon = GI.Polygon([linearring, linearring])
@test @inferred(GI.extent(polygon)) == Extent(X=(1, 5), Y=(2, 6))
@test GI.convert(GI, MyPolygon()) isa GI.Polygon
@test GI.convert(GI, polygon) === polygon
test_display(polygon, "Polygon{false, false}([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])])",
test_display(polygon, "Polygon{false, false}([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])])",
"Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])")
polygon_crs = GI.Polygon(polygon; crs=EPSG(4326))
@test parent(polygon_crs) === parent(polygon)
@test GI.crs(polygon_crs) === EPSG(4326)
test_display(polygon_crs, "Polygon{false, false}([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])], crs = EPSG{1}((4326,)))",
test_display(polygon_crs, "Polygon{false, false}([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])], crs = EPSG{1}((4326,)))",
"Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])")
# Make sure `linestring` is also ok in polygons
polygon = GI.Polygon([linestring, linestring])
Expand Down Expand Up @@ -229,7 +229,7 @@ test_display(multipoint, "MultiPoint{false, false}([(1, 2), (3, 4), (3, 2), (1,
multipoint_crs = GI.MultiPoint(multipoint; crs=EPSG(4326))
@test parent(multipoint_crs) == parent(multipoint)
@test GI.crs(multipoint_crs) === EPSG(4326)
test_display(multipoint_crs, "MultiPoint{false, false}([(1, 2), (3, 4), (3, 2), (1, 4), (7, 8), (9, 10)], crs = EPSG{1}((4326,)))", "MultiPoint([(1,2),(3,4),(3,2),(1,4),(7,8),(9,10)])")
test_display(multipoint_crs, "MultiPoint{false, false}([(1, 2), (3, 4), … (2) … , (7, 8), (9, 10)], crs = EPSG{1}((4326,)))", "MultiPoint([(1,2),(3,4),(3,2),(1,4),(7,8),(9,10)])")

# GeometryCollection
geoms = [line, linestring, linearring, multipoint, (1, 2)]
Expand All @@ -240,13 +240,13 @@ collection = GI.GeometryCollection(geoms)
@test !GI.is3d(collection)
@test GI.ncoord(collection) == 2
@test GI.extent(collection) == reduce(Extents.union, map(GI.extent, geoms))
test_display(collection, "GeometryCollection{false, false}([Line([(1, 2), (3, 4)]), LineString([(1, 2), (3, 4)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), MultiPoint([(1, 2), (3, 4), (3, 2), (1, 4), (7, 8), (9, 10)]), (1, 2)])",
"GeometryCollection([Line([(1,2),(3,4)]),LineString([(1,2),(3,4)]),LinearRing([(1,2),(3,4),(5,6),(1,2)]),MultiPoint([(1,2),(3,4),(3,2),(1,4),(7,8),(9,10)]),(1,2)])")
test_display(collection, "GeometryCollection{false, false}([Line([(1, 2), (3, 4)]), … (3) … , (1, 2)])",
"GeometryCollection([Line([(1,2),(3,4)]),LineString([(1,2),(3,4)]),…(2)…,(1,2)])")
collection_crs = GI.GeometryCollection(collection; crs=EPSG(4326))
@test parent(collection_crs) == parent(collection)
@test GI.crs(collection_crs) === EPSG(4326)
test_display(collection_crs, "GeometryCollection{false, false}([Line([(1, 2), (3, 4)]), LineString([(1, 2), (3, 4)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), MultiPoint([(1, 2), (3, 4), (3, 2), (1, 4), (7, 8), (9, 10)]), (1, 2)], crs = EPSG{1}((4326,)))",
"GeometryCollection([Line([(1,2),(3,4)]),LineString([(1,2),(3,4)]),LinearRing([(1,2),(3,4),(5,6),(1,2)]),MultiPoint([(1,2),(3,4),(3,2),(1,4),(7,8),(9,10)]),(1,2)])")
test_display(collection_crs, "GeometryCollection{false, false}([Line([(1, 2), (3, 4)]), … (3) … , (1, 2)], crs = EPSG{1}((4326,)))",
"GeometryCollection([Line([(1,2),(3,4)]),LineString([(1,2),(3,4)]),…(2)…,(1,2)])")

# MultiCurve
multicurve = GI.MultiCurve([linestring, linearring])
Expand All @@ -258,13 +258,13 @@ multicurve = GI.MultiCurve([linestring, linearring])
@test GI.extent(multicurve) == Extent(X=(1, 5), Y=(2, 6))
@test_throws ArgumentError GI.MultiCurve([pointz, polygon])
@test GI.testgeometry(multicurve)
test_display(multicurve, "MultiCurve{false, false}([LineString([(1, 2), (3, 4)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])])",
"MultiCurve([LineString([(1,2),(3,4)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])")
test_display(multicurve, "MultiCurve{false, false}([LineString([(1, 2), (3, 4)]), LinearRing([(1, 2), … (2) … , (1, 2)])])",
"MultiCurve([LineString([(1,2),(3,4)]),LinearRing([(1,2),(3,4),…(1)…,(1,2)])])")
multicurve_crs = GI.MultiCurve(multicurve; crs=EPSG(4326))
@test parent(multicurve_crs) == parent(multicurve)
@test GI.crs(multicurve_crs) === EPSG(4326)
test_display(multicurve_crs, "MultiCurve{false, false}([LineString([(1, 2), (3, 4)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])], crs = EPSG{1}((4326,)))",
"MultiCurve([LineString([(1,2),(3,4)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])")
test_display(multicurve_crs, "MultiCurve{false, false}([LineString([(1, 2), (3, 4)]), LinearRing([(1, 2), … (2) … , (1, 2)])], crs = EPSG{1}((4326,)))",
"MultiCurve([LineString([(1,2),(3,4)]),LinearRing([(1,2),(3,4),…(1)…,(1,2)])])")

# MultiPolygon
polygon = GI.Polygon([linearring, linearring])
Expand All @@ -273,8 +273,8 @@ multipolygon = GI.MultiPolygon([polygon])
@test GI.getgeom(multipolygon, 1) === polygon
@test !GI.is3d(multipolygon)
@test GI.ncoord(multipolygon) == 2
test_display(multipolygon, "MultiPolygon{false, false}([Polygon([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])])])",
"MultiPolygon([Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])])")
test_display(multipolygon, "MultiPolygon{false, false}([Polygon([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])])])",
"MultiPolygon([Polygon([LinearRing([(1,2),…(2)…,(1,2)]),LinearRing([(1,2),…(2)…,(1,2)])])])")
# MultiPolygon extent does not infer, maybe due to nesting
@test GI.extent(multipolygon) == Extent(X=(1, 5), Y=(2, 6))
@test collect(GI.getpoint(multipolygon)) == collect(GI.getpoint(polygon))
Expand All @@ -283,8 +283,8 @@ test_display(multipolygon, "MultiPolygon{false, false}([Polygon([LinearRing([(1,
multipolygon_crs = GI.MultiPolygon(multipolygon; crs=EPSG(4326))
@test parent(multipolygon_crs) == parent(multipolygon)
@test GI.crs(multipolygon_crs) === EPSG(4326)
test_display(multipolygon_crs, "MultiPolygon{false, false}([Polygon([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])])], crs = EPSG{1}((4326,)))",
"MultiPolygon([Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])])")
test_display(multipolygon_crs, "MultiPolygon{false, false}([Polygon([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])])], crs = EPSG{1}((4326,)))",
"MultiPolygon([Polygon([LinearRing([(1,2),…(2)…,(1,2)]),LinearRing([(1,2),…(2)…,(1,2)])])])")

# PolyhedralSurface
polyhedralsurface = GI.PolyhedralSurface([polygon, polygon])
Expand All @@ -297,13 +297,13 @@ polyhedralsurface = GI.PolyhedralSurface([polygon, polygon])
@test GI.getgeom(polyhedralsurface, 1) == polygon
@test collect(GI.getpoint(polyhedralsurface)) == vcat(collect(GI.getpoint(polygon)), collect(GI.getpoint(polygon)))
@test GI.testgeometry(polyhedralsurface)
test_display(polyhedralsurface, "PolyhedralSurface{false, false}([Polygon([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])]), Polygon([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])])])",
"PolyhedralSurface([Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])]),Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])])")
test_display(polyhedralsurface, "PolyhedralSurface{false, false}([Polygon([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])]), Polygon([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])])])",
"PolyhedralSurface([Polygon([LinearRing([(1,2),…(2)…,(1,2)]),LinearRing([(1,2),…(2)…,(1,2)])]),Polygon([LinearRing([(1,2),…(2)…,(1,2)]),LinearRing([(1,2),…(2)…,(1,2)])])])")
polyhedralsurface_crs = GI.PolyhedralSurface(polyhedralsurface; crs=EPSG(4326))
@test parent(polyhedralsurface_crs) == parent(polyhedralsurface)
@test GI.crs(polyhedralsurface_crs) === EPSG(4326)
test_display(polyhedralsurface_crs, "PolyhedralSurface{false, false}([Polygon([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])]), Polygon([LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)])])], crs = EPSG{1}((4326,)))",
"PolyhedralSurface([Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])]),Polygon([LinearRing([(1,2),(3,4),(5,6),(1,2)]),LinearRing([(1,2),(3,4),(5,6),(1,2)])])])")
test_display(polyhedralsurface_crs, "PolyhedralSurface{false, false}([Polygon([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])]), Polygon([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])])], crs = EPSG{1}((4326,)))",
"PolyhedralSurface([Polygon([LinearRing([(1,2),…(2)…,(1,2)]),LinearRing([(1,2),…(2)…,(1,2)])]),Polygon([LinearRing([(1,2),…(2)…,(1,2)]),LinearRing([(1,2),…(2)…,(1,2)])])])")

# Round-trip coordinates
multipolygon_coords = [[[[1, 2], [3, 4], [3, 2], [1, 4]]]]
Expand Down

0 comments on commit 640bfca

Please sign in to comment.