Mercurial > gemma
view pkg/controllers/cross.go @ 904:e4b72a199258
New default bottleneck colors
Mainly to make the stroke color one actually selectable in the ui.
In addition the pink does better match the collors used on the ECDIS layer.
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Tue, 02 Oct 2018 13:34:59 +0200 |
parents | 03e966b71a88 |
children | a244b18cb916 |
line wrap: on
line source
package controllers import ( "context" "database/sql" "fmt" "log" "net/http" "time" "gemma.intevation.de/gemma/pkg/models" "gemma.intevation.de/gemma/pkg/octree" ) const WGS84 = 4326 func reproject( rp *models.Reprojector, src models.GeoJSONLineCoordinates, ctx context.Context, ) (models.GeoJSONLineCoordinates, error) { dst := make(models.GeoJSONLineCoordinates, len(src)) for i, s := range src { var err error if dst[i].Lat, dst[i].Lon, err = rp.Reproject( s.Lat, s.Lon, ctx, ); err != nil { return nil, err } } return dst, nil } func projectBack( rp *models.Reprojector, lines octree.MultiLineStringZ, ctx context.Context, ) (models.GeoJSONMultiLineCoordinatesZ, error) { out := make(models.GeoJSONMultiLineCoordinatesZ, len(lines)) for i, segment := range lines { coords := make(models.GeoJSONLineCoordinatesZ, len(segment)) out[i] = coords for j, v := range segment { lat, lon, err := rp.Reproject(v.X, v.Y, ctx) if err != nil { return nil, err } coords[j] = models.GeoJSONCoordinateZ{Lat: lat, Lon: lon, Z: v.Z} } } return out, nil } const clipSQL = ` SELECT ST_AsBinary(ST_Transform(ST_Multi(ST_Intersection( ST_Transform(area::geometry, $1::integer), ST_GeomFromWKB($2, $1::integer))), 4326)) FROM waterway.sounding_results WHERE bottleneck_id = $3 AND date_info = $4::date` func clipAgainstArea( line octree.MultiLineStringZ, epsg uint32, bottleneck string, dateInfo time.Time, conn *sql.Conn, ctx context.Context, ) (models.GeoJSONMultiLineCoordinatesZ, error) { var mls models.GeoJSONMultiLineCoordinatesZ err := conn.QueryRowContext( ctx, clipSQL, epsg, line.AsWKB(), bottleneck, dateInfo, ).Scan(&mls) return mls, err } func crossSection( input interface{}, req *http.Request, conn *sql.Conn, ) (jr JSONResult, err error) { csi := input.(*models.CrossSectionInput) start := time.Now() tree, err := octree.Cache.Get( csi.Properties.Bottleneck, csi.Properties.Date.Time, conn, req.Context()) log.Printf("loading octree took: %s\n", time.Since(start)) if err != nil { return } if tree == nil { err = JSONError{ Code: http.StatusNotFound, Message: fmt.Sprintf("Cannot find survey for %s/%s.", csi.Properties.Bottleneck, csi.Properties.Date.Time), } return } // The coordinate system of the octree is an UTM projection. // The input coordinates are in WGS84. // So we need to reproject them. start = time.Now() var rp *models.Reprojector if rp, err = models.NewReprojector( conn, req.Context(), WGS84, tree.EPSG, ); err != nil { return } defer rp.Close() coords, err := reproject(rp, csi.Geometry.Coordinates, req.Context()) log.Printf("transforming input coords took: %s\n", time.Since(start)) if err != nil { return } start = time.Now() var segments octree.MultiLineStringZ for i := 0; i < len(coords)-1; i++ { c1 := &coords[i] c2 := &coords[i+1] verticalLine := octree.NewVerticalLine(c1.Lat, c1.Lon, c2.Lat, c2.Lon) var line octree.MultiLineStringZ tree.Vertical(c1.Lat, c1.Lon, c2.Lat, c2.Lon, func(t *octree.Triangle) { if ls := verticalLine.Intersection(t); len(ls) > 0 { line = append(line, ls) } }) if len(line) > 0 { log.Printf("line length: %d\n", len(line)) // They are all on the segment (c1.Lat, c1.Lon) - (c2.Lat, c2.Lon). // Sort them by project them on this line. joined := line.JoinOnLine(c1.Lat, c1.Lon, c2.Lat, c2.Lon) log.Printf("joined length: %d\n", len(joined)) segments = append(segments, joined...) } } log.Printf("octree traversal took: %s\n", time.Since(start)) start = time.Now() var joined models.GeoJSONMultiLineCoordinatesZ joined, err = clipAgainstArea( segments, tree.EPSG, csi.Properties.Bottleneck, csi.Properties.Date.Time, conn, req.Context(), ) log.Printf("clipping and projecting back took: %s\n", time.Since(start)) if err != nil { return } jr = JSONResult{ Result: &models.CrossSectionOutput{ Type: "Feature", Geometry: models.CrossSectionOutputGeometry{ Type: "MultiLineString", Coordinates: joined, }, Properties: map[string]interface{}{}, }, } return }