comparison pkg/imports/polygon.go @ 972:17a03a84b0e8

Split out polygon code out of sounding result importer source file.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 18 Oct 2018 12:22:08 +0200
parents
children a244b18cb916
comparison
equal deleted inserted replaced
971:f9fb6c399f3f 972:17a03a84b0e8
1 package imports
2
3 import (
4 "bytes"
5 "encoding/binary"
6 "fmt"
7 "math"
8
9 shp "github.com/jonas-p/go-shp"
10 )
11
12 type (
13 Point struct {
14 X float64
15 Y float64
16 }
17 LineString []Point
18 Polygon []LineString
19 )
20
21 const (
22 wkbNDR byte = 1
23 wkbPolygon uint32 = 3
24 )
25
26 func shapeToPolygon(s shp.Shape) (Polygon, error) {
27 switch p := s.(type) {
28 case *shp.Polygon:
29 return toPolygon(p.NumParts, p.Parts, p.Points), nil
30 case *shp.PolygonZ:
31 return toPolygon(p.NumParts, p.Parts, p.Points), nil
32 case *shp.PolygonM:
33 return toPolygon(p.NumParts, p.Parts, p.Points), nil
34 }
35 return nil, fmt.Errorf("Unsupported shape type %T", s)
36 }
37
38 func toPolygon(numParts int32, parts []int32, points []shp.Point) Polygon {
39 out := make(Polygon, numParts)
40 pos := 0
41 for i := range out {
42 ps := parts[i]
43 line := make(LineString, ps)
44 for j := int32(0); j < ps; j, pos = j+1, pos+1 {
45 p := &points[pos]
46 line[j] = Point{p.X, p.Y}
47 }
48 out[i] = line
49 }
50 return out
51 }
52
53 func (p Polygon) AsWBK() []byte {
54 if p == nil {
55 return nil
56 }
57 // pre-calculate size to avoid reallocations.
58 size := 1 + 4 + 4
59 for _, ring := range p {
60 size += 4 + len(ring)*2*8
61 }
62
63 buf := bytes.NewBuffer(make([]byte, 0, size))
64
65 binary.Write(buf, binary.LittleEndian, wkbNDR)
66 binary.Write(buf, binary.LittleEndian, wkbPolygon)
67 binary.Write(buf, binary.LittleEndian, uint32(len(p)))
68
69 for _, ring := range p {
70 binary.Write(buf, binary.LittleEndian, uint32(len(ring)))
71 for _, v := range ring {
72 binary.Write(buf, binary.LittleEndian, math.Float64bits(v.X))
73 binary.Write(buf, binary.LittleEndian, math.Float64bits(v.Y))
74 }
75 }
76
77 return buf.Bytes()
78 }