comparison 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
comparison
equal deleted inserted replaced
660:79db27e3a999 661:af1d4d44a88a
1 package main
2
3 import (
4 "bufio"
5 "database/sql"
6 "flag"
7 "io"
8 "log"
9 "os"
10 "time"
11
12 "github.com/golang/snappy"
13 "github.com/jackc/pgx"
14 "github.com/jackc/pgx/stdlib"
15 )
16
17 var (
18 bottleneck = flag.String("bottleneck", "", "bottleneck id")
19 date = flag.String("date", "", "date info")
20 file = flag.String("file", "", "save to file")
21
22 snap = flag.Bool("snappy", false, "use snappy compression")
23 dbhost = flag.String("dbhost", "localhost", "database host")
24 dbport = flag.Uint("dbport", 5432, "database port")
25 dbname = flag.String("dbname", "gemma", "database user")
26 dbuser = flag.String("dbuser", "scott", "database user")
27 dbpassword = flag.String("dbpw", "tiger", "database password")
28 dbssl = flag.String("dbssl", "prefer", "database SSL mode")
29 )
30
31 func run(fn func(*sql.DB) error) error {
32
33 // To ease SSL config ride a bit on parsing.
34 cc, err := pgx.ParseConnectionString("sslmode=" + *dbssl)
35 if err != nil {
36 return err
37 }
38
39 // Do the rest manually to allow whitespace in user/password.
40 cc.Host = *dbhost
41 cc.Port = uint16(*dbport)
42 cc.User = *dbuser
43 cc.Password = *dbpassword
44 cc.Database = *dbname
45
46 db := stdlib.OpenDB(cc)
47 defer db.Close()
48
49 return fn(db)
50 }
51
52 const tinSQL = `
53 SELECT ST_AsBinary(ST_DelaunayTriangles(point_cloud::geometry, 0, 2))
54 FROM waterway.sounding_results
55 WHERE bottleneck_id = $1 AND date_info = $2
56 `
57
58 func main() {
59 flag.Parse()
60
61 if *bottleneck == "" || *date == "" {
62 log.Fatalln("missing bottleneck or date option.")
63 }
64
65 dateInfo, err := time.Parse("2006-01-02", *date)
66 if err != nil {
67 log.Fatalf("error: %v\n", err)
68 }
69
70 var t tin
71
72 if err := run(func(db *sql.DB) error {
73 start := time.Now()
74 err := db.QueryRow(tinSQL, *bottleneck, dateInfo).Scan(&t)
75 switch {
76 case err == sql.ErrNoRows:
77 return nil
78 case err != nil:
79 return err
80 }
81 log.Printf("query took: %s\n", time.Since(start))
82 return nil
83 }); err != nil {
84 log.Fatalf("error: %v\n", err)
85 }
86
87 tb := &treeBuilder{t: &t}
88 tb.build()
89
90 if *file != "" {
91 f, err := os.Create(*file)
92 if err != nil {
93 log.Printf("error: %v\n", err)
94 }
95 type flusher interface {
96 io.Writer
97 Flush() error
98 }
99 var out flusher
100 if *snap {
101 out = snappy.NewBufferedWriter(f)
102 } else {
103 out = bufio.NewWriter(f)
104 }
105 if err := t.Serialize(out); err != nil {
106 f.Close()
107 log.Fatalf("error: %v\n", err)
108 }
109 if err := tb.Serialize(out); err != nil {
110 f.Close()
111 log.Fatalf("error: %v\n", err)
112 }
113 if err := out.Flush(); err != nil {
114 f.Close()
115 log.Fatalf("error: %v\n", err)
116 }
117 if err := f.Close(); err != nil {
118 log.Fatalf("error: %v\n", err)
119 }
120 }
121 }