Mercurial > gemma
comparison pkg/imports/sec.go @ 3171:c8ded555c2a8
Sections import: Added a sections import. Derived from the stretches import w/o the countries.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 06 May 2019 16:36:03 +0200 |
parents | |
children | 4acbee65275d |
comparison
equal
deleted
inserted
replaced
3170:5c8ecab9f2d4 | 3171:c8ded555c2a8 |
---|---|
1 // This is Free Software under GNU Affero General Public License v >= 3.0 | |
2 // without warranty, see README.md and license for details. | |
3 // | |
4 // SPDX-License-Identifier: AGPL-3.0-or-later | |
5 // License-Filename: LICENSES/AGPL-3.0.txt | |
6 // | |
7 // Copyright (C) 2018 by via donau | |
8 // – Österreichische Wasserstraßen-Gesellschaft mbH | |
9 // Software engineering by Intevation GmbH | |
10 // | |
11 // Author(s): | |
12 // * Sascha L. Teichmann <sascha.teichmann@intevation.de> | |
13 | |
14 package imports | |
15 | |
16 import ( | |
17 "context" | |
18 "database/sql" | |
19 "time" | |
20 | |
21 "gemma.intevation.de/gemma/pkg/models" | |
22 ) | |
23 | |
24 type Section struct { | |
25 Name string `json:"name"` | |
26 From models.Isrs `json:"from"` | |
27 To models.Isrs `json:"to"` | |
28 Tolerance float32 `json:"tolerance"` | |
29 ObjNam string `json:"objnam"` | |
30 NObjNam *string `json:"nobjnam"` | |
31 Source string `json:"source-organization"` | |
32 Date models.Date `json:"date-info"` | |
33 } | |
34 | |
35 const SECJobKind JobKind = "sec" | |
36 | |
37 type secJobCreator struct{} | |
38 | |
39 func init() { | |
40 RegisterJobCreator(SECJobKind, secJobCreator{}) | |
41 } | |
42 | |
43 func (secJobCreator) Description() string { return "section" } | |
44 | |
45 func (secJobCreator) AutoAccept() bool { return false } | |
46 | |
47 func (secJobCreator) Create() Job { return new(Section) } | |
48 | |
49 func (secJobCreator) Depends() []string { | |
50 return []string{ | |
51 "sections", | |
52 } | |
53 } | |
54 | |
55 const ( | |
56 secDeleteSQL = ` | |
57 DELETE FROM waterway.sections WHERE | |
58 staging_done AND name = ( | |
59 SELECT name | |
60 FROM waterway.sections WHERE | |
61 id = ( | |
62 SELECT key from import.track_imports | |
63 WHERE import_id = $1 AND | |
64 relation = 'waterway.sections'::regclass) | |
65 AND NOT staging_done | |
66 )` | |
67 | |
68 secStageDoneSQL = ` | |
69 UPDATE waterway.sections SET staging_done = true | |
70 WHERE id IN ( | |
71 SELECT key from import.track_imports | |
72 WHERE import_id = $1 AND | |
73 relation = 'waterway.sections'::regclass)` | |
74 | |
75 secInsertSQL = ` | |
76 WITH r AS ( | |
77 SELECT isrsrange( | |
78 least(($1::char(2), | |
79 $2::char(3), | |
80 $3::char(5), | |
81 $4::char(5), | |
82 $5::int)::isrs, | |
83 ($6::char(2), | |
84 $7::char(3), | |
85 $8::char(5), | |
86 $9::char(5), | |
87 $10::int)::isrs), | |
88 greatest(($1::char(2), | |
89 $2::char(3), | |
90 $3::char(5), | |
91 $4::char(5), | |
92 $5::int)::isrs, | |
93 ($6::char(2), | |
94 $7::char(3), | |
95 $8::char(5), | |
96 $9::char(5), | |
97 $10::int)::isrs) | |
98 ) AS r), | |
99 axs AS ( | |
100 SELECT ISRSrange_axis((SELECT r FROM r), $16::double precision) AS axs) | |
101 INSERT INTO waterway.sections ( | |
102 name, | |
103 stretch, | |
104 area, | |
105 objnam, | |
106 nobjnam, | |
107 date_info, | |
108 source_organization | |
109 ) VALUES ( | |
110 $11, | |
111 (SELECT r FROM r), | |
112 ST_Transform(ISRSrange_area( | |
113 (SELECT axs FROM axs), | |
114 (SELECT ST_Buffer(axs, 10000) FROM axs)), | |
115 4326), | |
116 $12, | |
117 $13, | |
118 $14, | |
119 $15) | |
120 RETURNING id` | |
121 ) | |
122 | |
123 // StageDone moves the imported stretch out of the staging area. | |
124 func (secJobCreator) StageDone( | |
125 ctx context.Context, | |
126 tx *sql.Tx, | |
127 id int64, | |
128 ) error { | |
129 if _, err := tx.ExecContext(ctx, secDeleteSQL, id); err != nil { | |
130 return err | |
131 } | |
132 _, err := tx.ExecContext(ctx, secStageDoneSQL, id) | |
133 return err | |
134 } | |
135 | |
136 // CleanUp of a stretch import is a NOP. | |
137 func (*Section) CleanUp() error { return nil } | |
138 | |
139 // Do executes the actual stretch import. | |
140 func (sec *Section) Do( | |
141 ctx context.Context, | |
142 importID int64, | |
143 conn *sql.Conn, | |
144 feedback Feedback, | |
145 ) (interface{}, error) { | |
146 | |
147 start := time.Now() | |
148 | |
149 if sec.Date.Time.IsZero() { | |
150 sec.Date = models.Date{Time: start} | |
151 } | |
152 | |
153 feedback.Info("Storing section '%s'", sec.Name) | |
154 | |
155 tx, err := conn.BeginTx(ctx, nil) | |
156 if err != nil { | |
157 return nil, err | |
158 } | |
159 defer tx.Rollback() | |
160 | |
161 var nobjnm sql.NullString | |
162 if sec.NObjNam != nil { | |
163 nobjnm = sql.NullString{String: *sec.NObjNam, Valid: true} | |
164 } | |
165 | |
166 feedback.Info("Section from %s to %s.", sec.From.String(), sec.To.String()) | |
167 feedback.Info("Tolerance used to snap waterway axis: %g", sec.Tolerance) | |
168 | |
169 var id int64 | |
170 if err := tx.QueryRowContext( | |
171 ctx, | |
172 secInsertSQL, | |
173 sec.From.CountryCode, | |
174 sec.From.LoCode, | |
175 sec.From.FairwaySection, | |
176 sec.From.Orc, | |
177 sec.From.Hectometre, | |
178 sec.To.CountryCode, | |
179 sec.To.LoCode, | |
180 sec.To.FairwaySection, | |
181 sec.To.Orc, | |
182 sec.To.Hectometre, | |
183 sec.Name, | |
184 sec.ObjNam, | |
185 nobjnm, | |
186 sec.Date.Time, | |
187 sec.Source, | |
188 sec.Tolerance, | |
189 ).Scan(&id); err != nil { | |
190 return nil, handleError(err) | |
191 } | |
192 | |
193 if err := track(ctx, tx, importID, "waterway.sections", id); err != nil { | |
194 return nil, err | |
195 } | |
196 | |
197 feedback.Info("Storing section '%s' took %s", sec.Name, time.Since(start)) | |
198 if err := tx.Commit(); err != nil { | |
199 return nil, err | |
200 } | |
201 feedback.Info("Import of section was successful") | |
202 | |
203 summary := struct { | |
204 Section string `json:"section"` | |
205 }{ | |
206 Section: sec.Name, | |
207 } | |
208 | |
209 return &summary, nil | |
210 } |