xy

package
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2024 License: BSD-2-Clause Imports: 12 Imported by: 0

Documentation

Overview

Package xy contains low-level planar (xy) geographic functions. The data can be of any dimension, however the first two ordinates for each coordinate must be the x,y coordinates. All other ordinates will be ignored.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Angle

func Angle(p0, p1 geom.Coord) float64

Angle calculates the angle of the vector from p0 to p1, relative to the positive X-axis. The angle is normalized to be in the range [ -Pi, Pi ].

Example
p1 := geom.Coord{-4.007890598483777e8, 7.149034067497588e8, -4.122305737303918e7}
p2 := geom.Coord{6.452880325856061e8, -7.013452035812421e7, 6.060122721006607e8}

angle := xy.Angle(p1, p2)
fmt.Println(angle)
Output:

-0.6437947786359727

func AngleBetween

func AngleBetween(tip1, tail, tip2 geom.Coord) float64

AngleBetween calculates the un-oriented smallest angle between two vectors. The computed angle will be in the range [0, Pi).

Param tip1 - the tip of one vector param tail - the tail of each vector param tip2 - the tip of the other vector

Example
p1 := geom.Coord{-8.6092078831365e7, -1.2832262246888882e8, -5.39892066777803e8}
p2 := geom.Coord{-4.125610572401442e7, 3.097372706101881e8, 1.5483271373430803e8}
p3 := geom.Coord{1.641532856745057e8, 3.949735922042323e7, 1.9570089185263705e8}

angle := xy.AngleBetween(p1, p2, p3)
fmt.Println(angle)
Output:

0.7519299818333081

func AngleBetweenOriented

func AngleBetweenOriented(tip1, tail, tip2 geom.Coord) float64

AngleBetweenOriented calculates the oriented smallest angle between two vectors. The computed angle will be in the range (-Pi, Pi]. A positive result corresponds to a counterclockwise (CCW) rotation from v1 to v2; A negative result corresponds to a clockwise (CW) rotation; A zero result corresponds to no rotation.

Example
p1 := geom.Coord{-1.3799002832563987e9, 5.999590771085212e8, -4.693581090182036e8}
p2 := geom.Coord{6.826007948791102e7, -8.657386626766933e8, -1.493830309099963e9}
p3 := geom.Coord{-6.183224805123262e8, 2.4666014745222422e8, 7271369.117346094}

angle := xy.AngleBetweenOriented(p1, p2, p3)
fmt.Println(angle)
Output:

-0.22640245255136904

func AngleFromOrigin

func AngleFromOrigin(p geom.Coord) float64

AngleFromOrigin calculates the angle that the vector from (0,0) to p, relative to the positive X-axis. The angle is normalized to be in the range ( -Pi, Pi ].

Example
p1 := geom.Coord{-643891.5406414514, 6.214131154131615e8, -9.241166163738243e7}
angle := xy.AngleFromOrigin(p1)
fmt.Println(angle)
Output:

1.571832499502282

func AngleOrientation

func AngleOrientation(ang1, ang2 float64) orientation.Type

AngleOrientation returns whether an angle must turn clockwise or counterclockwise overlap another angle.

Example
package main

import (
	"fmt"

	"github.com/twpayne/go-geom/xy"
)

func main() {
	p1 := 1.5973282539123574e8
	p2 := 1.0509666695558771e9

	orient := xy.AngleOrientation(p1, p2)
	fmt.Println(orient)
}
Output:

Clockwise

func Centroid

func Centroid(geometry geom.T) (centroid geom.Coord, err error)

Centroid calculates the centroid of the geometry. The centroid may be outside of the geometry depending on the topology of the geometry

func ConvexHull

func ConvexHull(geometry geom.T) geom.T

ConvexHull computes the convex hull of the geometry. A convex hull is the smallest convex geometry that contains all the points in the input geometry Uses the Graham Scan algorithm

