comparison pkg/imports/wx.go @ 5009:e8b2dc771f9e

Store axis as MultiLinestring MultiLinestrings could already be imported but we stored them as multiple Linestrings with identical attributes and even stored Linestrings with self-intersections as multiple single Linestrings with identical attributes. Avoid both by storing as MultiLinestring. In passing, removed unnecessary processing steps in the INSERT statemet for the sys_admin case and ensured that attempts to convert to valid simple features are made after transformation, which might lead to invalid features. Since isrsrange_axis() relies on single Linestrings for linear referencing, add an extra ST_Dump().
author Tom Gottfried <tom@intevation.de>
date Wed, 11 Mar 2020 17:11:23 +0100
parents 783d0bec86d3
children 7dff1015283d
comparison
equal deleted inserted replaced
5008:0b97f5301a17 5009:e8b2dc771f9e
98 insertWaterwayAxisSQL = ` 98 insertWaterwayAxisSQL = `
99 WITH resp AS ( 99 WITH resp AS (
100 SELECT users.current_user_area_utm() AS a 100 SELECT users.current_user_area_utm() AS a
101 ) 101 )
102 INSERT INTO waterway.waterway_axis (wtwaxs, objnam, nobjnam) 102 INSERT INTO waterway.waterway_axis (wtwaxs, objnam, nobjnam)
103 SELECT dmp.geom, $3, $4 103 SELECT
104 ST_Multi(ST_Node(ST_CollectionExtract(ST_Transform(new_ax, 4326), 2))),
105 $3, $4
104 FROM ST_GeomFromWKB($1, $2::integer) AS new_line (new_line), 106 FROM ST_GeomFromWKB($1, $2::integer) AS new_line (new_line),
105 ST_Dump(ST_Transform(ST_CollectionExtract( 107 LATERAL (SELECT
106 CASE WHEN pg_has_role('sys_admin', 'MEMBER') 108 CASE WHEN pg_has_role('sys_admin', 'MEMBER')
107 THEN ST_Node(ST_Transform(new_line, 109 THEN new_line
108 best_utm(ST_Transform(new_line, 4326))))
109 ELSE ST_Intersection((SELECT a FROM resp), 110 ELSE ST_Intersection((SELECT a FROM resp),
110 ST_Node(ST_Transform(new_line, (SELECT ST_SRID(a) FROM resp)))) 111 ST_Node(ST_Transform(new_line, (SELECT ST_SRID(a) FROM resp))))
111 END, 112 END) AS new_ax (new_ax)
112 2), 4326)) AS dmp 113 -- Do nothing if intersection is empty:
114 WHERE NOT ST_IsEmpty(new_ax)
113 RETURNING id 115 RETURNING id
114 ` 116 `
115 ) 117 )
116 118
117 // Do executes the actual waterway axis import. 119 // Do executes the actual waterway axis import.
220 var nobjnam sql.NullString 222 var nobjnam sql.NullString
221 if props.NObjNnm != nil { 223 if props.NObjNnm != nil {
222 nobjnam = sql.NullString{String: *props.NObjNnm, Valid: true} 224 nobjnam = sql.NullString{String: *props.NObjNnm, Valid: true}
223 } 225 }
224 226
227 var ls multiLineSlice
225 switch feature.Geometry.Type { 228 switch feature.Geometry.Type {
226 case "LineString": 229 case "LineString":
227 var l lineSlice 230 var l lineSlice
228 if err := json.Unmarshal(*feature.Geometry.Coordinates, &l); err != nil { 231 if err := json.Unmarshal(*feature.Geometry.Coordinates, &l); err != nil {
229 return err 232 return err
230 } 233 }
231 if err := storeLinestring( 234 ls = append(ls, l)
232 ctx,
233 savepoint,
234 feedback,
235 l,
236 epsg,
237 props,
238 nobjnam,
239 &outside,
240 &features,
241 insertStmt); err != nil {
242 return err
243 }
244 case "MultiLineString": 235 case "MultiLineString":
245 var ls []lineSlice
246 if err := json.Unmarshal(*feature.Geometry.Coordinates, &ls); err != nil { 236 if err := json.Unmarshal(*feature.Geometry.Coordinates, &ls); err != nil {
247 return err 237 return err
248 } 238 }
249 for _, l := range ls {
250 if err := storeLinestring(
251 ctx,
252 savepoint,
253 feedback,
254 l,
255 epsg,
256 props,
257 nobjnam,
258 &outside,
259 &features,
260 insertStmt); err != nil {
261 return err
262 }
263 }
264 default: 239 default:
265 unsupported[feature.Geometry.Type]++ 240 unsupported[feature.Geometry.Type]++
241 continue
242 }
243 if err := storeLinestring(
244 ctx,
245 savepoint,
246 feedback,
247 ls,
248 epsg,
249 props,
250 nobjnam,
251 &outside,
252 &features,
253 insertStmt); err != nil {
254 return err
266 } 255 }
267 } 256 }
268 return nil 257 return nil
269 }); err != nil { 258 }); err != nil {
270 return nil, err 259 return nil, err
300 289
301 func storeLinestring( 290 func storeLinestring(
302 ctx context.Context, 291 ctx context.Context,
303 savepoint func(func() error) error, 292 savepoint func(func() error) error,
304 feedback Feedback, 293 feedback Feedback,
305 l lineSlice, 294 l multiLineSlice,
306 epsg int, 295 epsg int,
307 props waterwayAxisProperties, 296 props waterwayAxisProperties,
308 nobjnam sql.NullString, 297 nobjnam sql.NullString,
309 outside, features *int, 298 outside, features *int,
310 insertStmt *sql.Stmt, 299 insertStmt *sql.Stmt,