/
point.go
88 lines (71 loc) · 1.79 KB
/
point.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package shp
import (
"encoding/binary"
"fmt"
"math"
"github.com/golang/geo/r2"
)
// Point is a single pair of X and Y coordinates.
type Point struct {
r2.Point
number uint32
box *BoundingBox
}
// MakePoint creates a new Point for the provided coordinate.
func MakePoint(x, y float64) Point {
return Point{
Point: r2.Point{X: x, Y: y},
}
}
// DecodePoint decodes a single point shape.
func DecodePoint(buf []byte, num uint32) (Point, error) {
return decodePoint(buf, num, nil)
}
// DecodePointP decodes a single point shape with specified precision.
func DecodePointP(buf []byte, num uint32, precision uint) (Point, error) {
return decodePoint(buf, num, &precision)
}
// Type is PointType.
func (p Point) Type() ShapeType {
return PointType
}
// RecordNumber returns the position in the shape file.
func (p Point) RecordNumber() uint32 {
return p.number
}
func (p Point) String() string {
return fmt.Sprintf("(%G,%G)", p.X, p.Y)
}
func (p Point) points() []r2.Point {
return []r2.Point{p.Point}
}
func decodePoint(buf []byte, num uint32, precision *uint) (Point, error) {
if len(buf) < 16 {
return Point{}, fmt.Errorf("expecting 16 bytes buf only have %d", len(buf))
}
float := bytesToFloat64Wrapper(precision)
return Point{
Point: r2.Point{
X: float(buf[0:8]),
Y: float(buf[8:16]),
},
number: num,
}, nil
}
func bytesToFloat64(buf []byte) float64 {
u := binary.LittleEndian.Uint64(buf)
return math.Float64frombits(u)
}
func bytesToFloat64P(buf []byte, precision uint) float64 {
f := bytesToFloat64(buf)
s := math.Pow(10, float64(precision))
return math.Round(f*s) / s
}
func bytesToFloat64Wrapper(precision *uint) func([]byte) float64 {
if precision == nil {
return bytesToFloat64
}
return func(buf []byte) float64 {
return bytesToFloat64P(buf, *precision)
}
}