Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions geom.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,48 @@ type Pointer interface {
XY() [2]float64
}

// PointZer is a 3D point.
type PointZer interface {
Geometry
XYZ() [3]float64
}

// PointMer is a 2D+1D point.
type PointMer interface {
Geometry
XYM() [3]float64
}

// PointZMer is a 3D+1D point.
type PointZMer interface {
Geometry
XYZM() [4]float64
}

// PointSer is a 2D point + SRID
type PointSer interface {
Geometry
XYS() struct {Srid uint32; Xy Point}
}

// PointZSer is a 3D point + SRID
type PointZSer interface {
Geometry
XYZS() struct {Srid uint32; Xyz PointZ}
}

// PointMSer is a 2D+1D point + SRID
type PointMSer interface {
Geometry
XYMS() struct {Srid uint32; Xym PointM}
}

// PointZMSer is a 3D+1D point + SRID
type PointZMSer interface {
Geometry
XYZMS() struct {Srid uint32; Xyzm PointZM}
}

// MultiPointer is a geometry with multiple points.
type MultiPointer interface {
Geometry
Expand Down
4 changes: 2 additions & 2 deletions point_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestPointSetter(t *testing.T) {

}
}
testcases := []tcase{
tests := []tcase{
{
point: [2]float64{10, 20},
setter: &geom.Point{15, 20},
Expand All @@ -56,7 +56,7 @@ func TestPointSetter(t *testing.T) {
},
}

for i, tc := range testcases {
for i, tc := range tests {
t.Run(strconv.FormatInt(int64(i), 10), fn(tc))
}
}
Expand Down
41 changes: 41 additions & 0 deletions pointm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package geom

import (
"errors"
)

// ErrNilPointM is thrown when a point is null but shouldn't be
var ErrNilPointM = errors.New("geom: nil PointM")

// Point describes a simple 2D+1D point
type PointM [3]float64

// XYM returns an array of 2D+1D coordinates
func (p PointM) XYM() [3]float64 {
return p
}

// XY returns an array of 2D coordinates
func (p PointM) XY() [2]float64 {
return Point{
p[0],
p[1],
}
}

// M returns the metric related to the 2D point
func (p PointM) M() float64 {
return p[2]
}

// SetXYM sets the three coordinates
func (p *PointM) SetXYM(xym [3]float64) (err error) {
if p == nil {
return ErrNilPointM
}

p[0] = xym[0]
p[1] = xym[1]
p[2] = xym[2]
return
}
95 changes: 95 additions & 0 deletions pointm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package geom_test

import (
"fmt"
"reflect"
"strconv"
"testing"

"github.com/go-spatial/geom"
)

func TestPointMSetter(t *testing.T) {
type tcase struct {
point [3]float64
setter geom.PointMSetter
expected geom.PointMSetter
err error
}

fn := func(tc tcase) func(*testing.T) {
return func(t *testing.T) {
err := tc.setter.SetXYM(tc.point)
if tc.err == nil && err != nil {
t.Errorf("error, expected nil got %v", err)
return
}
if tc.err != nil {
if tc.err.Error() != err.Error() {
t.Errorf("error, expected %v got %v", tc.err, err)
}
return
}

// compare the results
if !reflect.DeepEqual(tc.expected, tc.setter) {
t.Errorf("setter, expected %v got %v", tc.expected, tc.setter)
return
}
xym := tc.setter.XYM()
if !reflect.DeepEqual(tc.point, xym) {
t.Errorf("XYM, expected %v, got %v", tc.point, xym)
}
}
}
tests := []tcase{
{
point: [3]float64{10, 20, 1000.},
setter: &geom.PointM{15, 20, 1000.},
expected: &geom.PointM{10, 20, 1000.},
},
{
setter: (*geom.PointM)(nil),
err: geom.ErrNilPointM,
},
}

for i, tc := range tests {
t.Run(strconv.FormatInt(int64(i), 10), fn(tc))
}
}

func TestPointM(t *testing.T) {
fn := func(pt geom.PointM) (string, func(*testing.T)) {
return fmt.Sprintf("%v", pt),
func(t *testing.T) {
t.Run("xy", func(t *testing.T) {
xy := pt.XY()
exp_xy := geom.Point{pt[0], pt[1]}
if xy != exp_xy {
t.Errorf("xy, expected %v got %v", exp_xy, xy)
}
})
t.Run("xym", func(t *testing.T) {
xym := pt.XYM()
exp_xym := pt
if xym != exp_xym {
t.Errorf("xym, expected %v got %v", exp_xym, xym)
}
})
t.Run("m", func(t *testing.T) {
m := pt.M()
exp_m := pt[2]
if m != exp_m {
t.Errorf("m, expected %v got %v", exp_m, m)
}
})
}
}
tests := []geom.PointM{
{0, 1, 1000.}, {2, 2, 1000.}, {1, 2, 1000.},
}
for _, pt := range tests {
t.Run(fn(pt))
}
}
39 changes: 39 additions & 0 deletions pointms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package geom

import (
"errors"
)

// ErrNilPointMS is thrown when a point is null but shouldn't be
var ErrNilPointMS = errors.New("geom: nil PointMS")

// Point describes a simple 3D point with SRID
type PointMS struct {
Srid uint32
Xym PointM }

// XYMS returns the struct itself
func (p PointMS) XYMS() struct {Srid uint32; Xym PointM} {
return p
}

// XYM returns 3D+1D point
func (p PointMS) XYM() PointM {
return p.Xym
}

// S returns the srid as uint32
func (p PointMS) S() uint32 {
return p.Srid
}

// SetXYMS sets the XYM coordinates and the SRID
func (p *PointMS) SetXYMS(srid uint32, xym PointM) (err error) {
if p == nil {
return ErrNilPointMS
}

p.Srid = srid
p.Xym = xym
return
}
98 changes: 98 additions & 0 deletions pointms_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package geom_test

import (
"fmt"
"reflect"
"strconv"
"testing"

"github.com/go-spatial/geom"
)

func TestPointMSSetter(t *testing.T) {
type tcase struct {
point_srid uint32
point_xym geom.PointM
setter geom.PointMSSetter
expected geom.PointMSSetter
err error
}

fn := func(tc tcase) func(*testing.T) {
return func(t *testing.T) {
err := tc.setter.SetXYMS(tc.point_srid, tc.point_xym)
if tc.err == nil && err != nil {
t.Errorf("error, expected nil got %v", err)
return
}
if tc.err != nil {
if tc.err.Error() != err.Error() {
t.Errorf("error, expected %v got %v", tc.err, err)
}
return
}

// compare the results
if !reflect.DeepEqual(tc.expected, tc.setter) {
t.Errorf("setter, expected %v got %v", tc.expected, tc.setter)
return
}
xyms := tc.setter.XYMS()
tc_xyms := struct {Srid uint32; Xym geom.PointM}{tc.point_srid, geom.PointM{tc.point_xym[0], tc.point_xym[1], tc.point_xym[2]}}
if !reflect.DeepEqual(tc_xyms, xyms) {
t.Errorf("XYZS, expected %v, got %v", tc_xyms, xyms)
}
}
}
tests := []tcase{
{
point_srid: 4326,
point_xym: geom.PointM{10, 20, 1000},
setter: &geom.PointMS{4326, geom.PointM{15, 20, 1000}},
expected: &geom.PointMS{4326, geom.PointM{10, 20, 1000}},
},
{
setter: (*geom.PointMS)(nil),
err: geom.ErrNilPointMS,
},
}

for i, tc := range tests {
t.Run(strconv.FormatInt(int64(i), 10), fn(tc))
}
}

func TestPointMS(t *testing.T) {
fn := func(pt geom.PointMS) (string, func(*testing.T)) {
return fmt.Sprintf("%v", pt),
func(t *testing.T) {
t.Run("xym", func(t *testing.T) {
xym := pt.XYM()
exp_xym := pt.Xym
if xym != exp_xym {
t.Errorf("xym, expected %v got %v", exp_xym, xym)
}
})
t.Run("s", func(t *testing.T) {
s := pt.S()
exp_s := pt.Srid
if s != exp_s {
t.Errorf("srid, expected %v got %v", exp_s, s)
}
})
t.Run("xyms", func(t *testing.T) {
xyms := pt.XYMS()
exp_xyms := pt
if xyms != exp_xyms {
t.Errorf("xyms, expected %v got %v", exp_xyms, xyms)
}
})
}
}
tests := []geom.PointMS{
{4326, geom.PointM{0, 1, 1000}}, {4326, geom.PointM{2, 2, 300}}, {4326, geom.PointM{1, 2, 1000}},
}
for _, pt := range tests {
t.Run(fn(pt))
}
}
39 changes: 39 additions & 0 deletions points.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package geom

import (
"errors"
)

// ErrNilPointS is thrown when a point is null but shouldn't be
var ErrNilPointS = errors.New("geom: nil PointS")

// Point describes a simple 2D point with SRID
type PointS struct {
Srid uint32
Xy Point }

// XYS returns the struct itself
func (p PointS) XYS() struct {Srid uint32; Xy Point} {
return p
}

// XY returns 2D point
func (p PointS) XY() Point {
return p.Xy
}

// S returns the srid as uint32
func (p PointS) S() uint32 {
return p.Srid
}

// SetXYS sets the XY coordinates and the SRID
func (p *PointS) SetXYS(srid uint32, xy Point) (err error) {
if p == nil {
return ErrNilPointS
}

p.Srid = srid
p.Xy = xy
return
}
Loading