Mercurial > gemma
view pkg/controllers/cross.go @ 676:bd215c4325ce
Cross sections: Only join point in x/y plane.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 19 Sep 2018 16:09:09 +0200 |
parents | 288c496eca26 |
children | bb0788567609 |
line wrap: on
line source
package controllers import ( "database/sql" "log" "net/http" "time" "gemma.intevation.de/gemma/pkg/models" ) const crossSQL = ` WITH line AS ( SELECT ST_3DIntersection( ST_Translate( ST_Extrude( ST_GeomFromWKB($1, 4326), 0, 0, 1000), 0, 0, -500), geom) AS geom FROM waterway.meshes m JOIN waterway.sounding_results sr ON m.sounding_result_id = sr.id WHERE ST_Intersects(geom, ST_GeomFromWKB($1, 4326)) AND sr.bottleneck_id = $2 AND sr.date_info = $3 ) SELECT ST_AsBinary((ST_Dump(ST_Intersection(line.geom, sr.area::geometry))).geom) FROM line, waterway.sounding_results sr WHERE sr.bottleneck_id = $2 AND sr.date_info = $3 ` func crossSection( input interface{}, req *http.Request, db *sql.Conn, ) (jr JSONResult, err error) { csi := input.(*models.CrossSectionInput) start := time.Now() var rows *sql.Rows if rows, err = db.QueryContext( req.Context(), crossSQL, csi.Geometry.Coordinates.AsWKB(), csi.Properties.Bottleneck, csi.Properties.Date.Time, ); err != nil { return } defer rows.Close() var segments models.GeoJSONMultiLineCoordinatesZ for rows.Next() { var segment models.GeoJSONLineCoordinatesZ if err = rows.Scan(&segment); err != nil { return } segments = append(segments, segment) } if err = rows.Err(); err != nil { return } log.Printf("query took: %v\n", time.Since(start)) start = time.Now() joined := segments.Join() log.Printf("joining took: %v\n", time.Since(start)) log.Printf("segments before/after: %d %d\n", len(segments), len(joined)) /* if err2 := dumpProfile( csi.Geometry.Coordinates[0], csi.Geometry.Coordinates[len(csi.Geometry.Coordinates)-1], joined, ); err2 != nil { log.Printf("error: %v\n", err2) } */ jr = JSONResult{ Result: &models.CrossSectionOutput{ Type: "Feature", Geometry: models.CrossSectionOutputGeometry{ Type: "MultiLineString", Coordinates: joined, }, Properties: map[string]interface{}{}, }, } return } /* func dumpProfile( start models.GeoJSONCoordinate, stop models.GeoJSONCoordinate, segments models.GeoJSONMultiLineCoordinatesZ, ) error { w, err := os.Create("/tmp/cross.txt") if err != nil { return err } defer w.Close() begin := models.GeoJSONCoordinateZ{ Lat: start.Lat, Lon: start.Lon, } end := models.GeoJSONCoordinateZ{ Lat: stop.Lat, Lon: stop.Lon, } last := begin var total float64 minz := 10000.0 for _, line := range segments { for _, coord := range line { if coord.Z < minz { minz = coord.Z } total += last.Distance(coord) last = coord } } log.Printf("length: %.3f minz: %f\n", total, minz) var pos float64 for i, line := range segments { for j, coord := range line { if i == 0 && j == 0 { if !begin.Equals(coord) { pos = begin.Distance(coord) fmt.Fprintf(w, "%.3f %f\n", 0.0, 200.0) fmt.Fprintf(w, "%.3f %f\n", pos-0.0001, 200.0) fmt.Fprintf(w, "%.3f %f\n", pos, coord.Z-minz) continue } } else if j == 0 { fmt.Fprintf(w, "%.3f %f\n", pos+0.0001, 200.0) fmt.Fprintf(w, "%.3f %f\n", pos+last.Distance(coord)-0.0001, 200.0) continue } pos += last.Distance(coord) fmt.Fprintf(w, "%.3f %f\n", pos, coord.Z-minz) last = coord } } if !last.Equals(end) { fmt.Fprintf(w, "%.3f %f\n", pos+0.0001, 200.0) fmt.Fprintf(w, "%.3f %f\n", pos+last.Distance(end), 200.0) } return nil } */