Mercurial > gemma
comparison pkg/imports/wkb.go @ 1786:09349ca27dd7
Imports: Removed duplicated code path to store WKB polygons into database.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sun, 13 Jan 2019 13:02:39 +0100 |
parents | 614c6c766691 |
children | f54ac71db1ac |
comparison
equal
deleted
inserted
replaced
1785:614c6c766691 | 1786:09349ca27dd7 |
---|---|
23 ) | 23 ) |
24 | 24 |
25 type ( | 25 type ( |
26 lineSlice [][]float64 | 26 lineSlice [][]float64 |
27 polygonSlice [][][]float64 | 27 polygonSlice [][][]float64 |
28 | |
29 point struct { | |
30 X float64 | |
31 Y float64 | |
32 } | |
33 lineString []point | |
34 polygon []lineString | |
35 ) | 28 ) |
36 | 29 |
37 const ( | 30 const ( |
38 wkbNDR byte = 1 | 31 wkbNDR byte = 1 |
39 | 32 |
98 } | 91 } |
99 | 92 |
100 return buf.Bytes() | 93 return buf.Bytes() |
101 } | 94 } |
102 | 95 |
103 func shapeToPolygon(s shp.Shape) (polygon, error) { | 96 func shapeToPolygon(s shp.Shape) (polygonSlice, error) { |
104 switch p := s.(type) { | 97 switch p := s.(type) { |
105 case *shp.Polygon: | 98 case *shp.Polygon: |
106 return toPolygon(p.NumParts, p.Parts, p.Points), nil | 99 return toPolygon(p.NumParts, p.Parts, p.Points), nil |
107 case *shp.PolygonZ: | 100 case *shp.PolygonZ: |
108 return toPolygon(p.NumParts, p.Parts, p.Points), nil | 101 return toPolygon(p.NumParts, p.Parts, p.Points), nil |
110 return toPolygon(p.NumParts, p.Parts, p.Points), nil | 103 return toPolygon(p.NumParts, p.Parts, p.Points), nil |
111 } | 104 } |
112 return nil, fmt.Errorf("Unsupported shape type %T", s) | 105 return nil, fmt.Errorf("Unsupported shape type %T", s) |
113 } | 106 } |
114 | 107 |
115 func toPolygon(numParts int32, parts []int32, points []shp.Point) polygon { | 108 func toPolygon(numParts int32, parts []int32, points []shp.Point) polygonSlice { |
116 out := make(polygon, numParts) | 109 out := make(polygonSlice, numParts) |
117 var pos int32 | 110 var pos int32 |
118 | 111 |
119 for i := range out { | 112 for i := range out { |
120 var howMany int32 | 113 var howMany int32 |
121 if i+1 >= len(parts) { | 114 if i+1 >= len(parts) { |
122 howMany = int32(len(points)) - pos | 115 howMany = int32(len(points)) - pos |
123 } else { | 116 } else { |
124 howMany = parts[i+1] - parts[i] | 117 howMany = parts[i+1] - parts[i] |
125 } | 118 } |
126 | 119 |
127 line := make(lineString, howMany) | 120 line := make([][]float64, howMany) |
121 vertices := make([]float64, 2*howMany) | |
128 for j := int32(0); j < howMany; j, pos = j+1, pos+1 { | 122 for j := int32(0); j < howMany; j, pos = j+1, pos+1 { |
129 p := &points[pos] | 123 p := &points[pos] |
130 line[j] = point{p.X, p.Y} | 124 vertex := vertices[j*2 : j*2+2] |
125 vertex[0], vertex[1] = p.X, p.Y | |
126 line[j] = vertex | |
131 } | 127 } |
132 out[i] = line | 128 out[i] = line |
133 } | 129 } |
134 return out | 130 return out |
135 } | 131 } |
136 | |
137 func (p polygon) asWKB() []byte { | |
138 if p == nil { | |
139 return nil | |
140 } | |
141 // pre-calculate size to avoid reallocations. | |
142 size := 1 + 4 + 4 | |
143 for _, ring := range p { | |
144 size += 4 + len(ring)*2*8 | |
145 } | |
146 | |
147 buf := bytes.NewBuffer(make([]byte, 0, size)) | |
148 | |
149 binary.Write(buf, binary.LittleEndian, wkbNDR) | |
150 binary.Write(buf, binary.LittleEndian, wkbPolygon) | |
151 binary.Write(buf, binary.LittleEndian, uint32(len(p))) | |
152 | |
153 for _, ring := range p { | |
154 binary.Write(buf, binary.LittleEndian, uint32(len(ring))) | |
155 for _, v := range ring { | |
156 binary.Write(buf, binary.LittleEndian, math.Float64bits(v.X)) | |
157 binary.Write(buf, binary.LittleEndian, math.Float64bits(v.Y)) | |
158 } | |
159 } | |
160 | |
161 return buf.Bytes() | |
162 } |