Skip to content

Commit 1e4eb08

Browse files
authored
Merge pull request #19 from PDOK/wr/wms-fix-conversion-hierarchy
fix v2->v3 layer hierarchy conversion
2 parents 43eb0af + 478b345 commit 1e4eb08

File tree

14 files changed

+104
-96
lines changed

14 files changed

+104
-96
lines changed

api/v2beta1/wms_conversion.go

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -267,54 +267,67 @@ func (v2Service WMSService) GetTopLayer() (*WMSLayer, error) {
267267
return nil, errors.New("unable to detect the toplayer of this WMS service")
268268
}
269269

270-
func (v2Service WMSService) GetChildLayers(parent WMSLayer) ([]WMSLayer, error) {
271-
children := make([]WMSLayer, 0)
272-
270+
// MapLayersToV3
271+
func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer {
272+
// Creates map of Groups: layers in that group
273+
// and a list of all layers without a group
274+
groupedLayers := map[string][]pdoknlv3.Layer{}
275+
var notGroupedLayers []pdoknlv3.Layer
273276
for _, layer := range v2Service.Layers {
274-
if layer.Group != nil && *layer.Group == parent.Name {
275-
children = append(children, layer)
277+
if layer.Group == nil {
278+
notGroupedLayers = append(notGroupedLayers, layer.MapToV3(v2Service))
279+
} else {
280+
groupedLayers[*layer.Group] = append(groupedLayers[*layer.Group], layer.MapToV3(v2Service))
276281
}
277282
}
278283

279-
if len(children) == 0 {
280-
return children, errors.New("no child layers found")
284+
// if a topLayer is defined in the v2 it be the only layer without a group
285+
// and there are other layers that have the topLayer as their group
286+
// so if there is exactly 1 layer without a group
287+
// and the name of that layer exist as a key in the map of Groups: layer in that group
288+
// then that layer must be the topLayer
289+
var topLayer *pdoknlv3.Layer
290+
if len(notGroupedLayers) == 1 {
291+
_, ok := groupedLayers[*notGroupedLayers[0].Name]
292+
if ok {
293+
topLayer = &notGroupedLayers[0]
294+
}
281295
}
282296

283-
return children, nil
284-
}
285-
286-
// MapLayersToV3
287-
func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer {
288-
topLayer, err := v2Service.GetTopLayer()
289-
if err != nil {
290-
panic(err)
291-
}
297+
var middleLayers []pdoknlv3.Layer
292298

293-
var layer pdoknlv3.Layer
299+
// if the topLayer is not defined in the v2 layers
300+
// it needs to be created with defaults from the service
301+
// and in this case the middleLayers are all layers without a group
294302
if topLayer == nil {
295-
layer = pdoknlv3.Layer{
296-
Name: "wms",
303+
topLayer = &pdoknlv3.Layer{
297304
Title: &v2Service.Title,
298305
Abstract: &v2Service.Abstract,
299306
Keywords: v2Service.Keywords,
300307
Layers: &[]pdoknlv3.Layer{},
301308
}
309+
middleLayers = notGroupedLayers
310+
}
302311

303-
var childLayersV3 []pdoknlv3.Layer
304-
for _, childLayer := range v2Service.Layers {
305-
childLayersV3 = append(childLayersV3, childLayer.MapToV3(v2Service))
312+
// if the topLayer is defined in the v2 layers
313+
// meaning the topLayer has a name at this point
314+
// then the middleLayers are all layers that had the topLayer name as their group
315+
// and the bottomLayers are all layers that had a middleLayer as a group
316+
if topLayer.Name != nil {
317+
for _, layer := range groupedLayers[*topLayer.Name] {
318+
bottomLayers := groupedLayers[*layer.Name]
319+
layer.Layers = &bottomLayers
320+
middleLayers = append(middleLayers, layer)
306321
}
307-
layer.Layers = &childLayersV3
308-
} else {
309-
layer = topLayer.MapToV3(v2Service)
310322
}
323+
topLayer.Layers = &middleLayers
311324

312-
return layer
325+
return *topLayer
313326
}
314327

315328
func (v2Layer WMSLayer) MapToV3(v2Service WMSService) pdoknlv3.Layer {
316329
layer := pdoknlv3.Layer{
317-
Name: v2Layer.Name,
330+
Name: &v2Layer.Name,
318331
Title: v2Layer.Title,
319332
Abstract: v2Layer.Abstract,
320333
Keywords: v2Layer.Keywords,
@@ -382,17 +395,6 @@ func (v2Layer WMSLayer) MapToV3(v2Service WMSService) pdoknlv3.Layer {
382395

383396
if v2Layer.Data != nil {
384397
layer.Data = Pointer(ConvertV2DataToV3(*v2Layer.Data))
385-
} else {
386-
childLayersV2, err := v2Service.GetChildLayers(v2Layer)
387-
if err != nil {
388-
panic(err)
389-
}
390-
391-
var childLayersV3 []pdoknlv3.Layer
392-
for _, childLayer := range childLayersV2 {
393-
childLayersV3 = append(childLayersV3, childLayer.MapToV3(v2Service))
394-
}
395-
layer.Layers = &childLayersV3
396398
}
397399

398400
return layer
@@ -401,7 +403,7 @@ func (v2Layer WMSLayer) MapToV3(v2Service WMSService) pdoknlv3.Layer {
401403
func mapV3LayerToV2Layers(v3Layer pdoknlv3.Layer, parent *pdoknlv3.Layer, serviceEPSG string) []WMSLayer {
402404
var layers []WMSLayer
403405

404-
if parent == nil && v3Layer.Name == "wms" {
406+
if parent == nil && *v3Layer.Name == "wms" {
405407
// Default top layer, do not include in v2 layers
406408
if v3Layer.Layers != nil {
407409
for _, childLayer := range *v3Layer.Layers {
@@ -410,7 +412,7 @@ func mapV3LayerToV2Layers(v3Layer pdoknlv3.Layer, parent *pdoknlv3.Layer, servic
410412
}
411413
} else {
412414
v2Layer := WMSLayer{
413-
Name: v3Layer.Name,
415+
Name: *v3Layer.Name,
414416
Title: v3Layer.Title,
415417
Abstract: v3Layer.Abstract,
416418
Keywords: v3Layer.Keywords,
@@ -421,7 +423,7 @@ func mapV3LayerToV2Layers(v3Layer pdoknlv3.Layer, parent *pdoknlv3.Layer, servic
421423
v2Layer.Visible = PointerVal(v3Layer.Visible, true)
422424

423425
if parent != nil {
424-
v2Layer.Group = &parent.Name
426+
v2Layer.Group = parent.Name
425427
}
426428

427429
if v3Layer.DatasetMetadataURL != nil && v3Layer.DatasetMetadataURL.CSW != nil {

api/v3/wms_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ type ConfigMapRef struct {
8888
}
8989

9090
type Layer struct {
91-
Name string `json:"name"`
91+
Name *string `json:"name"`
9292
Title *string `json:"title,omitempty"`
9393
Abstract *string `json:"abstract,omitempty"`
9494
Keywords []string `json:"keywords"`

api/v3/wms_types_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package v3
33
import (
44
"github.com/google/go-cmp/cmp"
55
"github.com/pdok/smooth-operator/model"
6+
controller "github.com/pdok/smooth-operator/pkg/util"
67
"reflect"
78
"testing"
89
)
@@ -58,19 +59,19 @@ func TestLayer_setInheritedBoundingBoxes(t *testing.T) {
5859
{
5960
name: "setInheritedBoundingBoxes for layer",
6061
layer: Layer{
61-
Name: "toplayer",
62+
Name: controller.Pointer("toplayer"),
6263
BoundingBoxes: []WMSBoundingBox{first28992BoundingBox},
6364
Layers: &[]Layer{
6465
{
65-
Name: "grouplayer-1",
66+
Name: controller.Pointer("grouplayer-1"),
6667
BoundingBoxes: []WMSBoundingBox{first4326BoundingBox},
6768
Layers: &[]Layer{
6869
{
69-
Name: "datalayer-1",
70+
Name: controller.Pointer("datalayer-1"),
7071
BoundingBoxes: []WMSBoundingBox{first4258BoundingBox},
7172
},
7273
{
73-
Name: "datalayer-2",
74+
Name: controller.Pointer("datalayer-2"),
7475
BoundingBoxes: []WMSBoundingBox{second28992BoundingBox},
7576
},
7677
},
@@ -127,9 +128,9 @@ func TestLayer_setInheritedBoundingBoxes(t *testing.T) {
127128
}
128129

129130
func TestLayer_GetParent(t *testing.T) {
130-
childLayer2 := Layer{Name: "childlayer-2"}
131-
childLayer1 := Layer{Name: "childlayer-1", Layers: &[]Layer{childLayer2}}
132-
topLayer := Layer{Name: "toplayer", Layers: &[]Layer{childLayer1}}
131+
childLayer2 := Layer{Name: controller.Pointer("childlayer-2")}
132+
childLayer1 := Layer{Name: controller.Pointer("childlayer-1"), Layers: &[]Layer{childLayer2}}
133+
topLayer := Layer{Name: controller.Pointer("toplayer"), Layers: &[]Layer{childLayer1}}
133134

134135
type args struct {
135136
candidateLayer *Layer

api/v3/wms_validation.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ func validateWMS(wms *WMS, warnings *[]string, reasons *[]string) {
9595
wms.Spec.Service.Layer.setInheritedBoundingBoxes()
9696
for _, layer := range wms.Spec.Service.Layer.GetAllLayers() {
9797
var layerReasons []string
98-
if slices.Contains(names, layer.Name) {
99-
*reasons = append(*reasons, fmt.Sprintf("layer names must be unique, layer.name '%s' is duplicated", layer.Name))
98+
if slices.Contains(names, *layer.Name) {
99+
*reasons = append(*reasons, fmt.Sprintf("layer names must be unique, layer.name '%s' is duplicated", *layer.Name))
100100
}
101-
names = append(names, layer.Name)
101+
names = append(names, *layer.Name)
102102
if service.Mapfile != nil && layer.BoundingBoxes != nil {
103103
*warnings = append(*warnings, sharedValidation.FormatValidationWarning("layer.boundingBoxes is not used when service.mapfile is configured", wms.GroupVersionKind(), wms.GetName()))
104104
}
@@ -154,7 +154,7 @@ func validateWMS(wms *WMS, warnings *[]string, reasons *[]string) {
154154
}
155155
}
156156
if !rewriteGroupToDataLayers && validateChildStyleNameEqual {
157-
equalStylesNames, ok := equalChildStyleNames[layer.Name]
157+
equalStylesNames, ok := equalChildStyleNames[*layer.Name]
158158
if ok {
159159
for _, styleName := range equalStylesNames {
160160
layerReasons = append(layerReasons, fmt.Sprintf("invalid style: '%s': style.name from parent layer must not be set on a child layer", styleName))
@@ -188,7 +188,7 @@ func validateWMS(wms *WMS, warnings *[]string, reasons *[]string) {
188188
}
189189
}
190190
if len(layerReasons) != 0 {
191-
*reasons = append(*reasons, fmt.Sprintf("%s '%s' is invalid: ", layerType, layer.Name)+strings.Join(layerReasons, ", "))
191+
*reasons = append(*reasons, fmt.Sprintf("%s '%s' is invalid: ", layerType, *layer.Name)+strings.Join(layerReasons, ", "))
192192
}
193193
}
194194

@@ -212,7 +212,7 @@ func findEqualChildStyleNames(layer *Layer, equalStyleNames *map[string][]string
212212
}
213213
}
214214
if len(equalStyles) > 0 {
215-
equalChildStyleNames[childLayer.Name] = equalStyles
215+
equalChildStyleNames[*childLayer.Name] = equalStyles
216216
}
217217
findEqualChildStyleNames(&childLayer, equalStyleNames)
218218
}

api/v3/wms_validation_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package v3
22

33
import (
4+
controller "github.com/pdok/smooth-operator/pkg/util"
45
"reflect"
56
"testing"
67
)
@@ -19,21 +20,21 @@ func Test_getEqualChildStyleNames(t *testing.T) {
1920
name: "Test equal style names",
2021
args: args{
2122
layer: &Layer{
22-
Name: "toplayer",
23+
Name: controller.Pointer("toplayer"),
2324
Styles: []Style{
2425
{Name: "stylename-1"},
2526
{Name: "stylename-2"},
2627
},
2728
Layers: &[]Layer{
2829
{
29-
Name: "childlayer-1",
30+
Name: controller.Pointer("childlayer-1"),
3031
Styles: []Style{
3132
{Name: "stylename-2"},
3233
{Name: "stylename-3"},
3334
},
3435
Layers: &[]Layer{
3536
{
36-
Name: "childlayer-2",
37+
Name: controller.Pointer("childlayer-2"),
3738
Styles: []Style{
3839
{Name: "stylename-3"},
3940
{Name: "stylename-4"},
@@ -54,21 +55,21 @@ func Test_getEqualChildStyleNames(t *testing.T) {
5455
name: "Test no equal style names",
5556
args: args{
5657
layer: &Layer{
57-
Name: "toplayer",
58+
Name: controller.Pointer("toplayer"),
5859
Styles: []Style{
5960
{Name: "stylename-1"},
6061
{Name: "stylename-2"},
6162
},
6263
Layers: &[]Layer{
6364
{
64-
Name: "childlayer-1",
65+
Name: controller.Pointer("childlayer-1"),
6566
Styles: []Style{
6667
{Name: "stylename-3"},
6768
{Name: "stylename-4"},
6869
},
6970
Layers: &[]Layer{
7071
{
71-
Name: "childlayer-2",
72+
Name: controller.Pointer("childlayer-2"),
7273
Styles: []Style{
7374
{Name: "stylename-5"},
7475
{Name: "stylename-6"},

internal/controller/blobdownload/blob_download.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,14 @@ func downloadStylingAssets(sb *strings.Builder, wms *pdoknlv3.WMS) error {
170170

171171
func downloadLegends(sb *strings.Builder, wms *pdoknlv3.WMS) error {
172172
for _, layer := range wms.GetAllLayersWithLegend() {
173-
writeLine(sb, "mkdir -p %s/%s;", legendPath, layer.Name)
173+
writeLine(sb, "mkdir -p %s/%s;", legendPath, *layer.Name)
174174
for _, style := range layer.Styles {
175-
writeLine(sb, "rclone copyto blobs:/%s %s/%s/%s.png || exit 1;", style.Legend.BlobKey, legendPath, layer.Name, style.Name)
175+
writeLine(sb, "rclone copyto blobs:/%s %s/%s/%s.png || exit 1;", style.Legend.BlobKey, legendPath, *layer.Name, style.Name)
176176
fileName, err := getFilenameFromBlobKey(style.Legend.BlobKey)
177177
if err != nil {
178178
return err
179179
}
180-
writeLine(sb, "Copied legend %s to %s/%s/%s.png;", fileName, legendPath, layer.Name, style.Name)
180+
writeLine(sb, "Copied legend %s to %s/%s/%s.png;", fileName, legendPath, *layer.Name, style.Name)
181181
}
182182
}
183183
writeLine(sb, "chown -R 999:999 %s", legendPath)

internal/controller/blobdownload/blob_download_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func TestGetArgsForWMS(t *testing.T) {
145145
Service: v3.WMSService{
146146
Title: "wms-gpkg-service-title",
147147
Layer: v3.Layer{
148-
Name: "wms-gpkg-layer-name",
148+
Name: smoothoperatorutils.Pointer("wms-gpkg-layer-name"),
149149
Title: smoothoperatorutils.Pointer("wms-gpkg-layer-title"),
150150
Styles: []v3.Style{
151151
{
@@ -156,7 +156,7 @@ func TestGetArgsForWMS(t *testing.T) {
156156
},
157157
Layers: &[]v3.Layer{
158158
{
159-
Name: "wms-gpkg-layer-1-name",
159+
Name: smoothoperatorutils.Pointer("wms-gpkg-layer-1-name"),
160160
Title: smoothoperatorutils.Pointer("wms-gpkg-layer-1-title"),
161161
Styles: []v3.Style{
162162
{
@@ -177,7 +177,7 @@ func TestGetArgsForWMS(t *testing.T) {
177177
},
178178
},
179179
{
180-
Name: "wms-gpkg-layer-2-name",
180+
Name: smoothoperatorutils.Pointer("wms-gpkg-layer-2-name"),
181181
Title: smoothoperatorutils.Pointer("wms-gpkg-layer-2-title"),
182182
Styles: []v3.Style{
183183
{
@@ -222,11 +222,11 @@ func TestGetArgsForWMS(t *testing.T) {
222222
Service: v3.WMSService{
223223
Title: "wms-tif-service-title",
224224
Layer: v3.Layer{
225-
Name: "wms-tif-layer-name",
225+
Name: smoothoperatorutils.Pointer("wms-tif-layer-name"),
226226
Title: smoothoperatorutils.Pointer("wms-tif-layer-title"),
227227
Layers: &[]v3.Layer{
228228
{
229-
Name: "wms-tif-layer-1-name",
229+
Name: smoothoperatorutils.Pointer("wms-tif-layer-1-name"),
230230
Title: smoothoperatorutils.Pointer("wms-tif-layer-1-title"),
231231
Styles: []v3.Style{
232232
{
@@ -244,7 +244,7 @@ func TestGetArgsForWMS(t *testing.T) {
244244
},
245245
},
246246
{
247-
Name: "wms-tif-layer-2-name",
247+
Name: smoothoperatorutils.Pointer("wms-tif-layer-2-name"),
248248
Title: smoothoperatorutils.Pointer("wms-tif-layer-2-title"),
249249
Styles: []v3.Style{
250250
{

internal/controller/capabilitiesgenerator/mapper.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ func getLayers(wms *pdoknlv3.WMS, canonicalUrl string) []wms130.Layer {
588588
nestedLayer := wms130.Layer{
589589
Queryable: asPtr(1),
590590
Opaque: nil,
591-
Name: &layer.Name,
591+
Name: layer.Name,
592592
Title: pointerValOrDefault(layer.Title, ""),
593593
Abstract: layer.Abstract,
594594
KeywordList: &wms130.Keywords{
@@ -621,7 +621,7 @@ func getLayers(wms *pdoknlv3.WMS, canonicalUrl string) []wms130.Layer {
621621
OnlineResource: wms130.OnlineResource{
622622
Xlink: nil,
623623
Type: asPtr("simple"),
624-
Href: asPtr(canonicalUrl + "/legend/" + layer.Name + "/" + layer.Name + ".png"),
624+
Href: asPtr(canonicalUrl + "/legend/" + *layer.Name + "/" + style.Name + ".png"),
625625
},
626626
},
627627
StyleSheetURL: nil,

0 commit comments

Comments
 (0)