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