Mercurial > gemma
diff cmd/tin2octree/main.go @ 661:af1d4d44a88a octree
Experimental tin octree indexer.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 18 Sep 2018 00:11:32 +0200 |
parents | |
children | a3d722e1f593 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmd/tin2octree/main.go Tue Sep 18 00:11:32 2018 +0200 @@ -0,0 +1,121 @@ +package main + +import ( + "bufio" + "database/sql" + "flag" + "io" + "log" + "os" + "time" + + "github.com/golang/snappy" + "github.com/jackc/pgx" + "github.com/jackc/pgx/stdlib" +) + +var ( + bottleneck = flag.String("bottleneck", "", "bottleneck id") + date = flag.String("date", "", "date info") + file = flag.String("file", "", "save to file") + + snap = flag.Bool("snappy", false, "use snappy compression") + dbhost = flag.String("dbhost", "localhost", "database host") + dbport = flag.Uint("dbport", 5432, "database port") + dbname = flag.String("dbname", "gemma", "database user") + dbuser = flag.String("dbuser", "scott", "database user") + dbpassword = flag.String("dbpw", "tiger", "database password") + dbssl = flag.String("dbssl", "prefer", "database SSL mode") +) + +func run(fn func(*sql.DB) error) error { + + // To ease SSL config ride a bit on parsing. + cc, err := pgx.ParseConnectionString("sslmode=" + *dbssl) + if err != nil { + return err + } + + // Do the rest manually to allow whitespace in user/password. + cc.Host = *dbhost + cc.Port = uint16(*dbport) + cc.User = *dbuser + cc.Password = *dbpassword + cc.Database = *dbname + + db := stdlib.OpenDB(cc) + defer db.Close() + + return fn(db) +} + +const tinSQL = ` +SELECT ST_AsBinary(ST_DelaunayTriangles(point_cloud::geometry, 0, 2)) +FROM waterway.sounding_results +WHERE bottleneck_id = $1 AND date_info = $2 +` + +func main() { + flag.Parse() + + if *bottleneck == "" || *date == "" { + log.Fatalln("missing bottleneck or date option.") + } + + dateInfo, err := time.Parse("2006-01-02", *date) + if err != nil { + log.Fatalf("error: %v\n", err) + } + + var t tin + + if err := run(func(db *sql.DB) error { + start := time.Now() + err := db.QueryRow(tinSQL, *bottleneck, dateInfo).Scan(&t) + switch { + case err == sql.ErrNoRows: + return nil + case err != nil: + return err + } + log.Printf("query took: %s\n", time.Since(start)) + return nil + }); err != nil { + log.Fatalf("error: %v\n", err) + } + + tb := &treeBuilder{t: &t} + tb.build() + + if *file != "" { + f, err := os.Create(*file) + if err != nil { + log.Printf("error: %v\n", err) + } + type flusher interface { + io.Writer + Flush() error + } + var out flusher + if *snap { + out = snappy.NewBufferedWriter(f) + } else { + out = bufio.NewWriter(f) + } + if err := t.Serialize(out); err != nil { + f.Close() + log.Fatalf("error: %v\n", err) + } + if err := tb.Serialize(out); err != nil { + f.Close() + log.Fatalf("error: %v\n", err) + } + if err := out.Flush(); err != nil { + f.Close() + log.Fatalf("error: %v\n", err) + } + if err := f.Close(); err != nil { + log.Fatalf("error: %v\n", err) + } + } +}