Skip to content

Commit

Permalink
Merge pull request #489 from peterstace/bounding_diagonal
Browse files Browse the repository at this point in the history
Add `BoundingDiagonal()` method to `Envelope`
  • Loading branch information
peterstace committed Feb 6, 2023
2 parents 8e2f45d + 3046816 commit 0f60dd0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- Make `IgnoreOrder` a function rather than a global variable to prevent
consumers from erroneously altering its behaviour.

- Add a `BoundingDiagonal` method to the `Envelope` type.

## v0.41.0

2022-11-15
Expand Down
24 changes: 24 additions & 0 deletions geom/type_envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,27 @@ func (e Envelope) box() (rtree.Box, bool) {
MaxY: e.maxY,
}, !e.IsEmpty()
}

// BoundingDiagonal returns the LineString that goes from the point returned by
// Min() to the point returned by Max(). If the envelope is degenerate and
// represents a single point, then a Point is returned instead of a LineString.
// If the Envelope is empty, then the empty Geometry (representing an empty
// GeometryCollection) is returned.
func (e Envelope) BoundingDiagonal() Geometry {
if e.IsEmpty() {
return Geometry{}
}
if e.IsPoint() {
return e.min().asUncheckedPoint().AsGeometry()
}

// The Envelope has already been validated, so it's safe to skip validation
// when constructing the diagonal.
coords := []float64{e.minX(), e.minY, e.maxX, e.maxY}
seq := NewSequence(coords, DimXY)
ls, err := NewLineString(seq, DisableAllValidations)
if err != nil {
panic("programming error: validations disabled by LineString validation failed")
}
return ls.AsGeometry()
}
27 changes: 27 additions & 0 deletions geom/type_envelope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,3 +582,30 @@ func BenchmarkEnvelopeTransformXY(b *testing.B) {
expectNoErr(b, err)
}
}

func TestBoundingDiagonal(t *testing.T) {
for i, tc := range []struct {
env []XY
want string
}{
{
nil,
"GEOMETRYCOLLECTION EMPTY",
},
{
[]XY{{1, 2}},
"POINT(1 2)",
},
{
[]XY{{3, 2}, {1, 4}},
"LINESTRING(1 2,3 4)",
},
} {
t.Run(strconv.Itoa(i), func(t *testing.T) {
env, err := NewEnvelope(tc.env)
expectNoErr(t, err)
got := env.BoundingDiagonal()
expectGeomEqWKT(t, got, tc.want)
})
}
}

0 comments on commit 0f60dd0

Please sign in to comment.