Mercurial > gemma
changeset 971:f9fb6c399f3f
Moved generating of tins to octree package.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 18 Oct 2018 11:52:13 +0200 |
parents | 166782ebab96 |
children | 17a03a84b0e8 |
files | cmd/tin2octree/main.go pkg/imports/sr.go pkg/octree/tin.go |
diffstat | 3 files changed, 101 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/cmd/tin2octree/main.go Thu Oct 18 10:14:46 2018 +0200 +++ b/cmd/tin2octree/main.go Thu Oct 18 11:52:13 2018 +0200 @@ -2,6 +2,7 @@ import ( "bytes" + "context" "crypto/sha1" "database/sql" "encoding/base64" @@ -54,23 +55,6 @@ } const ( - tinUTMSQL = ` -WITH trans AS ( - SELECT - ST_Buffer(ST_Transform(area::geometry, $3::int), 0.001) AS area, - ST_Transform(point_cloud::geometry, $3::int) AS point_cloud - FROM waterway.sounding_results - WHERE bottleneck_id = $1 AND date_info = $2 -), -triangles AS ( - SELECT t.geom AS geom, ST_MakePolygon(ST_ExteriorRing(t.geom)) AS poly FROM ( - SELECT (st_dump( - ST_DelaunayTriangles(point_cloud, 0, 2))).geom - FROM trans) t -) -SELECT ST_AsBinary(ST_Collect(triangles.geom)) FROM triangles, trans -WHERE st_covers(trans.area, triangles.poly)` - centroidSQL = ` SELECT ST_X(ST_Centroid(point_cloud::geometry)), ST_Y(ST_Centroid(point_cloud::geometry)) FROM waterway.sounding_results @@ -78,14 +62,14 @@ ` ) -func utmZone(x, y float64) int { - var pref int +func utmZone(x, y float64) uint32 { + var pref uint32 if y > 0 { pref = 32600 } else { pref = 32700 } - zone := int(math.Floor((x+180)/6)) + 1 + zone := uint32(math.Floor((x+180)/6)) + 1 return zone + pref } @@ -101,13 +85,21 @@ log.Fatalf("error: %v\n", err) } - var t octree.Tin + var t *octree.Tin + + ctx := context.Background() if err := run(func(db *sql.DB) error { - var utmZ int + conn, err := db.Conn(ctx) + if err != nil { + return err + } + defer conn.Close() + var utmZ uint32 var cx, cy float64 - err := db.QueryRow(centroidSQL, *bottleneck, dateInfo).Scan(&cx, &cy) + + conn.QueryRowContext(ctx, centroidSQL, *bottleneck, dateInfo).Scan(&cx, &cy) switch { case err == sql.ErrNoRows: return nil @@ -119,23 +111,19 @@ log.Printf("UTM zone: %d\n", utmZ) start := time.Now() - err = db.QueryRow(tinUTMSQL, *bottleneck, dateInfo, utmZ).Scan(&t) - switch { - case err == sql.ErrNoRows: - return nil - case err != nil: - return err - } + t, err = octree.GenerateTin(conn, ctx, *bottleneck, dateInfo, utmZ) log.Printf("query took: %s\n", time.Since(start)) - - t.EPSG = uint32(utmZ) - - return nil + return err }); err != nil { log.Fatalf("error: %v\n", err) } - tb := octree.NewBuilder(&t) + if t == nil { + log.Fatalf("error: No such sounding result (%s, %s)\n", + *bottleneck, dateInfo) + } + + tb := octree.NewBuilder(t) tb.Build() if *insert {
--- a/pkg/imports/sr.go Thu Oct 18 10:14:46 2018 +0200 +++ b/pkg/imports/sr.go Thu Oct 18 11:52:13 2018 +0200 @@ -75,7 +75,13 @@ ST_Transform(ST_GeomFromWKB($5, $6::integer), 4326)::geography END) ) -RETURNING id` +RETURNING + id, + CASE WHEN ST_Y(ST_Centroid(point_cloud::geometry)) > 0 THEN + 32600 + ELSE + 32700 + END + floor((ST_X(ST_Centroid(point_cloud::geometry))+180)/6)::int + 1` ) func (srd *SoundingResultDate) UnmarshalJSON(data []byte) error { @@ -308,19 +314,21 @@ defer tx.Rollback() var id int64 + var epsg uint32 - err = tx.QueryRow(insertPointsSQL, + if err := tx.QueryRow(insertPointsSQL, m.Bottleneck, m.Date.Time, m.DepthReference, xyz.AsWKB(), polygon.AsWBK(), - m.EPSG).Scan(&id) - - if err != nil { + m.EPSG, + ).Scan(&id, &epsg); err != nil { return err } + log.Printf("EPSG: %d\n", epsg) + // TODO: Build octree // TODO: Generate iso-lines
--- a/pkg/octree/tin.go Thu Oct 18 10:14:46 2018 +0200 +++ b/pkg/octree/tin.go Thu Oct 18 11:52:13 2018 +0200 @@ -2,12 +2,15 @@ import ( "bytes" + "context" + "database/sql" "encoding/binary" "errors" "fmt" "io" "log" "math" + "time" ) var ( @@ -165,8 +168,69 @@ return nil } +const ( + tinSQLPrefix = `WITH trans AS ( + SELECT + ST_Buffer(ST_Transform(area::geometry, $1::int), 0.001) AS area, + ST_Transform(point_cloud::geometry, $1::int) AS point_cloud + FROM waterway.sounding_results +` + tinSQLSuffix = ` +), +triangles AS ( + SELECT t.geom AS geom, ST_MakePolygon(ST_ExteriorRing(t.geom)) AS poly FROM ( + SELECT (ST_Dump( + ST_DelaunayTriangles(point_cloud, 0, 2))).geom + FROM trans) t +) +SELECT ST_AsBinary(ST_Collect(triangles.geom)) FROM triangles, trans +WHERE ST_Covers(trans.area, triangles.poly)` + + loadTinSQL = tinSQLPrefix + `WHERE bottleneck_id = $2 AND date_info = $3` + tinSQLSuffix + loadTinByIDSQL = tinSQLPrefix + `WHERE id = $2` + tinSQLSuffix +) + +func GenerateTin( + conn *sql.Conn, + ctx context.Context, + bottleneck string, + date time.Time, + epsg uint32, +) (*Tin, error) { + var tin Tin + err := conn.QueryRowContext(ctx, loadTinSQL, epsg, bottleneck, date).Scan(&tin) + switch { + case err == sql.ErrNoRows: + return nil, nil + case err != nil: + return nil, err + } + tin.EPSG = epsg + return &tin, nil +} + +func GenerateTinByID( + conn *sql.Conn, + ctx context.Context, + id int64, + epsg uint32, +) (*Tin, error) { + var tin Tin + err := conn.QueryRowContext(ctx, loadTinByIDSQL, epsg, id).Scan(&tin) + switch { + case err == sql.ErrNoRows: + return nil, nil + case err != nil: + return nil, err + } + tin.EPSG = epsg + return &tin, nil +} + func (t *Tin) Scan(raw interface{}) error { - + if raw == nil { + return nil + } data, ok := raw.([]byte) if !ok { return errNoByteSlice