comparison pkg/imports/sr.go @ 1224:bc4b642c8d04

Started with an upload sounding result to temp upload area.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 19 Nov 2018 17:14:42 +0100
parents 58acc343b1b6
children 4d7c44f7044e
comparison
equal deleted inserted replaced
1223:a20fcfacda98 1224:bc4b642c8d04
18 "bufio" 18 "bufio"
19 "context" 19 "context"
20 "crypto/sha1" 20 "crypto/sha1"
21 "database/sql" 21 "database/sql"
22 "encoding/hex" 22 "encoding/hex"
23 "encoding/json"
24 "errors" 23 "errors"
25 "fmt" 24 "fmt"
26 "io" 25 "io"
27 "math" 26 "math"
28 "os" 27 "os"
32 "strings" 31 "strings"
33 "time" 32 "time"
34 33
35 shp "github.com/jonas-p/go-shp" 34 shp "github.com/jonas-p/go-shp"
36 35
36 "gemma.intevation.de/gemma/pkg/common"
37 "gemma.intevation.de/gemma/pkg/models"
37 "gemma.intevation.de/gemma/pkg/octree" 38 "gemma.intevation.de/gemma/pkg/octree"
38 ) 39 )
39 40
40 type SoundingResult string 41 type SoundingResult string
41
42 const SoundingResultDateFormat = "2006-01-02"
43
44 type (
45 SoundingResultDate struct{ time.Time }
46
47 SoundingResultMeta struct {
48 Date SoundingResultDate `json:"date"`
49 Bottleneck string `json:"bottleneck"`
50 EPSG uint `json:"epsg"`
51 DepthReference string `json:"depth-reference"`
52 }
53 )
54
55 const wgs84 = 4326
56 42
57 const ( 43 const (
58 contourStepWidth = 0.1 44 contourStepWidth = 0.1
59 contourTolerance = 0.1 45 contourTolerance = 0.1
60 ) 46 )
90 76
91 const ( 77 const (
92 srStageDoneSQL = ` 78 srStageDoneSQL = `
93 UPDATE waterway.sounding_results SET staging_done = true 79 UPDATE waterway.sounding_results SET staging_done = true
94 WHERE id = $1` 80 WHERE id = $1`
95
96 checkDepthReferenceSQL = `
97 SELECT true FROM depth_references WHERE depth_reference = $1`
98
99 checkBottleneckSQL = `
100 SELECT true FROM waterway.bottlenecks WHERE objnam = $1`
101 81
102 insertPointsSQL = ` 82 insertPointsSQL = `
103 INSERT INTO waterway.sounding_results ( 83 INSERT INTO waterway.sounding_results (
104 bottleneck_id, 84 bottleneck_id,
105 date_info, 85 date_info,
180 m, err := loadMeta(mf) 160 m, err := loadMeta(mf)
181 if err != nil { 161 if err != nil {
182 return err 162 return err
183 } 163 }
184 164
185 if err := m.validate(conn); err != nil { 165 if err := m.Validate(conn, ctx); err != nil {
186 return err 166 return common.ToError(err)
187 } 167 }
188 168
189 feedback.Info("Looking for '*.xyz'") 169 feedback.Info("Looking for '*.xyz'")
190 xyzf := find(".xyz", z.File) 170 xyzf := find(".xyz", z.File)
191 if xyzf == nil { 171 if xyzf == nil {
287 feedback.Info("Storing sounding result was successful.") 267 feedback.Info("Storing sounding result was successful.")
288 } 268 }
289 return err 269 return err
290 } 270 }
291 271
292 func (srd *SoundingResultDate) UnmarshalJSON(data []byte) error {
293 var s string
294 if err := json.Unmarshal(data, &s); err != nil {
295 return err
296 }
297 d, err := time.Parse(SoundingResultDateFormat, s)
298 if err == nil {
299 *srd = SoundingResultDate{d}
300 }
301 return err
302 }
303
304 func (sr SoundingResult) CleanUp() error { 272 func (sr SoundingResult) CleanUp() error {
305 return os.RemoveAll(string(sr)) 273 return os.RemoveAll(string(sr))
306 } 274 }
307 275
308 func find(needle string, haystack []*zip.File) *zip.File { 276 func find(needle string, haystack []*zip.File) *zip.File {
313 } 281 }
314 } 282 }
315 return nil 283 return nil
316 } 284 }
317 285
318 func loadMeta(f *zip.File) (*SoundingResultMeta, error) { 286 func loadMeta(f *zip.File) (*models.SoundingResultMeta, error) {
319 r, err := f.Open() 287 r, err := f.Open()
320 if err != nil { 288 if err != nil {
321 return nil, err 289 return nil, err
322 } 290 }
323 defer r.Close() 291 defer r.Close()
324 var m SoundingResultMeta 292 var m models.SoundingResultMeta
325 err = json.NewDecoder(r).Decode(&m) 293 return &m, m.Decode(r)
326 if err == nil {
327 if m.EPSG == 0 {
328 m.EPSG = wgs84
329 }
330 }
331 return &m, err
332 }
333
334 func (m *SoundingResultMeta) validate(conn *sql.Conn) error {
335
336 var b bool
337 err := conn.QueryRowContext(context.Background(),
338 checkDepthReferenceSQL,
339 m.DepthReference).Scan(&b)
340 switch {
341 case err == sql.ErrNoRows:
342 return fmt.Errorf("Unknown depth reference '%s'\n", m.DepthReference)
343 case err != nil:
344 return err
345 case !b:
346 return errors.New("Unexpected depth reference")
347 }
348
349 err = conn.QueryRowContext(context.Background(),
350 checkBottleneckSQL,
351 m.Bottleneck).Scan(&b)
352 switch {
353 case err == sql.ErrNoRows:
354 return fmt.Errorf("Unknown bottleneck '%s'\n", m.Bottleneck)
355 case err != nil:
356 return err
357 case !b:
358 return errors.New("Unexpected bottleneck")
359 }
360
361 return nil
362 } 294 }
363 295
364 func loadXYZReader(r io.Reader, feedback Feedback) (octree.MultiPointZ, error) { 296 func loadXYZReader(r io.Reader, feedback Feedback) (octree.MultiPointZ, error) {
365 mpz := make(octree.MultiPointZ, 0, 250000) 297 mpz := make(octree.MultiPointZ, 0, 250000)
366 s := bufio.NewScanner(r) 298 s := bufio.NewScanner(r)