Example
polygon := geom.NewLineStringFlat(geom.XY, []float64{1, 1, 3, 3, 4, 4, 2, 5})

convexHull := xy.ConvexHull(polygon)

fmt.Println(convexHull.FlatCoords())
Output:

[1 1 2 5 4 4 1 1]

func ConvexHullFlat

func ConvexHullFlat(layout geom.Layout, coords []float64) geom.T

ConvexHullFlat computes the convex hull of the geometry. A convex hull is the smallest convex geometry that contains all the points in the input coordinates Uses the Graham Scan algorithm

Example
polygon := geom.NewLineStringFlat(geom.XY, []float64{1, 1, 3, 3, 4, 4, 2, 5})

convexHull := xy.ConvexHullFlat(polygon.Layout(), polygon.FlatCoords())

fmt.Println(convexHull.FlatCoords())
Output:

[1 1 2 5 4 4 1 1]

func Diff

func Diff(ang1, ang2 float64) float64

Diff computes the un-oriented smallest difference between two angles. The angles are assumed to be normalized to the range [-Pi, Pi]. The result will be in the range [0, Pi].

Param ang1 - the angle of one vector (in [-Pi, Pi] ) Param ang2 - the angle of the other vector (in range [-Pi, Pi] )

Example
package main

import (
	"fmt"

	"github.com/twpayne/go-geom/xy"
)

func main() {
	p1 := -5.976261773911254e7
	p2 := 1.5847324519716722e8

	diff := xy.Diff(p1, p2)
	fmt.Println(diff)
}
Output:

-2.1823585665309447e+08

func Distance

func Distance(c1, c2 geom.Coord) float64

Distance calculates the 2d distance between the two coordinates

Example
coords := []float64{10, 10, 10, -10}
distance := xy.Distance(geom.Coord(coords[0:2]), geom.Coord(coords[2:4]))
fmt.Println(distance)
Output:

20

func DistanceFromLineToLine

func DistanceFromLineToLine(line1Start, line1End, line2Start, line2End geom.Coord) float64

DistanceFromLineToLine computes the distance from a line segment line1(Start/End) to a line segment line2(Start/End)

Note: NON-ROBUST!

param line1Start - the start point of line1 param line1End - the end point of line1 (must be different to line1Start) param line2Start - the start point of line2 param line2End - the end point of line2 (must be different to line2Start)

Example
line1 := geom.NewLineStringFlat(geom.XY, []float64{0, 0, 10, 10})
line2 := geom.NewLineStringFlat(geom.XY, []float64{-10, -10, 0, -10})
distance := xy.DistanceFromLineToLine(line1.Coord(0), line1.Coord(1), line2.Coord(0), line2.Coord(1))
fmt.Println(distance)
Output:

10

func DistanceFromPointToLine

func DistanceFromPointToLine(p, lineStart, lineEnd geom.Coord) float64

DistanceFromPointToLine computes the distance from a point p to a line segment lineStart/lineEnd

Note: NON-ROBUST!

Example
p := geom.Coord{0, 0}
lineStart := geom.Coord{10, -10}
lineEnd := geom.Coord{10, 10}
distance := xy.DistanceFromPointToLine(p, lineStart, lineEnd)
fmt.Println(distance)
Output:

10

func DistanceFromPointToLineString

func DistanceFromPointToLineString(layout geom.Layout, p geom.Coord, line []float64) float64

DistanceFromPointToLineString computes the distance from a point to a sequence of line segments.

Param p - a point Param line - a sequence of contiguous line segments defined by their vertices

Example
p := geom.Coord{50, 50}
lineString := geom.NewLineStringFlat(geom.XY, []float64{0, 0, 10, 10, 10, 20, 10, 100})
distance := xy.DistanceFromPointToLineString(lineString.Layout(), p, lineString.FlatCoords())
fmt.Println(distance)
Output:

40

func DoLinesOverlap

