From 732c871808ea2d4950e535a3d25e86f601b6a3eb Mon Sep 17 00:00:00 2001 From: Peter Stace Date: Mon, 25 Sep 2023 04:53:57 +1000 Subject: [PATCH] Rename unchecked point constructors - Renames the `asUncheckedPoint` helper methods on `XY` and `Coordinates` to `asPoint. - Removes the `newUncheckedPoint` function (it's now functionally equivalent to `NewPoint`). --- geom/alg_convex_hull.go | 2 +- geom/alg_intersection.go | 2 +- geom/alg_linear_interpolation.go | 4 ++-- geom/alg_point_on_surface.go | 2 +- geom/dcel_interaction_points_test.go | 2 +- geom/twkb_parser.go | 16 ++++++++-------- geom/type_coordinates.go | 8 ++++---- geom/type_envelope.go | 10 +++++----- geom/type_geometry_collection.go | 6 +++--- geom/type_line_string.go | 8 ++++---- geom/type_multi_line_string.go | 6 +++--- geom/type_multi_point.go | 2 +- geom/type_multi_polygon.go | 2 +- geom/type_point.go | 24 +----------------------- geom/type_polygon.go | 2 +- geom/xy.go | 12 +++--------- 16 files changed, 40 insertions(+), 68 deletions(-) diff --git a/geom/alg_convex_hull.go b/geom/alg_convex_hull.go index 9d45c647..0d253376 100644 --- a/geom/alg_convex_hull.go +++ b/geom/alg_convex_hull.go @@ -17,7 +17,7 @@ func convexHull(g Geometry) Geometry { // Check for point case: if !hasAtLeast2DistinctPointsInXYs(pts) { - return pts[0].asUncheckedPoint().AsGeometry() + return pts[0].asPoint().AsGeometry() } hull := monotoneChain(pts) diff --git a/geom/alg_intersection.go b/geom/alg_intersection.go index 879c4f92..71ea95d0 100644 --- a/geom/alg_intersection.go +++ b/geom/alg_intersection.go @@ -17,7 +17,7 @@ func intersectionOfIndexedLines( } if inter.ptA == inter.ptB { if xy := inter.ptA; !seen[xy] { - pt := xy.asUncheckedPoint() + pt := xy.asPoint() pts = append(pts, pt) seen[xy] = true } diff --git a/geom/alg_linear_interpolation.go b/geom/alg_linear_interpolation.go index 3abe65c4..780680b5 100644 --- a/geom/alg_linear_interpolation.go +++ b/geom/alg_linear_interpolation.go @@ -29,7 +29,7 @@ func (l linearInterpolator) interpolate(frac float64) Point { frac = math.Max(0, math.Min(1, frac)) idx := sort.SearchFloat64s(l.cumulative, frac*l.total) if idx == l.seq.Length() { - return l.seq.Get(idx - 1).asUncheckedPoint() + return l.seq.Get(idx - 1).asPoint() } p0 := l.seq.Get(idx) @@ -49,7 +49,7 @@ func (l linearInterpolator) interpolate(frac float64) Point { Z: lerp(p0.Z, p1.Z, partial), M: lerp(p0.M, p1.M, partial), Type: l.seq.CoordinatesType(), - }.asUncheckedPoint() + }.asPoint() } func lerp(a, b, ratio float64) float64 { diff --git a/geom/alg_point_on_surface.go b/geom/alg_point_on_surface.go index 5326f892..24c11469 100644 --- a/geom/alg_point_on_surface.go +++ b/geom/alg_point_on_surface.go @@ -133,7 +133,7 @@ func pointOnAreaSurface(poly Polygon) (Point, float64) { } midX := (bestA + bestB) / 2 - return XY{midX, midY}.asUncheckedPoint(), bestB - bestA + return XY{midX, midY}.asPoint(), bestB - bestA } func sortAndUniquifyFloats(fs []float64) []float64 { diff --git a/geom/dcel_interaction_points_test.go b/geom/dcel_interaction_points_test.go index ed7baec4..82a87498 100644 --- a/geom/dcel_interaction_points_test.go +++ b/geom/dcel_interaction_points_test.go @@ -153,7 +153,7 @@ func TestFindInteractionPoints(t *testing.T) { gotXYs := findInteractionPoints(inputs) var gotPoints []Point for xy := range gotXYs { - gotPoints = append(gotPoints, xy.asUncheckedPoint()) + gotPoints = append(gotPoints, xy.asPoint()) } got := NewMultiPoint(gotPoints).AsGeometry() diff --git a/geom/twkb_parser.go b/geom/twkb_parser.go index 51d2a662..2aed4078 100644 --- a/geom/twkb_parser.go +++ b/geom/twkb_parser.go @@ -343,8 +343,8 @@ func (p *twkbParser) parseBBoxHeader(twkb []byte) (bbox []Point, err error) { maxZ := p.scalings[2] * float64(p.bbox[4]+p.bbox[5]) maxM := p.scalings[3] * float64(p.bbox[6]+p.bbox[7]) - minPt := newUncheckedPoint(Coordinates{XY: XY{minX, minY}, Z: minZ, M: minM, Type: p.ctype}) - maxPt := newUncheckedPoint(Coordinates{XY: XY{maxX, maxY}, Z: maxZ, M: maxM, Type: p.ctype}) + minPt := NewPoint(Coordinates{XY: XY{minX, minY}, Z: minZ, M: minM, Type: p.ctype}) + maxPt := NewPoint(Coordinates{XY: XY{maxX, maxY}, Z: maxZ, M: maxM, Type: p.ctype}) bbox = []Point{minPt, maxPt} } else if p.hasZ { @@ -356,8 +356,8 @@ func (p *twkbParser) parseBBoxHeader(twkb []byte) (bbox []Point, err error) { maxY := p.scalings[1] * float64(p.bbox[2]+p.bbox[3]) maxZ := p.scalings[2] * float64(p.bbox[4]+p.bbox[5]) - minPt := newUncheckedPoint(Coordinates{XY: XY{minX, minY}, Z: minZ, Type: p.ctype}) - maxPt := newUncheckedPoint(Coordinates{XY: XY{maxX, maxY}, Z: maxZ, Type: p.ctype}) + minPt := NewPoint(Coordinates{XY: XY{minX, minY}, Z: minZ, Type: p.ctype}) + maxPt := NewPoint(Coordinates{XY: XY{maxX, maxY}, Z: maxZ, Type: p.ctype}) bbox = []Point{minPt, maxPt} } else if p.hasM { @@ -369,8 +369,8 @@ func (p *twkbParser) parseBBoxHeader(twkb []byte) (bbox []Point, err error) { maxY := p.scalings[1] * float64(p.bbox[2]+p.bbox[3]) maxM := p.scalings[2] * float64(p.bbox[4]+p.bbox[5]) - minPt := newUncheckedPoint(Coordinates{XY: XY{minX, minY}, M: minM, Type: p.ctype}) - maxPt := newUncheckedPoint(Coordinates{XY: XY{maxX, maxY}, M: maxM, Type: p.ctype}) + minPt := NewPoint(Coordinates{XY: XY{minX, minY}, M: minM, Type: p.ctype}) + maxPt := NewPoint(Coordinates{XY: XY{maxX, maxY}, M: maxM, Type: p.ctype}) bbox = []Point{minPt, maxPt} } else { @@ -380,8 +380,8 @@ func (p *twkbParser) parseBBoxHeader(twkb []byte) (bbox []Point, err error) { maxX := p.scalings[0] * float64(p.bbox[0]+p.bbox[1]) maxY := p.scalings[1] * float64(p.bbox[2]+p.bbox[3]) - minPt := newUncheckedPoint(Coordinates{XY: XY{minX, minY}, Type: p.ctype}) - maxPt := newUncheckedPoint(Coordinates{XY: XY{maxX, maxY}, Type: p.ctype}) + minPt := NewPoint(Coordinates{XY: XY{minX, minY}, Type: p.ctype}) + maxPt := NewPoint(Coordinates{XY: XY{maxX, maxY}, Type: p.ctype}) bbox = []Point{minPt, maxPt} } return bbox, nil diff --git a/geom/type_coordinates.go b/geom/type_coordinates.go index 0f05c02b..68147c0c 100644 --- a/geom/type_coordinates.go +++ b/geom/type_coordinates.go @@ -63,8 +63,8 @@ func (c Coordinates) appendFloat64s(dst []float64) []float64 { } } -// asUncheckedPoint shadows the asUncheckedPoint method on XY so that it's not -// accidentally called. -func (c Coordinates) asUncheckedPoint() Point { - return newUncheckedPoint(c) +// asPoint shadows the asPoint method on XY so that it's not accidentally +// called. +func (c Coordinates) asPoint() Point { + return NewPoint(c) } diff --git a/geom/type_envelope.go b/geom/type_envelope.go index 4c9162dc..03b570ed 100644 --- a/geom/type_envelope.go +++ b/geom/type_envelope.go @@ -109,7 +109,7 @@ func (e Envelope) AsGeometry() Geometry { case e.IsEmpty(): return Geometry{} case e.IsPoint(): - return e.min().asUncheckedPoint().AsGeometry() + return e.min().asPoint().AsGeometry() case e.IsLine(): ln := line{e.min(), e.max()} return ln.asLineString().AsGeometry() @@ -134,7 +134,7 @@ func (e Envelope) Min() Point { if e.IsEmpty() { return Point{} } - return e.min().asUncheckedPoint() + return e.min().asPoint() } // Max returns the point in the envelope with the maximum X and Y values. @@ -142,7 +142,7 @@ func (e Envelope) Max() Point { if e.IsEmpty() { return Point{} } - return e.max().asUncheckedPoint() + return e.max().asPoint() } // MinMaxXYs returns the two XY values in the envelope that contain the minimum @@ -220,7 +220,7 @@ func (e Envelope) Center() Point { return e.min(). Add(e.max()). Scale(0.5). - asUncheckedPoint() + asPoint() } // Covers returns true if and only if this envelope entirely covers another @@ -302,7 +302,7 @@ func (e Envelope) BoundingDiagonal() Geometry { return Geometry{} } if e.IsPoint() { - return e.min().asUncheckedPoint().AsGeometry() + return e.min().asPoint().AsGeometry() } coords := []float64{e.minX(), e.minY, e.maxX, e.maxY} diff --git a/geom/type_geometry_collection.go b/geom/type_geometry_collection.go index 8c1bc848..acb12c30 100644 --- a/geom/type_geometry_collection.go +++ b/geom/type_geometry_collection.go @@ -336,7 +336,7 @@ func (c GeometryCollection) pointCentroid() Point { } } }) - return sumPoints.Scale(1 / float64(numPoints)).asUncheckedPoint() + return sumPoints.Scale(1 / float64(numPoints)).asPoint() } func (c GeometryCollection) linearCentroid() Point { @@ -367,7 +367,7 @@ func (c GeometryCollection) linearCentroid() Point { } } }) - return weightedCentroid.Scale(1 / lengthSum).asUncheckedPoint() + return weightedCentroid.Scale(1 / lengthSum).asPoint() } func (c GeometryCollection) arealCentroid() Point { @@ -390,7 +390,7 @@ func (c GeometryCollection) arealCentroid() Point { centroid.Scale(area / areaSum)) } }) - return weightedCentroid.asUncheckedPoint() + return weightedCentroid.asPoint() } // CoordinatesType returns the CoordinatesType used to represent points making diff --git a/geom/type_line_string.go b/geom/type_line_string.go index bd02e8b3..5e73bd9b 100644 --- a/geom/type_line_string.go +++ b/geom/type_line_string.go @@ -73,7 +73,7 @@ func (s LineString) StartPoint() Point { return NewEmptyPoint(s.CoordinatesType()) } c := s.seq.Get(0) - return newUncheckedPoint(c) + return NewPoint(c) } // EndPoint gives the last point of the LineString. If the LineString is empty @@ -84,7 +84,7 @@ func (s LineString) EndPoint() Point { } end := s.seq.Length() - 1 c := s.seq.Get(end) - return newUncheckedPoint(c) + return NewPoint(c) } // AsText returns the WKT (Well Known Text) representation of this geometry. @@ -327,7 +327,7 @@ func (s LineString) Centroid() Point { if sumLength == 0 { return NewEmptyPoint(DimXY) } - return sumXY.Scale(1.0 / sumLength).asUncheckedPoint() + return sumXY.Scale(1.0 / sumLength).asPoint() } func sumCentroidAndLengthOfLineString(s LineString) (sumXY XY, sumLength float64) { @@ -392,7 +392,7 @@ func (s LineString) PointOnSurface() Point { n := s.seq.Length() nearest := newNearestPointAccumulator(s.Centroid()) for i := 1; i < n-1; i++ { - candidate := s.seq.GetXY(i).asUncheckedPoint() + candidate := s.seq.GetXY(i).asPoint() nearest.consider(candidate) } if !nearest.point.IsEmpty() { diff --git a/geom/type_multi_line_string.go b/geom/type_multi_line_string.go index e529a2b9..c552e507 100644 --- a/geom/type_multi_line_string.go +++ b/geom/type_multi_line_string.go @@ -181,7 +181,7 @@ func (m MultiLineString) IsSimple() bool { return rtree.Stop } boundary := intersectionOfMultiPointAndMultiPoint(ls.Boundary(), otherLS.Boundary()) - if !hasIntersectionPointWithMultiPoint(inter.ptA.asUncheckedPoint(), boundary) { + if !hasIntersectionPointWithMultiPoint(inter.ptA.asPoint(), boundary) { isSimple = false return rtree.Stop } @@ -364,7 +364,7 @@ func (m MultiLineString) Centroid() Point { if sumLength == 0 { return NewEmptyPoint(DimXY) } - return sumXY.Scale(1.0 / sumLength).asUncheckedPoint() + return sumXY.Scale(1.0 / sumLength).asPoint() } // Reverse in the case of MultiLineString outputs each component line string in their @@ -428,7 +428,7 @@ func (m MultiLineString) PointOnSurface() Point { seq := m.LineStringN(i).Coordinates() n := seq.Length() for j := 1; j < n-1; j++ { - candidate := seq.GetXY(j).asUncheckedPoint() + candidate := seq.GetXY(j).asPoint() nearest.consider(candidate) } } diff --git a/geom/type_multi_point.go b/geom/type_multi_point.go index dbc74f78..80626361 100644 --- a/geom/type_multi_point.go +++ b/geom/type_multi_point.go @@ -246,7 +246,7 @@ func (m MultiPoint) Centroid() Point { if n == 0 { return NewEmptyPoint(DimXY) } - return sum.Scale(1 / float64(n)).asUncheckedPoint() + return sum.Scale(1 / float64(n)).asPoint() } // Reverse in the case of MultiPoint outputs each component point in their diff --git a/geom/type_multi_polygon.go b/geom/type_multi_polygon.go index 87b22b4c..e29885df 100644 --- a/geom/type_multi_polygon.go +++ b/geom/type_multi_polygon.go @@ -373,7 +373,7 @@ func (m MultiPolygon) Centroid() Point { weightedCentroid = weightedCentroid.Add(centroid.Scale(areas[i] / totalArea)) } } - return weightedCentroid.asUncheckedPoint() + return weightedCentroid.asPoint() } // Reverse in the case of MultiPolygon outputs the component polygons in their original order, diff --git a/geom/type_point.go b/geom/type_point.go index 0b294204..273c662b 100644 --- a/geom/type_point.go +++ b/geom/type_point.go @@ -35,28 +35,6 @@ func (p Point) Validate() error { return p.coords.XY.validate() } -// newUncheckedPoint constructs a point without checking any validations. It -// may be used internally when the caller is sure that the coordinates don't -// come directly from outside the library, or have already otherwise been -// validated. -// -// An examples of valid use: -// -// - The coordinates have just been validated. -// -// - The coordinates are taken directly from the control points of a geometry -// that has been validated. -// -// - The coordinates are derived from calculations based on control points of a -// geometry that has been validated. Technically, these calculations could -// overflow to +/- inf. However if control points are originally close to -// infinity, many of the algorithms will be already broken in many other ways. -// -// TODO: this is the same as NewPoint, so it should be removed. -func newUncheckedPoint(c Coordinates) Point { - return Point{c, true} -} - // NewEmptyPoint creates a Point that is empty. func NewEmptyPoint(ctype CoordinatesType) Point { return Point{Coordinates{Type: ctype}, false} @@ -202,7 +180,7 @@ func (p Point) TransformXY(fn func(XY) XY) Point { } newC := p.coords newC.XY = fn(newC.XY) - return newUncheckedPoint(newC) + return NewPoint(newC) } // Centroid of a point is that point. diff --git a/geom/type_polygon.go b/geom/type_polygon.go index 96c1abef..f0ae1c10 100644 --- a/geom/type_polygon.go +++ b/geom/type_polygon.go @@ -442,7 +442,7 @@ func (p Polygon) Centroid() Point { centroid = centroid.Add( weightedCentroid(p.InteriorRingN(i), areas[i+1], sumAreas)) } - return centroid.asUncheckedPoint() + return centroid.asPoint() } func weightedCentroid(ring LineString, ringArea, totalArea float64) XY { diff --git a/geom/xy.go b/geom/xy.go index 2a56c4fd..9458b98d 100644 --- a/geom/xy.go +++ b/geom/xy.go @@ -36,16 +36,10 @@ func (w XY) AsPoint(opts ...ConstructorOption) (Point, error) { return pt, nil } -// asUncheckedPoint is a convenience function to convert this XY value into a -// Point. The Point is constructed without checking any validations. It may be -// used internally when the caller is sure that the XY value doesn't come -// directly from outside of the library without first being validated. -// -// TODO: This method should be removed (caller can use AsPoint instead once its -// ConstructorOptions and error are removed). -func (w XY) asUncheckedPoint() Point { +// asPoint is a convenience function to convert this XY value into a Point. +func (w XY) asPoint() Point { coords := Coordinates{XY: w, Type: DimXY} - return newUncheckedPoint(coords) + return NewPoint(coords) } // uncheckedEnvelope is a convenience function to convert this XY value into