comparison pkg/imports/sr.go @ 3600:6590733e2ebc

SR import: If in single beam mode and no boundary is given eliminate triangles which have at least an edge with is longer than 98% of the overall edge lengths.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 04 Jun 2019 18:37:15 +0200
parents eeeb7bf14217
children 6248a4bc10c7
comparison
equal deleted inserted replaced
3599:73add36de413 3600:6590733e2ebc
26 "io" 26 "io"
27 "math" 27 "math"
28 "os" 28 "os"
29 "path" 29 "path"
30 "path/filepath" 30 "path/filepath"
31 "sort"
31 "strconv" 32 "strconv"
32 "strings" 33 "strings"
33 "time" 34 "time"
34 35
35 shp "github.com/jonas-p/go-shp" 36 shp "github.com/jonas-p/go-shp"
37 "gonum.org/v1/gonum/stat"
36 38
37 "gemma.intevation.de/gemma/pkg/common" 39 "gemma.intevation.de/gemma/pkg/common"
38 "gemma.intevation.de/gemma/pkg/misc" 40 "gemma.intevation.de/gemma/pkg/misc"
39 "gemma.intevation.de/gemma/pkg/models" 41 "gemma.intevation.de/gemma/pkg/models"
40 "gemma.intevation.de/gemma/pkg/octree" 42 "gemma.intevation.de/gemma/pkg/octree"
174 AND grwl.validity = bns.gauge_validity 176 AND grwl.validity = bns.gauge_validity
175 WHERE bns.objnam = $1 AND grwl.depth_reference like 'LDC%' 177 WHERE bns.objnam = $1 AND grwl.depth_reference like 'LDC%'
176 ` 178 `
177 179
178 reprojectPointsSingleBeamSQL = ` 180 reprojectPointsSingleBeamSQL = `
179 SELECT ST_AsBinary( 181 SELECT
180 ST_Transform( 182 ST_AsBinary(
181 ST_GeomFromWKB($1, $2::integer), 183 ST_Transform(
182 best_utm(CAST(ST_GeomFromWKB($1, $2::integer) AS geography))), 184 ST_GeomFromWKB($1, $2::integer),
183 best_utm(CAST(ST_GeomFromWKB($1, $2::integer) AS geography)) 185 best_utm(CAST(ST_Transform(ST_GeomFromWKB($1, $2::integer), 4326) AS geography)))),
186 best_utm(CAST(ST_Transform(ST_GeomFromWKB($1, $2::integer), 4326) AS geography))
184 ` 187 `
185 ) 188 )
186 189
187 func (sr *SoundingResult) isSingleBeam() bool { 190 func (sr *SoundingResult) isSingleBeam() bool {
188 return sr.SingleBeam != nil && *sr.SingleBeam 191 return sr.SingleBeam != nil && *sr.SingleBeam
203 return nil, err 206 return nil, err
204 } 207 }
205 defer z.Close() 208 defer z.Close()
206 209
207 feedback.Info("Looking for 'meta.json'") 210 feedback.Info("Looking for 'meta.json'")
211
208 mf := common.FindInZIP(z, "meta.json") 212 mf := common.FindInZIP(z, "meta.json")
209 if mf == nil && !sr.completeOverride() { 213 if mf == nil && !sr.completeOverride() {
210 return nil, errors.New("Cannot find 'meta.json'") 214 return nil, errors.New("Cannot find 'meta.json'")
211 } 215 }
212 216
340 m.EPSG, 344 m.EPSG,
341 ).Scan(&reproj, &epsg); err != nil { 345 ).Scan(&reproj, &epsg); err != nil {
342 return nil, err 346 return nil, err
343 } 347 }
344 348
349 if err := xyz.FromWKB(reproj); err != nil {
350 return nil, err
351 }
352
345 feedback.Info("Reprojecting points to EPSG %d took %v.", 353 feedback.Info("Reprojecting points to EPSG %d took %v.",
346 epsg, time.Since(start)) 354 epsg, time.Since(start))
355 feedback.Info("Number of reprojected points: %d", len(xyz))
356
357 start = time.Now()
358 tri, err := octree.Triangulate(xyz)
359 if err != nil {
360 return nil, err
361 }
362 feedback.Info("Triangulation took %v.", time.Since(start))
363 feedback.Info("Number triangles: %d.", len(tri.Triangles)/3)
364
365 if boundary == nil {
366 feedback.Info("No boundary given.")
367 feedback.Info("Eliminate triangles with long edges.")
368
369 lens := make([]float64, len(tri.Triangles)/3)
370 for i := 0; i < len(tri.Triangles); i += 3 {
371 vs := tri.Triangles[i : i+3]
372 var max float64
373 for j := 0; j < 3; j++ {
374 k := (j + 1) % 3
375 if l := tri.Points[vs[j]].SquaredDistance2D(tri.Points[vs[k]]); l > max {
376 max = l
377 }
378 }
379 lens[i/3] = max
380 }
381 qs := make([]float64, len(lens))
382 copy(qs, lens)
383 sort.Float64s(qs)
384 q := stat.Quantile(0.98, stat.LinInterp, qs, nil)
385 feedback.Info("98%% quantile of the edge lengths: %.2f\n", math.Sqrt(q))
386
387 ts := tri.Triangles
388
389 for i := len(lens) - 1; i >= 0; i-- {
390 if lens[i] >= q {
391 if i != len(lens)-1 {
392 copy(ts[i*3:], ts[(i+1)*3:])
393 }
394 ts = ts[:len(ts)-3]
395 }
396 }
397 feedback.Info("Remaining triangles: %d (%.2f%%)\n",
398 len(ts)/3, float64(len(ts))/float64(len(tri.Triangles))*100.0)
399 }
347 400
348 // TODO: Implement me! 401 // TODO: Implement me!
349 return nil, errors.New("Not implemented, yet!") 402 return nil, errors.New("Not implemented, yet!")
350 } 403 }
351 404