func DoLinesOverlap(line1End1, line1End2, line2End1, line2End2 geom.Coord) bool

DoLinesOverlap calculates if the bounding boxes of the two lines (line1End1, line1End2) and (line2End1, line2End2) overlap

Example
line1Start := geom.Coord{0, 0}
line1End := geom.Coord{10, 10}
line2Start := geom.Coord{0, -10}
line2End := geom.Coord{10, 5}
overlaps := xy.DoLinesOverlap(line1Start, line1End, line2Start, line2End)
fmt.Println(overlaps)
Output:

true

func Equal

func Equal(coords1 []float64, start1 int, coords2 []float64, start2 int) bool

Equal checks if the point starting at start one in array coords1 is equal to the point starting at start2 in the array coords2. Only x and y ordinates are compared and x is assumed to be the first ordinate and y as the second This is a utility method intended to be used only when performance is critical as it reduces readability.

Example
package main

import (
	"fmt"

	"github.com/twpayne/go-geom/xy"
)

func main() {
	coords := []float64{10, 30, 30, 10}
	isEqual := xy.Equal(coords, 0, coords, 1)
	fmt.Println(isEqual)
}
Output:

false

func InteriorAngle

func InteriorAngle(p0, p1, p2 geom.Coord) float64

InteriorAngle cmputes the interior angle between two segments of a ring. The ring is assumed to be oriented in a clockwise direction. The computed angle will be in the range [0, 2Pi]

Example
p1 := geom.Coord{9.339625086270301e7, 9.494327011462314e8, -8.832231914445356e8}
p2 := geom.Coord{-8.685036396637098e7, -9827198.1341636, -5.130707858094123e8}
p3 := geom.Coord{5.48739535964397e8, 8.532792391532723e8, 2.8251807396930236e8}

angle := xy.InteriorAngle(p1, p2, p3)
fmt.Println(angle)
Output:

0.44900284899855447

func IsAcute

func IsAcute(endpoint1, base, endpoint2 geom.Coord) bool

IsAcute tests whether the angle between endpoint1-base-endpoint2 is acute. An angle is acute if it is less than 90 degrees.

Note: this implementation is not precise (deterministic) for angles very close to 90 degrees

Example
p1 := geom.Coord{-2.9746056181996536e8, 1.283116247239797e9, 3.0124856147872955e8}
p2 := geom.Coord{2.9337112870686615e8, -1.0822405666887188e9, 9.613329966907622e7}
p3 := geom.Coord{-3.402935182393674e7, -8.477260955562395e8, 2.4474783489619292e7}

isAcute := xy.IsAcute(p1, p2, p3)
fmt.Println(isAcute)
Output:

true

func IsObtuse

func IsObtuse(endpoint1, base, endpoint2 geom.Coord) bool

IsObtuse tests whether the angle between endpoint1-base-endpoint2 is obtuse. An angle is obtuse if it is greater than 90 degrees.

Note: this implementation is not precise (deterministic) for angles very close to 90 degrees

Example
p1 := geom.Coord{-6.581881182734076e8, -5.1226495000032324e8, 4.942792920863176e8}
p2 := geom.Coord{-2.8760338491412956e8, -2.7637897930097174e7, -1.3120283887929991e8}
p3 := geom.Coord{-7.253118635362322e8, 2.854840728999085e8, -3.3865131338040566e8}

isObtuse := xy.IsObtuse(p1, p2, p3)
fmt.Println(isObtuse)
Output:

false

func IsOnLine

func IsOnLine(layout geom.Layout, point geom.Coord, lineSegmentCoordinates []float64) bool

IsOnLine tests whether a point lies on the line segments defined by a list of coordinates.

Returns true if the point is a vertex of the line or lies in the interior of a line segment in the linestring

