changeset 1637:dd31be75ce6d

Implemented gauge measurement import.
author Raimund Renkert <raimund.renkert@intevation.de>
date Thu, 20 Dec 2018 12:06:37 +0100
parents 37ee25bc2bbe
children 2a35bbbb4d93
files pkg/controllers/gmimports.go pkg/controllers/routes.go pkg/imports/gm.go pkg/models/gauge.go pkg/soap/nts/service.go
diffstat 5 files changed, 1981 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/controllers/gmimports.go	Thu Dec 20 12:06:37 2018 +0100
@@ -0,0 +1,66 @@
+// 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):
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+
+package controllers
+
+import (
+	"database/sql"
+	"log"
+	"net/http"
+
+	"gemma.intevation.de/gemma/pkg/auth"
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/imports"
+	"gemma.intevation.de/gemma/pkg/models"
+)
+
+func importGaugeMeasurement(
+	input interface{},
+	req *http.Request,
+	conn *sql.Conn,
+) (jr JSONResult, err error) {
+
+	bi := input.(*models.GaugeMeasurementImport)
+
+	bn := &imports.GaugeMeasurement{
+		URL:      bi.URL,
+		Insecure: bi.Insecure,
+	}
+
+	var serialized string
+	serialized, err = common.ToJSONString(bn)
+	if err != nil {
+		return
+	}
+
+	session, _ := auth.GetSession(req)
+
+	jobID, err := imports.AddJob(imports.GMJobKind, session.User, serialized)
+	if err != nil {
+		return
+	}
+
+	log.Printf("info: added import #%d to queue\n", jobID)
+
+	result := struct {
+		ID int64 `json:"id"`
+	}{
+		ID: jobID,
+	}
+
+	jr = JSONResult{
+		Code:   http.StatusCreated,
+		Result: &result,
+	}
+	return
+}
--- a/pkg/controllers/routes.go	Thu Dec 20 12:05:30 2018 +0100
+++ b/pkg/controllers/routes.go	Thu Dec 20 12:06:37 2018 +0100
@@ -176,6 +176,11 @@
 		Handle: importBottleneck,
 	})).Methods(http.MethodPost)
 
