Mercurial > gemma
changeset 1859:9780cb4ef6a6
Distance marks virtual import: Implemented.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 17 Jan 2019 13:12:37 +0100 |
parents | 108a049c8394 |
children | f54ac71db1ac |
files | pkg/imports/dmv.go |
diffstat | 1 files changed, 138 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/imports/dmv.go Thu Jan 17 12:42:19 2019 +0100 +++ b/pkg/imports/dmv.go Thu Jan 17 13:12:37 2019 +0100 @@ -17,8 +17,15 @@ "context" "database/sql" "errors" + "fmt" + "log" + "strings" + "time" "gemma.intevation.de/gemma/pkg/common" + "gemma.intevation.de/gemma/pkg/models" + "gemma.intevation.de/gemma/pkg/soap" + "gemma.intevation.de/gemma/pkg/soap/erdms" ) type DistanceMarksVirtual struct { @@ -65,6 +72,27 @@ // CleanUp does nothing as there is nothing to cleanup with distance marks virtual. func (*DistanceMarksVirtual) CleanUp() error { return nil } +const ( + deleteDistanceMarksVirtualSQL = ` +DELETE FROM waterway.distance_marks_virtual +WHERE (location_code).country_code = $1 +` + insertDistanceMarksVirtualSQL = ` +INSERT INTO waterway.distance_marks_virtual ( + location_code, + geom, + related_enc +) +VALUES ( + ($1::char(2), $2::char(3), $3::char(5), $4::char(5), $5::int), + ST_SetSRID(ST_MakePoint($6, $7), 4326)::geography, + $8 +) ON CONFLICT (location_code) DO UPDATE SET + geom = ST_SetSRID(ST_MakePoint($6, $7), 4326)::geography, + related_enc = $8 +` +) + func (dmv *DistanceMarksVirtual) Do( ctx context.Context, importID int64, @@ -72,7 +100,115 @@ feedback Feedback, ) (interface{}, error) { - // TODO: Implement me! + start := time.Now() + + tx, err := conn.BeginTx(ctx, nil) + if err != nil { + return nil, err + } + defer tx.Rollback() + + var country string + err = tx.QueryRowContext(ctx, selectCurrentUserCountrySQL).Scan(&country) + switch { + case err == sql.ErrNoRows: + return nil, errors.New("Cannot figure out user country") + case err != nil: + return nil, err + } + + country = strings.ToUpper(country) + feedback.Info("Using country '%s'.", country) + + var auth *soap.BasicAuth + if dmv.Username != "" { + auth = &soap.BasicAuth{ + Login: dmv.Username, + Password: dmv.Password, + } + } + + client := erdms.NewRefService(dmv.URL, dmv.Insecure, auth) + + request := &erdms.GetRisDataXML{ + GetRisDataXMLType: &erdms.GetRisDataXMLType{ + Subcode: erdms.NoNS{Text: country + "%"}, + Funcode: erdms.NoNS{Text: "DISMAR"}, + }, + } + + data, err := client.GetRisDataXML(request) + + if err != nil { + log.Printf("error: %v\n", err) + return nil, fmt.Errorf("Error requesting ERDMS service: %v", err) + } + + if _, err := tx.ExecContext(ctx, deleteDistanceMarksVirtualSQL, country); err != nil { + return nil, err + } + + insertStmt, err := tx.PrepareContext(ctx, insertDistanceMarksVirtualSQL) + if err != nil { + return nil, err + } + defer insertStmt.Close() + + var ignored, features int - return nil, errors.New("Not implemented, yet!") + for _, dr := range data.RisdataReturn { + if dr.RisidxCode == nil { + ignored++ + continue + } + + code, err := models.IsrsFromString(string(*dr.RisidxCode)) + if err != nil { + feedback.Warn("invalid ISRS code %v", err) + ignored++ + continue + } + + if dr.Lat == nil || dr.Lon == nil { + feedback.Warn("missing lat/lon: %s", code) + ignored++ + continue + } + + if dr.Relenc == nil { + feedback.Warn("missing relnec: %s", code) + ignored++ + continue + } + + if _, err := insertStmt.ExecContext( + ctx, + code.CountryCode, + code.LoCode, + code.FairwaySection, + code.Orc, + code.Hectometre, + float64(*dr.Lat), float64(*dr.Lon), + string(*dr.Relenc), + ); err != nil { + return nil, err + } + features++ + } + feedback.Info("ignored: %d", ignored) + feedback.Info("features: %d", features) + + if features == 0 { + return nil, errors.New("No features found") + } + + if err = tx.Commit(); err == nil { + feedback.Info("Refreshing distant marks virtual successfully took %s.", + time.Since(start)) + } else { + feedback.Error("Refreshing distant marks virtual failed after %s.", + time.Since(start)) + } + + return nil, nil }