Mercurial > gemma
comparison pkg/imports/wx.go @ 2726:dff749c07ae0
Warn if imported axis linestrings cross each other
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Tue, 19 Mar 2019 12:57:11 +0100 |
parents | a10022399e24 |
children | 7cb027be277d |
comparison
equal
deleted
inserted
replaced
2725:9465749410ba | 2726:dff749c07ae0 |
---|---|
87 ) | 87 ) |
88 DELETE FROM waterway.waterway_axis | 88 DELETE FROM waterway.waterway_axis |
89 WHERE pg_has_role('sys_admin', 'MEMBER') | 89 WHERE pg_has_role('sys_admin', 'MEMBER') |
90 OR ST_Covers((SELECT a FROM resp), | 90 OR ST_Covers((SELECT a FROM resp), |
91 ST_Transform(wtwaxs::geometry, (SELECT t FROM resp))) | 91 ST_Transform(wtwaxs::geometry, (SELECT t FROM resp))) |
92 ` | |
93 | |
94 checkCrossingAxisSQL = ` | |
95 SELECT ST_AsText(ST_Intersection(new_line.wtwaxs, axis.wtwaxs)) | |
96 FROM waterway.waterway_axis AS axis, waterway.waterway_axis AS new_line | |
97 WHERE new_line.id = $1 AND axis.id <> $1 | |
98 AND ST_Crosses(new_line.wtwaxs::geometry, axis.wtwaxs::geometry) | |
92 ` | 99 ` |
93 | 100 |
94 insertWaterwayAxisSQL = ` | 101 insertWaterwayAxisSQL = ` |
95 WITH resp AS ( | 102 WITH resp AS ( |
96 SELECT best_utm(area::geometry) AS t, | 103 SELECT best_utm(area::geometry) AS t, |
108 THEN new_line | 115 THEN new_line |
109 ELSE ST_Intersection(a, new_line) | 116 ELSE ST_Intersection(a, new_line) |
110 END | 117 END |
111 )).geom AS geom | 118 )).geom AS geom |
112 ) AS clipped | 119 ) AS clipped |
120 RETURNING id | |
113 ` | 121 ` |
114 ) | 122 ) |
115 | 123 |
116 // Do executes the actual waterway axis import. | 124 // Do executes the actual waterway axis import. |
117 func (wx *WaterwayAxis) Do( | 125 func (wx *WaterwayAxis) Do( |
164 insertStmt, err := tx.PrepareContext(ctx, insertWaterwayAxisSQL) | 172 insertStmt, err := tx.PrepareContext(ctx, insertWaterwayAxisSQL) |
165 if err != nil { | 173 if err != nil { |
166 return nil, err | 174 return nil, err |
167 } | 175 } |
168 defer insertStmt.Close() | 176 defer insertStmt.Close() |
177 | |
178 checkCrossingStmt, err := tx.PrepareContext(ctx, checkCrossingAxisSQL) | |
179 if err != nil { | |
180 return nil, err | |
181 } | |
182 defer checkCrossingStmt.Close() | |
169 | 183 |
170 // Delete the old features. | 184 // Delete the old features. |
171 if _, err := tx.ExecContext(ctx, deleteWaterwayAxisSQL); err != nil { | 185 if _, err := tx.ExecContext(ctx, deleteWaterwayAxisSQL); err != nil { |
172 return nil, err | 186 return nil, err |
173 } | 187 } |
225 case "LineString": | 239 case "LineString": |
226 var l lineSlice | 240 var l lineSlice |
227 if err := json.Unmarshal(*feature.Geometry.Coordinates, &l); err != nil { | 241 if err := json.Unmarshal(*feature.Geometry.Coordinates, &l); err != nil { |
228 return err | 242 return err |
229 } | 243 } |
230 if _, err := insertStmt.ExecContext( | 244 if err := storeLinestring( |
231 ctx, | 245 ctx, |
232 l.asWKB(), | 246 tx, |
247 feedback, | |
248 l, | |
233 epsg, | 249 epsg, |
234 props.ObjNam, | 250 props, |
235 nobjnam, | 251 nobjnam, |
236 ); err != nil { | 252 checkCrossingStmt, |
253 insertStmt); err != nil { | |
237 return err | 254 return err |
238 } | 255 } |
239 features++ | 256 features++ |
240 case "MultiLineString": | 257 case "MultiLineString": |
241 var ls []lineSlice | 258 var ls []lineSlice |
242 if err := json.Unmarshal(*feature.Geometry.Coordinates, &ls); err != nil { | 259 if err := json.Unmarshal(*feature.Geometry.Coordinates, &ls); err != nil { |
243 return err | 260 return err |
244 } | 261 } |
245 for _, l := range ls { | 262 for _, l := range ls { |
246 if _, err := insertStmt.ExecContext( | 263 if err := storeLinestring( |
247 ctx, | 264 ctx, |
248 l.asWKB(), | 265 tx, |
266 feedback, | |
267 l, | |
249 epsg, | 268 epsg, |
250 props.ObjNam, | 269 props, |
251 nobjnam, | 270 nobjnam, |
252 ); err != nil { | 271 checkCrossingStmt, |
272 insertStmt); err != nil { | |
253 return err | 273 return err |
254 } | 274 } |
255 features++ | 275 features++ |
256 } | 276 } |
257 default: | 277 default: |
286 features, time.Since(start)) | 306 features, time.Since(start)) |
287 } | 307 } |
288 | 308 |
289 return nil, err | 309 return nil, err |
290 } | 310 } |
311 | |
312 func storeLinestring( | |
313 ctx context.Context, | |
314 tx *sql.Tx, | |
315 feedback Feedback, | |
316 l lineSlice, | |
317 epsg int, | |
318 props waterwayAxisProperties, | |
319 nobjnam sql.NullString, | |
320 checkCrossingStmt, insertStmt *sql.Stmt, | |
321 ) error { | |
322 var id int | |
323 if err := insertStmt.QueryRowContext( | |
324 ctx, | |
325 l.asWKB(), | |
326 epsg, | |
327 props.ObjNam, | |
328 nobjnam, | |
329 ).Scan(&id); err != nil { | |
330 return err | |
331 } | |
332 | |
333 var crossing string | |
334 switch err := checkCrossingStmt.QueryRowContext( | |
335 ctx, | |
336 id, | |
337 ).Scan(&crossing); { | |
338 case err != nil && err != sql.ErrNoRows: | |
339 return err | |
340 case err == nil: | |
341 feedback.Warn( | |
342 "Linestring %d crosses previously imported linestring near %s. Finding a contiguous axis may not work here", | |
343 id, crossing) | |
344 } | |
345 return nil | |
346 } |