+	api.Handle("/imports/gaugemeasurement", waterwayAdmin(&JSONHandler{
+		Input:  func() interface{} { return new(models.GaugeMeasurementImport) },
+		Handle: importGaugeMeasurement,
+	})).Methods(http.MethodPost)
+
 	// Import scheduler configuration
 	api.Handle("/imports/config/{id:[0-9]+}",
 		waterwayAdmin(&JSONHandler{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/gm.go	Thu Dec 20 12:06:37 2018 +0100
@@ -0,0 +1,262 @@
+// 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):
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+package imports
+
+import (
+	"context"
+	"database/sql"
+	"errors"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/models"
+	"gemma.intevation.de/gemma/pkg/soap/nts"
+)
+
+type GaugeMeasurement struct {
+	URL      string `json:"url"`
+	Insecure bool   `json:"insecure"`
+}
+
+const GMJobKind JobKind = "gm"
+
+const (
+	listGaugesSQL = `
+SELECT
+  (location).country_code,
+  (location).locode,
+  (location).fairway_section,
+  (location).orc,
+  (location).hectometre
+FROM waterway.gauges
+WHERE (location).country_code = users.current_user_country()`
+
+	hasGaugeMeasurementSQL = `
+SELECT true FROM waterway.gauge_measurements WHERE fk_gauge_id = $1`
+
+	insertGMSQL = `
+INSERT INTO waterway.gauge_measurements (
+  fk_gauge_id,
+  measure_date,
+  sender,
+  language_code,
+  date_issue,
+  water_level,
+  predicted,
+  is_waterlevel,
+  value_min,
+  value_max,
+  date_info,
+  source_organization
+) VALUES(
+  ($1, $2, $3, $4, $5),
+  $6,
+  $7,
+  $8,
+  $9,
+  $10,
+  $11,
+  $12,
+  $13,
+  $14,
+  $15,
+  $16
+)
+RETURNING id`
+)
+
+type gmJobCreator struct{}
+
+func init() {
+	RegisterJobCreator(GMJobKind, gmJobCreator{})
+}
+
+func (gmJobCreator) Create(_ JobKind, data string) (Job, error) {
+	gm := new(GaugeMeasurement)
+	if err := common.FromJSONString(data, gm); err != nil {
+		return nil, err
+	}
+	return gm, nil
+}
+
+func (gmJobCreator) Depends() []string {
+	return []string{
+		"waterway.gauges",
+		"waterway.gauge_measurements",
+	}
+}
+
+// StageDone moves the imported gauge measurement out of the staging area.
+// Currently doing nothing.
+func (gmJobCreator) StageDone(
+	ctx context.Context,
+	tx *sql.Tx,
+	id int64,
+) error {
+	return nil
+}
+
+// CleanUp of a gauge measurement import is a NOP.
+func (gm *GaugeMeasurement) CleanUp() error { return nil }
+
+// Do executes the actual bottleneck import.
+func (gm *GaugeMeasurement) Do(
+	ctx context.Context,
+	importID int64,
+	conn *sql.Conn,
+	feedback Feedback,
+) (interface{}, error) {
+
+	// Get available gauges from database for use as filter in SOAP request
+	var rows *sql.Rows
+
+	rows, err := conn.QueryContext(ctx, listGaugesSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+
+	gauges := []models.GaugeMeasurement{}
+
+	for rows.Next() {
+		var g models.GaugeMeasurement
+		if err = rows.Scan(
+			&g.Gauge.CountryCode,
+			&g.Gauge.LoCode,
+			&g.Gauge.FairwaySection,
+			&g.Gauge.Orc,
+			&g.Gauge.Hectometre,
+		); err != nil {
+			return nil, err
+		}
+		gauges = append(gauges, g)
+	}
+
+	if err = rows.Err(); err != nil {
+		return nil, err
+	}
+
+	// TODO get date_issue for selected gauges
+	gids, err := gm.doForGM(ctx, gauges, conn, feedback)
+	if err != nil {
+		feedback.Error("Error processing %d gauges: %s", len(gauges), err)
+	}
+	if len(gids) == 0 {
+		feedback.Error("No new gauge measurements found")
+		return nil, errors.New("No new gauge measurements found")
+	}
+	// TODO: needs to be filled more useful.
+	summary := struct {
+		GaugeMeasuremets []string `json:"gaugeMeasurements"`
+	}{
+		GaugeMeasuremets: gids,
+	}
+	return &summary, err
+}
+
+func (gm *GaugeMeasurement) doForGM(
+	ctx context.Context,
+	gauges []models.GaugeMeasurement,
+	conn *sql.Conn,
+	feedback Feedback,
+) ([]string, error) {
+	start := time.Now()
+
+	client := nts.NewINtSMessageService(gm.URL, gm.Insecure, nil)
+
+	var idPairs []*nts.Id_pair
+	for _, g := range gauges {
+		isrs := g.Gauge.String()
+		isrsID := nts.Isrs_code_type(isrs)
+		idPairs = append(idPairs, &nts.Id_pair{
+			Id: &isrsID,
+		})
+	}
+	mt := nts.Message_type_typeWRM
+	req := &nts.Get_messages_query{
+		Message_type: &mt,
+		Ids:          idPairs,
+	}
+	resp, err := client.Get_messages(req)
+	if err != nil {
+		feedback.Error("%v", err)
+		return nil, err
+	}
+
+	if resp.Result_message == nil {
+		err := errors.New("no Gauge Measurements found")
+		for i, e := range resp.Result_error {
+			feedback.Error("%d: %v", i, string(*e))
+		}
+		return nil, err
+	}
+
+	result := resp.Result_message
+
+	tx, err := conn.BeginTx(ctx, nil)
+	if err != nil {
+		return nil, err
+	}
+	defer tx.Rollback()
+
+	insertStmt, err := tx.PrepareContext(ctx, insertGMSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertStmt.Close()
+
+	var gid int64
+	var gids []string
+	for _, msg := range result {
+		feedback.Info("Found %d gauges with measurements", len(msg.Wrm))
+		for _, wrm := range msg.Wrm {
+			currIsrs, err := models.IsrsFromString(string(*wrm.Geo_object.Id))
+			for _, measure := range wrm.Measure {
+				isWaterlevel := false
+				if *measure.Measure_code == nts.Measure_code_enumWAL {
+					isWaterlevel = true
+				}
+				err = insertStmt.QueryRowContext(
+					ctx,
+					currIsrs.CountryCode,
+					currIsrs.LoCode,
+					currIsrs.FairwaySection,
+					currIsrs.Orc,
+					currIsrs.Hectometre,
+					measure.Measuredate,
+					msg.Identification.From,
+					msg.Identification.Language_code,
+					msg.Identification.Date_issue,
+					measure.Value,
+					measure.Predicted,
+					isWaterlevel,
+					measure.Value_min,
+					measure.Value_max,
+					msg.Identification.Date_issue,
+					msg.Identification.Originator,
+				).Scan(&gid)
+				if err != nil {
+					return nil, err
+				}
+				feedback.Info("Inserted '%s'", currIsrs)
+			}
+			gids = append(gids, currIsrs.String())
+		}
+	}
+	feedback.Info("Storing gauge measurements took %s", time.Since(start))
+	if err = tx.Commit(); err == nil {
+		feedback.Info("Import of gauge measurements was successful")
+	}
+
+	return gids, nil
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/models/gauge.go	Thu Dec 20 12:06:37 2018 +0100
@@ -0,0 +1,70 @@
+// 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):
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+
+package models
+
+import (
+	"fmt"
+	"strconv"
+	"time"
+)
+
+// GaugeMeasurementImport contains data used to define the endpoint
+type GaugeMeasurementImport struct {
+	URL      string `json:"url"`
+	Insecure bool   `json:"insecure"`
+}
+
+// GaugeMeasurement holds information about a gauge and the latest measurement
+type GaugeMeasurement struct {
+	Gauge           Isrs
+	LatestDateIssue time.Time
+}
+
+// Isrs represents the gauge identification data structure
+type Isrs struct {
+	CountryCode    string
+	LoCode         string
+	FairwaySection string
+	Orc            string
+	Hectometre     int
+}
+
+// IsrsFromString converts string representation of isrs code to type Isrs
+func IsrsFromString(isrsCode string) (*Isrs, error) {
+	if len(isrsCode) < 20 {
+		return nil, fmt.Errorf("to short")
+	}
+	hm, err := strconv.Atoi(isrsCode[15:20])
+	if err != nil {
+		return nil, err
+	}
+	isrs := Isrs{
+		CountryCode:    isrsCode[0:2],
+		LoCode:         isrsCode[2:5],
+		FairwaySection: isrsCode[5:10],
+		Orc:            isrsCode[10:15],
+		Hectometre:     hm,
+	}
+	return &isrs, nil
+}
+
+// ToString creates a isrs code string from Isrs
+func (isrs *Isrs) String() string {
+	return fmt.Sprintf("%s%s%s%s%05d",
+		isrs.CountryCode,
+		isrs.LoCode,
+		isrs.FairwaySection,
+		isrs.Orc,
+		isrs.Hectometre)
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/soap/nts/service.go	Thu Dec 20 12:06:37 2018 +0100
@@ -0,0 +1,1578 @@
+// 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):
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+
+package nts
+
+import (
+	"crypto/tls"
+	"encoding/xml"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/soap"
+)
+
+// against "unused imports"
+var _ time.Time
+var _ xml.Name
+
+type Message_type_type string
+
+const (
+	Message_type_typeFTM Message_type_type = "FTM"
+
+	Message_type_typeWRM Message_type_type = "WRM"
+
+	Message_type_typeICEM Message_type_type = "ICEM"
+
+	Message_type_typeWERM Message_type_type = "WERM"
+)
+
+type Error_code_type string
+
+type NonNegativeInteger uint
+
+type GYear uint
+
+type Duration string
+
+const (
+
+	// Description: message type not supported, Explanation: web service does not support the requested message type
+	Error_code_typeE010 Error_code_type = "e010"
+
+	// Description: paging parameters inconsistent with messages, Explanation: parameters for paging mechanism do not fit the available messages, e.g. Offset >= Total Count
+	Error_code_typeE030 Error_code_type = "e030"
+
+	// Description: syntax error in request, Explanation: request violates the schema for requests
+	Error_code_typeE100 Error_code_type = "e100"
+
+	// Description: incorrect message type, Explanation: given message type is not known
+	Error_code_typeE110 Error_code_type = "e110"
+
+	// Description: incorrect type-specific parameters, Explanation: type-specific parameters are erroneous
+	Error_code_typeE120 Error_code_type = "e120"
+
+	// Description: incorrect paging parameters, Explanation: given parameters for the paging mechanism are erroneous
+	Error_code_typeE130 Error_code_type = "e130"
+
+	// Description: operation not known, Explanation: the requested operation is unknown
+	Error_code_typeE200 Error_code_type = "e200"
+
+	// Description: data source unavailable, Explanation: data source of the web service for the NtS data is temporarily unavailable
+	Error_code_typeE300 Error_code_type = "e300"
+
+	// Description: too many results for request, Explanation: server is unable to handle number of results
+	Error_code_typeE310 Error_code_type = "e310"
+)
+
+type Get_messages_query struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts.ms/2.0.4.0 get_messages_query"`
+
+	Message_type *Message_type_type `xml:"http://www.ris.eu/nts.ms/2.0.4.0 message_type,omitempty"`
+
+	Ids []*Id_pair `xml:"ids,omitempty"`
+
+	Validity_period *Validity_period_type `xml:"validity_period,omitempty"`
+
+	Dates_issue []*Date_pair `xml:"dates_issue,omitempty"`
+
+	Paging_request *Paging_request_type `xml:"paging_request,omitempty"`
+}
+
+type Get_messages_result struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts.ms/2.0.4.0 get_messages_result"`
+
+	Result_message []*RIS_Message_Type `xml:"result_message,omitempty"`
+
+	Result_error []*Error_code_type `xml:"result_error,omitempty"`
+
+	Paging_result *Paging_result_type `xml:"paging_result,omitempty"`
+}
+
+type Id_pair struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts.ms/2.0.4.0 ids"`
+
+	Id *Isrs_code_type `xml:"http://www.ris.eu/nts.ms/2.0.4.0 id,omitempty"`
+}
+
+type Date_pair struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 date_pair"`
+
+	Date_start time.Time `xml:"date_start,omitempty"`
+
+	Date_end time.Time `xml:"date_end,omitempty"`
+}
+
+type Paging_request_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 paging_request"`
+
+	Offset *NonNegativeInteger `xml:"offset,omitempty"`
+
+	Limit *NonNegativeInteger `xml:"limit,omitempty"`
+
+	Total_count bool `xml:"total_count,omitempty"`
+}
+
+type Paging_result_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 paging_result"`
+
+	Offset *NonNegativeInteger `xml:"offset,omitempty"`
+
+	Count *NonNegativeInteger `xml:"count,omitempty"`
+
+	Total_count *NonNegativeInteger `xml:"total_count,omitempty"`
+}
+
+type Country_code_enum string
+
+const (
+	Country_code_enumAT Country_code_enum = "AT"
+
+	Country_code_enumBE Country_code_enum = "BE"
+
+	Country_code_enumBG Country_code_enum = "BG"
+
+	Country_code_enumCH Country_code_enum = "CH"
+
+	Country_code_enumCY Country_code_enum = "CY"
+
+	Country_code_enumCZ Country_code_enum = "CZ"
+
+	Country_code_enumDE Country_code_enum = "DE"
+
+	Country_code_enumDK Country_code_enum = "DK"
+
+	Country_code_enumEE Country_code_enum = "EE"
+
+	Country_code_enumES Country_code_enum = "ES"
+
+	Country_code_enumFI Country_code_enum = "FI"
+
+	Country_code_enumFR Country_code_enum = "FR"
+
+	Country_code_enumGB Country_code_enum = "GB"
+
+	Country_code_enumGR Country_code_enum = "GR"
+
+	Country_code_enumHR Country_code_enum = "HR"
+
+	Country_code_enumHU Country_code_enum = "HU"
+
+	Country_code_enumIE Country_code_enum = "IE"
+
+	Country_code_enumIT Country_code_enum = "IT"
+
+	Country_code_enumLT Country_code_enum = "LT"
+
+	Country_code_enumLU Country_code_enum = "LU"
+
+	Country_code_enumLV Country_code_enum = "LV"
+
+	Country_code_enumMD Country_code_enum = "MD"
+
+	Country_code_enumME Country_code_enum = "ME"
+
+	Country_code_enumMT Country_code_enum = "MT"
+
+	Country_code_enumNL Country_code_enum = "NL"
+
+	Country_code_enumPL Country_code_enum = "PL"
+
+	Country_code_enumPT Country_code_enum = "PT"
+
+	Country_code_enumRO Country_code_enum = "RO"
+
+	Country_code_enumRS Country_code_enum = "RS"
+
+	Country_code_enumSE Country_code_enum = "SE"
+
+	Country_code_enumSI Country_code_enum = "SI"
+
+	Country_code_enumSK Country_code_enum = "SK"
+
+	Country_code_enumRU Country_code_enum = "RU"
+
+	Country_code_enumUA Country_code_enum = "UA"
+)
+
+type Language_code_enum string
+
+const (
+	Language_code_enumDE Language_code_enum = "DE"
+
+	Language_code_enumEN Language_code_enum = "EN"
+
+	Language_code_enumFR Language_code_enum = "FR"
+
+	Language_code_enumNL Language_code_enum = "NL"
+
+	Language_code_enumSK Language_code_enum = "SK"
+
+	Language_code_enumHU Language_code_enum = "HU"
+
+	Language_code_enumHR Language_code_enum = "HR"
+
+	Language_code_enumSR Language_code_enum = "SR"
+
+	Language_code_enumBG Language_code_enum = "BG"
+
+	Language_code_enumRO Language_code_enum = "RO"
+
+	Language_code_enumRU Language_code_enum = "RU"
+
+	Language_code_enumCS Language_code_enum = "CS"
+
+	Language_code_enumPL Language_code_enum = "PL"
+
+	Language_code_enumPT Language_code_enum = "PT"
+
+	Language_code_enumES Language_code_enum = "ES"
+
+	Language_code_enumSV Language_code_enum = "SV"
+
+	Language_code_enumFI Language_code_enum = "FI"
+
+	Language_code_enumDA Language_code_enum = "DA"
+
+	Language_code_enumET Language_code_enum = "ET"
+
+	Language_code_enumLV Language_code_enum = "LV"
+
+	Language_code_enumLT Language_code_enum = "LT"
+
+	Language_code_enumIT Language_code_enum = "IT"
+
+	Language_code_enumMT Language_code_enum = "MT"
+
+	Language_code_enumEL Language_code_enum = "EL"
+
+	Language_code_enumSL Language_code_enum = "SL"
+)
+
+type Subject_code_enum string
+
+const (
+	Subject_code_enumANNOUN Subject_code_enum = "ANNOUN"
+
+	Subject_code_enumWARNIN Subject_code_enum = "WARNIN"
+
+	Subject_code_enumCANCEL Subject_code_enum = "CANCEL"
+
+	Subject_code_enumINFSER Subject_code_enum = "INFSER"
+
+	Subject_code_enumOBSTRU Subject_code_enum = "OBSTRU"
+
+	Subject_code_enumPAROBS Subject_code_enum = "PAROBS"
+
+	Subject_code_enumDELAY Subject_code_enum = "DELAY"
+
+	Subject_code_enumVESLEN Subject_code_enum = "VESLEN"
+
+	Subject_code_enumVESHEI Subject_code_enum = "VESHEI"
+
+	Subject_code_enumVESBRE Subject_code_enum = "VESBRE"
+
+	Subject_code_enumVESDRA Subject_code_enum = "VESDRA"
+
+	Subject_code_enumAVALEN Subject_code_enum = "AVALEN"
+
+	Subject_code_enumCLEHEI Subject_code_enum = "CLEHEI"
+
+	Subject_code_enumCLEWID Subject_code_enum = "CLEWID"
+
+	Subject_code_enumAVADEP Subject_code_enum = "AVADEP"
+
+	Subject_code_enumNOMOOR Subject_code_enum = "NOMOOR"
+
+	Subject_code_enumSERVIC Subject_code_enum = "SERVIC"
+
+	Subject_code_enumNOSERV Subject_code_enum = "NOSERV"
+
+	Subject_code_enumSPEED Subject_code_enum = "SPEED"
+
+	Subject_code_enumWAVWAS Subject_code_enum = "WAVWAS"
+
+	Subject_code_enumPASSIN Subject_code_enum = "PASSIN"
+
+	Subject_code_enumANCHOR Subject_code_enum = "ANCHOR"
+
+	Subject_code_enumOVRTAK Subject_code_enum = "OVRTAK"
+
+	Subject_code_enumMINPWR Subject_code_enum = "MINPWR"
+
+	Subject_code_enumDREDGE Subject_code_enum = "DREDGE"
+
+	Subject_code_enumWORK Subject_code_enum = "WORK"
+
+	Subject_code_enumEVENT Subject_code_enum = "EVENT"
+
+	Subject_code_enumCHGMAR Subject_code_enum = "CHGMAR"
+
+	Subject_code_enumCHGSER Subject_code_enum = "CHGSER"
+
+	Subject_code_enumSPCMAR Subject_code_enum = "SPCMAR"
+
+	Subject_code_enumEXERC Subject_code_enum = "EXERC"
+
+	Subject_code_enumLEADEP Subject_code_enum = "LEADEP"
+
+	Subject_code_enumLEVDEC Subject_code_enum = "LEVDEC"
+
+	Subject_code_enumLEVRIS Subject_code_enum = "LEVRIS"
+
+	Subject_code_enumLIMITA Subject_code_enum = "LIMITA"
+
+	Subject_code_enumMISECH Subject_code_enum = "MISECH"
+
+	Subject_code_enumECDISU Subject_code_enum = "ECDISU"
+
+	Subject_code_enumNEWOBJ Subject_code_enum = "NEWOBJ"
+
+	Subject_code_enumCHWWY Subject_code_enum = "CHWWY"
+
+	Subject_code_enumCONWWY Subject_code_enum = "CONWWY"
+
+	Subject_code_enumDIVER Subject_code_enum = "DIVER"
+
+	Subject_code_enumSPECTR Subject_code_enum = "SPECTR"
+
+	Subject_code_enumLOCRUL Subject_code_enum = "LOCRUL"
+
+	Subject_code_enumVHFCOV Subject_code_enum = "VHFCOV"
+
+	Subject_code_enumHIGVOL Subject_code_enum = "HIGVOL"
+
+	Subject_code_enumTURNIN Subject_code_enum = "TURNIN"
+
+	Subject_code_enumCONBRE Subject_code_enum = "CONBRE"
+
+	Subject_code_enumCONLEN Subject_code_enum = "CONLEN"
+
+	Subject_code_enumREMOBJ Subject_code_enum = "REMOBJ"
+)
+
+type Reason_code_enum string
+
+const (
+	Reason_code_enumEVENT Reason_code_enum = "EVENT"
+
+	Reason_code_enumWORK Reason_code_enum = "WORK"
+
+	Reason_code_enumDREDGE Reason_code_enum = "DREDGE"
+
+	Reason_code_enumEXERC Reason_code_enum = "EXERC"
+
+	Reason_code_enumHIGWAT Reason_code_enum = "HIGWAT"
+
+	Reason_code_enumHIWAI Reason_code_enum = "HIWAI"
+
+	Reason_code_enumHIWAII Reason_code_enum = "HIWAII"
+
+	Reason_code_enumLOWWAT Reason_code_enum = "LOWWAT"
+
+	Reason_code_enumSHALLO Reason_code_enum = "SHALLO"
+
+	Reason_code_enumCALAMI Reason_code_enum = "CALAMI"
+
+	Reason_code_enumLAUNCH Reason_code_enum = "LAUNCH"
+
+	Reason_code_enumDECLEV Reason_code_enum = "DECLEV"
+
+	Reason_code_enumFLOMEA Reason_code_enum = "FLOMEA"
+
+	Reason_code_enumBLDWRK Reason_code_enum = "BLDWRK"
+
+	Reason_code_enumREPAIR Reason_code_enum = "REPAIR"
+
+	Reason_code_enumINSPEC Reason_code_enum = "INSPEC"
+
+	Reason_code_enumFIRWRK Reason_code_enum = "FIRWRK"
+
+	Reason_code_enumLIMITA Reason_code_enum = "LIMITA"
+
+	Reason_code_enumCHGFWY Reason_code_enum = "CHGFWY"
+
+	Reason_code_enumCONSTR Reason_code_enum = "CONSTR"
+
+	Reason_code_enumDIVING Reason_code_enum = "DIVING"
+
+	Reason_code_enumSPECTR Reason_code_enum = "SPECTR"
+
+	Reason_code_enumEXT Reason_code_enum = "EXT"
+
+	Reason_code_enumMIN Reason_code_enum = "MIN"
+
+	Reason_code_enumSOUND Reason_code_enum = "SOUND"
+
+	Reason_code_enumOTHER Reason_code_enum = "OTHER"
+
+	Reason_code_enumSTRIKE Reason_code_enum = "STRIKE"
+
+	Reason_code_enumFLOMAT Reason_code_enum = "FLOMAT"
+
+	Reason_code_enumEXPLOS Reason_code_enum = "EXPLOS"
+
+	Reason_code_enumICE Reason_code_enum = "ICE"
+
+	Reason_code_enumOBSTAC Reason_code_enum = "OBSTAC"
+
+	Reason_code_enumCHGMAR Reason_code_enum = "CHGMAR"
+
+	Reason_code_enumDAMMAR Reason_code_enum = "DAMMAR"
+
+	Reason_code_enumFALMAT Reason_code_enum = "FALMAT"
+
+	Reason_code_enumMISECH Reason_code_enum = "MISECH"
+
+	Reason_code_enumHEARIS Reason_code_enum = "HEARIS"
+
+	Reason_code_enumHIGVOL Reason_code_enum = "HIGVOL"
+
+	Reason_code_enumECDISU Reason_code_enum = "ECDISU"
+
+	Reason_code_enumLOCRUL Reason_code_enum = "LOCRUL"
+
+	Reason_code_enumNEWOBJ Reason_code_enum = "NEWOBJ"
+
+	Reason_code_enumOBUNWA Reason_code_enum = "OBUNWA"
+
+	Reason_code_enumVHFCOV Reason_code_enum = "VHFCOV"
+
+	Reason_code_enumREMOBJ Reason_code_enum = "REMOBJ"
+
+	Reason_code_enumLEVRIS Reason_code_enum = "LEVRIS"
+
+	Reason_code_enumSPCMAR Reason_code_enum = "SPCMAR"
+
+	Reason_code_enumWERMCO Reason_code_enum = "WERMCO"
+
+	Reason_code_enumINFSER Reason_code_enum = "INFSER"
+)
+
+type Reporting_code_enum string
+
+const (
+	Reporting_code_enumINF Reporting_code_enum = "INF"
+
+	Reporting_code_enumADD Reporting_code_enum = "ADD"
+
+	Reporting_code_enumREG Reporting_code_enum = "REG"
+)
+
+type Communication_code_enum string
+
+const (
+	Communication_code_enumTE Communication_code_enum = "TE"
+
+	Communication_code_enumAP Communication_code_enum = "AP"
+
+	Communication_code_enumEM Communication_code_enum = "EM"
+
+	Communication_code_enumAH Communication_code_enum = "AH"
+
+	Communication_code_enumTT Communication_code_enum = "TT"
+
+	Communication_code_enumFX Communication_code_enum = "FX"
+
+	Communication_code_enumLS Communication_code_enum = "LS"
+
+	Communication_code_enumFS Communication_code_enum = "FS"
+
+	Communication_code_enumSO Communication_code_enum = "SO"
+
+	Communication_code_enumEI Communication_code_enum = "EI"
+)
+
+type Measure_code_enum string
+
+const (
+	Measure_code_enumDIS Measure_code_enum = "DIS"
+
+	Measure_code_enumREG Measure_code_enum = "REG"
+
+	Measure_code_enumBAR Measure_code_enum = "BAR"
+
+	Measure_code_enumVER Measure_code_enum = "VER"
+
+	Measure_code_enumLSD Measure_code_enum = "LSD"
+
+	Measure_code_enumWAL Measure_code_enum = "WAL"
+
+	Measure_code_enumNOM Measure_code_enum = "NOM"
+)
+
+type Barrage_code_enum string
+
+const (
+	Barrage_code_enumCLD Barrage_code_enum = "CLD"
+
+	Barrage_code_enumOPG Barrage_code_enum = "OPG"
+
+	Barrage_code_enumCLG Barrage_code_enum = "CLG"
+
+	Barrage_code_enumOPD Barrage_code_enum = "OPD"
+
+	Barrage_code_enumOPN Barrage_code_enum = "OPN"
+)
+
+type Regime_code_enum string
+
+const (
+	Regime_code_enumNO Regime_code_enum = "NO"
+
+	Regime_code_enumHI Regime_code_enum = "HI"
+
+	Regime_code_enumII Regime_code_enum = "II"
+
+	Regime_code_enumI Regime_code_enum = "I"
+
+	Regime_code_enumNN Regime_code_enum = "NN"
+
+	Regime_code_enumLO Regime_code_enum = "LO"
+)
+
+type Ice_condition_code_enum string
+
+const (
+	Ice_condition_code_enumA Ice_condition_code_enum = "A"
+
+	Ice_condition_code_enumB Ice_condition_code_enum = "B"
+
+	Ice_condition_code_enumC Ice_condition_code_enum = "C"
+
+	Ice_condition_code_enumD Ice_condition_code_enum = "D"
+
+	Ice_condition_code_enumE Ice_condition_code_enum = "E"
+
+	Ice_condition_code_enumF Ice_condition_code_enum = "F"
+
+	Ice_condition_code_enumG Ice_condition_code_enum = "G"
+
+	Ice_condition_code_enumH Ice_condition_code_enum = "H"
+
+	Ice_condition_code_enumK Ice_condition_code_enum = "K"
+
+	Ice_condition_code_enumL Ice_condition_code_enum = "L"
+
+	Ice_condition_code_enumM Ice_condition_code_enum = "M"
+
+	Ice_condition_code_enumP Ice_condition_code_enum = "P"
+
+	Ice_condition_code_enumR Ice_condition_code_enum = "R"
+
+	Ice_condition_code_enumS Ice_condition_code_enum = "S"
+
+	Ice_condition_code_enumU Ice_condition_code_enum = "U"
+
+	Ice_condition_code_enumO Ice_condition_code_enum = "O"
+
+	Ice_condition_code_enumV Ice_condition_code_enum = "V"
+)
+
+type Ice_accessibility_code_enum string
+
+const (
+	Ice_accessibility_code_enumA Ice_accessibility_code_enum = "A"
+
+	Ice_accessibility_code_enumB Ice_accessibility_code_enum = "B"
+
+	Ice_accessibility_code_enumF Ice_accessibility_code_enum = "F"
+
+	Ice_accessibility_code_enumL Ice_accessibility_code_enum = "L"
+
+	Ice_accessibility_code_enumC Ice_accessibility_code_enum = "C"
+
+	Ice_accessibility_code_enumD Ice_accessibility_code_enum = "D"
+
+	Ice_accessibility_code_enumE Ice_accessibility_code_enum = "E"
+
+	Ice_accessibility_code_enumG Ice_accessibility_code_enum = "G"
+
+	Ice_accessibility_code_enumH Ice_accessibility_code_enum = "H"
+
+	Ice_accessibility_code_enumM Ice_accessibility_code_enum = "M"
+
+	Ice_accessibility_code_enumK Ice_accessibility_code_enum = "K"
+
+	Ice_accessibility_code_enumT Ice_accessibility_code_enum = "T"
+
+	Ice_accessibility_code_enumP Ice_accessibility_code_enum = "P"
+
+	Ice_accessibility_code_enumV Ice_accessibility_code_enum = "V"
+
+	Ice_accessibility_code_enumX Ice_accessibility_code_enum = "X"
+)
+
+type Ice_classification_code_enum string
+
+const (
+	Ice_classification_code_enumA Ice_classification_code_enum = "A"
+
+	Ice_classification_code_enumB Ice_classification_code_enum = "B"
+
+	Ice_classification_code_enumC Ice_classification_code_enum = "C"
+
+	Ice_classification_code_enumD Ice_classification_code_enum = "D"
+
+	Ice_classification_code_enumE Ice_classification_code_enum = "E"
+)
+
+type Ice_situation_code_enum string
+
+const (
+	Ice_situation_code_enumNOL Ice_situation_code_enum = "NOL"
+
+	Ice_situation_code_enumLIM Ice_situation_code_enum = "LIM"
+
+	Ice_situation_code_enumNON Ice_situation_code_enum = "NON"
+)
+
+type Weather_class_code_enum string
+
+const (
+	Weather_class_code_enumCLR Weather_class_code_enum = "CLR"
+
+	Weather_class_code_enumCLDY Weather_class_code_enum = "CLDY"
+
+	Weather_class_code_enumOCST Weather_class_code_enum = "OCST"
+
+	Weather_class_code_enumDZZL Weather_class_code_enum = "DZZL"
+
+	Weather_class_code_enumRAIN Weather_class_code_enum = "RAIN"
+
+	Weather_class_code_enumLRAIN Weather_class_code_enum = "LRAIN"
+
+	Weather_class_code_enumORAIN Weather_class_code_enum = "ORAIN"
+
+	Weather_class_code_enumHRAIN Weather_class_code_enum = "HRAIN"
+
+	Weather_class_code_enumSLEET Weather_class_code_enum = "SLEET"
+
+	Weather_class_code_enumSNOW Weather_class_code_enum = "SNOW"
+
+	Weather_class_code_enumSNFALL Weather_class_code_enum = "SNFALL"
+
+	Weather_class_code_enumHAIL Weather_class_code_enum = "HAIL"
+
+	Weather_class_code_enumSHWRS Weather_class_code_enum = "SHWRS"
+
+	Weather_class_code_enumTHSTRM Weather_class_code_enum = "THSTRM"
+
+	Weather_class_code_enumHAZY Weather_class_code_enum = "HAZY"
+
+	Weather_class_code_enumFOG Weather_class_code_enum = "FOG"
+
+	Weather_class_code_enumFOGPAT Weather_class_code_enum = "FOGPAT"
+
+	Weather_class_code_enumGALE Weather_class_code_enum = "GALE"
+
+	Weather_class_code_enumSTRM Weather_class_code_enum = "STRM"
+
+	Weather_class_code_enumHURRC Weather_class_code_enum = "HURRC"
+
+	Weather_class_code_enumFZRA Weather_class_code_enum = "FZRA"
+)
+
+type Weather_item_code_enum string
+
+const (
+	Weather_item_code_enumWI Weather_item_code_enum = "WI"
+
+	Weather_item_code_enumWA Weather_item_code_enum = "WA"
+
+	Weather_item_code_enumFG Weather_item_code_enum = "FG"
+
+	Weather_item_code_enumRN Weather_item_code_enum = "RN"
+
+	Weather_item_code_enumSN Weather_item_code_enum = "SN"
+
+	Weather_item_code_enumAT Weather_item_code_enum = "AT"
+
+	Weather_item_code_enumWT Weather_item_code_enum = "WT"
+)
+
+type Weather_category_code_enum string
+
+const (
+	Weather_category_code_enum0 Weather_category_code_enum = "0"
+
+	Weather_category_code_enum1 Weather_category_code_enum = "1"
+
+	Weather_category_code_enum2 Weather_category_code_enum = "2"
+
+	Weather_category_code_enum3 Weather_category_code_enum = "3"
+
+	Weather_category_code_enum4 Weather_category_code_enum = "4"
+
+	Weather_category_code_enum5 Weather_category_code_enum = "5"
+
+	Weather_category_code_enum6 Weather_category_code_enum = "6"
+
+	Weather_category_code_enum7 Weather_category_code_enum = "7"
+
+	Weather_category_code_enum8 Weather_category_code_enum = "8"
+
+	Weather_category_code_enum9 Weather_category_code_enum = "9"
+
+	Weather_category_code_enum10 Weather_category_code_enum = "10"
+
+	Weather_category_code_enum11 Weather_category_code_enum = "11"
+
+	Weather_category_code_enum12 Weather_category_code_enum = "12"
+
+	Weather_category_code_enum13 Weather_category_code_enum = "13"
+
+	Weather_category_code_enum14 Weather_category_code_enum = "14"
+
+	Weather_category_code_enum15 Weather_category_code_enum = "15"
+
+	Weather_category_code_enum16 Weather_category_code_enum = "16"
+
+	Weather_category_code_enum17 Weather_category_code_enum = "17"
+
+	Weather_category_code_enum18 Weather_category_code_enum = "18"
+
+	Weather_category_code_enum19 Weather_category_code_enum = "19"
+
+	Weather_category_code_enum20 Weather_category_code_enum = "20"
+
+	Weather_category_code_enum21 Weather_category_code_enum = "21"
+
+	Weather_category_code_enum22 Weather_category_code_enum = "22"
+)
+
+type Weather_direction_code_enum string
+
+const (
+	Weather_direction_code_enumN Weather_direction_code_enum = "N"
+
+	Weather_direction_code_enumNE Weather_direction_code_enum = "NE"
+
+	Weather_direction_code_enumE Weather_direction_code_enum = "E"
+
+	Weather_direction_code_enumSE Weather_direction_code_enum = "SE"
+
+	Weather_direction_code_enumS Weather_direction_code_enum = "S"
+
+	Weather_direction_code_enumSW Weather_direction_code_enum = "SW"
+
+	Weather_direction_code_enumW Weather_direction_code_enum = "W"
+
+	Weather_direction_code_enumNW Weather_direction_code_enum = "NW"
+
+	Weather_direction_code_enumWRB Weather_direction_code_enum = "WRB"
+)
+
+// Internal ID - best practice: global unique identifier
+type Internal_id_type string
+
+// ISRS location code, unique identification of the geo object as defined in RIS Index encoding guide
+type Isrs_code_type string
+
+type Type_code_enum string
+
+const (
+	Type_code_enumRIV Type_code_enum = "RIV"
+
+	Type_code_enumCAN Type_code_enum = "CAN"
+
+	Type_code_enumLAK Type_code_enum = "LAK"
+
+	Type_code_enumFWY Type_code_enum = "FWY"
+
+	Type_code_enumLCK Type_code_enum = "LCK"
+
+	Type_code_enumBRI Type_code_enum = "BRI"
+
+	Type_code_enumRMP Type_code_enum = "RMP"
+
+	Type_code_enumBAR Type_code_enum = "BAR"
+
+	Type_code_enumBNK Type_code_enum = "BNK"
+
+	Type_code_enumGAU Type_code_enum = "GAU"
+
+	Type_code_enumBUO Type_code_enum = "BUO"
+
+	Type_code_enumBEA Type_code_enum = "BEA"
+
+	Type_code_enumANC Type_code_enum = "ANC"
+
+	Type_code_enumBER Type_code_enum = "BER"
+
+	Type_code_enumMOO Type_code_enum = "MOO"
+
+	Type_code_enumTER Type_code_enum = "TER"
+
+	Type_code_enumHAR Type_code_enum = "HAR"
+
+	Type_code_enumFDO Type_code_enum = "FDO"
+
+	Type_code_enumCAB Type_code_enum = "CAB"
+
+	Type_code_enumFER Type_code_enum = "FER"
+
+	Type_code_enumPIP Type_code_enum = "PIP"
+
+	Type_code_enumPPO Type_code_enum = "PPO"
+
+	Type_code_enumHFA Type_code_enum = "HFA"
+
+	Type_code_enumHMO Type_code_enum = "HMO"
+
+	Type_code_enumSHY Type_code_enum = "SHY"
+
+	Type_code_enumREF Type_code_enum = "REF"
+
+	Type_code_enumMAR Type_code_enum = "MAR"
+
+	Type_code_enumLIG Type_code_enum = "LIG"
+
+	Type_code_enumSIG Type_code_enum = "SIG"
+
+	Type_code_enumTUR Type_code_enum = "TUR"
+
+	Type_code_enumCBR Type_code_enum = "CBR"
+
+	Type_code_enumTUN Type_code_enum = "TUN"
+
+	Type_code_enumBCO Type_code_enum = "BCO"
+
+	Type_code_enumREP Type_code_enum = "REP"
+
+	Type_code_enumFLO Type_code_enum = "FLO"
+
+	Type_code_enumSLI Type_code_enum = "SLI"
+
+	Type_code_enumDUK Type_code_enum = "DUK"
+
+	Type_code_enumVTC Type_code_enum = "VTC"
+
+	Type_code_enumRES Type_code_enum = "RES"
+
+	Type_code_enumLKB Type_code_enum = "LKB"
+
+	Type_code_enumBRO Type_code_enum = "BRO"
+
+	Type_code_enumBNS Type_code_enum = "BNS"
+)
+
+type Interval_code_enum string
+
+const (
+	Interval_code_enumCON Interval_code_enum = "CON"
+
+	Interval_code_enumDAY Interval_code_enum = "DAY"
+
+	Interval_code_enumWRK Interval_code_enum = "WRK"
+
+	Interval_code_enumWKN Interval_code_enum = "WKN"
+
+	Interval_code_enumSUN Interval_code_enum = "SUN"
+
+	Interval_code_enumMON Interval_code_enum = "MON"
+
+	Interval_code_enumTUE Interval_code_enum = "TUE"
+
+	Interval_code_enumWED Interval_code_enum = "WED"
+
+	Interval_code_enumTHU Interval_code_enum = "THU"
+
+	Interval_code_enumFRI Interval_code_enum = "FRI"
+
+	Interval_code_enumSAT Interval_code_enum = "SAT"
+
+	Interval_code_enumDTI Interval_code_enum = "DTI"
+
+	Interval_code_enumNTI Interval_code_enum = "NTI"
+
+	Interval_code_enumRVI Interval_code_enum = "RVI"
+
+	Interval_code_enumEXC Interval_code_enum = "EXC"
+
+	Interval_code_enumWRD Interval_code_enum = "WRD"
+)
+
+type Limitation_code_enum string
+
+const (
+	Limitation_code_enumOBSTRU Limitation_code_enum = "OBSTRU"
+
+	Limitation_code_enumPAROBS Limitation_code_enum = "PAROBS"
+
+	Limitation_code_enumDELAY Limitation_code_enum = "DELAY"
+
+	Limitation_code_enumVESLEN Limitation_code_enum = "VESLEN"
+
+	Limitation_code_enumVESHEI Limitation_code_enum = "VESHEI"
+
+	Limitation_code_enumVESBRE Limitation_code_enum = "VESBRE"
+
+	Limitation_code_enumVESDRA Limitation_code_enum = "VESDRA"
+
+	Limitation_code_enumAVALEN Limitation_code_enum = "AVALEN"
+
+	Limitation_code_enumCLEHEI Limitation_code_enum = "CLEHEI"
+
+	Limitation_code_enumCLEWID Limitation_code_enum = "CLEWID"
+
+	Limitation_code_enumAVADEP Limitation_code_enum = "AVADEP"
+
+	Limitation_code_enumNOMOOR Limitation_code_enum = "NOMOOR"
+
+	Limitation_code_enumSERVIC Limitation_code_enum = "SERVIC"
+
+	Limitation_code_enumNOSERV Limitation_code_enum = "NOSERV"
+
+	Limitation_code_enumSPEED Limitation_code_enum = "SPEED"
+
+	Limitation_code_enumWAVWAS Limitation_code_enum = "WAVWAS"
+
+	Limitation_code_enumPASSIN Limitation_code_enum = "PASSIN"
+
+	Limitation_code_enumANCHOR Limitation_code_enum = "ANCHOR"
+
+	Limitation_code_enumOVRTAK Limitation_code_enum = "OVRTAK"
+
+	Limitation_code_enumMINPWR Limitation_code_enum = "MINPWR"
+
+	Limitation_code_enumALTER Limitation_code_enum = "ALTER"
+
+	Limitation_code_enumCAUTIO Limitation_code_enum = "CAUTIO"
+
+	Limitation_code_enumNOLIM Limitation_code_enum = "NOLIM"
+
+	Limitation_code_enumTURNIN Limitation_code_enum = "TURNIN"
+
+	Limitation_code_enumNOSHORE Limitation_code_enum = "NOSHORE"
+
+	Limitation_code_enumCONBRE Limitation_code_enum = "CONBRE"
+
+	Limitation_code_enumCONLEN Limitation_code_enum = "CONLEN"
+
+	Limitation_code_enumLEADEP Limitation_code_enum = "LEADEP"
+
+	Limitation_code_enumNOBERT Limitation_code_enum = "NOBERT"
+)
+
+type Position_code_enum string
+
+const (
+	Position_code_enumAL Position_code_enum = "AL"
+
+	Position_code_enumLE Position_code_enum = "LE"
+
+	Position_code_enumMI Position_code_enum = "MI"
+
+	Position_code_enumRI Position_code_enum = "RI"
+
+	Position_code_enumLB Position_code_enum = "LB"
+
+	Position_code_enumRB Position_code_enum = "RB"
+
+	Position_code_enumN Position_code_enum = "N"
+
+	Position_code_enumNE Position_code_enum = "NE"
+
+	Position_code_enumE Position_code_enum = "E"
+
+	Position_code_enumSE Position_code_enum = "SE"
+
+	Position_code_enumS Position_code_enum = "S"
+
+	Position_code_enumSW Position_code_enum = "SW"
+
+	Position_code_enumW Position_code_enum = "W"
+
+	Position_code_enumNW Position_code_enum = "NW"
+
+	Position_code_enumBI Position_code_enum = "BI"
+
+	Position_code_enumSM Position_code_enum = "SM"
+
+	Position_code_enumOL Position_code_enum = "OL"
+
+	Position_code_enumEW Position_code_enum = "EW"
+
+	Position_code_enumMP Position_code_enum = "MP"
+
+	Position_code_enumFP Position_code_enum = "FP"
+
+	Position_code_enumVA Position_code_enum = "VA"
+
+	Position_code_enumRY Position_code_enum = "RY"
+
+	Position_code_enumGY Position_code_enum = "GY"
+)
+
+type Reference_code_enum string
+
+const (
+	Reference_code_enumNAP Reference_code_enum = "NAP"
+
+	Reference_code_enumKP Reference_code_enum = "KP"
+
+	Reference_code_enumFZP Reference_code_enum = "FZP"
+
+	Reference_code_enumADR Reference_code_enum = "ADR"
+
+	Reference_code_enumTAW Reference_code_enum = "TAW"
+
+	Reference_code_enumPUL Reference_code_enum = "PUL"
+
+	Reference_code_enumNGM Reference_code_enum = "NGM"
+
+	Reference_code_enumETRS Reference_code_enum = "ETRS"
+
+	Reference_code_enumPOT Reference_code_enum = "POT"
+
+	Reference_code_enumLDC Reference_code_enum = "LDC"
+
+	Reference_code_enumHDC Reference_code_enum = "HDC"
+
+	Reference_code_enumZPG Reference_code_enum = "ZPG"
+
+	Reference_code_enumGLW Reference_code_enum = "GLW"
+
+	Reference_code_enumHSW Reference_code_enum = "HSW"
+
+	Reference_code_enumLNW Reference_code_enum = "LNW"
+
+	Reference_code_enumHNW Reference_code_enum = "HNW"
+
+	Reference_code_enumIGN Reference_code_enum = "IGN"
+
+	Reference_code_enumWGS Reference_code_enum = "WGS"
+
+	Reference_code_enumRN Reference_code_enum = "RN"
+
+	Reference_code_enumHBO Reference_code_enum = "HBO"
+)
+
+type Indication_code_enum string
+
+const (
+	Indication_code_enumMAX Indication_code_enum = "MAX"
+
+	Indication_code_enumMIN Indication_code_enum = "MIN"
+
+	Indication_code_enumRED Indication_code_enum = "RED"
+)
+
+type Target_group_code_enum string
+
+const (
+	Target_group_code_enumALL Target_group_code_enum = "ALL"
+
+	Target_group_code_enumCDG Target_group_code_enum = "CDG"
+
+	Target_group_code_enumCOM Target_group_code_enum = "COM"
+
+	Target_group_code_enumPAX Target_group_code_enum = "PAX"
+
+	Target_group_code_enumPLE Target_group_code_enum = "PLE"
+
+	Target_group_code_enumCNV Target_group_code_enum = "CNV"
+
+	Target_group_code_enumPUS Target_group_code_enum = "PUS"
+
+	Target_group_code_enumNNU Target_group_code_enum = "NNU"
+
+	Target_group_code_enumLOA Target_group_code_enum = "LOA"
+
+	Target_group_code_enumSMA Target_group_code_enum = "SMA"
+
+	Target_group_code_enumCND Target_group_code_enum = "CND"
+
+	Target_group_code_enumWOC Target_group_code_enum = "WOC"
+
+	Target_group_code_enumMOV Target_group_code_enum = "MOV"
+
+	Target_group_code_enumNMV Target_group_code_enum = "NMV"
+)
+
+type Direction_code_enum string
+
+const (
+	Direction_code_enumALL Direction_code_enum = "ALL"
+
+	Direction_code_enumUPS Direction_code_enum = "UPS"
+
+	Direction_code_enumDWN Direction_code_enum = "DWN"
+)
+
+type Unit_enum string
+
+const (
+	Unit_enumCm Unit_enum = "cm"
+
+	Unit_enumM3s Unit_enum = "m³/s"
+
+	Unit_enumH Unit_enum = "h"
+
+	Unit_enumKmh Unit_enum = "km/h"
+
+	Unit_enumKW Unit_enum = "kW"
+
+	Unit_enumMs Unit_enum = "m/s"
+
+	Unit_enumMmh Unit_enum = "mm/h"
+
+	Unit_enumC Unit_enum = "°C"
+)
+
+type RIS_Message_Type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts.ms/2.0.4.0 result_message"`
+
+	// Identification section
+	Identification *Identification_type `xml:"identification,omitempty"`
+
+	// Fairway and traffic related section
+	Ftm []*Ftm_type `xml:"ftm,omitempty"`
+
+	// Water related section
+	Wrm []*Wrm_type `xml:"wrm,omitempty"`
+
+	// Ice related section
+	Icem []*Icem_type `xml:"icem,omitempty"`
+
+	// Weather related section
+	Werm []*Werm_type `xml:"werm,omitempty"`
+}
+
+type Identification_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 identification"`
+
+	// Internal ID
+	Internal_id *Internal_id_type `xml:"internal_id,omitempty"`
+
+	// Sender (System) of the message
+	From string `xml:"from,omitempty"`
+
+	// Originator (initiator) of the information in this message
+	Originator string `xml:"originator,omitempty"`
+
+	// Country where message is valid
+	Country_code *Country_code_enum `xml:"country_code,omitempty"`
+
+	// Original language used in the textual info. (contents)
+	Language_code *Language_code_enum `xml:"language_code,omitempty"`
+
+	// District / Region within the specified country, where the message is applicable
+	District string `xml:"district,omitempty"`
+
+	// Date and time of publication including time zone
+	Date_issue time.Time `xml:"date_issue,omitempty"`
+}
+
+type Ftm_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 ftm_type"`
+
+	// Internal ID
+	Internal_id *Internal_id_type `xml:"internal_id,omitempty"`
+
+	// NtS Number
+	Nts_number *Nts_number_type `xml:"nts_number,omitempty"`
+
+	// Target group information
+	Target_group []*Target_group_type `xml:"target_group,omitempty"`
+
+	// Subject code must contain one of the following: Announcement (ANNOUN), Warning (WARNIN), Notice withdrawn (CANCEL) or Information service (INFSER). More information on the use of codes can be found in the NtS Encoding Guide.
+	Subject_code *Subject_code_enum `xml:"subject_code,omitempty"`
+
+	// Overall period of validity
+	Validity_period *Validity_period_type `xml:"validity_period,omitempty"`
+
+	// Additional information in local language
+	Contents string `xml:"contents,omitempty"`
+
+	// Notice source (name of authority)
+	Source string `xml:"source,omitempty"`
+
+	// Reason / justification of the notice
+	Reason_code *Reason_code_enum `xml:"reason_code,omitempty"`
+
+	// Communication channel information
+	Communication []*Communication_type `xml:"communication,omitempty"`
+
+	// Fairway section
+	Fairway_section *Fairway_section_type `xml:"fairway_section,omitempty"`
+
+	// Object section
+	Object *Object_type `xml:"object,omitempty"`
+}
+
+type Communication_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 communication_type"`
+
+	// Reporting regime (information, or duty to report)
+	Reporting_code *Reporting_code_enum `xml:"reporting_code,omitempty"`
+
+	// Communication code (telephone, VHF etc.)
+	Communication_code *Communication_code_enum `xml:"communication_code,omitempty"`
+
+	// Telephone, VHF number (including callsign), e-mail address, URL or teletext
+	Number string `xml:"number,omitempty"`
+
+	// Name of the attachment or additional information
+	Label string `xml:"label,omitempty"`
+
+	// Additional remarks concerning the communication
+	Remark string `xml:"remark,omitempty"`
+}
+
+type Object_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 object_type"`
+
+	// Geo Information of object
+	Geo_object *Geo_object_type `xml:"geo_object,omitempty"`
+
+	// Object limitation section
+	Limitation []*Limitation_type `xml:"limitation,omitempty"`
+}
+
+type Wrm_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 wrm"`
+
+	// Internal ID
+	Internal_id *Internal_id_type `xml:"internal_id,omitempty"`
+
+	// NtS Number
+	Nts_number *Nts_number_type `xml:"nts_number,omitempty"`
+
+	// Overall period of validity
+	Validity_period *Validity_period_type `xml:"validity_period,omitempty"`
+
+	// Object section
+	Geo_object *Geo_object_type `xml:"geo_object,omitempty"`
+
+	// Value reference (measurement reference)
+	Reference_code *Reference_code_enum `xml:"reference_code,omitempty"`
+
+	// Measurements (normal or predicted values)
+	Measure []*Measure_type `xml:"measure,omitempty"`
+}
+
+type Measure_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 measure"`
+
+	// Predicted measurement (1 or true) or real measurement (0 or false)
+	Predicted bool `xml:"predicted,omitempty"`
+
+	// Kind of water related information
+	Measure_code *Measure_code_enum `xml:"measure_code,omitempty"`
+
+	// Measured or predicted value
+	Value float32 `xml:"value,omitempty"`
+
+	// Lowest value of confidence interval
+	Value_min float32 `xml:"value_min,omitempty"`
+
+	// Highest value of confidence interval
+	Value_max float32 `xml:"value_max,omitempty"`
+
+	// Unit of the water related value
+	Unit *Unit_enum `xml:"unit,omitempty"`
+
+	// Barrage status
+	Barrage_code *Barrage_code_enum `xml:"barrage_code,omitempty"`
+
+	// Regime applicable
+	Regime_code *Regime_code_enum `xml:"regime_code,omitempty"`
+
+	// Date and Time of measurement or predicted value including time zone
+	Measuredate time.Time `xml:"measuredate,omitempty"`
+
+	// Difference with comparative value
+	Difference *Difference_type `xml:"difference,omitempty"`
+}
+
+type Difference_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 difference"`
+
+	// Difference with comparative value
+	Value_difference float32 `xml:"value_difference,omitempty"`
+
+	// Time difference with measuredata of comparative measurement
+	Time_difference *Duration `xml:"time_difference,omitempty"`
+}
+
+type Icem_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 icem_type"`
+
+	// Internal ID
+	Internal_id *Internal_id_type `xml:"internal_id,omitempty"`
+
+	// NtS Number
+	Nts_number *Nts_number_type `xml:"nts_number,omitempty"`
+
+	// Overall period of validity
+	Validity_period *Validity_period_type `xml:"validity_period,omitempty"`
+
+	// Fairway section - the limitation inside the fairway section cannot be used in the ICEM
+	Fairway_section *Fairway_section_type `xml:"fairway_section,omitempty"`
+
+	// Ice conditions
+	Ice_condition []*Ice_condition_type `xml:"ice_condition,omitempty"`
+}
+
+type Ice_condition_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 ice_condition_type"`
+
+	// Date and Time of measurement or prediction including time zone
+	Measuredate time.Time `xml:"measuredate,omitempty"`
+
+	// Condition code
+	Ice_condition_code *Ice_condition_code_enum `xml:"ice_condition_code,omitempty"`
+
+	// Accessibility code
+	Ice_accessibility_code *Ice_accessibility_code_enum `xml:"ice_accessibility_code,omitempty"`
+
+	// Classification code
+	Ice_classification_code *Ice_classification_code_enum `xml:"ice_classification_code,omitempty"`
+
+	// Situation code
+	Ice_situation_code *Ice_situation_code_enum `xml:"ice_situation_code,omitempty"`
+}
+
+type Werm_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 werm_type"`
+
+	// Internal ID
+	Internal_id *Internal_id_type `xml:"internal_id,omitempty"`
+
+	// NtS Number
+	Nts_number *Nts_number_type `xml:"nts_number,omitempty"`
+
+	// Overall period of validity
+	Validity_period *Validity_period_type `xml:"validity_period,omitempty"`
+
+	// Fairway section
+	Fairway_section *Fairway_section_werm_type `xml:"fairway_section,omitempty"`
+
+	// Actual or Forecast report sections
+	Weather_report *Weather_report_type `xml:"weather_report,omitempty"`
+}
+
+type Fairway_section_werm_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 fairway_section_werm_type"`
+
+	// Geo Information of fairway
+	Geo_object *Geo_object_type `xml:"geo_object,omitempty"`
+}
+
+type Weather_report_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 weather_report_type"`
+
+	// Date and time of measurement or predicted value including timezone
+	Measuredate time.Time `xml:"measuredate,omitempty"`
+
+	// Forecast (true or 1) OR Actual report (false or 0)
+	Forecast bool `xml:"forecast,omitempty"`
+
+	// Classification of weather report
+	Weather_class_code []*Weather_class_code_enum `xml:"weather_class_code,omitempty"`
+
+	// Weather items
+	Weather_item []*Weather_item_type `xml:"weather_item,omitempty"`
+}
+
+type Weather_item_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 weather_item_type"`
+
+	// Weather item type (Wind, Wave etc)
+	Weather_item_code *Weather_item_code_enum `xml:"weather_item_code,omitempty"`
+
+	// Actual or Minimum value
+	Value_min float32 `xml:"value_min,omitempty"`
+
+	// Maximum value
+	Value_max float32 `xml:"value_max,omitempty"`
+
+	// Gusts value (Wind)
+	Value_gusts float32 `xml:"value_gusts,omitempty"`
+
+	// Unit of the value
+	Unit *Unit_enum `xml:"unit,omitempty"`
+
+	// Classification of wind report
+	Weather_category_code *Weather_category_code_enum `xml:"weather_category_code,omitempty"`
+
+	// Direction of wind or wave
+	Direction_code_min *Weather_direction_code_enum `xml:"direction_code_min,omitempty"`
+
+	// Direction of wind or wave
+	Direction_code_max *Weather_direction_code_enum `xml:"direction_code_max,omitempty"`
+}
+
+type Nts_number_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 nts_number"`
+
+	// Name of the publishing organisation (NtS Provider)
+	Organisation string `xml:"organisation,omitempty"`
+
+	// Year of first issuing of the notice
+	Year *GYear `xml:"year,omitempty"`
+
+	// Number of the notice (per year, starting with: 1, 0 shall not be used for published notices)
+	Number int32 `xml:"number,omitempty"`
+
+	// Serial number of notice (replacements and withdrawals), original notice: 0
+	Serial_number int32 `xml:"serial_number,omitempty"`
+}
+
+type Validity_period_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 validity_period"`
+
+	// Start date of validity period including time zone
+	Date_start string `xml:"date_start,omitempty"`
+
+	// End date of validity period including time zone
+	Date_end string `xml:"date_end,omitempty"`
+}
+
+type Fairway_section_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 fairway_section_type"`
+
+	// Geo information of fairway
+	Geo_object *Geo_object_type `xml:"geo_object,omitempty"`
+
+	// Fairway section limitations
+	Limitation []*Limitation_type `xml:"limitation,omitempty"`
+}
+
+type Geo_object_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 geo_object"`
+
+	// ISRS Location Code of the fairway/object
+	Id *Isrs_code_type `xml:"id,omitempty"`
+
+	// Local name of the fairway section
+	Name string `xml:"name,omitempty"`
+
+	// Type of geographical object
+	Type_code *Type_code_enum `xml:"type_code,omitempty"`
+
+	// Describes the position related to the fairway
+	Position_code *Position_code_enum `xml:"position_code,omitempty"`
+
+	// Fairway section begin and end coordinates
+	Coordinate *Coordinate_type `xml:"coordinate,omitempty"`
+
+	// Waterway name (usefull if no RIS Index is available)
+	Fairway_name string `xml:"fairway_name,omitempty"`
+}
+
+type Coordinate_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 coordinate"`
+
+	Lat string `xml:"lat,omitempty"`
+
+	Long string `xml:"long,omitempty"`
+}
+
+type Limitation_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 limitation_type"`
+
+	// Limitation periods / intervals
+	Limitation_period []*Limitation_period_type `xml:"limitation_period,omitempty"`
+
+	// Kind of limitation
+	Limitation_code *Limitation_code_enum `xml:"limitation_code,omitempty"`
+
+	// Describes the position of the limitation related to the fairway
+	Position_code *Position_code_enum `xml:"position_code,omitempty"`
+
+	// Value of limitation (i.e.  max draught)
+	Value float32 `xml:"value,omitempty"`
+
+	// Unit of the value of the limitation
+	Unit *Unit_enum `xml:"unit,omitempty"`
+
+	// Value reference
+	Reference_code *Reference_code_enum `xml:"reference_code,omitempty"`
+
+	// Minimum or maximum or reduced by
+	Indication_code *Indication_code_enum `xml:"indication_code,omitempty"`
+
+	// Target group information
+	Target_group []*Target_group_type `xml:"target_group,omitempty"`
+}
+
+type Limitation_period_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 limitation_period_type"`
+
+	// Start date of limitation period including time zone
+	Date_start time.Time `xml:"date_start,omitempty"`
+
+	// End date of limitation period including time zone
+	Date_end time.Time `xml:"date_end,omitempty"`
+
+	// Start time of limitation period without time zone
+	Time_start time.Time `xml:"time_start,omitempty"`
+
+	// End time of limitation period without time zone
+	Time_end time.Time `xml:"time_end,omitempty"`
+
+	// Interval for limitation if applicable
+	Interval_code *Interval_code_enum `xml:"interval_code,omitempty"`
+}
+
+type Target_group_type struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/nts/4.0.4.0 target_group_type"`
+
+	// Target group (vessel type)
+	Target_group_code *Target_group_code_enum `xml:"target_group_code,omitempty"`
+
+	// Upstream or downstream traffic, or both
+	Direction_code *Direction_code_enum `xml:"direction_code,omitempty"`
+}
+
+type NtS_message_service interface {
+	Get_messages(request *Get_messages_query) (*Get_messages_result, error)
+}
+
+type INtSMessageService struct {
+	client *soap.SOAPClient
+}
+
+func NewINtSMessageService(url string, tls bool, auth *soap.BasicAuth) *INtSMessageService {
+	if url == "" {
+		url = ""
+	}
+	client := soap.NewSOAPClient(url, tls, auth)
+	return &INtSMessageService{
+		client: client,
+	}
+}
+
+func NewINtSMessageServiceWithTLSConfig(url string, tlsCfg *tls.Config, auth *soap.BasicAuth) *INtSMessageService {
+	if url == "" {
+		url = ""
+	}
+	client := soap.NewSOAPClientWithTLSConfig(url, tlsCfg, auth)
+
+	return &INtSMessageService{
+		client: client,
+	}
+}
+
+func (service *INtSMessageService) Get_messages(request *Get_messages_query) (*Get_messages_result, error) {
+	response := new(Get_messages_result)
+	err := service.client.Call("http://www.ris.eu/nts.ms/get_messages", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}