Example
line := geom.NewLineString(geom.XY)
line.MustSetCoords([]geom.Coord{
	{0, 0},
	{10, 0},
	{10, 20},
})
onLine := xy.IsOnLine(line.Layout(), geom.Coord{5, 0}, line.FlatCoords())
fmt.Println(onLine)
Output:

true

func IsPointInRing

func IsPointInRing(layout geom.Layout, p geom.Coord, ring []float64) bool

IsPointInRing tests whether a point lies inside or on a ring. The ring may be oriented in either direction. A point lying exactly on the ring boundary is considered to be inside the ring.

This method does <i>not</i> first check the point against the envelope of the ring.

p - point to check for ring inclusion ring - an array of coordinates representing the ring (which must have first point identical to last point) Returns true if p is inside ring

Example
ring := geom.NewLinearRingFlat(geom.XY, []float64{10, 10, 20, 10, 30, 30, 10, 30, 10, 10})
inRing := xy.IsPointInRing(ring.Layout(), geom.Coord{1, 1}, ring.FlatCoords())
fmt.Println(inRing)
Output:

false

func IsPointWithinLineBounds

func IsPointWithinLineBounds(p, lineEndpoint1, lineEndpoint2 geom.Coord) bool

IsPointWithinLineBounds calculates if the point p lays within the bounds of the line between end points lineEndpoint1 and lineEndpoint2

Example
point := geom.Coord{0, 0}
line := geom.NewLineStringFlat(geom.XY, []float64{-10, -10, 0, -10})
isWithinLineBounds := xy.IsPointWithinLineBounds(point, line.Coord(0), line.Coord(1))
fmt.Println(isWithinLineBounds)
Output:

false

func IsRingCounterClockwise

func IsRingCounterClockwise(layout geom.Layout, ring []float64) bool

IsRingCounterClockwise computes whether a ring defined by an array of geom.Coords is oriented counter-clockwise.

- The list of points is assumed to have the first and last points equal. - This will handle coordinate lists which contain repeated points.

This algorithm is <b>only</b> guaranteed to work with valid rings. If the ring is invalid (e.g. self-crosses or touches), the computed result may not be correct.

Param ring - an array of Coordinates forming a ring Returns true if the ring is oriented counter-clockwise. Panics if there are too few points to determine orientation (< 3)

Example
ring := geom.NewLinearRingFlat(geom.XY, []float64{10, 10, 20, 10, 30, 30, 10, 30, 10, 10})
clockwise := xy.IsRingCounterClockwise(ring.Layout(), ring.FlatCoords())
fmt.Println(clockwise)
Output:

true

func LinearRingsCentroid

func LinearRingsCentroid(line *geom.LinearRing, extraLines ...*geom.LinearRing) (centroid geom.Coord)

LinearRingsCentroid computes the centroid of all the LinearRings provided as arguments.

Algorithm: Compute the average of the midpoints of all line segments weighted by the segment length.

Example
line1 := geom.NewLinearRingFlat(geom.XY, []float64{0, 0, 1, 1, 3, 3, 0, 0})
line2 := geom.NewLinearRingFlat(geom.XY, []float64{10, 10, 11, 11, 13, 13, 10, 10})
centroid := xy.LinearRingsCentroid(line1, line2)
fmt.Println(centroid)
Output:

func LinesCentroid

func LinesCentroid(line *geom.LineString, extraLines ...*geom.LineString) (centroid geom.Coord)

LinesCentroid computes the centroid of all the LineStrings provided as arguments.

Algorithm: Compute the average of the midpoints of all line segments weighted by the segment length.

Example
line1 := geom.NewLineStringFlat(geom.XY, []float64{0, 0, 1, 1, 3, 3})
line2 := geom.NewLineStringFlat(geom.XY, []float64{10, 10, 11, 11, 13, 13})
centroid := xy.LinesCentroid(line1, line2)
fmt.Println(centroid)
Output:

[6.5 6.5]

func LocatePointInRing

