From 790450c8668d9c85410f4d854c928bea7dbff671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20van=20der=20Kaap?= Date: Fri, 4 Apr 2025 14:32:49 +0200 Subject: [PATCH 1/7] Started on WMS Capabilities Generator input --- api/v3/shared_types.go | 14 +----- api/v3/wfs_types.go | 4 ++ api/v3/wms_types.go | 4 ++ .../capabilities_generator.go | 18 +++++-- .../capabilities_generator_test.go | 32 ++++++++++++ .../capabilitiesgenerator/mapper.go | 49 +++++++++++++++++-- 6 files changed, 101 insertions(+), 20 deletions(-) diff --git a/api/v3/shared_types.go b/api/v3/shared_types.go index e08a688..c56bc74 100644 --- a/api/v3/shared_types.go +++ b/api/v3/shared_types.go @@ -35,6 +35,7 @@ type WMSWFS interface { HasPostgisData() bool // Sha1 hash of the objects name ID() string + URLPath() string } type Mapfile struct { @@ -112,18 +113,7 @@ func GetHost() string { } func GetBaseURLPath[T WMSWFS](o T) string { - var serviceURL string - switch any(o).(type) { - case *WFS: - if WFS, ok := any(o).(*WFS); ok { - serviceURL = WFS.Spec.Service.URL - } - case *WMS: - if WMS, ok := any(o).(*WMS); ok { - serviceURL = WMS.Spec.Service.URL - } - } - + serviceURL := o.URLPath() parsed, _ := url.Parse(serviceURL) return strings.TrimPrefix(parsed.Path, "/") } diff --git a/api/v3/wfs_types.go b/api/v3/wfs_types.go index 7eadf44..f94b49b 100644 --- a/api/v3/wfs_types.go +++ b/api/v3/wfs_types.go @@ -150,3 +150,7 @@ func (wfs *WFS) Options() *Options { func (wfs *WFS) ID() string { return Sha1HashOfName(wfs) } + +func (wfs *WFS) URLPath() string { + return wfs.Spec.Service.URL +} diff --git a/api/v3/wms_types.go b/api/v3/wms_types.go index f0e32e0..874ac9b 100644 --- a/api/v3/wms_types.go +++ b/api/v3/wms_types.go @@ -267,3 +267,7 @@ func (wms *WMS) Options() *Options { func (wms *WMS) ID() string { return Sha1HashOfName(wms) } + +func (wms *WMS) URLPath() string { + return wms.Spec.Service.URL +} diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator.go b/internal/controller/capabilitiesgenerator/capabilities_generator.go index bbd3076..5fbd7ac 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator.go @@ -1,7 +1,6 @@ package capabilitiesgenerator import ( - "errors" "fmt" pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" @@ -37,8 +36,8 @@ func GetInput[W pdoknlv3.WMSWFS](webservice W, ownerInfo *smoothoperatorv1.Owner return createInputForWFS(WFS, ownerInfo) } case *pdoknlv3.WMS: - if _, ok := any(webservice).(*pdoknlv3.WMS); ok { - return "", errors.New("not implemented for WMS") + if WMS, ok := any(webservice).(*pdoknlv3.WMS); ok { + return createInputForWMS(WMS, ownerInfo) } default: return "", fmt.Errorf("unexpected input, webservice should be of type WFS or WMS, webservice: %v", webservice) @@ -58,3 +57,16 @@ func createInputForWFS(wfs *pdoknlv3.WFS, ownerInfo *smoothoperatorv1.OwnerInfo) return string(yamlInput), nil } + +func createInputForWMS(wms *pdoknlv3.WMS, ownerInfo *smoothoperatorv1.OwnerInfo) (config string, err error) { + input, err := MapWMSToCapabilitiesGeneratorInput(wms, ownerInfo) + if err != nil { + return "", err + } + yamlInput, err := yaml.Marshal(input) + if err != nil { + return "", fmt.Errorf("failed to marshal the capabilities generator input to yaml: %w", err) + } + + return string(yamlInput), nil +} diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index b723f21..456f5fc 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -3,6 +3,8 @@ package capabilitiesgenerator import ( pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" smoothoperatorv1 "github.com/pdok/smooth-operator/api/v1" + "github.com/pdok/smooth-operator/model" + "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" @@ -116,6 +118,7 @@ func TestGetInputForWFS(t *testing.T) { }, Spec: pdoknlv3.WFSSpec{ Service: pdoknlv3.WFSService{ + URL: "/datasetOwner/dataset/theme/wfs/v1_0", Title: "some Service title", Abstract: "some \"Service\" abstract", Keywords: []string{"service-keyword-1", "service-keyword-2", "infoFeatureAccessService"}, @@ -201,3 +204,32 @@ func TestGetInputForWFS(t *testing.T) { }) } } + +func TestInputForWMS(t *testing.T) { + wms := pdoknlv3.WMS{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{}, + Spec: pdoknlv3.WMSSpec{}, + Status: model.OperatorStatus{}, + } + + ownerInfo := smoothoperatorv1.OwnerInfo{ + Spec: smoothoperatorv1.OwnerInfoSpec{ + NamespaceTemplate: "http://{{prefix}}.geonovum.nl", + MetadataUrls: smoothoperatorv1.MetadataUrls{ + CSW: smoothoperatorv1.MetadataURL{ + HrefTemplate: "https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id={{identifier}}", + }, + }, + WFS: smoothoperatorv1.WFS{ + ServiceProvider: smoothoperatorv1.ServiceProvider{ + ProviderName: smoothoperatorutils.Pointer("PDOK"), + }, + }, + }, + } + + input, err := GetInput(&wms, &ownerInfo) + assert.NoError(t, err) + println(input) +} diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index dc655ab..8171a55 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -1,7 +1,9 @@ package capabilitiesgenerator import ( + "encoding/xml" "fmt" + "github.com/pdok/ogc-specifications/pkg/wms130" "strconv" "strings" @@ -15,9 +17,10 @@ import ( ) const ( - inspireSchemaLocations = "http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 http://inspire.ec.europa.eu/schemas/inspire_dls/1.0/inspire_dls.xsd" - capabilitiesFilename = "/var/www/config/capabilities_wfs_200.xml" - metadataMediaType = "application/vnd.ogc.csw.GetRecordByIdResponse_xml" + inspireSchemaLocations = "http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 http://inspire.ec.europa.eu/schemas/inspire_dls/1.0/inspire_dls.xsd" + wfsCapabilitiesFilename = "/var/www/config/capabilities_wfs_200.xml" + wmsCapabilitiesFilename = "/var/www/config/capabilities_wms_130.xml" + metadataMediaType = "application/vnd.ogc.csw.GetRecordByIdResponse_xml" ) func MapWFSToCapabilitiesGeneratorInput(wfs *pdoknlv3.WFS, ownerInfo *smoothoperatorv1.OwnerInfo) (*capabilitiesgenerator.Config, error) { @@ -31,12 +34,12 @@ func MapWFSToCapabilitiesGeneratorInput(wfs *pdoknlv3.WFS, ownerInfo *smoothoper Namespace: mapperutils.GetNamespaceURI(wfs.Spec.Service.Prefix, ownerInfo), Prefix: wfs.Spec.Service.Prefix, Onlineresourceurl: pdoknlv3.GetHost(), - Path: mapperutils.GetPath(wfs), + Path: "/" + pdoknlv3.GetBaseURLPath(wfs), Version: *mapperutils.GetLabelValueByKey(wfs.ObjectMeta.Labels, "service-version"), }, Services: capabilitiesgenerator.Services{ WFS200Config: &capabilitiesgenerator.WFS200Config{ - Filename: capabilitiesFilename, + Filename: wfsCapabilitiesFilename, Wfs200: wfs200.GetCapabilitiesResponse{ ServiceProvider: mapServiceProvider(&ownerInfo.Spec.WFS.ServiceProvider), @@ -200,3 +203,39 @@ func mapServiceProvider(provider *smoothoperatorv1.ServiceProvider) (serviceProv return serviceProvider } + +func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoperatorv1.OwnerInfo) (*capabilitiesgenerator.Config, error) { + //featureTypeList, err := getFeatureTypeList(wms, ownerInfo) + //if err != nil { + // return nil, err + //} + + config := capabilitiesgenerator.Config{ + Global: capabilitiesgenerator.Global{ + Namespace: mapperutils.GetNamespaceURI("prefix", ownerInfo), + Prefix: "prefix", + Onlineresourceurl: pdoknlv3.GetHost(), + Path: pdoknlv3.GetBaseURLPath(wms), + Version: *mapperutils.GetLabelValueByKey(wms.ObjectMeta.Labels, "service-version"), + }, + Services: capabilitiesgenerator.Services{ + WMS130Config: &capabilitiesgenerator.WMS130Config{ + Filename: wmsCapabilitiesFilename, + Wms130: wms130.GetCapabilitiesResponse{ + XMLName: xml.Name{}, + Namespaces: wms130.Namespaces{}, + WMSService: wms130.WMSService{}, + Capabilities: wms130.Capabilities{}, + }, + }, + }, + } + + if wms.Spec.Service.Inspire != nil { + config.Global.AdditionalSchemaLocations = inspireSchemaLocations + //metadataURL, _ := replaceMustachTemplate(ownerInfo.Spec.MetadataUrls.CSW.HrefTemplate, wms.Spec.Service.Inspire.ServiceMetadataURL.CSW.MetadataIdentifier) + + } + + return &config, nil +} From e1c201797eafd26870cabe822b27f3c43ec89adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20van=20der=20Kaap?= Date: Mon, 7 Apr 2025 15:24:56 +0200 Subject: [PATCH 2/7] Worked out mapped data a bit more. Upgraded ogc-specifications for nullability --- go.mod | 2 +- go.sum | 2 + .../capabilities_generator_test.go | 76 +++++++++-- .../capabilitiesgenerator/mapper.go | 121 ++++++++++++++++-- 4 files changed, 181 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index b8dff2c..0baf18e 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/onsi/ginkgo/v2 v2.22.2 github.com/onsi/gomega v1.36.2 github.com/pdok/ogc-capabilities-generator v1.0.0-beta5 - github.com/pdok/ogc-specifications v1.0.0-beta4 + github.com/pdok/ogc-specifications v1.0.0-beta5 github.com/pdok/smooth-operator v0.0.9 github.com/traefik/traefik/v3 v3.3.4 k8s.io/api v0.32.0 diff --git a/go.sum b/go.sum index 0ab6cd6..2b76737 100644 --- a/go.sum +++ b/go.sum @@ -362,6 +362,8 @@ github.com/pdok/ogc-capabilities-generator v1.0.0-beta5 h1:nwkIbFcUW4FIYnf6fLfzp github.com/pdok/ogc-capabilities-generator v1.0.0-beta5/go.mod h1:qG2auFy7MDL8Zp1eOfdaUJat+jNW5oLGVd+g7Mbth4Q= github.com/pdok/ogc-specifications v1.0.0-beta4 h1:/Dgi6ArgR0YPCkErpNyCQTCYMkH/cIfWe+VCoUUZZN0= github.com/pdok/ogc-specifications v1.0.0-beta4/go.mod h1:YDngwkwrWOfc5MYnEYseiv97K1Y9bZXlVzwi/8EaIl8= +github.com/pdok/ogc-specifications v1.0.0-beta5 h1:j7JrXUeW55mVU9ZmJ67r8V6DhbKdgTDiGE1YKFpRWx4= +github.com/pdok/ogc-specifications v1.0.0-beta5/go.mod h1:YDngwkwrWOfc5MYnEYseiv97K1Y9bZXlVzwi/8EaIl8= github.com/pdok/smooth-operator v0.0.9 h1:UaOPc23BaHDWzBatSWnOxEjffV0WMiy1LPUkRdqdIGI= github.com/pdok/smooth-operator v0.0.9/go.mod h1:oZWFuIKJGjN/C6ocgMNfMZ7SbLQi+N0qaWj7j95Wdec= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index 456f5fc..242c621 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -3,7 +3,6 @@ package capabilitiesgenerator import ( pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" smoothoperatorv1 "github.com/pdok/smooth-operator/api/v1" - "github.com/pdok/smooth-operator/model" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -206,11 +205,60 @@ func TestGetInputForWFS(t *testing.T) { } func TestInputForWMS(t *testing.T) { + var maxSize int32 = 123 + wms := pdoknlv3.WMS{ - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{}, - Spec: pdoknlv3.WMSSpec{}, - Status: model.OperatorStatus{}, + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "dataset": "dataset", + "dataset-owner": "datasetOwner", + "theme": "theme", + "service-version": "v1_0", + }, + }, + Spec: pdoknlv3.WMSSpec{ + Service: pdoknlv3.WMSService{ + URL: "/datasetOwner/dataset/theme/wms/v1_0", + Title: "some Service title", + Abstract: "some \"Service\" abstract", + Keywords: []string{"service-keyword-1", "service-keyword-2", "infoFeatureAccessService"}, + AccessConstraints: "http://creativecommons.org/publicdomain/zero/1.0/deed.nl", + MaxSize: &maxSize, + Inspire: &pdoknlv3.Inspire{ + ServiceMetadataURL: pdoknlv3.MetadataURL{ + CSW: &pdoknlv3.Metadata{ + MetadataIdentifier: "metameta-meta-meta-meta-metametameta", + }, + }, + Language: "dut", + SpatialDatasetIdentifier: "datadata-data-data-data-datadatadata", + }, + DataEPSG: "EPSG:28992", + StylingAssets: nil, + Mapfile: nil, + Layer: pdoknlv3.Layer{ + Name: "", + Title: nil, + Abstract: nil, + Keywords: nil, + BoundingBoxes: nil, + Visible: nil, + Authority: nil, + DatasetMetadataURL: nil, + MinScaleDenominator: nil, + MaxScaleDenominator: nil, + Styles: nil, + LabelNoClip: false, + Data: nil, + Layers: nil, + }, + }, + }, + } + + contactPersonPrimary := smoothoperatorv1.ContactPersonPrimary{ + ContactPerson: asPtr("KlantContactCenter PDOK"), + ContactOrganization: asPtr("PDOK"), } ownerInfo := smoothoperatorv1.OwnerInfo{ @@ -221,9 +269,21 @@ func TestInputForWMS(t *testing.T) { HrefTemplate: "https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id={{identifier}}", }, }, - WFS: smoothoperatorv1.WFS{ - ServiceProvider: smoothoperatorv1.ServiceProvider{ - ProviderName: smoothoperatorutils.Pointer("PDOK"), + WMS: smoothoperatorv1.WMS{ + ContactInformation: &smoothoperatorv1.ContactInformation{ + ContactPersonPrimary: &contactPersonPrimary, + ContactPosition: asPtr("pointOfContact"), + ContactAddress: &smoothoperatorv1.ContactAddress{ + AddressType: asPtr("Work"), + Address: nil, + City: asPtr("Apeldoorn"), + StateOrProvince: nil, + PostCode: nil, + Country: asPtr("The Netherlands"), + }, + ContactVoiceTelephone: nil, + ContactFacsimileTelephone: nil, + ContactElectronicMailAddress: asPtr("BeheerPDOK@kadaster.nl"), }, }, }, diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index 8171a55..2c6fbc5 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -1,7 +1,6 @@ package capabilitiesgenerator import ( - "encoding/xml" "fmt" "github.com/pdok/ogc-specifications/pkg/wms130" "strconv" @@ -205,27 +204,51 @@ func mapServiceProvider(provider *smoothoperatorv1.ServiceProvider) (serviceProv } func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoperatorv1.OwnerInfo) (*capabilitiesgenerator.Config, error) { - //featureTypeList, err := getFeatureTypeList(wms, ownerInfo) - //if err != nil { - // return nil, err - //} + abstract := mapperutils.EscapeQuotes(wms.Spec.Service.Abstract) + var fees *string = nil + if wms.Spec.Service.Fees != nil { + feesPtr := mapperutils.EscapeQuotes(*wms.Spec.Service.Fees) + fees = &feesPtr + } config := capabilitiesgenerator.Config{ Global: capabilitiesgenerator.Global{ Namespace: mapperutils.GetNamespaceURI("prefix", ownerInfo), Prefix: "prefix", Onlineresourceurl: pdoknlv3.GetHost(), - Path: pdoknlv3.GetBaseURLPath(wms), + Path: "/" + pdoknlv3.GetBaseURLPath(wms), Version: *mapperutils.GetLabelValueByKey(wms.ObjectMeta.Labels, "service-version"), }, Services: capabilitiesgenerator.Services{ WMS130Config: &capabilitiesgenerator.WMS130Config{ Filename: wmsCapabilitiesFilename, Wms130: wms130.GetCapabilitiesResponse{ - XMLName: xml.Name{}, - Namespaces: wms130.Namespaces{}, - WMSService: wms130.WMSService{}, - Capabilities: wms130.Capabilities{}, + WMSService: wms130.WMSService{ + Name: "WMS", + Title: mapperutils.EscapeQuotes(wms.Spec.Service.Title), + Abstract: &abstract, + KeywordList: &wms130.Keywords{Keyword: wms.Spec.Service.Keywords}, + OnlineResource: wms130.OnlineResource{Href: &wms.Spec.Service.URL}, + ContactInformation: getContactInformation(ownerInfo), + Fees: fees, + AccessConstraints: &wms.Spec.Service.AccessConstraints, + LayerLimit: nil, + MaxWidth: nil, + MaxHeight: nil, + }, + Capabilities: wms130.Capabilities{ + WMSCapabilities: wms130.WMSCapabilities{ + Request: wms130.Request{ + GetCapabilities: wms130.RequestType{}, + GetMap: wms130.RequestType{}, + GetFeatureInfo: nil, + }, + Exception: wms130.ExceptionType{Format: []string{"XML", "BLANK"}}, + ExtendedCapabilities: nil, + Layer: nil, + }, + OptionalConstraints: wms130.OptionalConstraints{}, + }, }, }, }, @@ -233,9 +256,85 @@ func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoper if wms.Spec.Service.Inspire != nil { config.Global.AdditionalSchemaLocations = inspireSchemaLocations - //metadataURL, _ := replaceMustachTemplate(ownerInfo.Spec.MetadataUrls.CSW.HrefTemplate, wms.Spec.Service.Inspire.ServiceMetadataURL.CSW.MetadataIdentifier) + metadataURL, _ := replaceMustachTemplate(ownerInfo.Spec.MetadataUrls.CSW.HrefTemplate, wms.Spec.Service.Inspire.ServiceMetadataURL.CSW.MetadataIdentifier) + defaultLanguage := wms130.Language{Language: wms.Spec.Service.Inspire.Language} + + config.Services.WMS130Config.Wms130.Capabilities.ExtendedCapabilities = &wms130.ExtendedCapabilities{ + MetadataURL: wms130.ExtendedMetadataURL{URL: metadataURL, MediaType: metadataMediaType}, + SupportedLanguages: wms130.SupportedLanguages{ + DefaultLanguage: defaultLanguage, + SupportedLanguage: &[]wms130.Language{defaultLanguage}, + }, + ResponseLanguage: defaultLanguage, + } } return &config, nil } + +func getContactInformation(ownerInfo *smoothoperatorv1.OwnerInfo) *wms130.ContactInformation { + result := wms130.ContactInformation{ + ContactPersonPrimary: nil, + ContactPosition: nil, + ContactAddress: nil, + ContactVoiceTelephone: nil, + ContactFacsimileTelephone: nil, + ContactElectronicMailAddress: nil, + } + + providedContactInformation := ownerInfo.Spec.WMS.ContactInformation + + if providedContactInformation == nil { + return &result + } + + if providedContactInformation.ContactPersonPrimary != nil { + contactPerson := "" + if providedContactInformation.ContactPersonPrimary.ContactPerson != nil { + contactPerson = *providedContactInformation.ContactPersonPrimary.ContactPerson + } + contactOrganisation := "" + if providedContactInformation.ContactPersonPrimary.ContactOrganization != nil { + contactOrganisation = *providedContactInformation.ContactPersonPrimary.ContactOrganization + } + + contactPersonPrimary := wms130.ContactPersonPrimary{ + ContactPerson: contactPerson, + ContactOrganization: contactOrganisation, + } + result.ContactPersonPrimary = &contactPersonPrimary + } + + result.ContactPosition = providedContactInformation.ContactPosition + if providedContactInformation.ContactAddress != nil { + contactAddressInput := providedContactInformation.ContactAddress + contactAddress := wms130.ContactAddress{ + AddressType: pointerValOrDefault(contactAddressInput.AddressType, ""), + Address: pointerValOrDefault(contactAddressInput.Address, ""), + City: pointerValOrDefault(contactAddressInput.City, ""), + StateOrProvince: pointerValOrDefault(contactAddressInput.StateOrProvince, ""), + PostalCode: pointerValOrDefault(contactAddressInput.PostCode, ""), + Country: pointerValOrDefault(contactAddressInput.Country, ""), + } + result.ContactAddress = &contactAddress + } + + result.ContactVoiceTelephone = providedContactInformation.ContactVoiceTelephone + result.ContactFacsimileTelephone = providedContactInformation.ContactFacsimileTelephone + result.ContactElectronicMailAddress = providedContactInformation.ContactElectronicMailAddress + + return &result +} + +func pointerValOrDefault[T any](pointer *T, defaultValue T) T { + if pointer != nil { + return *pointer + } else { + return defaultValue + } +} + +func asPtr[T any](value T) *T { + return &value +} From 2ad1a5be70342df4355cfc48b3024d75841f5fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20van=20der=20Kaap?= Date: Mon, 7 Apr 2025 17:15:16 +0200 Subject: [PATCH 3/7] Pulled out V2 to V3 conversion code. --- api/v2beta1/wms_conversion.go | 9 ++- api/v2beta1/wms_conversion_test.go | 20 +++++++ .../capabilities_generator_test.go | 58 +++---------------- .../capabilitiesgenerator/mapper.go | 2 + 4 files changed, 37 insertions(+), 52 deletions(-) create mode 100644 api/v2beta1/wms_conversion_test.go diff --git a/api/v2beta1/wms_conversion.go b/api/v2beta1/wms_conversion.go index c1d01dc..4fda47e 100644 --- a/api/v2beta1/wms_conversion.go +++ b/api/v2beta1/wms_conversion.go @@ -43,6 +43,13 @@ func (src *WMS) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*pdoknlv3.WMS) log.Printf("ConvertTo: Converting WMS from Spoke version v2beta1 to Hub version v3;"+ "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + V3HubFromV2(src, dst) + + return nil +} + +func V3HubFromV2(src *WMS, target *pdoknlv3.WMS) { + dst := target dst.ObjectMeta = src.ObjectMeta dst.Annotations[SERVICE_METADATA_IDENTIFIER_ANNOTATION] = src.Spec.Service.MetadataIdentifier @@ -126,8 +133,6 @@ func (src *WMS) ConvertTo(dstRaw conversion.Hub) error { } dst.Spec.Service = service - - return nil } // ConvertFrom converts the Hub version (v3) to this WMS (v2beta1). diff --git a/api/v2beta1/wms_conversion_test.go b/api/v2beta1/wms_conversion_test.go new file mode 100644 index 0000000..08ac014 --- /dev/null +++ b/api/v2beta1/wms_conversion_test.go @@ -0,0 +1,20 @@ +package v2beta1 + +import ( + pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" + "github.com/stretchr/testify/assert" + "sigs.k8s.io/yaml" + "testing" +) + +func TestV2ToV3(t *testing.T) { + input := "apiVersion: pdok.nl/v2beta1\nkind: WMS\nmetadata:\n name: rws-nwbwegen-v1-0\n labels:\n dataset-owner: rws\n dataset: nwbwegen\n service-version: v1_0\n service-type: wms\n annotations:\n lifecycle-phase: prod\n service-bundle-id: b39c152b-393b-52f5-a50c-e1ffe904b6fb\nspec:\n general:\n datasetOwner: rws\n dataset: nwbwegen\n serviceVersion: v1_0\n kubernetes:\n healthCheck:\n boundingbox: 135134.89,457152.55,135416.03,457187.82\n resources:\n limits:\n ephemeralStorage: 1535Mi\n memory: 4G\n requests:\n cpu: 2000m\n ephemeralStorage: 1535Mi\n memory: 4G\n options:\n automaticCasing: true\n disableWebserviceProxy: false\n includeIngress: true\n validateRequests: true\n service:\n title: NWB - Wegen WMS\n abstract:\n Dit is de web map service van het Nationaal Wegen Bestand (NWB) - wegen.\n Deze dataset bevat alleen de wegvakken en hectometerpunten. Het Nationaal Wegen\n Bestand - Wegen is een digitaal geografisch bestand van alle wegen in Nederland.\n Opgenomen zijn alle wegen die worden beheerd door wegbeheerders als het Rijk,\n provincies, gemeenten en waterschappen, echter alleen voor zover deze zijn voorzien\n van een straatnaam of nummer.\n authority:\n name: rws\n url: https://www.rijkswaterstaat.nl\n dataEPSG: EPSG:28992\n extent: -59188.44333693248 304984.64144318487 308126.88473339565 858328.516489961\n inspire: true\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Wegvakken\n - Hectometerpunten\n - HVD\n - Mobiliteit\n stylingAssets:\n configMapRefs:\n - name: includes\n keys:\n - nwb_wegen_hectopunten.symbol\n - hectopunten.style\n - wegvakken.style\n blobKeys:\n - resources/fonts/liberation-sans.ttf\n layers:\n - abstract:\n Deze laag bevat de wegvakken uit het Nationaal Wegen bestand (NWB)\n en geeft gedetailleerde informatie per wegvak zoals straatnaam, wegnummer,\n routenummer, wegbeheerder, huisnummers, enz. weer.\n data:\n gpkg:\n columns:\n - objectid\n - wvk_id\n - wvk_begdat\n - jte_id_beg\n - jte_id_end\n - wegbehsrt\n - wegnummer\n - wegdeelltr\n - hecto_lttr\n - bst_code\n - rpe_code\n - admrichtng\n - rijrichtng\n - stt_naam\n - stt_bron\n - wpsnaam\n - gme_id\n - gme_naam\n - hnrstrlnks\n - hnrstrrhts\n - e_hnr_lnks\n - e_hnr_rhts\n - l_hnr_lnks\n - l_hnr_rhts\n - begafstand\n - endafstand\n - beginkm\n - eindkm\n - pos_tv_wol\n - wegbehcode\n - wegbehnaam\n - distrcode\n - distrnaam\n - dienstcode\n - dienstnaam\n - wegtype\n - wgtype_oms\n - routeltr\n - routenr\n - routeltr2\n - routenr2\n - routeltr3\n - routenr3\n - routeltr4\n - routenr4\n - wegnr_aw\n - wegnr_hmp\n - geobron_id\n - geobron_nm\n - bronjaar\n - openlr\n - bag_orl\n - frc\n - fow\n - alt_naam\n - alt_nr\n - rel_hoogte\n - st_lengthshape\n geometryType: MultiLineString\n blobKey: geopackages/rws/nwbwegen/410a6d1e-e767-41b4-ba8d-9e1e955dd013/1/nwb_wegen.gpkg\n table: wegvakken\n datasetMetadataIdentifier: a9b7026e-0a81-4813-93bd-ba49e6f28502\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Wegvakken\n maxScale: 50000.0\n minScale: 1.0\n name: wegvakken\n sourceMetadataIdentifier: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff\n styles:\n - name: wegvakken\n title: NWB - Wegvakken\n visualization: wegvakken.style\n title: Wegvakken\n visible: true\n - abstract:\n Deze laag bevat de hectopunten uit het Nationaal Wegen Bestand (NWB)\n en geeft gedetailleerde informatie per hectopunt zoals hectometrering, afstand,\n zijde en hectoletter weer.\n data:\n gpkg:\n columns:\n - objectid\n - hectomtrng\n - afstand\n - wvk_id\n - wvk_begdat\n - zijde\n - hecto_lttr\n geometryType: MultiPoint\n blobKey: geopackages/rws/nwbwegen/410a6d1e-e767-41b4-ba8d-9e1e955dd013/1/nwb_wegen.gpkg\n table: hectopunten\n datasetMetadataIdentifier: a9b7026e-0a81-4813-93bd-ba49e6f28502\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Hectometerpunten\n maxScale: 50000.0\n minScale: 1.0\n name: hectopunten\n sourceMetadataIdentifier: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff\n styles:\n - name: hectopunten\n title: NWB - Hectopunten\n visualization: hectopunten.style\n title: Hectopunten\n visible: true\n metadataIdentifier: f2437a92-ddd3-4777-a1bc-fdf4b4a7fcb8\n" + var v2wms WMS + err := yaml.Unmarshal([]byte(input), &v2wms) + assert.NoError(t, err) + var target pdoknlv3.WMS + V3HubFromV2(&v2wms, &target) + assert.Equal(t, "NWB - Wegen WMS", target.Spec.Service.Title) + a := 0 + _ = a +} diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index 242c621..6573ae4 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -1,10 +1,12 @@ package capabilitiesgenerator import ( + "github.com/pdok/mapserver-operator/api/v2beta1" pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" smoothoperatorv1 "github.com/pdok/smooth-operator/api/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/yaml" "testing" @@ -205,56 +207,12 @@ func TestGetInputForWFS(t *testing.T) { } func TestInputForWMS(t *testing.T) { - var maxSize int32 = 123 - - wms := pdoknlv3.WMS{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "dataset": "dataset", - "dataset-owner": "datasetOwner", - "theme": "theme", - "service-version": "v1_0", - }, - }, - Spec: pdoknlv3.WMSSpec{ - Service: pdoknlv3.WMSService{ - URL: "/datasetOwner/dataset/theme/wms/v1_0", - Title: "some Service title", - Abstract: "some \"Service\" abstract", - Keywords: []string{"service-keyword-1", "service-keyword-2", "infoFeatureAccessService"}, - AccessConstraints: "http://creativecommons.org/publicdomain/zero/1.0/deed.nl", - MaxSize: &maxSize, - Inspire: &pdoknlv3.Inspire{ - ServiceMetadataURL: pdoknlv3.MetadataURL{ - CSW: &pdoknlv3.Metadata{ - MetadataIdentifier: "metameta-meta-meta-meta-metametameta", - }, - }, - Language: "dut", - SpatialDatasetIdentifier: "datadata-data-data-data-datadatadata", - }, - DataEPSG: "EPSG:28992", - StylingAssets: nil, - Mapfile: nil, - Layer: pdoknlv3.Layer{ - Name: "", - Title: nil, - Abstract: nil, - Keywords: nil, - BoundingBoxes: nil, - Visible: nil, - Authority: nil, - DatasetMetadataURL: nil, - MinScaleDenominator: nil, - MaxScaleDenominator: nil, - Styles: nil, - LabelNoClip: false, - Data: nil, - Layers: nil, - }, - }, - }, - } + v2wmsstring := "apiVersion: pdok.nl/v2beta1\nkind: WMS\nmetadata:\n name: rws-nwbwegen-v1-0\n labels:\n dataset-owner: rws\n dataset: nwbwegen\n service-version: v1_0\n service-type: wms\n annotations:\n lifecycle-phase: prod\n service-bundle-id: b39c152b-393b-52f5-a50c-e1ffe904b6fb\nspec:\n general:\n datasetOwner: rws\n dataset: nwbwegen\n serviceVersion: v1_0\n kubernetes:\n healthCheck:\n boundingbox: 135134.89,457152.55,135416.03,457187.82\n resources:\n limits:\n ephemeralStorage: 1535Mi\n memory: 4G\n requests:\n cpu: 2000m\n ephemeralStorage: 1535Mi\n memory: 4G\n options:\n automaticCasing: true\n disableWebserviceProxy: false\n includeIngress: true\n validateRequests: true\n service:\n title: NWB - Wegen WMS\n abstract:\n Dit is de web map service van het Nationaal Wegen Bestand (NWB) - wegen.\n Deze dataset bevat alleen de wegvakken en hectometerpunten. Het Nationaal Wegen\n Bestand - Wegen is een digitaal geografisch bestand van alle wegen in Nederland.\n Opgenomen zijn alle wegen die worden beheerd door wegbeheerders als het Rijk,\n provincies, gemeenten en waterschappen, echter alleen voor zover deze zijn voorzien\n van een straatnaam of nummer.\n authority:\n name: rws\n url: https://www.rijkswaterstaat.nl\n dataEPSG: EPSG:28992\n extent: -59188.44333693248 304984.64144318487 308126.88473339565 858328.516489961\n inspire: true\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Wegvakken\n - Hectometerpunten\n - HVD\n - Mobiliteit\n stylingAssets:\n configMapRefs:\n - name: includes\n keys:\n - nwb_wegen_hectopunten.symbol\n - hectopunten.style\n - wegvakken.style\n blobKeys:\n - resources/fonts/liberation-sans.ttf\n layers:\n - abstract:\n Deze laag bevat de wegvakken uit het Nationaal Wegen bestand (NWB)\n en geeft gedetailleerde informatie per wegvak zoals straatnaam, wegnummer,\n routenummer, wegbeheerder, huisnummers, enz. weer.\n data:\n gpkg:\n columns:\n - objectid\n - wvk_id\n - wvk_begdat\n - jte_id_beg\n - jte_id_end\n - wegbehsrt\n - wegnummer\n - wegdeelltr\n - hecto_lttr\n - bst_code\n - rpe_code\n - admrichtng\n - rijrichtng\n - stt_naam\n - stt_bron\n - wpsnaam\n - gme_id\n - gme_naam\n - hnrstrlnks\n - hnrstrrhts\n - e_hnr_lnks\n - e_hnr_rhts\n - l_hnr_lnks\n - l_hnr_rhts\n - begafstand\n - endafstand\n - beginkm\n - eindkm\n - pos_tv_wol\n - wegbehcode\n - wegbehnaam\n - distrcode\n - distrnaam\n - dienstcode\n - dienstnaam\n - wegtype\n - wgtype_oms\n - routeltr\n - routenr\n - routeltr2\n - routenr2\n - routeltr3\n - routenr3\n - routeltr4\n - routenr4\n - wegnr_aw\n - wegnr_hmp\n - geobron_id\n - geobron_nm\n - bronjaar\n - openlr\n - bag_orl\n - frc\n - fow\n - alt_naam\n - alt_nr\n - rel_hoogte\n - st_lengthshape\n geometryType: MultiLineString\n blobKey: geopackages/rws/nwbwegen/410a6d1e-e767-41b4-ba8d-9e1e955dd013/1/nwb_wegen.gpkg\n table: wegvakken\n datasetMetadataIdentifier: a9b7026e-0a81-4813-93bd-ba49e6f28502\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Wegvakken\n maxScale: 50000.0\n minScale: 1.0\n name: wegvakken\n sourceMetadataIdentifier: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff\n styles:\n - name: wegvakken\n title: NWB - Wegvakken\n visualization: wegvakken.style\n title: Wegvakken\n visible: true\n - abstract:\n Deze laag bevat de hectopunten uit het Nationaal Wegen Bestand (NWB)\n en geeft gedetailleerde informatie per hectopunt zoals hectometrering, afstand,\n zijde en hectoletter weer.\n data:\n gpkg:\n columns:\n - objectid\n - hectomtrng\n - afstand\n - wvk_id\n - wvk_begdat\n - zijde\n - hecto_lttr\n geometryType: MultiPoint\n blobKey: geopackages/rws/nwbwegen/410a6d1e-e767-41b4-ba8d-9e1e955dd013/1/nwb_wegen.gpkg\n table: hectopunten\n datasetMetadataIdentifier: a9b7026e-0a81-4813-93bd-ba49e6f28502\n keywords:\n - Vervoersnetwerken\n - Menselijke gezondheid en veiligheid\n - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai)\n - Nationaal\n - Voertuigen\n - Verkeer\n - Hectometerpunten\n maxScale: 50000.0\n minScale: 1.0\n name: hectopunten\n sourceMetadataIdentifier: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff\n styles:\n - name: hectopunten\n title: NWB - Hectopunten\n visualization: hectopunten.style\n title: Hectopunten\n visible: true\n metadataIdentifier: f2437a92-ddd3-4777-a1bc-fdf4b4a7fcb8\n" + var v2wms v2beta1.WMS + err := yaml.Unmarshal([]byte(v2wmsstring), &v2wms) + assert.NoError(t, err) + var wms pdoknlv3.WMS + v2beta1.V3HubFromV2(&v2wms, &wms) contactPersonPrimary := smoothoperatorv1.ContactPersonPrimary{ ContactPerson: asPtr("KlantContactCenter PDOK"), diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index 2c6fbc5..a1c3672 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -209,6 +209,8 @@ func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoper if wms.Spec.Service.Fees != nil { feesPtr := mapperutils.EscapeQuotes(*wms.Spec.Service.Fees) fees = &feesPtr + } else { + fees = asPtr("NONE") } config := capabilitiesgenerator.Config{ From 79831a09fe67eb0663e229bb2246563e6d7d7434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20van=20der=20Kaap?= Date: Tue, 8 Apr 2025 11:25:49 +0200 Subject: [PATCH 4/7] Started on translating layer --- .../capabilitiesgenerator/mapper.go | 202 +++++++++++++++++- 1 file changed, 198 insertions(+), 4 deletions(-) diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index a1c3672..9cb93b4 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -204,6 +204,8 @@ func mapServiceProvider(provider *smoothoperatorv1.ServiceProvider) (serviceProv } func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoperatorv1.OwnerInfo) (*capabilitiesgenerator.Config, error) { + canonicalServiceUrl := "https://service.pdok.nl" + "/" + pdoknlv3.GetBaseURLPath(wms) + abstract := mapperutils.EscapeQuotes(wms.Spec.Service.Abstract) var fees *string = nil if wms.Spec.Service.Fees != nil { @@ -241,13 +243,22 @@ func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoper Capabilities: wms130.Capabilities{ WMSCapabilities: wms130.WMSCapabilities{ Request: wms130.Request{ - GetCapabilities: wms130.RequestType{}, - GetMap: wms130.RequestType{}, - GetFeatureInfo: nil, + GetCapabilities: wms130.RequestType{ + Format: []string{"text/xml"}, + DCPType: getDcpType(canonicalServiceUrl, false), + }, + GetMap: wms130.RequestType{ + Format: []string{"image/png", "image/jpeg", "image/png; mode=8bit", "image/vnd.jpeg-png", "image/vnd.jpeg-png8"}, + DCPType: getDcpType(canonicalServiceUrl, true), + }, + GetFeatureInfo: &wms130.RequestType{ + Format: []string{"application/json", "application/json; subtype=geojson", "application/vnd.ogc.gml", "text/html", "text/plain", "text/xml", "text/xml; subtype=gml/3.1.1"}, + DCPType: getDcpType(canonicalServiceUrl, true), + }, }, Exception: wms130.ExceptionType{Format: []string{"XML", "BLANK"}}, ExtendedCapabilities: nil, - Layer: nil, + Layer: getLayers(wms), }, OptionalConstraints: wms130.OptionalConstraints{}, }, @@ -329,6 +340,189 @@ func getContactInformation(ownerInfo *smoothoperatorv1.OwnerInfo) *wms130.Contac return &result } +func getDcpType(url string, fillPost bool) *wms130.DCPType { + get := wms130.Method{ + OnlineResource: wms130.OnlineResource{ + Xlink: nil, + Type: nil, + Href: asPtr(url), + }, + } + + var post *wms130.Method = nil + if fillPost { + post = &get + } + + result := wms130.DCPType{ + HTTP: struct { + Get wms130.Method `xml:"Get" yaml:"get"` + Post *wms130.Method `xml:"Post" yaml:"post"` + }{ + Get: get, + Post: post, + }, + } + return &result +} + +func getLayers(wms *pdoknlv3.WMS) []wms130.Layer { + result := make([]wms130.Layer, 0) + referenceLayer := wms.Spec.Service.Layer + title := referenceLayer.Title + if title != nil { + title = asPtr(mapperutils.EscapeQuotes(*referenceLayer.Title)) + } else { + title = asPtr("") + } + + defaultCrs := []wms130.CRS{{ + Namespace: "EPSG", + Code: 28992, + }, { + Namespace: "EPSG", + Code: 25831, + }, { + Namespace: "EPSG", + Code: 25832, + }, { + Namespace: "EPSG", + Code: 3034, + }, { + Namespace: "EPSG", + Code: 3035, + }, { + Namespace: "EPSG", + Code: 3857, + }, { + Namespace: "EPSG", + Code: 4258, + }, { + Namespace: "EPSG", + Code: 4326, + }, { + Namespace: "CRS", + Code: 84, + }} + + defaultBoundingBox := wms130.EXGeographicBoundingBox{ + WestBoundLongitude: 2.52713, + EastBoundLongitude: 7.37403, + SouthBoundLatitude: 50.2129, + NorthBoundLatitude: 55.7212, + } + + allDefaultBoundingBoxes := make([]*wms130.LayerBoundingBox, 0) + allDefaultBoundingBoxes = append(allDefaultBoundingBoxes, + &wms130.LayerBoundingBox{ + CRS: "EPSG:28992", + Minx: -25000, + Miny: 250000, + Maxx: 280000, + Maxy: 860000, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "EPSG:25831", + Minx: -470271, + Miny: 5.56231e+06, + Maxx: 795163, + Maxy: 6.18197e+06, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "EPSG:25832", + Minx: 62461.6, + Miny: 5.56555e+06, + Maxx: 397827, + Maxy: 6.19042e+06, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "EPSG:3034", + Minx: 2.61336e+06, + Miny: 3.509e+06, + Maxx: 3.22007e+06, + Maxy: 3.84003e+06, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "EPSG:3035", + Minx: 3.01676e+06, + Miny: 3.81264e+06, + Maxx: 3.64485e+06, + Maxy: 4.15586e+06, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "EPSG:3857", + Minx: 281318, + Miny: 6.48322e+06, + Maxx: 820873, + Maxy: 7.50311e+06, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "EPSG:4258", + Minx: 50.2129, + Miny: 2.52713, + Maxx: 55.7212, + Maxy: 7.37403, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "EPSG:4326", + Minx: 50.2129, + Miny: 2.52713, + Maxx: 55.7212, + Maxy: 7.37403, + Resx: 0, + Resy: 0, + }, + &wms130.LayerBoundingBox{ + CRS: "CRS:84", + Minx: 2.52713, + Miny: 50.2129, + Maxx: 7.37403, + Maxy: 55.7212, + Resx: 0, + Resy: 0, + }) + + topLayer := wms130.Layer{ + Queryable: asPtr(1), + Opaque: nil, + Name: nil, + Title: *title, + Abstract: asPtr(mapperutils.EscapeQuotes(wms.Spec.Service.Abstract)), + KeywordList: &wms130.Keywords{Keyword: referenceLayer.Keywords}, + CRS: defaultCrs, + EXGeographicBoundingBox: &defaultBoundingBox, + BoundingBox: allDefaultBoundingBoxes, + Dimension: nil, + Attribution: nil, + AuthorityURL: nil, + Identifier: nil, + MetadataURL: nil, + DataURL: nil, + FeatureListURL: nil, + Style: nil, + MinScaleDenominator: nil, + MaxScaleDenominator: nil, + Layer: nil, + } + + result = append(result, topLayer) + return result +} + func pointerValOrDefault[T any](pointer *T, defaultValue T) T { if pointer != nil { return *pointer From aa643f9a691fda654922165f09a1f51ffe08e330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20van=20der=20Kaap?= Date: Tue, 8 Apr 2025 15:58:34 +0200 Subject: [PATCH 5/7] Finished first seemingly complete version --- .../capabilitiesgenerator/mapper.go | 133 ++++++++++++++++-- 1 file changed, 123 insertions(+), 10 deletions(-) diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index 9cb93b4..a2994ce 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -204,7 +204,8 @@ func mapServiceProvider(provider *smoothoperatorv1.ServiceProvider) (serviceProv } func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoperatorv1.OwnerInfo) (*capabilitiesgenerator.Config, error) { - canonicalServiceUrl := "https://service.pdok.nl" + "/" + pdoknlv3.GetBaseURLPath(wms) + hostBaseUrl := "https://service.pdok.nl" + canonicalServiceUrl := hostBaseUrl + "/" + pdoknlv3.GetBaseURLPath(wms) abstract := mapperutils.EscapeQuotes(wms.Spec.Service.Abstract) var fees *string = nil @@ -215,6 +216,14 @@ func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoper fees = asPtr("NONE") } + maxWidth := 4000 + maxHeight := 4000 + + accessContraints := wms.Spec.Service.AccessConstraints + if accessContraints == "" { + accessContraints = "https://creativecommons.org/publicdomain/zero/1.0/deed.nl" + } + config := capabilitiesgenerator.Config{ Global: capabilitiesgenerator.Global{ Namespace: mapperutils.GetNamespaceURI("prefix", ownerInfo), @@ -232,13 +241,13 @@ func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoper Title: mapperutils.EscapeQuotes(wms.Spec.Service.Title), Abstract: &abstract, KeywordList: &wms130.Keywords{Keyword: wms.Spec.Service.Keywords}, - OnlineResource: wms130.OnlineResource{Href: &wms.Spec.Service.URL}, + OnlineResource: wms130.OnlineResource{Href: &hostBaseUrl}, ContactInformation: getContactInformation(ownerInfo), Fees: fees, - AccessConstraints: &wms.Spec.Service.AccessConstraints, + AccessConstraints: &accessContraints, LayerLimit: nil, - MaxWidth: nil, - MaxHeight: nil, + MaxWidth: &maxWidth, + MaxHeight: &maxHeight, }, Capabilities: wms130.Capabilities{ WMSCapabilities: wms130.WMSCapabilities{ @@ -258,7 +267,7 @@ func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoper }, Exception: wms130.ExceptionType{Format: []string{"XML", "BLANK"}}, ExtendedCapabilities: nil, - Layer: getLayers(wms), + Layer: getLayers(wms, canonicalServiceUrl), }, OptionalConstraints: wms130.OptionalConstraints{}, }, @@ -366,7 +375,7 @@ func getDcpType(url string, fillPost bool) *wms130.DCPType { return &result } -func getLayers(wms *pdoknlv3.WMS) []wms130.Layer { +func getLayers(wms *pdoknlv3.WMS, canonicalUrl string) []wms130.Layer { result := make([]wms130.Layer, 0) referenceLayer := wms.Spec.Service.Layer title := referenceLayer.Title @@ -496,6 +505,24 @@ func getLayers(wms *pdoknlv3.WMS) []wms130.Layer { Resy: 0, }) + var authorityUrl *wms130.AuthorityURL = nil + var identifier *wms130.Identifier = nil + + if referenceLayer.Authority != nil { + authorityUrl = &wms130.AuthorityURL{ + Name: referenceLayer.Authority.Name, + OnlineResource: wms130.OnlineResource{ + Xlink: nil, + Type: nil, + Href: &referenceLayer.Authority.URL, + }, + } + identifier = &wms130.Identifier{ + Authority: referenceLayer.Authority.Name, + Value: referenceLayer.Authority.SpatialDatasetIdentifier, + } + } + topLayer := wms130.Layer{ Queryable: asPtr(1), Opaque: nil, @@ -508,15 +535,101 @@ func getLayers(wms *pdoknlv3.WMS) []wms130.Layer { BoundingBox: allDefaultBoundingBoxes, Dimension: nil, Attribution: nil, - AuthorityURL: nil, - Identifier: nil, + AuthorityURL: authorityUrl, + Identifier: identifier, MetadataURL: nil, DataURL: nil, FeatureListURL: nil, Style: nil, MinScaleDenominator: nil, MaxScaleDenominator: nil, - Layer: nil, + Layer: []*wms130.Layer{}, + } + + for _, layer := range *referenceLayer.Layers { + var minScaleDenom *float64 + var maxScaleDenom *float64 + var innerIdentifier *wms130.Identifier + metadataUrls := make([]*wms130.MetadataURL, 0) + + if layer.MinScaleDenominator != nil { + float, err := strconv.ParseFloat(*layer.MinScaleDenominator, 64) + if err == nil { + minScaleDenom = &float + } + } + + if layer.MaxScaleDenominator != nil { + float, err := strconv.ParseFloat(*layer.MaxScaleDenominator, 64) + if err == nil { + maxScaleDenom = &float + } + } + + if layer.DatasetMetadataURL != nil { + metadataUrls = append(metadataUrls, &wms130.MetadataURL{ + Type: asPtr("TC211"), + Format: asPtr("text/plain"), + OnlineResource: wms130.OnlineResource{ + Xlink: nil, + Type: asPtr("simple"), + Href: asPtr("https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=" + layer.DatasetMetadataURL.CSW.MetadataIdentifier), + }, + }) + } + + if layer.Authority != nil { + innerIdentifier = &wms130.Identifier{ + Authority: layer.Authority.Name, + Value: layer.Authority.SpatialDatasetIdentifier, + } + } + + nestedLayer := wms130.Layer{ + Queryable: asPtr(1), + Opaque: nil, + Name: &layer.Name, + Title: pointerValOrDefault(layer.Title, ""), + Abstract: layer.Abstract, + KeywordList: &wms130.Keywords{ + Keyword: layer.Keywords, + }, + CRS: defaultCrs, + EXGeographicBoundingBox: &defaultBoundingBox, + BoundingBox: allDefaultBoundingBoxes, + Dimension: nil, + Attribution: nil, + AuthorityURL: authorityUrl, + Identifier: innerIdentifier, + MetadataURL: metadataUrls, + DataURL: nil, + FeatureListURL: nil, + Style: []*wms130.Style{}, + MinScaleDenominator: minScaleDenom, + MaxScaleDenominator: maxScaleDenom, + Layer: nil, + } + for _, style := range layer.Styles { + newStyle := wms130.Style{ + Name: style.Name, + Title: pointerValOrDefault(style.Title, ""), + Abstract: style.Abstract, + LegendURL: &wms130.LegendURL{ + Width: 78, + Height: 20, + Format: "image/png", + OnlineResource: wms130.OnlineResource{ + Xlink: nil, + Type: asPtr("simple"), + Href: asPtr(canonicalUrl + "/legend/" + layer.Name + "/" + layer.Name + ".png"), + }, + }, + StyleSheetURL: nil, + } + nestedLayer.Style = append(nestedLayer.Style, &newStyle) + } + + topLayer.Layer = append(topLayer.Layer, &nestedLayer) } result = append(result, topLayer) From 641d8904f4ee8bc1f4cb436cef4affdb7d376b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20van=20der=20Kaap?= Date: Tue, 8 Apr 2025 16:03:10 +0200 Subject: [PATCH 6/7] Finished test --- .../capabilities_generator_test.go | 463 +++++++++++++++++- 1 file changed, 462 insertions(+), 1 deletion(-) diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index 6573ae4..ba9c327 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -90,6 +90,467 @@ services: - urn:ogc:def:crs:EPSG::4326 metadataUrl: href: https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=datadata-data-data-data-datadatadata +` + WMSInput = `global: + prefix: prefix + namespace: http://prefix.geonovum.nl + onlineResourceUrl: "" + path: /rws/nwbwegen/wms/v1_0 + version: v1_0 + additionalSchemaLocations: http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 http://inspire.ec.europa.eu/schemas/inspire_dls/1.0/inspire_dls.xsd +services: + wms130: + filename: /var/www/config/capabilities_wms_130.xml + definition: + wmsCapabilities: + space: "" + local: "" + namespaces: + wms: "" + sld: "" + xlink: "" + xsi: "" + version: "" + schemaLocation: "" + service: + name: WMS + title: NWB - Wegen WMS + abstract: Dit is de web map service van het Nationaal Wegen Bestand (NWB) - wegen. Deze dataset bevat alleen de wegvakken en hectometerpunten. Het Nationaal Wegen Bestand - Wegen is een digitaal geografisch bestand van alle wegen in Nederland. Opgenomen zijn alle wegen die worden beheerd door wegbeheerders als het Rijk, provincies, gemeenten en waterschappen, echter alleen voor zover deze zijn voorzien van een straatnaam of nummer. + keywordList: + keyword: + - Vervoersnetwerken + - Menselijke gezondheid en veiligheid + - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai) + - Nationaal + - Voertuigen + - Verkeer + - Wegvakken + - Hectometerpunten + - HVD + - Mobiliteit + onlineResource: + xlink: null + type: null + href: https://service.pdok.nl + contactInformation: + contactPersonPrimary: + contactPerson: KlantContactCenter PDOK + contactOrganization: PDOK + contactPosition: pointOfContact + contactAddress: + addressType: Work + address: "" + city: Apeldoorn + stateOrProvince: "" + postalCode: "" + country: The Netherlands + contactVoiceTelephone: null + contactFacsimileTelephone: null + contactElectronicMailAddress: BeheerPDOK@kadaster.nl + fees: NONE + accessConstraints: https://creativecommons.org/publicdomain/zero/1.0/deed.nl + layerLimit: null + maxWidth: 4000 + maxHeight: 4000 + capability: + wmsCapabilities: + request: + getCapabilities: + format: + - text/xml + dcpType: + http: + get: + onlineResource: + xlink: null + type: null + href: https://service.pdok.nl/rws/nwbwegen/wms/v1_0 + post: null + getMap: + format: + - image/png + - image/jpeg + - image/png; mode=8bit + - image/vnd.jpeg-png + - image/vnd.jpeg-png8 + dcpType: + http: + get: + onlineResource: + xlink: null + type: null + href: https://service.pdok.nl/rws/nwbwegen/wms/v1_0 + post: + onlineResource: + xlink: null + type: null + href: https://service.pdok.nl/rws/nwbwegen/wms/v1_0 + getFeatureInfo: + format: + - application/json + - application/json; subtype=geojson + - application/vnd.ogc.gml + - text/html + - text/plain + - text/xml + - text/xml; subtype=gml/3.1.1 + dcpType: + http: + get: + onlineResource: + xlink: null + type: null + href: https://service.pdok.nl/rws/nwbwegen/wms/v1_0 + post: + onlineResource: + xlink: null + type: null + href: https://service.pdok.nl/rws/nwbwegen/wms/v1_0 + exception: + format: + - XML + - BLANK + extendedCapabilities: + metadataUrl: + url: https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=f2437a92-ddd3-4777-a1bc-fdf4b4a7fcb8 + mediaType: application/vnd.ogc.csw.GetRecordByIdResponse_xml + supportedLanguages: + defaultLanguage: + language: nl + supportedLanguage: + - language: nl + responseLanguage: + language: nl + layer: + - queryable: 1 + opaque: null + name: null + title: NWB - Wegen WMS + abstract: Dit is de web map service van het Nationaal Wegen Bestand (NWB) - wegen. Deze dataset bevat alleen de wegvakken en hectometerpunten. Het Nationaal Wegen Bestand - Wegen is een digitaal geografisch bestand van alle wegen in Nederland. Opgenomen zijn alle wegen die worden beheerd door wegbeheerders als het Rijk, provincies, gemeenten en waterschappen, echter alleen voor zover deze zijn voorzien van een straatnaam of nummer. + keywordList: + keyword: + - Vervoersnetwerken + - Menselijke gezondheid en veiligheid + - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai) + - Nationaal + - Voertuigen + - Verkeer + - Wegvakken + - Hectometerpunten + - HVD + - Mobiliteit + crs: + - namespace: EPSG + code: 28992 + - namespace: EPSG + code: 25831 + - namespace: EPSG + code: 25832 + - namespace: EPSG + code: 3034 + - namespace: EPSG + code: 3035 + - namespace: EPSG + code: 3857 + - namespace: EPSG + code: 4258 + - namespace: EPSG + code: 4326 + - namespace: CRS + code: 84 + exGeographicBoundingBox: + westBoundLongitude: 2.52713 + eastBoundLongitude: 7.37403 + southBoundLatitude: 50.2129 + northBoundLatitude: 55.7212 + boundingBox: + - crs: EPSG:28992 + minx: -25000 + miny: 250000 + maxx: 280000 + maxy: 860000 + - crs: EPSG:25831 + minx: -470271 + miny: 5.56231e+06 + maxx: 795163 + maxy: 6.18197e+06 + - crs: EPSG:25832 + minx: 62461.6 + miny: 5.56555e+06 + maxx: 397827 + maxy: 6.19042e+06 + - crs: EPSG:3034 + minx: 2.61336e+06 + miny: 3.509e+06 + maxx: 3.22007e+06 + maxy: 3.84003e+06 + - crs: EPSG:3035 + minx: 3.01676e+06 + miny: 3.81264e+06 + maxx: 3.64485e+06 + maxy: 4.15586e+06 + - crs: EPSG:3857 + minx: 281318 + miny: 6.48322e+06 + maxx: 820873 + maxy: 7.50311e+06 + - crs: EPSG:4258 + minx: 50.2129 + miny: 2.52713 + maxx: 55.7212 + maxy: 7.37403 + - crs: EPSG:4326 + minx: 50.2129 + miny: 2.52713 + maxx: 55.7212 + maxy: 7.37403 + - crs: CRS:84 + minx: 2.52713 + miny: 50.2129 + maxx: 7.37403 + maxy: 55.7212 + dimension: [] + attribution: null + authorityUrl: null + identifier: null + metadataUrl: [] + dataUrl: null + featureListUrl: null + style: [] + minScaleDenominator: null + maxScaleDenominator: null + layer: + - queryable: 1 + opaque: null + name: wegvakken + title: Wegvakken + abstract: Deze laag bevat de wegvakken uit het Nationaal Wegen bestand (NWB) en geeft gedetailleerde informatie per wegvak zoals straatnaam, wegnummer, routenummer, wegbeheerder, huisnummers, enz. weer. + keywordList: + keyword: + - Vervoersnetwerken + - Menselijke gezondheid en veiligheid + - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai) + - Nationaal + - Voertuigen + - Verkeer + - Wegvakken + crs: + - namespace: EPSG + code: 28992 + - namespace: EPSG + code: 25831 + - namespace: EPSG + code: 25832 + - namespace: EPSG + code: 3034 + - namespace: EPSG + code: 3035 + - namespace: EPSG + code: 3857 + - namespace: EPSG + code: 4258 + - namespace: EPSG + code: 4326 + - namespace: CRS + code: 84 + exGeographicBoundingBox: + westBoundLongitude: 2.52713 + eastBoundLongitude: 7.37403 + southBoundLatitude: 50.2129 + northBoundLatitude: 55.7212 + boundingBox: + - crs: EPSG:28992 + minx: -25000 + miny: 250000 + maxx: 280000 + maxy: 860000 + - crs: EPSG:25831 + minx: -470271 + miny: 5.56231e+06 + maxx: 795163 + maxy: 6.18197e+06 + - crs: EPSG:25832 + minx: 62461.6 + miny: 5.56555e+06 + maxx: 397827 + maxy: 6.19042e+06 + - crs: EPSG:3034 + minx: 2.61336e+06 + miny: 3.509e+06 + maxx: 3.22007e+06 + maxy: 3.84003e+06 + - crs: EPSG:3035 + minx: 3.01676e+06 + miny: 3.81264e+06 + maxx: 3.64485e+06 + maxy: 4.15586e+06 + - crs: EPSG:3857 + minx: 281318 + miny: 6.48322e+06 + maxx: 820873 + maxy: 7.50311e+06 + - crs: EPSG:4258 + minx: 50.2129 + miny: 2.52713 + maxx: 55.7212 + maxy: 7.37403 + - crs: EPSG:4326 + minx: 50.2129 + miny: 2.52713 + maxx: 55.7212 + maxy: 7.37403 + - crs: CRS:84 + minx: 2.52713 + miny: 50.2129 + maxx: 7.37403 + maxy: 55.7212 + dimension: [] + attribution: null + authorityUrl: null + identifier: + authority: rws + value: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff + metadataUrl: + - type: TC211 + format: text/plain + onlineResource: + xlink: null + type: simple + href: https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=a9b7026e-0a81-4813-93bd-ba49e6f28502 + dataUrl: null + featureListUrl: null + style: + - name: wegvakken + title: NWB - Wegvakken + abstract: null + legendUrl: + width: 78 + height: 20 + format: image/png + onlineResource: + xlink: null + type: simple + href: https://service.pdok.nl/rws/nwbwegen/wms/v1_0/legend/wegvakken/wegvakken.png + styleSheetUrl: null + minScaleDenominator: 1 + maxScaleDenominator: 50000 + layer: [] + - queryable: 1 + opaque: null + name: hectopunten + title: Hectopunten + abstract: Deze laag bevat de hectopunten uit het Nationaal Wegen Bestand (NWB) en geeft gedetailleerde informatie per hectopunt zoals hectometrering, afstand, zijde en hectoletter weer. + keywordList: + keyword: + - Vervoersnetwerken + - Menselijke gezondheid en veiligheid + - Geluidsbelasting hoofdwegen (Richtlijn Omgevingslawaai) + - Nationaal + - Voertuigen + - Verkeer + - Hectometerpunten + crs: + - namespace: EPSG + code: 28992 + - namespace: EPSG + code: 25831 + - namespace: EPSG + code: 25832 + - namespace: EPSG + code: 3034 + - namespace: EPSG + code: 3035 + - namespace: EPSG + code: 3857 + - namespace: EPSG + code: 4258 + - namespace: EPSG + code: 4326 + - namespace: CRS + code: 84 + exGeographicBoundingBox: + westBoundLongitude: 2.52713 + eastBoundLongitude: 7.37403 + southBoundLatitude: 50.2129 + northBoundLatitude: 55.7212 + boundingBox: + - crs: EPSG:28992 + minx: -25000 + miny: 250000 + maxx: 280000 + maxy: 860000 + - crs: EPSG:25831 + minx: -470271 + miny: 5.56231e+06 + maxx: 795163 + maxy: 6.18197e+06 + - crs: EPSG:25832 + minx: 62461.6 + miny: 5.56555e+06 + maxx: 397827 + maxy: 6.19042e+06 + - crs: EPSG:3034 + minx: 2.61336e+06 + miny: 3.509e+06 + maxx: 3.22007e+06 + maxy: 3.84003e+06 + - crs: EPSG:3035 + minx: 3.01676e+06 + miny: 3.81264e+06 + maxx: 3.64485e+06 + maxy: 4.15586e+06 + - crs: EPSG:3857 + minx: 281318 + miny: 6.48322e+06 + maxx: 820873 + maxy: 7.50311e+06 + - crs: EPSG:4258 + minx: 50.2129 + miny: 2.52713 + maxx: 55.7212 + maxy: 7.37403 + - crs: EPSG:4326 + minx: 50.2129 + miny: 2.52713 + maxx: 55.7212 + maxy: 7.37403 + - crs: CRS:84 + minx: 2.52713 + miny: 50.2129 + maxx: 7.37403 + maxy: 55.7212 + dimension: [] + attribution: null + authorityUrl: null + identifier: + authority: rws + value: 8f0497f0-dbd7-4bee-b85a-5fdec484a7ff + metadataUrl: + - type: TC211 + format: text/plain + onlineResource: + xlink: null + type: simple + href: https://www.nationaalgeoregister.nl/geonetwork/srv/dut/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&elementsetname=full&id=a9b7026e-0a81-4813-93bd-ba49e6f28502 + dataUrl: null + featureListUrl: null + style: + - name: hectopunten + title: NWB - Hectopunten + abstract: null + legendUrl: + width: 78 + height: 20 + format: image/png + onlineResource: + xlink: null + type: simple + href: https://service.pdok.nl/rws/nwbwegen/wms/v1_0/legend/hectopunten/hectopunten.png + styleSheetUrl: null + minScaleDenominator: 1 + maxScaleDenominator: 50000 + layer: [] + optionalConstraints: {} ` ) @@ -249,5 +710,5 @@ func TestInputForWMS(t *testing.T) { input, err := GetInput(&wms, &ownerInfo) assert.NoError(t, err) - println(input) + assert.Equal(t, WMSInput, input) } From d61bcc9e2a6ccb08edf1f97ccbd6de4b8942dae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20van=20der=20Kaap?= Date: Tue, 8 Apr 2025 16:12:20 +0200 Subject: [PATCH 7/7] Fixed issue with global in text --- .../capabilitiesgenerator/capabilities_generator_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index ba9c327..b04e71d 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -94,7 +94,7 @@ services: WMSInput = `global: prefix: prefix namespace: http://prefix.geonovum.nl - onlineResourceUrl: "" + onlineResourceUrl: http://localhost path: /rws/nwbwegen/wms/v1_0 version: v1_0 additionalSchemaLocations: http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 http://inspire.ec.europa.eu/schemas/inspire_dls/1.0/inspire_dls.xsd @@ -674,6 +674,7 @@ func TestInputForWMS(t *testing.T) { assert.NoError(t, err) var wms pdoknlv3.WMS v2beta1.V3HubFromV2(&v2wms, &wms) + pdoknlv3.SetHost("http://localhost") contactPersonPrimary := smoothoperatorv1.ContactPersonPrimary{ ContactPerson: asPtr("KlantContactCenter PDOK"),