Skip to content

Commit f0f708a

Browse files
committed
Merge branch 'master' into PDOK-17803-mapserver-operator-featureinfo-generator-configmap
2 parents 296ecad + 1be1d70 commit f0f708a

20 files changed

+1938
-79
lines changed

api/v2beta1/wms_conversion.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ func (src *WMS) ConvertTo(dstRaw conversion.Hub) error {
4343
dst := dstRaw.(*pdoknlv3.WMS)
4444
log.Printf("ConvertTo: Converting WMS from Spoke version v2beta1 to Hub version v3;"+
4545
"source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name)
46+
V3HubFromV2(src, dst)
47+
48+
return nil
49+
}
50+
51+
func V3HubFromV2(src *WMS, target *pdoknlv3.WMS) {
52+
dst := target
4653

4754
dst.ObjectMeta = src.ObjectMeta
4855
dst.Annotations[SERVICE_METADATA_IDENTIFIER_ANNOTATION] = src.Spec.Service.MetadataIdentifier
@@ -126,8 +133,6 @@ func (src *WMS) ConvertTo(dstRaw conversion.Hub) error {
126133
}
127134

128135
dst.Spec.Service = service
129-
130-
return nil
131136
}
132137

133138
// ConvertFrom converts the Hub version (v3) to this WMS (v2beta1).

api/v2beta1/wms_conversion_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package v2beta1
2+
3+
import (
4+
pdoknlv3 "github.com/pdok/mapserver-operator/api/v3"
5+
"github.com/stretchr/testify/assert"
6+
"sigs.k8s.io/yaml"
7+
"testing"
8+
)
9+
10+
func TestV2ToV3(t *testing.T) {
11+
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"
12+
var v2wms WMS
13+
err := yaml.Unmarshal([]byte(input), &v2wms)
14+
assert.NoError(t, err)
15+
var target pdoknlv3.WMS
16+
V3HubFromV2(&v2wms, &target)
17+
assert.Equal(t, "NWB - Wegen WMS", target.Spec.Service.Title)
18+
a := 0
19+
_ = a
20+
}

api/v3/shared_types.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type WMSWFS interface {
3535
HasPostgisData() bool
3636
// Sha1 hash of the objects name
3737
ID() string
38+
URLPath() string
3839
}
3940

4041
type Mapfile struct {
@@ -112,18 +113,7 @@ func GetHost() string {
112113
}
113114

114115
func GetBaseURLPath[T WMSWFS](o T) string {
115-
var serviceURL string
116-
switch any(o).(type) {
117-
case *WFS:
118-
if WFS, ok := any(o).(*WFS); ok {
119-
serviceURL = WFS.Spec.Service.URL
120-
}
121-
case *WMS:
122-
if WMS, ok := any(o).(*WMS); ok {
123-
serviceURL = WMS.Spec.Service.URL
124-
}
125-
}
126-
116+
serviceURL := o.URLPath()
127117
parsed, _ := url.Parse(serviceURL)
128118
return strings.TrimPrefix(parsed.Path, "/")
129119
}

api/v3/wfs_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,7 @@ func (wfs *WFS) Options() *Options {
150150
func (wfs *WFS) ID() string {
151151
return Sha1HashOfName(wfs)
152152
}
153+
154+
func (wfs *WFS) URLPath() string {
155+
return wfs.Spec.Service.URL
156+
}

api/v3/wms_types.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,34 @@ func (layer *Layer) IsGroupLayer(service *WMSService) bool {
231231
return layer.GetLayerType(service) == GroupLayer
232232
}
233233

234+
func (layer *Layer) hasBoundingBoxForCRS(crs string) bool {
235+
for _, bbox := range layer.BoundingBoxes {
236+
if bbox.CRS == crs {
237+
return true
238+
}
239+
}
240+
return false
241+
}
242+
243+
func (layer *Layer) setInheritedBoundingBoxes() {
244+
if layer.Layers == nil || len(*layer.Layers) == 0 {
245+
return
246+
}
247+
248+
var updatedLayers []Layer
249+
for _, childLayer := range *layer.Layers {
250+
// Inherit parent boundingboxes
251+
for _, boundingBox := range layer.BoundingBoxes {
252+
if !childLayer.hasBoundingBoxForCRS(boundingBox.CRS) {
253+
childLayer.BoundingBoxes = append(childLayer.BoundingBoxes, boundingBox)
254+
}
255+
}
256+
childLayer.setInheritedBoundingBoxes()
257+
updatedLayers = append(updatedLayers, childLayer)
258+
}
259+
*layer.Layers = updatedLayers
260+
}
261+
234262
func (wms *WMS) GetAllLayersWithLegend() (layers []Layer) {
235263
for _, layer := range wms.Spec.Service.Layer.GetAllLayers() {
236264
if !layer.hasData() || len(layer.Styles) == 0 {
@@ -310,3 +338,7 @@ func (wms *WMS) Options() *Options {
310338
func (wms *WMS) ID() string {
311339
return Sha1HashOfName(wms)
312340
}
341+
342+
func (wms *WMS) URLPath() string {
343+
return wms.Spec.Service.URL
344+
}

api/v3/wms_types_test.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,131 @@
11
package v3
22

33
import (
4+
"github.com/google/go-cmp/cmp"
5+
"github.com/pdok/smooth-operator/model"
46
"reflect"
57
"testing"
68
)
79

10+
func TestLayer_setInheritedBoundingBoxes(t *testing.T) {
11+
first28992BoundingBox := WMSBoundingBox{
12+
CRS: "EPSG:28992",
13+
BBox: model.BBox{
14+
MinX: "482.06",
15+
MaxX: "306602.42",
16+
MinY: "284182.97",
17+
MaxY: "637049.52",
18+
},
19+
}
20+
first4326BoundingBox := WMSBoundingBox{
21+
CRS: "EPSG:4326",
22+
BBox: model.BBox{
23+
MinX: "2.35417303",
24+
MaxX: "7.5553525",
25+
MinY: "50.71447164",
26+
MaxY: "55.66948102",
27+
},
28+
}
29+
first4258BoundingBox := WMSBoundingBox{
30+
CRS: "EPSG:4258",
31+
BBox: model.BBox{
32+
MinX: "2.354173",
33+
MaxX: "7.5553527",
34+
MinY: "50.71447",
35+
MaxY: "55.66948",
36+
}}
37+
second28992BoundingBox := WMSBoundingBox{
38+
CRS: "EPSG:28992",
39+
BBox: model.BBox{
40+
MinX: "0.00",
41+
MaxX: "310000.00",
42+
MinY: "275000.00",
43+
MaxY: "650000.00",
44+
}}
45+
46+
tests := []struct {
47+
name string
48+
layer Layer
49+
toplayerExpectedBoundingBoxCount int
50+
toplayerExpectedBoundingBoxes []WMSBoundingBox
51+
grouplayer1ExpectedBoundingBoxCount int
52+
grouplayer1ExpectedBoundingBoxes []WMSBoundingBox
53+
datalayer1ExpectedBoundingBoxCount int
54+
datalayer1ExpectedBoundingBoxes []WMSBoundingBox
55+
datalayer2ExpectedBoundingBoxCount int
56+
datalayer2ExpectedBoundingBoxes []WMSBoundingBox
57+
}{
58+
{
59+
name: "setInheritedBoundingBoxes for layer",
60+
layer: Layer{
61+
Name: "toplayer",
62+
BoundingBoxes: []WMSBoundingBox{first28992BoundingBox},
63+
Layers: &[]Layer{
64+
{
65+
Name: "grouplayer-1",
66+
BoundingBoxes: []WMSBoundingBox{first4326BoundingBox},
67+
Layers: &[]Layer{
68+
{
69+
Name: "datalayer-1",
70+
BoundingBoxes: []WMSBoundingBox{first4258BoundingBox},
71+
},
72+
{
73+
Name: "datalayer-2",
74+
BoundingBoxes: []WMSBoundingBox{second28992BoundingBox},
75+
},
76+
},
77+
},
78+
},
79+
},
80+
toplayerExpectedBoundingBoxCount: 1,
81+
toplayerExpectedBoundingBoxes: []WMSBoundingBox{first28992BoundingBox},
82+
grouplayer1ExpectedBoundingBoxCount: 2,
83+
grouplayer1ExpectedBoundingBoxes: []WMSBoundingBox{first4326BoundingBox, first28992BoundingBox},
84+
datalayer1ExpectedBoundingBoxCount: 3,
85+
datalayer1ExpectedBoundingBoxes: []WMSBoundingBox{first4258BoundingBox, first4326BoundingBox, first28992BoundingBox},
86+
datalayer2ExpectedBoundingBoxCount: 2,
87+
datalayer2ExpectedBoundingBoxes: []WMSBoundingBox{second28992BoundingBox, first4326BoundingBox},
88+
},
89+
}
90+
for _, tt := range tests {
91+
t.Run(tt.name, func(t *testing.T) {
92+
layer := tt.layer
93+
layer.setInheritedBoundingBoxes()
94+
95+
topChildLayers := *layer.Layers
96+
groupLayer1 := topChildLayers[0]
97+
groupChildLayers := *groupLayer1.Layers
98+
dataLayer1 := groupChildLayers[0]
99+
dataLayer2 := groupChildLayers[1]
100+
101+
if len(layer.BoundingBoxes) != tt.toplayerExpectedBoundingBoxCount {
102+
t.Errorf("Toplayer has unexpected number of bounding boxes = %v, want %v", len(layer.BoundingBoxes), tt.toplayerExpectedBoundingBoxCount)
103+
}
104+
if !cmp.Equal(layer.BoundingBoxes, tt.toplayerExpectedBoundingBoxes) {
105+
t.Errorf("Toplayer has unexpected bounding boxes = %v, want %v", layer.BoundingBoxes, tt.toplayerExpectedBoundingBoxes)
106+
}
107+
if len(groupLayer1.BoundingBoxes) != tt.grouplayer1ExpectedBoundingBoxCount {
108+
t.Errorf("Grouplayer has unexpected number of bounding boxes = %v, want %v", len(groupLayer1.BoundingBoxes), tt.grouplayer1ExpectedBoundingBoxCount)
109+
}
110+
if !cmp.Equal(groupLayer1.BoundingBoxes, tt.grouplayer1ExpectedBoundingBoxes) {
111+
t.Errorf("Grouplayer has unexpected bounding boxes = %v, want %v", groupLayer1.BoundingBoxes, tt.grouplayer1ExpectedBoundingBoxes)
112+
}
113+
if len(dataLayer1.BoundingBoxes) != tt.datalayer1ExpectedBoundingBoxCount {
114+
t.Errorf("Datalayer1 has unexpected number of bounding boxes = %v, want %v", len(dataLayer1.BoundingBoxes), tt.datalayer1ExpectedBoundingBoxCount)
115+
}
116+
if !cmp.Equal(dataLayer1.BoundingBoxes, tt.datalayer1ExpectedBoundingBoxes) {
117+
t.Errorf("Datalayer1 has unexpected bounding boxes = %v, want %v", dataLayer1.BoundingBoxes, tt.datalayer1ExpectedBoundingBoxes)
118+
}
119+
if len(dataLayer2.BoundingBoxes) != tt.datalayer2ExpectedBoundingBoxCount {
120+
t.Errorf("Datalayer2 has unexpected number of bounding boxes = %v, want %v", len(dataLayer2.BoundingBoxes), tt.datalayer2ExpectedBoundingBoxCount)
121+
}
122+
if !cmp.Equal(dataLayer2.BoundingBoxes, tt.datalayer2ExpectedBoundingBoxes) {
123+
t.Errorf("Datalayer2 has unexpected bounding boxes = %v, want %v", dataLayer2.BoundingBoxes, tt.datalayer2ExpectedBoundingBoxes)
124+
}
125+
})
126+
}
127+
}
128+
8129
func TestLayer_GetParent(t *testing.T) {
9130
childLayer2 := Layer{Name: "childlayer-2"}
10131
childLayer1 := Layer{Name: "childlayer-1", Layers: &[]Layer{childLayer2}}

0 commit comments

Comments
 (0)