Mercurial > gemma
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 } |