func LocatePointInRing(layout geom.Layout, p geom.Coord, ring []float64) location.Type

LocatePointInRing determines whether a point lies in the interior, on the boundary, or in the exterior of a ring. The ring may be oriented in either direction.

This method does <i>not</i> first check the point against the envelope of the ring.

p - point to check for ring inclusion ring - an array of coordinates representing the ring (which must have first point identical to last point)

Returns the Location of p relative to the ring

Example
ring := geom.NewLinearRingFlat(geom.XY, []float64{10, 10, 20, 10, 30, 30, 10, 30, 10, 10})
pointInRing := xy.LocatePointInRing(ring.Layout(), geom.Coord{15, 15}, ring.FlatCoords())
fmt.Println(pointInRing)
Output:

Interior

func MultiLineCentroid

func MultiLineCentroid(line *geom.MultiLineString) (centroid geom.Coord)

MultiLineCentroid computes the centroid of the MultiLineString string

Algorithm: Compute the average of the midpoints of all line segments weighted by the segment length.

Example
line := geom.NewMultiLineStringFlat(geom.XY, []float64{0, 0, 1, 1, 3, 3, 10, 10, 11, 11, 13, 13}, []int{6, 12})
centroid := xy.MultiLineCentroid(line)
fmt.Println(centroid)
Output:

[6.5 6.5]

func MultiPointCentroid

func MultiPointCentroid(point *geom.MultiPoint) geom.Coord

MultiPointCentroid computes the centroid of the multi point argument

Algorithm: average of all points in MultiPoint

Example
multiPoint := geom.NewMultiPointFlat(geom.XY, []float64{
	0, 0,
	2, 0,
	2, 2,
	0, 2,
})
centroid := xy.MultiPointCentroid(multiPoint)

fmt.Println(centroid)
Output:

[1 1]

func MultiPolygonCentroid

func MultiPolygonCentroid(polygon *geom.MultiPolygon) (centroid geom.Coord)

MultiPolygonCentroid computes the centroid of an area geometry. (MultiPolygon)

Algorithm Based on the usual algorithm for calculating the centroid as a weighted sum of the centroids of a decomposition of the area into (possibly overlapping) triangles.

The algorithm has been extended to handle holes and multi-polygons.

See http://www.faqs.org/faqs/graphics/algorithms-faq/ for further details of the basic approach.

The code has also be extended to handle degenerate (zero-area) polygons.

In this case, the centroid of the line segments in the polygon will be returned.

func NewRadialSorting

func NewRadialSorting(layout geom.Layout, coordData []float64, focalPoint geom.Coord) sort.Interface

NewRadialSorting creates an implementation sort.Interface which will sort the wrapped coordinate array radially around the focal point. The comparison is based on the angle and distance from the focal point. First the angle is checked. Counter clockwise indicates a greater value and clockwise indicates a lesser value If co-linear then the coordinate nearer to the focalPoint is considered less.

Example
coords := []float64{10, 10, 20, 20, 20, 0, 30, 10, 0, 0, 1, 1}
sorting := xy.NewRadialSorting(geom.XY, coords, geom.Coord{10, 10})
sort.Sort(sorting)
fmt.Println(coords)
Output:

[10 10 20 20 30 10 20 0 1 1 0 0]

func Normalize

func Normalize(angle float64) float64

Normalize computes the normalized value of an angle, which is the equivalent angle in the range ( -Pi, Pi ].

Example
package main

import (
	"fmt"

	"github.com/twpayne/go-geom/xy"
)

func main() {
	p1 := 7.089301226008829e8

	normalized := xy.Normalize(p1)
	fmt.Println(normalized)
}
Output:

0.7579033437162295

func NormalizePositive

func NormalizePositive(angle float64) float64

