diff --git a/geom.go b/geom.go index 8a88b1f..fd73eb3 100644 --- a/geom.go +++ b/geom.go @@ -18,44 +18,56 @@ type Pointer interface { // PointZer is a 3D point. type PointZer interface { - Geometry - XYZ() [3]float64 + Geometry + XYZ() [3]float64 } // PointMer is a 2D+1D point. type PointMer interface { - Geometry - XYM() [3]float64 + Geometry + XYM() [3]float64 } // PointZMer is a 3D+1D point. type PointZMer interface { - Geometry - XYZM() [4]float64 + Geometry + XYZM() [4]float64 } // PointSer is a 2D point + SRID type PointSer interface { - Geometry - XYS() struct {Srid uint32; Xy Point} + Geometry + XYS() struct { + Srid uint32 + Xy Point + } } // PointZSer is a 3D point + SRID type PointZSer interface { - Geometry - XYZS() struct {Srid uint32; Xyz PointZ} + Geometry + XYZS() struct { + Srid uint32 + Xyz PointZ + } } // PointMSer is a 2D+1D point + SRID type PointMSer interface { - Geometry - XYMS() struct {Srid uint32; Xym PointM} + Geometry + XYMS() struct { + Srid uint32 + Xym PointM + } } // PointZMSer is a 3D+1D point + SRID type PointZMSer interface { - Geometry - XYZMS() struct {Srid uint32; Xyzm PointZM} + Geometry + XYZMS() struct { + Srid uint32 + Xyzm PointZM + } } // MultiPointer is a geometry with multiple points. @@ -70,6 +82,60 @@ type LineStringer interface { Vertices() [][2]float64 } +// LineStringMer is a line of two or more M points. +type LineStringMer interface { + Geometry + Vertices() [][3]float64 +} + +// LineStringZer is a line of two or more Z points. +type LineStringZer interface { + Geometry + Vertices() [][3]float64 +} + +// LineStringZMer is a line of two or more ZM points. +type LineStringZMer interface { + Geometry + Vertices() [][4]float64 +} + +// LineStringSer is a line of two or more points + SRID. +type LineStringSer interface { + Geometry + Vertices() struct { + Srid uint32 + Ls LineString + } +} + +// LineStringMSer is a line of two or more M points + SRID. +type LineStringMSer interface { + Geometry + Vertices() struct { + Srid uint32 + Lsm LineStringM + } +} + +// LineStringZSer is a line of two or more Z points + SRID. +type LineStringZSer interface { + Geometry + Vertices() struct { + Srid uint32 + Lsz LineStringZ + } +} + +// LineStringZMSer is a line of two or more ZM points + SRID. +type LineStringZMSer interface { + Geometry + Vertices() struct { + Srid uint32 + Lszm LineStringZM + } +} + // MultiLineStringer is a geometry with multiple LineStrings. type MultiLineStringer interface { Geometry diff --git a/line_stringm.go b/line_stringm.go new file mode 100644 index 0000000..042b660 --- /dev/null +++ b/line_stringm.go @@ -0,0 +1,41 @@ +package geom + +import ( + "errors" +) + +// ErrNilLineStringM is thrown when a LineStringM is nil but shouldn't be +var ErrNilLineStringM = errors.New("geom: nil LineStringM") + +// ErrInvalidLineStringM is thrown when a LineStringM is malformed +var ErrInvalidLineStringM = errors.New("geom: invalid LineStringM") + +// LineString is a basic line type which is made up of two or more points that don't interacted. +type LineStringM [][3]float64 + +// Vertices returns a slice of XYM values +func (lsm LineStringM) Vertices() [][3]float64 { return lsm } + +// SetVertices modifies the array of 2D+1 coordinates +func (lsm *LineStringM) SetVertices(input [][3]float64) (err error) { + if lsm == nil { + return ErrNilLineStringM + } + + *lsm = append((*lsm)[:0], input...) + return +} + +// Get the simple 2D linestring +func (lsm LineStringM) LineString() LineString { + var lsv [][2]float64 + var ls LineString + + verts := lsm.Vertices() + for i := 0; i < len(verts); i++ { + lsv = append(lsv, [2]float64{verts[i][0], verts[i][1]}) + } + + ls.SetVertices(lsv) + return ls +} diff --git a/line_stringm_test.go b/line_stringm_test.go new file mode 100644 index 0000000..a13c258 --- /dev/null +++ b/line_stringm_test.go @@ -0,0 +1,66 @@ +package geom_test + +import ( + "reflect" + "strconv" + "testing" + + "github.com/go-spatial/geom" +) + +func TestLineStringMSetter(t *testing.T) { + type tcase struct { + points [][3]float64 + setter geom.LineStringMSetter + expected geom.LineStringMSetter + err error + } + fn := func(t *testing.T, tc tcase) { + err := tc.setter.SetVertices(tc.points) + 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) + } + lsm := tc.setter.Vertices() + if !reflect.DeepEqual(tc.points, lsm) { + t.Errorf("Vertices, expected %v got %v", tc.points, lsm) + } + } + tests := []tcase{ + { + points: [][3]float64{ + {15, 20, 30}, + {35, 40, 30}, + {-15, -5, 12}, + }, + setter: &geom.LineStringM{ + {10, 20, 30}, + {30, 40, 30}, + {-10, -5, -2}, + }, + expected: &geom.LineStringM{ + {15, 20, 30}, + {35, 40, 30}, + {-15, -5, 12}, + }, + }, + { + setter: (*geom.LineStringM)(nil), + err: geom.ErrNilLineStringM, + }, + } + for i, tc := range tests { + tc := tc + t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) { fn(t, tc) }) + } +} diff --git a/line_stringms.go b/line_stringms.go new file mode 100644 index 0000000..e59403f --- /dev/null +++ b/line_stringms.go @@ -0,0 +1,39 @@ +package geom + +import ( + "errors" +) + +// ErrNilLineStringMS is thrown when a LineStringS is nil but shouldn't be +var ErrNilLineStringMS = errors.New("geom: nil LineStringMS") + +// ErrInvalidLineStringMS is thrown when a LineStringMS is malformed +var ErrInvalidLineStringMS = errors.New("geom: invalid LineStringMS") + +// LineStringMS is a basic line type which is made up of two or more points that don't interacted. +type LineStringMS struct { + Srid uint32 + Lsm LineStringM +} + +// Vertices returns a slice of referenced XYM values +func (lsms LineStringMS) Vertices() struct { + Srid uint32 + Lsm LineStringM +} { return lsms } + +// SetVertices modifies the struct containing the SRID int and the array of 2D + 1 coordinates +func (lsms *LineStringMS) SetSRID(srid uint32, lsm LineStringM) (err error) { + if lsms == nil { + return ErrNilLineStringMS + } + + lsms.Srid = srid + lsms.Lsm = lsm + return +} + +// Get the simple 2D + 1 linestring +func (lsms LineStringMS) LineStringM() LineStringM { + return lsms.Lsm +} diff --git a/line_stringms_test.go b/line_stringms_test.go new file mode 100644 index 0000000..ee1f038 --- /dev/null +++ b/line_stringms_test.go @@ -0,0 +1,61 @@ +package geom_test + +import ( + "reflect" + "strconv" + "testing" + + "github.com/go-spatial/geom" +) + +func TestLineStringMSSetter(t *testing.T) { + type tcase struct { + srid uint32 + linestringm geom.LineStringM + setter geom.LineStringMSSetter + expected geom.LineStringMSSetter + err error + } + fn := func(t *testing.T, tc tcase) { + err := tc.setter.SetSRID(tc.srid, tc.linestringm) + 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) + } + + lsms := tc.setter.Vertices() + tc_lsms := struct { + Srid uint32 + Lsm geom.LineStringM + }{tc.srid, tc.linestringm} + if !reflect.DeepEqual(tc_lsms, lsms) { + t.Errorf("Referenced LineString, expected %v got %v", tc_lsms, lsms) + } + } + tests := []tcase{ + { + srid: 4326, + linestringm: geom.LineStringM{{10, 20, 0.5}, {30, 40, 0.9}}, + setter: &geom.LineStringMS{Srid: 4326, Lsm: geom.LineStringM{{15, 20, 0.5}, {35, 40, 0.9}}}, + expected: &geom.LineStringMS{Srid: 4326, Lsm: geom.LineStringM{{10, 20, 0.5}, {30, 40, 0.9}}}, + }, + { + setter: (*geom.LineStringMS)(nil), + err: geom.ErrNilLineStringMS, + }, + } + for i, tc := range tests { + tc := tc + t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) { fn(t, tc) }) + } +} diff --git a/line_strings.go b/line_strings.go new file mode 100644 index 0000000..999d1e7 --- /dev/null +++ b/line_strings.go @@ -0,0 +1,39 @@ +package geom + +import ( + "errors" +) + +// ErrNilLineStringS is thrown when a LineStringS is nil but shouldn't be +var ErrNilLineStringS = errors.New("geom: nil LineStringS") + +// ErrInvalidLineStringS is thrown when a LineStringS is malformed +var ErrInvalidLineStringS = errors.New("geom: invalid LineStringS") + +// LineString is a basic line type which is made up of two or more points that don't interacted. +type LineStringS struct { + Srid uint32 + Ls LineString +} + +// Vertices returns a slice of referenced XY values +func (lss LineStringS) Vertices() struct { + Srid uint32 + Ls LineString +} { return lss } + +// SetVertices modifies the struct containing the SRID int and the array of 2D coordinates +func (lss *LineStringS) SetSRID(srid uint32, ls LineString) (err error) { + if lss == nil { + return ErrNilLineStringS + } + + lss.Srid = srid + lss.Ls = ls + return +} + +// Get the simple 2D linestring +func (lss LineStringS) LineString() LineString { + return lss.Ls +} diff --git a/line_strings_test.go b/line_strings_test.go new file mode 100644 index 0000000..f6a6c81 --- /dev/null +++ b/line_strings_test.go @@ -0,0 +1,61 @@ +package geom_test + +import ( + "reflect" + "strconv" + "testing" + + "github.com/go-spatial/geom" +) + +func TestLineStringSSetter(t *testing.T) { + type tcase struct { + srid uint32 + linestring geom.LineString + setter geom.LineStringSSetter + expected geom.LineStringSSetter + err error + } + fn := func(t *testing.T, tc tcase) { + err := tc.setter.SetSRID(tc.srid, tc.linestring) + 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) + } + + lss := tc.setter.Vertices() + tc_lss := struct { + Srid uint32 + Ls geom.LineString + }{tc.srid, tc.linestring} + if !reflect.DeepEqual(tc_lss, lss) { + t.Errorf("Referenced LineString, expected %v got %v", tc_lss, lss) + } + } + tests := []tcase{ + { + srid: 4326, + linestring: geom.LineString{{10, 20}, {30, 40}}, + setter: &geom.LineStringS{Srid: 4326, Ls: geom.LineString{{15, 20}, {35, 40}}}, + expected: &geom.LineStringS{Srid: 4326, Ls: geom.LineString{{10, 20}, {30, 40}}}, + }, + { + setter: (*geom.LineStringS)(nil), + err: geom.ErrNilLineStringS, + }, + } + for i, tc := range tests { + tc := tc + t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) { fn(t, tc) }) + } +} diff --git a/line_stringz.go b/line_stringz.go new file mode 100644 index 0000000..72bc7c7 --- /dev/null +++ b/line_stringz.go @@ -0,0 +1,41 @@ +package geom + +import ( + "errors" +) + +// ErrNilLineStringZ is thrown when a LineStringZ is nil but shouldn't be +var ErrNilLineStringZ = errors.New("geom: nil LineStringZ") + +// ErrInvalidLineStringZ is thrown when a LineStringZ is malformed +var ErrInvalidLineStringZ = errors.New("geom: invalid LineStringZ") + +// LineString is a basic line type which is made up of two or more points that don't interacted. +type LineStringZ [][3]float64 + +// Vertices returns a slice of XYM values +func (lsz LineStringZ) Vertices() [][3]float64 { return lsz } + +// SetVertices modifies the array of 3D coordinates +func (lsz *LineStringZ) SetVertices(input [][3]float64) (err error) { + if lsz == nil { + return ErrNilLineStringZ + } + + *lsz = append((*lsz)[:0], input...) + return +} + +// Get the simple 2D linestring +func (lsz LineStringZ) LineString() LineString { + var lsv [][2]float64 + var ls LineString + + verts := lsz.Vertices() + for i := 0; i < len(verts); i++ { + lsv = append(lsv, [2]float64{verts[i][0], verts[i][1]}) + } + + ls.SetVertices(lsv) + return ls +} diff --git a/line_stringz_test.go b/line_stringz_test.go new file mode 100644 index 0000000..61a1ad9 --- /dev/null +++ b/line_stringz_test.go @@ -0,0 +1,66 @@ +package geom_test + +import ( + "reflect" + "strconv" + "testing" + + "github.com/go-spatial/geom" +) + +func TestLineStringZSetter(t *testing.T) { + type tcase struct { + points [][3]float64 + setter geom.LineStringZSetter + expected geom.LineStringZSetter + err error + } + fn := func(t *testing.T, tc tcase) { + err := tc.setter.SetVertices(tc.points) + 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) + } + lsm := tc.setter.Vertices() + if !reflect.DeepEqual(tc.points, lsm) { + t.Errorf("Vertices, expected %v got %v", tc.points, lsm) + } + } + tests := []tcase{ + { + points: [][3]float64{ + {15, 20, 30}, + {35, 40, 30}, + {-15, -5, 12}, + }, + setter: &geom.LineStringZ{ + {10, 20, 30}, + {30, 40, 30}, + {-10, -5, -2}, + }, + expected: &geom.LineStringZ{ + {15, 20, 30}, + {35, 40, 30}, + {-15, -5, 12}, + }, + }, + { + setter: (*geom.LineStringZ)(nil), + err: geom.ErrNilLineStringZ, + }, + } + for i, tc := range tests { + tc := tc + t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) { fn(t, tc) }) + } +} diff --git a/line_stringzm.go b/line_stringzm.go new file mode 100644 index 0000000..a9b92f2 --- /dev/null +++ b/line_stringzm.go @@ -0,0 +1,41 @@ +package geom + +import ( + "errors" +) + +// ErrNilLineStringZM is thrown when a LineStringZM is nil but shouldn't be +var ErrNilLineStringZM = errors.New("geom: nil LineStringZM") + +// ErrInvalidLineStringZM is thrown when a LineStringZM is malformed +var ErrInvalidLineStringZM = errors.New("geom: invalid LineStringZM") + +// LineString is a basic line type which is made up of two or more points that don't interacted. +type LineStringZM [][4]float64 + +// Vertices returns a slice of XYM values +func (lszm LineStringZM) Vertices() [][4]float64 { return lszm } + +// SetVertices modifies the array of 3D + 1 coordinates +func (lszm *LineStringZM) SetVertices(input [][4]float64) (err error) { + if lszm == nil { + return ErrNilLineStringZM + } + + *lszm = append((*lszm)[:0], input...) + return +} + +// Get the simple 2D linestring +func (lszm LineStringZM) LineString() LineString { + var lsv [][2]float64 + var ls LineString + + verts := lszm.Vertices() + for i := 0; i < len(verts); i++ { + lsv = append(lsv, [2]float64{verts[i][0], verts[i][1]}) + } + + ls.SetVertices(lsv) + return ls +} diff --git a/line_stringzm_test.go b/line_stringzm_test.go new file mode 100644 index 0000000..f362a4f --- /dev/null +++ b/line_stringzm_test.go @@ -0,0 +1,66 @@ +package geom_test + +import ( + "reflect" + "strconv" + "testing" + + "github.com/go-spatial/geom" +) + +func TestLineStringZMSetter(t *testing.T) { + type tcase struct { + points [][4]float64 + setter geom.LineStringZMSetter + expected geom.LineStringZMSetter + err error + } + fn := func(t *testing.T, tc tcase) { + err := tc.setter.SetVertices(tc.points) + 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) + } + lszm := tc.setter.Vertices() + if !reflect.DeepEqual(tc.points, lszm) { + t.Errorf("Vertices, expected %v got %v", tc.points, lszm) + } + } + tests := []tcase{ + { + points: [][4]float64{ + {15, 20, 30, 40}, + {35, 40, 30, 40}, + {-15, -5, 12, -3}, + }, + setter: &geom.LineStringZM{ + {10, 20, 30, 40}, + {30, 40, 30, 40}, + {-10, -5, -2, -3}, + }, + expected: &geom.LineStringZM{ + {15, 20, 30, 40}, + {35, 40, 30, 40}, + {-15, -5, 12, -3}, + }, + }, + { + setter: (*geom.LineStringZM)(nil), + err: geom.ErrNilLineStringZM, + }, + } + for i, tc := range tests { + tc := tc + t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) { fn(t, tc) }) + } +} diff --git a/line_stringzms.go b/line_stringzms.go new file mode 100644 index 0000000..0dc78a5 --- /dev/null +++ b/line_stringzms.go @@ -0,0 +1,39 @@ +package geom + +import ( + "errors" +) + +// ErrNilLineStringZMS is thrown when a LineStringZMS is nil but shouldn't be +var ErrNilLineStringZMS = errors.New("geom: nil LineStringZMS") + +// ErrInvalidLineStringZMS is thrown when a LineStringZMS is malformed +var ErrInvalidLineStringZMS = errors.New("geom: invalid LineStringZMS") + +// LineStringZMS is a basic line type which is made up of two or more points that don't interacted. +type LineStringZMS struct { + Srid uint32 + Lszm LineStringZM +} + +// Vertices returns a slice of referenced XYZM values +func (lszms LineStringZMS) Vertices() struct { + Srid uint32 + Lszm LineStringZM +} { return lszms } + +// SetVertices modifies the struct containing the SRID int and the array of 3D + 1 coordinates +func (lszms *LineStringZMS) SetSRID(srid uint32, lszm LineStringZM) (err error) { + if lszms == nil { + return ErrNilLineStringZMS + } + + lszms.Srid = srid + lszms.Lszm = lszm + return +} + +// Get the simple 3D + 1 linestring +func (lszms LineStringZMS) LineStringZM() LineStringZM { + return lszms.Lszm +} diff --git a/line_stringzms_test.go b/line_stringzms_test.go new file mode 100644 index 0000000..b3ef66d --- /dev/null +++ b/line_stringzms_test.go @@ -0,0 +1,61 @@ +package geom_test + +import ( + "reflect" + "strconv" + "testing" + + "github.com/go-spatial/geom" +) + +func TestLineStringZMSSetter(t *testing.T) { + type tcase struct { + srid uint32 + linestringzm geom.LineStringZM + setter geom.LineStringZMSSetter + expected geom.LineStringZMSSetter + err error + } + fn := func(t *testing.T, tc tcase) { + err := tc.setter.SetSRID(tc.srid, tc.linestringzm) + 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) + } + + lszms := tc.setter.Vertices() + tc_lszms := struct { + Srid uint32 + Lszm geom.LineStringZM + }{tc.srid, tc.linestringzm} + if !reflect.DeepEqual(tc_lszms, lszms) { + t.Errorf("Referenced LineString, expected %v got %v", tc_lszms, lszms) + } + } + tests := []tcase{ + { + srid: 4326, + linestringzm: geom.LineStringZM{{10, 20, 50, 0.5}, {30, 40, 90, 0.9}}, + setter: &geom.LineStringZMS{Srid: 4326, Lszm: geom.LineStringZM{{15, 20, 50, 0.5}, {35, 40, 90, 0.9}}}, + expected: &geom.LineStringZMS{Srid: 4326, Lszm: geom.LineStringZM{{10, 20, 50, 0.5}, {30, 40, 90, 0.9}}}, + }, + { + setter: (*geom.LineStringZMS)(nil), + err: geom.ErrNilLineStringZMS, + }, + } + for i, tc := range tests { + tc := tc + t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) { fn(t, tc) }) + } +} diff --git a/line_stringzs.go b/line_stringzs.go new file mode 100644 index 0000000..c84ca82 --- /dev/null +++ b/line_stringzs.go @@ -0,0 +1,39 @@ +package geom + +import ( + "errors" +) + +// ErrNilLineStringZS is thrown when a LineStringS is nil but shouldn't be +var ErrNilLineStringZS = errors.New("geom: nil LineStringZS") + +// ErrInvalidLineStringZS is thrown when a LineStringZS is malformed +var ErrInvalidLineStringZS = errors.New("geom: invalid LineStringZS") + +// LineStringZS is a basic line type which is made up of two or more points that don't interacted. +type LineStringZS struct { + Srid uint32 + Lsz LineStringZ +} + +// Vertices returns a slice of referenced XYM values +func (lszs LineStringZS) Vertices() struct { + Srid uint32 + Lsz LineStringZ +} { return lszs } + +// SetVertices modifies the struct containing the SRID int and the array of 3D coordinates +func (lszs *LineStringZS) SetSRID(srid uint32, lsz LineStringZ) (err error) { + if lszs == nil { + return ErrNilLineStringZS + } + + lszs.Srid = srid + lszs.Lsz = lsz + return +} + +// Get the simple 3D linestring +func (lszs LineStringZS) LineStringZ() LineStringZ { + return lszs.Lsz +} diff --git a/line_stringzs_test.go b/line_stringzs_test.go new file mode 100644 index 0000000..6e741ec --- /dev/null +++ b/line_stringzs_test.go @@ -0,0 +1,61 @@ +package geom_test + +import ( + "reflect" + "strconv" + "testing" + + "github.com/go-spatial/geom" +) + +func TestLineStringZSSetter(t *testing.T) { + type tcase struct { + srid uint32 + linestringz geom.LineStringZ + setter geom.LineStringZSSetter + expected geom.LineStringZSSetter + err error + } + fn := func(t *testing.T, tc tcase) { + err := tc.setter.SetSRID(tc.srid, tc.linestringz) + 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) + } + + lszs := tc.setter.Vertices() + tc_lszs := struct { + Srid uint32 + Lsz geom.LineStringZ + }{tc.srid, tc.linestringz} + if !reflect.DeepEqual(tc_lszs, lszs) { + t.Errorf("Referenced LineString, expected %v got %v", tc_lszs, lszs) + } + } + tests := []tcase{ + { + srid: 4326, + linestringz: geom.LineStringZ{{10, 20, 50}, {30, 40, 90}}, + setter: &geom.LineStringZS{Srid: 4326, Lsz: geom.LineStringZ{{15, 20, 50}, {35, 40, 90}}}, + expected: &geom.LineStringZS{Srid: 4326, Lsz: geom.LineStringZ{{10, 20, 50}, {30, 40, 90}}}, + }, + { + setter: (*geom.LineStringZS)(nil), + err: geom.ErrNilLineStringZS, + }, + } + for i, tc := range tests { + tc := tc + t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) { fn(t, tc) }) + } +} diff --git a/pointm.go b/pointm.go index ec7f721..39845a4 100644 --- a/pointm.go +++ b/pointm.go @@ -12,20 +12,20 @@ type PointM [3]float64 // XYM returns an array of 2D+1D coordinates func (p PointM) XYM() [3]float64 { - return p + return p } // XY returns an array of 2D coordinates func (p PointM) XY() [2]float64 { return Point{ - p[0], - p[1], - } + p[0], + p[1], + } } // M returns the metric related to the 2D point func (p PointM) M() float64 { - return p[2] + return p[2] } // SetXYM sets the three coordinates diff --git a/pointm_test.go b/pointm_test.go index a70a7cc..9729018 100644 --- a/pointm_test.go +++ b/pointm_test.go @@ -71,25 +71,25 @@ func TestPointM(t *testing.T) { } }) 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) - } - }) + 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) - } - }) + 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.}, - } + {0, 1, 1000.}, {2, 2, 1000.}, {1, 2, 1000.}, + } for _, pt := range tests { t.Run(fn(pt)) - } + } } diff --git a/pointms.go b/pointms.go index 149bbef..448df1a 100644 --- a/pointms.go +++ b/pointms.go @@ -10,11 +10,15 @@ var ErrNilPointMS = errors.New("geom: nil PointMS") // Point describes a simple 3D point with SRID type PointMS struct { Srid uint32 - Xym PointM } + Xym PointM +} // XYMS returns the struct itself -func (p PointMS) XYMS() struct {Srid uint32; Xym PointM} { - return p +func (p PointMS) XYMS() struct { + Srid uint32 + Xym PointM +} { + return p } // XYM returns 3D+1D point @@ -24,7 +28,7 @@ func (p PointMS) XYM() PointM { // S returns the srid as uint32 func (p PointMS) S() uint32 { - return p.Srid + return p.Srid } // SetXYMS sets the XYM coordinates and the SRID diff --git a/pointms_test.go b/pointms_test.go index 8821b8d..9d81b75 100644 --- a/pointms_test.go +++ b/pointms_test.go @@ -38,7 +38,10 @@ func TestPointMSSetter(t *testing.T) { 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]}} + 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) } @@ -73,26 +76,26 @@ func TestPointMS(t *testing.T) { 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("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) - } - }) + 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)) - } + } } diff --git a/points.go b/points.go index c2742ef..761feb0 100644 --- a/points.go +++ b/points.go @@ -10,11 +10,15 @@ var ErrNilPointS = errors.New("geom: nil PointS") // Point describes a simple 2D point with SRID type PointS struct { Srid uint32 - Xy Point } + Xy Point +} // XYS returns the struct itself -func (p PointS) XYS() struct {Srid uint32; Xy Point} { - return p +func (p PointS) XYS() struct { + Srid uint32 + Xy Point +} { + return p } // XY returns 2D point @@ -24,7 +28,7 @@ func (p PointS) XY() Point { // S returns the srid as uint32 func (p PointS) S() uint32 { - return p.Srid + return p.Srid } // SetXYS sets the XY coordinates and the SRID diff --git a/points_test.go b/points_test.go index 617b132..d799a06 100644 --- a/points_test.go +++ b/points_test.go @@ -38,7 +38,10 @@ func TestPointSSetter(t *testing.T) { return } xys := tc.setter.XYS() - tc_xys := struct {Srid uint32; Xy geom.Point}{tc.point_srid, geom.Point{tc.point_xy[0], tc.point_xy[1]}} + tc_xys := struct { + Srid uint32 + Xy geom.Point + }{tc.point_srid, geom.Point{tc.point_xy[0], tc.point_xy[1]}} if !reflect.DeepEqual(tc_xys, xys) { t.Errorf("XYZ, expected %v, got %v", tc_xys, xys) } @@ -73,26 +76,26 @@ func TestPointS(t *testing.T) { t.Errorf("xy, expected %v got %v", exp_xy, xy) } }) - 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("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("xys", func(t *testing.T) { - xys := pt.XYS() - exp_xys := pt - if xys != exp_xys { - t.Errorf("xys, expected %v got %v", exp_xys, xys) - } - }) + xys := pt.XYS() + exp_xys := pt + if xys != exp_xys { + t.Errorf("xys, expected %v got %v", exp_xys, xys) + } + }) } } tests := []geom.PointS{ {4326, geom.Point{0, 1}}, {4326, geom.Point{2, 2}}, {4326, geom.Point{1, 2}}, - } + } for _, pt := range tests { t.Run(fn(pt)) - } + } } diff --git a/pointz.go b/pointz.go index 88d0b72..0813a08 100644 --- a/pointz.go +++ b/pointz.go @@ -13,15 +13,15 @@ type PointZ [3]float64 // XYZ returns an array of 3D coordinates func (p PointZ) XYZ() [3]float64 { - return p + return p } // XY returns an array of 2D coordinates func (p PointZ) XY() [2]float64 { return Point{ - p[0], - p[1], - } + p[0], + p[1], + } } // SetXYZ sets the three coordinates diff --git a/pointz_test.go b/pointz_test.go index 80f0ecf..8f03878 100644 --- a/pointz_test.go +++ b/pointz_test.go @@ -2,10 +2,10 @@ package geom_test import ( "fmt" + "math" "reflect" "strconv" "testing" - "math" "github.com/go-spatial/geom" ) @@ -72,25 +72,25 @@ func TestPointZ(t *testing.T) { } }) t.Run("xyz", func(t *testing.T) { - xyz := pt.XYZ() - exp_xyz := pt - if xyz != exp_xyz { - t.Errorf("xyz, expected %v got %v", exp_xyz, xyz) - } - }) + xyz := pt.XYZ() + exp_xyz := pt + if xyz != exp_xyz { + t.Errorf("xyz, expected %v got %v", exp_xyz, xyz) + } + }) t.Run("magnitude", func(t *testing.T) { - m := pt.Magnitude() - exp_m := math.Sqrt((pt[0] * pt[0]) + (pt[1] * pt[1]) + (pt[2] * pt[2])) - if m != exp_m { - t.Errorf("magnitude, expected %v got %v", exp_m, m) - } - }) + m := pt.Magnitude() + exp_m := math.Sqrt((pt[0] * pt[0]) + (pt[1] * pt[1]) + (pt[2] * pt[2])) + if m != exp_m { + t.Errorf("magnitude, expected %v got %v", exp_m, m) + } + }) } } tests := []geom.PointZ{ - {0, 1, 2}, {2, 2, 3}, {1, 2, 3}, - } + {0, 1, 2}, {2, 2, 3}, {1, 2, 3}, + } for _, pt := range tests { t.Run(fn(pt)) - } + } } diff --git a/pointzm.go b/pointzm.go index 7f18377..0e563ee 100644 --- a/pointzm.go +++ b/pointzm.go @@ -12,21 +12,21 @@ type PointZM [4]float64 // XYZM returns an array of 3D+1D coordinates func (p PointZM) XYZM() [4]float64 { - return p + return p } // XYZ returns an array of 3D coordinates func (p PointZM) XYZ() [3]float64 { return PointZ{ - p[0], - p[1], + p[0], + p[1], p[2], - } + } } // M returns the metric related to the 2D point func (p PointZM) M() float64 { - return p[3] + return p[3] } // SetXYZM sets the three coordinates diff --git a/pointzm_test.go b/pointzm_test.go index 6676ade..c180661 100644 --- a/pointzm_test.go +++ b/pointzm_test.go @@ -71,25 +71,25 @@ func TestPointZM(t *testing.T) { } }) t.Run("xyzm", func(t *testing.T) { - xyzm := pt.XYZM() - exp_xyzm := pt - if xyzm != exp_xyzm { - t.Errorf("xyzm, expected %v got %v", exp_xyzm, xyzm) - } - }) + xyzm := pt.XYZM() + exp_xyzm := pt + if xyzm != exp_xyzm { + t.Errorf("xyzm, expected %v got %v", exp_xyzm, xyzm) + } + }) t.Run("m", func(t *testing.T) { - m := pt.M() - exp_m := pt[3] - if m != exp_m { - t.Errorf("m, expected %v got %v", exp_m, m) - } - }) + m := pt.M() + exp_m := pt[3] + if m != exp_m { + t.Errorf("m, expected %v got %v", exp_m, m) + } + }) } } tests := []geom.PointZM{ - {0, 1, 2, 1000.}, {2, 2, 3, 1000.}, {1, 2, 3, 1000.}, - } + {0, 1, 2, 1000.}, {2, 2, 3, 1000.}, {1, 2, 3, 1000.}, + } for _, pt := range tests { t.Run(fn(pt)) - } + } } diff --git a/pointzms.go b/pointzms.go index 154a99b..adf9920 100644 --- a/pointzms.go +++ b/pointzms.go @@ -10,11 +10,15 @@ var ErrNilPointZMS = errors.New("geom: nil PointZMS") // Point describes a simple 3D+1D point with SRID type PointZMS struct { Srid uint32 - Xyzm PointZM } + Xyzm PointZM +} // XYZMS returns the struct itself -func (p PointZMS) XYZMS() struct {Srid uint32; Xyzm PointZM} { - return p +func (p PointZMS) XYZMS() struct { + Srid uint32 + Xyzm PointZM +} { + return p } // XYZM returns 3D+1D point @@ -24,7 +28,7 @@ func (p PointZMS) XYZM() PointZM { // S returns the srid as uint32 func (p PointZMS) S() uint32 { - return p.Srid + return p.Srid } // SetXYZMS sets the XYZM coordinates and the SRID diff --git a/pointzms_test.go b/pointzms_test.go index dc23417..304842a 100644 --- a/pointzms_test.go +++ b/pointzms_test.go @@ -38,7 +38,10 @@ func TestPointZMSSetter(t *testing.T) { return } xyzms := tc.setter.XYZMS() - tc_xyzms := struct {Srid uint32; Xyzm geom.PointZM}{tc.point_srid, geom.PointZM{tc.point_xyzm[0], tc.point_xyzm[1], tc.point_xyzm[2], tc.point_xyzm[3]}} + tc_xyzms := struct { + Srid uint32 + Xyzm geom.PointZM + }{tc.point_srid, geom.PointZM{tc.point_xyzm[0], tc.point_xyzm[1], tc.point_xyzm[2], tc.point_xyzm[3]}} if !reflect.DeepEqual(tc_xyzms, xyzms) { t.Errorf("XYZS, expected %v, got %v", tc_xyzms, xyzms) } @@ -73,26 +76,26 @@ func TestPointZMS(t *testing.T) { t.Errorf("xyzm, expected %v got %v", exp_xyzm, xyzm) } }) - 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("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("xyzms", func(t *testing.T) { - xyzms := pt.XYZMS() - exp_xyzms := pt - if xyzms != exp_xyzms { - t.Errorf("xyzms, expected %v got %v", exp_xyzms, xyzms) - } - }) + xyzms := pt.XYZMS() + exp_xyzms := pt + if xyzms != exp_xyzms { + t.Errorf("xyzms, expected %v got %v", exp_xyzms, xyzms) + } + }) } } tests := []geom.PointZMS{ {4326, geom.PointZM{0, 1, 2, 1000}}, {4326, geom.PointZM{2, 2, 3, 1000}}, {4326, geom.PointZM{1, 2, 3, 1000}}, - } + } for _, pt := range tests { t.Run(fn(pt)) - } + } } diff --git a/pointzs.go b/pointzs.go index f4e227f..f59faaa 100644 --- a/pointzs.go +++ b/pointzs.go @@ -10,11 +10,15 @@ var ErrNilPointZS = errors.New("geom: nil PointZS") // Point describes a simple 3D point with SRID type PointZS struct { Srid uint32 - Xyz PointZ } + Xyz PointZ +} // XYZS returns the struct itself -func (p PointZS) XYZS() struct {Srid uint32; Xyz PointZ} { - return p +func (p PointZS) XYZS() struct { + Srid uint32 + Xyz PointZ +} { + return p } // XYZ returns 3D point @@ -24,7 +28,7 @@ func (p PointZS) XYZ() PointZ { // S returns the srid as uint32 func (p PointZS) S() uint32 { - return p.Srid + return p.Srid } // SetXYZS sets the XYZ coordinates and the SRID diff --git a/pointzs_test.go b/pointzs_test.go index cd4fefa..e557a7f 100644 --- a/pointzs_test.go +++ b/pointzs_test.go @@ -38,7 +38,10 @@ func TestPointZSSetter(t *testing.T) { return } xyzs := tc.setter.XYZS() - tc_xyzs := struct {Srid uint32; Xyz geom.PointZ}{tc.point_srid, geom.PointZ{tc.point_xyz[0], tc.point_xyz[1], tc.point_xyz[2]}} + tc_xyzs := struct { + Srid uint32 + Xyz geom.PointZ + }{tc.point_srid, geom.PointZ{tc.point_xyz[0], tc.point_xyz[1], tc.point_xyz[2]}} if !reflect.DeepEqual(tc_xyzs, xyzs) { t.Errorf("XYZS, expected %v, got %v", tc_xyzs, xyzs) } @@ -73,26 +76,26 @@ func TestPointZS(t *testing.T) { t.Errorf("xyz, expected %v got %v", exp_xyz, xyz) } }) - 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("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("xyzs", func(t *testing.T) { - xyzs := pt.XYZS() - exp_xyzs := pt - if xyzs != exp_xyzs { - t.Errorf("xyzs, expected %v got %v", exp_xyzs, xyzs) - } - }) + xyzs := pt.XYZS() + exp_xyzs := pt + if xyzs != exp_xyzs { + t.Errorf("xyzs, expected %v got %v", exp_xyzs, xyzs) + } + }) } } tests := []geom.PointZS{ {4326, geom.PointZ{0, 1, 2}}, {4326, geom.PointZ{2, 2, 3}}, {4326, geom.PointZ{1, 2, 3}}, - } + } for _, pt := range tests { t.Run(fn(pt)) - } + } } diff --git a/set_geom.go b/set_geom.go index db179a2..dc31a2b 100644 --- a/set_geom.go +++ b/set_geom.go @@ -24,32 +24,32 @@ type PointMSetter interface { // PointZMSetter is a mutable PointZMer type PointZMSetter interface { - PointZMer - SetXYZM([4]float64) error + PointZMer + SetXYZM([4]float64) error } // PointSSetter is a mutable PointSer type PointSSetter interface { - PointSer + PointSer SetXYS(srid uint32, xy Point) error } // PointZSSetter is a mutable PointZSer type PointZSSetter interface { - PointZSer + PointZSer SetXYZS(srid uint32, xyz PointZ) error } // PointMSSetter is a mutable PointMer type PointMSSetter interface { - PointMSer - SetXYMS(srid uint32, xym PointM) error + PointMSer + SetXYMS(srid uint32, xym PointM) error } // PointZMSSetter is a mutable PointZMer type PointZMSSetter interface { - PointZMSer - SetXYZMS(srid uint32, xyzm PointZM) error + PointZMSer + SetXYZMS(srid uint32, xyzm PointZM) error } // MultiPointSetter is a mutable MultiPointer. @@ -64,6 +64,48 @@ type LineStringSetter interface { SetVertices([][2]float64) error } +// LineStringMSetter is a mutable LineStringMer. +type LineStringMSetter interface { + LineStringMer + SetVertices([][3]float64) error +} + +// LineStringZSetter is a mutable LineStringZer. +type LineStringZSetter interface { + LineStringZer + SetVertices([][3]float64) error +} + +// LineStringZMSetter is a mutable LineStringZMer. +type LineStringZMSetter interface { + LineStringZMer + SetVertices([][4]float64) error +} + +// LineStringSSetter is a mutable LineStringSer. +type LineStringSSetter interface { + LineStringSer + SetSRID(srid uint32, ls LineString) error +} + +// LineStringMSSetter is a mutable LineStringMSer. +type LineStringMSSetter interface { + LineStringMSer + SetSRID(srid uint32, lsm LineStringM) error +} + +// LineStringZSSetter is a mutable LineStringZSer. +type LineStringZSSetter interface { + LineStringZSer + SetSRID(srid uint32, lsz LineStringZ) error +} + +// LineStringZMSSetter is a mutable LineStringZMSer. +type LineStringZMSSetter interface { + LineStringZMSer + SetSRID(srid uint32, lszm LineStringZM) error +} + // MultiLineStringSetter is a mutable MultiLineStringer. type MultiLineStringSetter interface { MultiLineStringer