view pkg/models/sr.go @ 3945:3bdbaf1b282a

SR import: Negate the Z values in the XYZ files if the flag `negate-z` is set.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 14 Jul 2019 17:19:22 +0200
parents 07b2df71bb4a
children 98e2041c7ebf
line wrap: on
line source

// This is Free Software under GNU Affero General Public License v >= 3.0
// without warranty, see README.md and license for details.
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// License-Filename: LICENSES/AGPL-3.0.txt
//
// Copyright (C) 2018 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
//  * Bernhard E. Reiter <bernhard.reiter@intevation.de>

package models

import (
	"context"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"gemma.intevation.de/gemma/pkg/common"
)

type (
	SoundingResultMeta struct {
		Date           Date   `json:"date"`
		Bottleneck     string `json:"bottleneck"`
		EPSG           uint   `json:"epsg"`
		DepthReference string `json:"depth-reference"`
		SingleBeam     bool   `json:"single-beam"`
		NegateZ        bool   `json:"negate-z,omitempty"`
	}
)

const (
	checkDepthReferenceSQL = `
SELECT EXISTS(SELECT 1
  FROM waterway.bottlenecks bn
    JOIN waterway.gauges g
      ON bn.gauge_location = g.location AND bn.gauge_validity = g.validity
    JOIN waterway.gauges_reference_water_levels rl
      ON g.location = rl.location AND g.validity = rl.validity
  WHERE bn.objnam = $1
    AND rl.depth_reference = $2)`

	checkBottleneckSQL = `
SELECT true FROM waterway.bottlenecks WHERE objnam = $1`

	checkBottleneckDateUniqueSQL = `
SELECT true FROM waterway.sounding_results sr JOIN
  waterway.bottlenecks bn ON sr.bottleneck_id = bn.bottleneck_id
WHERE bn.objnam = $1 AND sr.date_info = $2`
)

func (m *SoundingResultMeta) Decode(r io.Reader) error {
	err := json.NewDecoder(r).Decode(m)
	if err == nil && m.EPSG == 0 {
		m.EPSG = WGS84
	}
	return err
}

func (m *SoundingResultMeta) Validate(ctx context.Context, conn *sql.Conn) []error {

	var errs []error

	var b bool
	err := conn.QueryRowContext(ctx,
		checkBottleneckSQL,
		m.Bottleneck).Scan(&b)
	switch {
	case err == sql.ErrNoRows:
		errs = append(errs, fmt.Errorf("unknown bottleneck '%s'", m.Bottleneck))
	case err != nil:
		errs = append(errs, err)
	case !b:
		errs = append(errs, errors.New("unexpected bottleneck"))
	}

	if m.DepthReference != "ZPG" {
		err = conn.QueryRowContext(ctx,
			checkDepthReferenceSQL,
			m.Bottleneck,
			m.DepthReference).Scan(&b)
		switch {
		case !b:
			errs = append(errs,
				fmt.Errorf("unknown depth reference '%s'", m.DepthReference))
		case err != nil:
			errs = append(errs, err)
		}
	}

	err = conn.QueryRowContext(ctx,
		checkBottleneckDateUniqueSQL,
		m.Bottleneck, m.Date.Time).Scan(&b)
	switch {
	case err == sql.ErrNoRows: // good! -> unique.
	case err != nil:
		errs = append(errs, err)
	case b:
		errs = append(errs,
			fmt.Errorf("sounding result for date %s already exists at bottleneck '%s'",
				m.Date.Time.Format(common.DateFormat),
				m.Bottleneck))
	}

	return errs
}