NormalizePositive computes the normalized positive value of an angle, which is the equivalent angle in the range [ 0, 2*Pi ). E.g.: * normalizePositive(0.0) = 0.0 * normalizePositive(-PI) = PI * normalizePositive(-2PI) = 0.0 * normalizePositive(-3PI) = PI * normalizePositive(-4PI) = 0 * normalizePositive(PI) = PI * normalizePositive(2PI) = 0.0 * normalizePositive(3PI) = PI * normalizePositive(4PI) = 0.0

Example
package main

import (
	"fmt"

	"github.com/twpayne/go-geom/xy"
)

func main() {
	p1 := -2.269415841413788e8

	normalized := xy.NormalizePositive(p1)
	fmt.Println(normalized)
}
Output:

0.4870605702066726

func OrientationIndex

func OrientationIndex(vectorOrigin, vectorEnd, point geom.Coord) orientation.Type

OrientationIndex returns the index of the direction of the point <code>q</code> relative to a vector specified by <code>p1-p2</code>.

vectorOrigin - the origin point of the vector vectorEnd - the final point of the vector point - the point to compute the direction to

Example
vectorOrigin := geom.Coord{10.0, 10.0}
vectorEnd := geom.Coord{20.0, 20.0}
target := geom.Coord{10.0, 20.0}

orientation := xy.OrientationIndex(vectorOrigin, vectorEnd, target)

fmt.Println(orientation)
Output:

CounterClockwise

func PerpendicularDistanceFromPointToLine

func PerpendicularDistanceFromPointToLine(p, lineStart, lineEnd geom.Coord) float64

PerpendicularDistanceFromPointToLine computes the perpendicular distance from a point p to the (infinite) line containing the points lineStart/lineEnd

Example
p := geom.Coord{0, 0}
lineStart := geom.Coord{10, 5}
lineEnd := geom.Coord{10, 10}
distance := xy.PerpendicularDistanceFromPointToLine(p, lineStart, lineEnd)
fmt.Println(distance)
Output:

10

func PointsCentroid

func PointsCentroid(point *geom.Point, extra ...*geom.Point) geom.Coord

PointsCentroid computes the centroid of the point arguments

Algorithm: average of all points

Example
centroid := xy.PointsCentroid(
	geom.NewPointFlat(geom.XY, []float64{0, 0}),
	geom.NewPointFlat(geom.XY, []float64{2, 0}),
	geom.NewPointFlat(geom.XY, []float64{2, 2}),
	geom.NewPointFlat(geom.XY, []float64{0, 2}))

fmt.Println(centroid)
Output:

[1 1]

func PointsCentroidFlat

func PointsCentroidFlat(layout geom.Layout, pointData []float64) geom.Coord

PointsCentroidFlat computes the centroid of the points in the coordinate array. layout is only used to determine how to find each coordinate. X-Y are assumed to be the first two elements in each coordinate.

Algorithm: average of all points

Example
multiPoint := geom.NewMultiPointFlat(geom.XY, []float64{0, 0, 2, 0, 2, 2, 0, 2})
centroid := xy.PointsCentroidFlat(multiPoint.Layout(), multiPoint.FlatCoords())
fmt.Println(centroid)
Output:

[1 1]

func PolygonsCentroid

func PolygonsCentroid(polygon *geom.Polygon, extraPolys ...*geom.Polygon) (centroid geom.Coord)

PolygonsCentroid computes the centroid of an area geometry. (Polygon)

Algorithm Based on the usual algorithm for calculating the centroid as a weighted sum of the centroids of a decomposition of the area into (possibly overlapping) triangles.

The algorithm has been extended to handle holes and multi-polygons.

See http://www.faqs.org/faqs/graphics/algorithms-faq/ for further details of the basic approach.

The code has also be extended to handle degenerate (zero-area) polygons.

In this case, the centroid of the line segments in the polygon will be returned.

Example
poly1 := geom.NewPolygonFlat(geom.XY, []float64{0, 0, -10, 0, -10, -10, 0, -10, 0, 0}, []int{10})
poly2 := geom.NewPolygonFlat(geom.XY, []float64{0, 0, 10, 0, 10, 10, 0, 10, 0, 0}, []int{10})

