Mercurial > gemma
view cmd/octreediff/main.go @ 2468:27cc04bbda46 octree-diff
Bail out if the EPSG codes of the datasets don't match.
Need to implement a transformation slow pass to make this work.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 25 Feb 2019 21:51:39 +0100 |
parents | dbdc50d9e0f8 |
children | 1312953defab |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package main import ( "context" "database/sql" "errors" "flag" "fmt" "log" "runtime" "sync" "time" "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/octree" ) var ( bottleneck = flag.String("bottleneck", "", "name of the bottleneck") first = flag.String("first", "", "date of the first sounding result") second = flag.String("second", "", "date of the second sounding result") ) const ( loadOctreeSQL = ` SELECT sr.octree_index FROM waterway.sounding_results sr JOIN waterway.bottlenecks bn ON sr.bottleneck_id = bn.id WHERE bn.bottleneck_id = $1 AND sr.date_info = $2::date AND sr.octree_index IS NOT NULL` ) func check(err error) { if err != nil { log.Fatalf("error: %v\n", err) } } func process(bottleneck string, firstDate, secondDate time.Time) error { start := time.Now() defer func() { log.Printf("processing took %v\n", time.Since(start)) }() ctx := context.Background() return run(func(db *sql.DB) error { conn, err := db.Conn(ctx) if err != nil { return err } defer conn.Close() type load struct { date time.Time data []byte err *error dst **octree.Tree } out := make(chan *load) wg := new(sync.WaitGroup) n := runtime.NumCPU() if n > 2 { n = 2 } for i := 0; i < n; i++ { wg.Add(1) go func() { defer wg.Done() for l := range out { if *l.err == nil { *l.dst, *l.err = octree.Deserialize(l.data) } } }() } var firstErr, secondErr error var first, second *octree.Tree for _, l := range []*load{ {date: firstDate, dst: &first, err: &firstErr}, {date: secondDate, dst: &second, err: &secondErr}, } { var data []byte if err := conn.QueryRowContext( ctx, loadOctreeSQL, bottleneck, l.date, ).Scan(&data); err != nil { *l.err = err } else { l.data = data } out <- l } close(out) wg.Wait() if firstErr != nil || secondErr != nil { if firstErr != nil && secondErr != nil { return fmt.Errorf("%v, %v", firstErr, secondErr) } if firstErr != nil { return firstErr } return secondErr } if first.EPSG != second.EPSG { return errors.New("EPSG codes mismatch. Needs transformation slow pass.") } log.Printf("loading took %v\n", time.Since(start)) setin := time.Now() vf := first.Vertices() nvf := make([]octree.Vertex, 0, len(vf)) for i := range vf { v := &vf[i] if z, found := second.Value(v.X, v.Y); found { nvf = append(nvf, octree.Vertex{v.X, v.Y, v.Z - z}) } } vs := second.Vertices() nsf := make([]octree.Vertex, 0, len(vs)) for i := range vs { v := &vs[i] if z, found := first.Value(v.X, v.Y); found { nsf = append(nsf, octree.Vertex{v.X, v.Y, z - v.Z}) } } log.Printf("setting in took %v\n", time.Since(setin)) log.Printf("new vertices first: %d\n", len(nvf)) log.Printf("new vertices second: %d\n", len(nsf)) return nil }) } func main() { flag.Parse() firstDate, err := time.Parse(common.DateFormat, *first) check(err) secondDate, err := time.Parse(common.DateFormat, *second) check(err) if *bottleneck == "" { log.Fatalln("Missing bottleneck name") } check(process(*bottleneck, firstDate, secondDate)) }