comparison pkg/controllers/cross.go @ 801:b6a1779ffb42

Removed old cross section controller.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 27 Sep 2018 13:18:50 +0200
parents pkg/controllers/octreecross.go@0cc97135717c
children e10a8a682297
comparison
equal deleted inserted replaced
800:0689f4b7c99f 801:b6a1779ffb42
1 package controllers 1 package controllers
2 2
3 import ( 3 import (
4 "context"
4 "database/sql" 5 "database/sql"
5 "log" 6 "log"
6 "net/http" 7 "net/http"
7 "time" 8 "time"
8 9
9 "gemma.intevation.de/gemma/pkg/models" 10 "gemma.intevation.de/gemma/pkg/models"
11 "gemma.intevation.de/gemma/pkg/octree"
10 ) 12 )
11 13
12 const crossSQL = ` 14 const WGS84 = 4326
13 WITH line AS ( 15
14 SELECT ST_LineMerge(ST_Union(ST_3DIntersection( 16 func reproject(
15 ST_Translate( 17 rp *models.Reprojector,
16 ST_Extrude( 18 src models.GeoJSONLineCoordinates,
17 ST_GeomFromWKB($1, 4326), 19 ctx context.Context,
18 0, 0, 1000), 20 ) (models.GeoJSONLineCoordinates, error) {
19 0, 0, -500), 21
20 geom))) AS geom 22 dst := make(models.GeoJSONLineCoordinates, len(src))
21 FROM waterway.meshes m JOIN waterway.sounding_results sr ON m.sounding_result_id = sr.id 23 for i, s := range src {
22 WHERE ST_Intersects(geom, ST_GeomFromWKB($1, 4326)) AND 24 var err error
23 sr.bottleneck_id = $2 AND sr.date_info = $3 25 if dst[i].Lat, dst[i].Lon, err = rp.Reproject(
24 ) 26 s.Lat, s.Lon, ctx,
25 SELECT ST_AsBinary((ST_Dump(ST_Intersection(line.geom, sr.area::geometry))).geom) 27 ); err != nil {
26 FROM line, waterway.sounding_results sr 28 return nil, err
27 WHERE sr.bottleneck_id = $2 AND sr.date_info = $3 29 }
28 ` 30 }
31 return dst, nil
32 }
33
34 func projectBack(
35 rp *models.Reprojector,
36 lines octree.MultiLineStringZ,
37 ctx context.Context,
38 ) (models.GeoJSONMultiLineCoordinatesZ, error) {
39
40 out := make(models.GeoJSONMultiLineCoordinatesZ, len(lines))
41
42 for i, segment := range lines {
43
44 coords := make(models.GeoJSONLineCoordinatesZ, len(segment))
45 out[i] = coords
46 for j, v := range segment {
47 lat, lon, err := rp.Reproject(v.X, v.Y, ctx)
48 if err != nil {
49 return nil, err
50 }
51 coords[j] = models.GeoJSONCoordinateZ{Lat: lat, Lon: lon, Z: v.Z}
52 }
53 }
54 return out, nil
55 }
29 56
30 func crossSection( 57 func crossSection(
31 input interface{}, 58 input interface{},
32 req *http.Request, 59 req *http.Request,
33 db *sql.Conn, 60 conn *sql.Conn,
34 ) (jr JSONResult, err error) { 61 ) (jr JSONResult, err error) {
35 62
36 csi := input.(*models.CrossSectionInput) 63 csi := input.(*models.CrossSectionInput)
37 64
38 start := time.Now() 65 start := time.Now()
39 66
40 var rows *sql.Rows 67 tree, err := octree.Cache.Get(
41 if rows, err = db.QueryContext( 68 csi.Properties.Bottleneck, csi.Properties.Date.Time,
42 req.Context(), 69 conn, req.Context())
43 crossSQL, 70
44 csi.Geometry.Coordinates.AsWKB(), 71 log.Printf("loading octree took: %s\n", time.Since(start))
45 csi.Properties.Bottleneck, 72 if err != nil {
46 csi.Properties.Date.Time, 73 return
74 }
75
76 // The coordinate system of the octree is an UTM projection.
77 // The input coordinates are in WGS84.
78 // So we need to reproject them.
79
80 start = time.Now()
81
82 var rp *models.Reprojector
83 if rp, err = models.NewReprojector(
84 conn, req.Context(),
85 WGS84, tree.EPSG,
47 ); err != nil { 86 ); err != nil {
48 return 87 return
49 } 88 }
50 defer rows.Close() 89 defer rp.Close()
51 90
52 var segments models.GeoJSONMultiLineCoordinatesZ 91 coords, err := reproject(rp, csi.Geometry.Coordinates, req.Context())
53 92
54 for rows.Next() { 93 log.Printf("transforming input coords took: %s\n", time.Since(start))
55 var segment models.GeoJSONLineCoordinatesZ 94 if err != nil {
56 if err = rows.Scan(&segment); err != nil {
57 return
58 }
59 segments = append(segments, segment)
60 }
61
62 if err = rows.Err(); err != nil {
63 return 95 return
64 } 96 }
65 97
66 log.Printf("query took: %v\n", time.Since(start))
67
68 start = time.Now() 98 start = time.Now()
69 99
70 joined := segments.Join() 100 var segments octree.MultiLineStringZ
71 101
72 log.Printf("joining took: %v\n", time.Since(start)) 102 for i := 0; i < len(coords)-1; i++ {
73 log.Printf("segments before/after: %d %d\n", len(segments), len(joined)) 103 c1 := &coords[i]
104 c2 := &coords[i+1]
74 105
75 /* 106 verticalLine := octree.NewVerticalLine(c1.Lat, c1.Lon, c2.Lat, c2.Lon)
76 if err2 := dumpProfile( 107
77 csi.Geometry.Coordinates[0], 108 var line octree.MultiLineStringZ
78 csi.Geometry.Coordinates[len(csi.Geometry.Coordinates)-1], 109 tree.Vertical(c1.Lat, c1.Lon, c2.Lat, c2.Lon, func(t *octree.Triangle) {
79 joined, 110 if ls := verticalLine.Intersection(t); len(ls) > 0 {
80 ); err2 != nil { 111 line = append(line, ls)
81 log.Printf("error: %v\n", err2) 112 }
113 })
114
115 if len(line) > 0 {
116 log.Printf("line length: %d\n", len(line))
117 // They are all on the segment (c1.Lat, c1.Lon) - (c2.Lat, c2.Lon).
118 // Sort them by project them on this line.
119 joined := line.JoinOnLine(c1.Lat, c1.Lon, c2.Lat, c2.Lon)
120 log.Printf("joined length: %d\n", len(joined))
121 segments = append(segments, joined...)
82 } 122 }
83 */ 123
124 }
125 log.Printf("octree traversal took: %s\n", time.Since(start))
126
127 // The result have to be WGS84. So project the result back.
128 start = time.Now()
129
130 rp.FromEPSG, rp.ToEPSG = tree.EPSG, WGS84
131
132 var joined models.GeoJSONMultiLineCoordinatesZ
133 joined, err = projectBack(rp, segments, req.Context())
134
135 log.Printf("projecting back took: %s\n", time.Since(start))
136 if err != nil {
137 return
138 }
84 139
85 jr = JSONResult{ 140 jr = JSONResult{
86 Result: &models.CrossSectionOutput{ 141 Result: &models.CrossSectionOutput{
87 Type: "Feature", 142 Type: "Feature",
88 Geometry: models.CrossSectionOutputGeometry{ 143 Geometry: models.CrossSectionOutputGeometry{
93 }, 148 },
94 } 149 }
95 150
96 return 151 return
97 } 152 }
98
99 /*
100 func dumpProfile(
101 start models.GeoJSONCoordinate,
102 stop models.GeoJSONCoordinate,
103 segments models.GeoJSONMultiLineCoordinatesZ,
104 ) error {
105
106 w, err := os.Create("/tmp/cross.txt")
107 if err != nil {
108 return err
109 }
110 defer w.Close()
111
112 begin := models.GeoJSONCoordinateZ{
113 Lat: start.Lat,
114 Lon: start.Lon,
115 }
116 end := models.GeoJSONCoordinateZ{
117 Lat: stop.Lat,
118 Lon: stop.Lon,
119 }
120
121 last := begin
122
123 var total float64
124
125 minz := 10000.0
126
127 for _, line := range segments {
128 for _, coord := range line {
129 if coord.Z < minz {
130 minz = coord.Z
131 }
132 total += last.Distance(coord)
133 last = coord
134 }
135 }
136
137 log.Printf("length: %.3f minz: %f\n", total, minz)
138
139 var pos float64
140
141 for i, line := range segments {
142 for j, coord := range line {
143 if i == 0 && j == 0 {
144 if !begin.Equals(coord) {
145 pos = begin.Distance(coord)
146 fmt.Fprintf(w, "%.3f %f\n", 0.0, 200.0)
147 fmt.Fprintf(w, "%.3f %f\n", pos-0.0001, 200.0)
148 fmt.Fprintf(w, "%.3f %f\n", pos, coord.Z-minz)
149 continue
150 }
151 } else if j == 0 {
152 fmt.Fprintf(w, "%.3f %f\n", pos+0.0001, 200.0)
153 fmt.Fprintf(w, "%.3f %f\n", pos+last.Distance(coord)-0.0001, 200.0)
154 continue
155 }
156 pos += last.Distance(coord)
157 fmt.Fprintf(w, "%.3f %f\n", pos, coord.Z-minz)
158 last = coord
159 }
160 }
161
162 if !last.Equals(end) {
163 fmt.Fprintf(w, "%.3f %f\n", pos+0.0001, 200.0)
164 fmt.Fprintf(w, "%.3f %f\n", pos+last.Distance(end), 200.0)
165 }
166
167 return nil
168 }
169 */