centroid := xy.PolygonsCentroid(poly1, poly2)

fmt.Println(centroid)
Output:

[0 0]

func SignedArea

func SignedArea(layout geom.Layout, ring []float64) float64

SignedArea computes the signed area for a ring. The signed area is positive if the ring is oriented CW, negative if the ring is oriented CCW, and zero if the ring is degenerate or flat.

Example
ring := geom.NewLinearRingFlat(geom.XY, []float64{10, 10, 20, 10, 30, 30, 10, 30, 10, 10})
singedArea := xy.SignedArea(ring.Layout(), ring.FlatCoords())
fmt.Println(singedArea)
Output:

-300

func SimplifyFlatCoords

func SimplifyFlatCoords(flatCoords []float64, threshold float64, stride int) []int

Adopted from https://github.com/paulmach/orb/blob/master/simplify/douglas_peucker.go Original license:

The MIT License (MIT) Copyright (c) 2017 Paul Mach Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

SimplifyFlatCoords uses the Douglas-Peucker algorithm to simplify a 2D flatCoords. It returns the indexes of the points. Note that the indexes are based on points, So acesss to x, y pair should be:

x := flatCoords[i*stride] y := flatCoords[i*stride+1]

Threshold is the distance between a point and the selected start and end line segment. It returns the indexes of the points.

Example
pnts := []float64{0, 0, 0, 1, -1, 2, 0, 3, 0, 4, 1, 4, 2, 4.5, 3, 4, 3.5, 4, 4, 4}

stride := 2
ii := SimplifyFlatCoords(pnts, 0.4, stride)

for i, j := range ii {
	if i == j*stride {
		continue
	}
	pnts[i*stride], pnts[i*stride+1] = pnts[j*stride], pnts[j*stride+1]
}
pnts = pnts[:len(ii)*stride]
fmt.Printf("%#v", pnts)
Output:

[]float64{0, 0, 0, 1, -1, 2, 0, 3, 0, 4, 2, 4.5, 4, 4}

Types

type AreaCentroidCalculator

type AreaCentroidCalculator struct {
	// contains filtered or unexported fields
}

AreaCentroidCalculator is the data structure that contains the centroid calculation data. This type cannot be used using its 0 values, it must be created using NewAreaCentroid

func NewAreaCentroidCalculator

func NewAreaCentroidCalculator(layout geom.Layout) *AreaCentroidCalculator

NewAreaCentroidCalculator creates a new instance of the calculator. Once a calculator is created polygons can be added to it and the GetCentroid method can be used at any point to get the current centroid the centroid will naturally change each time a polygon is added

func (*AreaCentroidCalculator) AddPolygon

func (calc *AreaCentroidCalculator) AddPolygon(polygon *geom.Polygon)

AddPolygon adds a polygon to the calculation.

Example
polygons := []*geom.Polygon{
	geom.NewPolygonFlat(geom.XY, []float64{0, 0, -10, 0, -10, -10, 0, -10, 0, 0}, []int{10}),
	geom.NewPolygonFlat(geom.XY, []float64{0, 0, 10, 0, 10, 10, 0, 10, 0, 0}, []int{10}),
}

calculator := xy.NewAreaCentroidCalculator(geom.XY)

for _, p := range polygons {
	calculator.AddPolygon(p)
}

fmt.Println(calculator.GetCentroid())
Output:

[0 0]

func (*AreaCentroidCalculator) GetCentroid

func (calc *AreaCentroidCalculator) GetCentroid() geom.Coord

GetCentroid obtains centroid currently calculated. Returns a 0 coord if no geometries have been added

type LineCentroidCalculator

type LineCentroidCalculator struct {
	// contains filtered or unexported fields
}

LineCentroidCalculator is the data structure that contains the centroid calculation data. This type cannot be used using its 0 values, it must be created using NewLineCentroid

func NewLineCentroidCalculator

func NewLineCentroidCalculator(layout geom.Layout) *LineCentroidCalculator

NewLineCentroidCalculator creates a new instance of the calculator. Once a calculator is created polygons, linestrings or linear rings can be added and the GetCentroid method can be used at any point to get the current centroid the centroid will naturally change each time a geometry is added

Example
calculator := xy.NewLineCentroidCalculator(geom.XY)
calculator.AddLine(geom.NewLineStringFlat(geom.XY, []float64{0, 0, 1, 1, 3, 3}))
calculator.AddLine(geom.NewLineStringFlat(geom.XY, []float64{10, 10, 11, 11, 13, 13}))
centroid := calculator.GetCentroid()
fmt.Println(centroid)
Output:

[6.5 6.5]

func (*LineCentroidCalculator) AddLine

func (calc *LineCentroidCalculator) AddLine(line *geom.LineString) *LineCentroidCalculator

AddLine adds a LineString to the current calculation

func (*LineCentroidCalculator) AddLinearRing

func (calc *LineCentroidCalculator) AddLinearRing(line *geom.LinearRing) *LineCentroidCalculator

AddLinearRing adds a LinearRing to the current calculation

func (*LineCentroidCalculator) AddPolygon

func (calc *LineCentroidCalculator) AddPolygon(polygon *geom.Polygon) *LineCentroidCalculator

AddPolygon adds a Polygon to the calculation.

Example
calculator := xy.NewLineCentroidCalculator(geom.XY)
calculator.AddPolygon(geom.NewPolygonFlat(geom.XY, []float64{0, 0, 1, 1, 3, 3}, []int{6}))
centroid := calculator.GetCentroid()
fmt.Println(centroid)
Output:

[1.5 1.5]

func (*LineCentroidCalculator) GetCentroid

func (calc *LineCentroidCalculator) GetCentroid() geom.Coord

GetCentroid obtains centroid currently calculated. Returns a 0 coord if no geometries have been added

type PointCentroidCalculator

type PointCentroidCalculator struct {
	// contains filtered or unexported fields
}

PointCentroidCalculator is the data structure that contains the centroid calculation data. This type cannot be used using its 0 values, it must be created using NewPointCentroid

func NewPointCentroidCalculator

func NewPointCentroidCalculator() PointCentroidCalculator

NewPointCentroidCalculator creates a new calculator. Once the coordinates or points can be added to the calculator and GetCentroid can be used to get the current centroid at any point

Example
polygon := geom.NewPolygonFlat(geom.XY, []float64{0, 0, 2, 0, 2, 2, 0, 2}, []int{8})
calculator := xy.NewPointCentroidCalculator()
coords := polygon.FlatCoords()
stride := polygon.Layout().Stride()

for i := 0; i < len(coords); i += stride {
	calculator.AddCoord(geom.Coord(coords[i : i+stride]))
}

fmt.Println(calculator.GetCentroid())
Output:

[1 1]

func (*PointCentroidCalculator) AddCoord

func (calc *PointCentroidCalculator) AddCoord(point geom.Coord)

AddCoord adds a point to the calculation

func (*PointCentroidCalculator) AddPoint

func (calc *PointCentroidCalculator) AddPoint(point *geom.Point)

AddPoint adds a point to the calculation

func (*PointCentroidCalculator) GetCentroid

func (calc *PointCentroidCalculator) GetCentroid() geom.Coord

GetCentroid obtains centroid currently calculated. Returns a 0 coord if no coords have been added

Directories

Path Synopsis
robustdeterminate
Package robustdeterminate implements an algorithm to compute the sign of a 2x2 determinant for double precision values robustly.
Package robustdeterminate implements an algorithm to compute the sign of a 2x2 determinant for double precision values robustly.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL