Skip to content

Commit 6e0e593

Browse files
committed
boundingboxes
1 parent 5710fb3 commit 6e0e593

File tree

9 files changed

+441
-275
lines changed

9 files changed

+441
-275
lines changed

api/v2beta1/wms_conversion.go

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,10 @@ func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer {
362362
// it needs to be created with defaults from the service
363363
// and in this case the middleLayers are all layers without a group
364364
if topLayer == nil {
365-
boundingBoxes := make([]pdoknlv3.WMSBoundingBox, 0)
365+
var bbox *pdoknlv3.WMSBoundingBox
366366
if v2Service.Extent != nil {
367367
bboxStringList := strings.Split(*v2Service.Extent, " ")
368-
bbox := pdoknlv3.WMSBoundingBox{
368+
bbox = &pdoknlv3.WMSBoundingBox{
369369
CRS: v2Service.DataEPSG,
370370
BBox: smoothoperatormodel.BBox{
371371
MinX: bboxStringList[0],
@@ -374,15 +374,14 @@ func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer {
374374
MaxY: bboxStringList[3],
375375
},
376376
}
377-
boundingBoxes = append(boundingBoxes, bbox)
378377
}
379378

380379
topLayer = &pdoknlv3.Layer{
381380
Title: &v2Service.Title,
382381
Abstract: &v2Service.Abstract,
383382
Keywords: v2Service.Keywords,
384383
Layers: []pdoknlv3.Layer{},
385-
BoundingBoxes: boundingBoxes,
384+
BoundingBoxes: getDefaultWMSLayerBoundingBoxes(bbox),
386385
Visible: true,
387386
}
388387

@@ -410,6 +409,102 @@ func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer {
410409
return *topLayer
411410
}
412411

412+
func getDefaultWMSLayerBoundingBoxes(defaultBbox *pdoknlv3.WMSBoundingBox) []pdoknlv3.WMSBoundingBox {
413+
defaultBboxes := []pdoknlv3.WMSBoundingBox{
414+
{
415+
CRS: "EPSG:28992",
416+
BBox: smoothoperatormodel.BBox{
417+
MinX: "-25000",
418+
MinY: "250000",
419+
MaxX: "280000",
420+
MaxY: "860000",
421+
},
422+
},
423+
{
424+
CRS: "EPSG:25831",
425+
BBox: smoothoperatormodel.BBox{
426+
MinX: "-470271",
427+
MinY: "5.56231e+06",
428+
MaxX: "795163",
429+
MaxY: "6.18197e+06",
430+
},
431+
},
432+
{
433+
CRS: "EPSG:25832",
434+
BBox: smoothoperatormodel.BBox{
435+
MinX: "62461.6",
436+
MinY: "5.56555e+06",
437+
MaxX: "397827",
438+
MaxY: "6.19042e+06",
439+
},
440+
},
441+
{
442+
CRS: "EPSG:3034",
443+
BBox: smoothoperatormodel.BBox{
444+
MinX: "2.61336e+06",
445+
MinY: "3.509e+06",
446+
MaxX: "3.22007e+06",
447+
MaxY: "3.84003e+06",
448+
},
449+
},
450+
{
451+
CRS: "EPSG:3035",
452+
BBox: smoothoperatormodel.BBox{
453+
MinX: "3.01676e+06",
454+
MinY: "3.81264e+06",
455+
MaxX: "3.64485e+06",
456+
MaxY: "4.15586e+06",
457+
},
458+
},
459+
{
460+
CRS: "EPSG:3857",
461+
BBox: smoothoperatormodel.BBox{
462+
MinX: "281318",
463+
MinY: "6.48322e+06",
464+
MaxX: "820873",
465+
MaxY: "7.50311e+06",
466+
},
467+
},
468+
{
469+
CRS: "EPSG:4258",
470+
BBox: smoothoperatormodel.BBox{
471+
MinX: "50.2129",
472+
MinY: "2.52713",
473+
MaxX: "55.7212",
474+
MaxY: "7.37403",
475+
},
476+
},
477+
{
478+
CRS: "EPSG:4326",
479+
BBox: smoothoperatormodel.BBox{
480+
MinX: "50.2129",
481+
MinY: "2.52713",
482+
MaxX: "55.7212",
483+
MaxY: "7.37403",
484+
},
485+
},
486+
{
487+
CRS: "CRS:84",
488+
BBox: smoothoperatormodel.BBox{
489+
MinX: "2.52713",
490+
MinY: "50.2129",
491+
MaxX: "7.37403",
492+
MaxY: "55.7212",
493+
},
494+
},
495+
}
496+
bboxes := []pdoknlv3.WMSBoundingBox{}
497+
if defaultBbox != nil {
498+
bboxes = []pdoknlv3.WMSBoundingBox{*defaultBbox}
499+
}
500+
for _, bbox := range defaultBboxes {
501+
if defaultBbox == nil || bbox.CRS != defaultBbox.CRS {
502+
bboxes = append(bboxes, bbox)
503+
}
504+
}
505+
return bboxes
506+
}
507+
413508
func (v2Layer WMSLayer) MapToV3(v2Service WMSService) pdoknlv3.Layer {
414509
layer := pdoknlv3.Layer{
415510
Name: &v2Layer.Name,

config/crd/update_openapi.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func updateLayersV3(version *v1.CustomResourceDefinitionVersion) {
9393

9494
// Level 1
9595
layerSpecLevel1 := layer.DeepCopy()
96-
layerSpecLevel1.Required = append(layerSpecLevel1.Required, "title", "abstract", "keywords", "layers")
96+
layerSpecLevel1.Required = append(layerSpecLevel1.Required, "title", "abstract", "keywords", "boundingBoxes", "layers")
9797
layerSpecLevel1.XValidations = []v1.ValidationRule{
9898
{Rule: "self.visible", Message: "TopLayer must be visible", FieldPath: ".visible"},
9999
{Rule: "!has(self.name) || has(self.styles)", Message: "If TopLayer has a name, it must have styles", FieldPath: ".styles"},

internal/controller/capabilitiesgenerator/mapper.go

Lines changed: 114 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ func mapContactInfo(contactInfo smoothoperatorv1.ContactInfo) (serviceContactInf
264264
func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoperatorv1.OwnerInfo) (*capabilitiesgenerator.Config, error) {
265265
canonicalServiceURL := wms.URL()
266266

267+
layer, err := getLayers(wms, canonicalServiceURL.String())
268+
if err != nil {
269+
return nil, err
270+
}
271+
267272
abstract := mapperutils.EscapeQuotes(wms.Spec.Service.Abstract)
268273

269274
config := capabilitiesgenerator.Config{
@@ -310,7 +315,7 @@ func MapWMSToCapabilitiesGeneratorInput(wms *pdoknlv3.WMS, ownerInfo *smoothoper
310315
},
311316
Exception: wms130.ExceptionType{Format: []string{"XML", "BLANK"}},
312317
ExtendedCapabilities: nil,
313-
Layer: getLayers(wms, canonicalServiceURL.String()),
318+
Layer: layer,
314319
},
315320
OptionalConstraints: nil,
316321
},
@@ -413,13 +418,15 @@ func getDcpType(url string, fillPost bool) *wms130.DCPType {
413418
return &result
414419
}
415420

416-
func getLayers(wms *pdoknlv3.WMS, canonicalURL string) []wms130.Layer {
417-
return []wms130.Layer{
418-
mapLayer(wms.Spec.Service.Layer, canonicalURL, nil, nil, nil),
421+
func getLayers(wms *pdoknlv3.WMS, canonicalURL string) ([]wms130.Layer, error) {
422+
layer, err := mapLayer(wms.Spec.Service.Layer, canonicalURL, nil, nil, nil, nil)
423+
if err != nil {
424+
return nil, err
419425
}
426+
return []wms130.Layer{*layer}, nil
420427
}
421428

422-
func mapLayer(layer pdoknlv3.Layer, canonicalURL string, authorityURL *wms130.AuthorityURL, identifier *wms130.Identifier, parentStyleNames []string) wms130.Layer {
429+
func mapLayer(layer pdoknlv3.Layer, canonicalURL string, authorityURL *wms130.AuthorityURL, identifier *wms130.Identifier, parentStyleNames []string, parentBBoxes []*wms130.LayerBoundingBox) (*wms130.Layer, error) {
423430
if layer.Authority != nil {
424431
authorityURL = &wms130.AuthorityURL{
425432
Name: layer.Authority.Name,
@@ -435,39 +442,46 @@ func mapLayer(layer pdoknlv3.Layer, canonicalURL string, authorityURL *wms130.Au
435442
}
436443
}
437444

445+
crsses, exBbox, bboxes, err := mapBBoxes(layer.BoundingBoxes, parentBBoxes)
446+
if err != nil {
447+
return nil, err
448+
}
449+
438450
l := wms130.Layer{
439-
Queryable: smoothoperatorutils.Pointer(1),
440-
Opaque: nil,
441-
Name: layer.Name,
442-
Title: mapperutils.EscapeQuotes(smoothoperatorutils.PointerVal(layer.Title, "")),
443-
Abstract: smoothoperatorutils.Pointer(mapperutils.EscapeQuotes(smoothoperatorutils.PointerVal(layer.Abstract, ""))),
444-
KeywordList: &wms130.Keywords{Keyword: layer.Keywords},
445-
// TODO
446-
//CRS: defaultCrs,
447-
//EXGeographicBoundingBox: &defaultBoundingBox,
448-
//BoundingBox: allDefaultBoundingBoxes,
449-
Dimension: nil,
450-
Attribution: nil,
451-
AuthorityURL: authorityURL,
452-
Identifier: identifier,
453-
DataURL: nil,
454-
FeatureListURL: nil,
455-
Style: getLayerStyles(layer, canonicalURL, parentStyleNames),
456-
Layer: []*wms130.Layer{},
451+
Queryable: smoothoperatorutils.Pointer(1),
452+
Opaque: nil,
453+
Name: layer.Name,
454+
Title: mapperutils.EscapeQuotes(smoothoperatorutils.PointerVal(layer.Title, "")),
455+
Abstract: smoothoperatorutils.Pointer(mapperutils.EscapeQuotes(smoothoperatorutils.PointerVal(layer.Abstract, ""))),
456+
KeywordList: &wms130.Keywords{Keyword: layer.Keywords},
457+
CRS: crsses,
458+
EXGeographicBoundingBox: exBbox,
459+
BoundingBox: bboxes,
460+
Dimension: nil,
461+
Attribution: nil,
462+
AuthorityURL: authorityURL,
463+
Identifier: identifier,
464+
DataURL: nil,
465+
FeatureListURL: nil,
466+
Style: getLayerStyles(layer, canonicalURL, parentStyleNames),
467+
Layer: []*wms130.Layer{},
457468
}
458469

459470
if layer.MinScaleDenominator != nil {
460471
float, err := strconv.ParseFloat(*layer.MinScaleDenominator, 64)
461-
if err == nil {
462-
l.MinScaleDenominator = &float
472+
if err != nil {
473+
return nil, err
463474
}
475+
l.MinScaleDenominator = &float
476+
464477
}
465478

466479
if layer.MaxScaleDenominator != nil {
467480
float, err := strconv.ParseFloat(*layer.MaxScaleDenominator, 64)
468-
if err == nil {
469-
l.MaxScaleDenominator = &float
481+
if err != nil {
482+
return nil, err
470483
}
484+
l.MaxScaleDenominator = &float
471485
}
472486

473487
if layer.DatasetMetadataURL != nil {
@@ -489,11 +503,81 @@ func mapLayer(layer pdoknlv3.Layer, canonicalURL string, authorityURL *wms130.Au
489503

490504
// Map sublayers
491505
for _, sublayer := range layer.Layers {
492-
mapped := mapLayer(sublayer, canonicalURL, authorityURL, identifier, append(parentStyleNames, layerStyleNames...))
493-
l.Layer = append(l.Layer, &mapped)
506+
mapped, err := mapLayer(sublayer, canonicalURL, authorityURL, identifier, append(parentStyleNames, layerStyleNames...), bboxes)
507+
if err != nil {
508+
return nil, err
509+
}
510+
l.Layer = append(l.Layer, mapped)
494511
}
495512

496-
return l
513+
return &l, nil
514+
}
515+
516+
func mapBBoxes(layerBBoxes []pdoknlv3.WMSBoundingBox, parentBBoxes []*wms130.LayerBoundingBox) ([]wms130.CRS, *wms130.EXGeographicBoundingBox, []*wms130.LayerBoundingBox, error) {
517+
bboxMap := make(map[string]*wms130.LayerBoundingBox)
518+
crsstrings := []string{}
519+
for _, bbox := range parentBBoxes {
520+
crsstrings = append(crsstrings, bbox.CRS)
521+
bboxMap[bbox.CRS] = bbox
522+
}
523+
for _, bbox := range layerBBoxes {
524+
minX, err := strconv.ParseFloat(bbox.BBox.MinX, 64)
525+
if err != nil {
526+
return nil, nil, nil, err
527+
}
528+
minY, err := strconv.ParseFloat(bbox.BBox.MinY, 64)
529+
if err != nil {
530+
return nil, nil, nil, err
531+
}
532+
maxX, err := strconv.ParseFloat(bbox.BBox.MaxX, 64)
533+
if err != nil {
534+
return nil, nil, nil, err
535+
}
536+
maxY, err := strconv.ParseFloat(bbox.BBox.MaxY, 64)
537+
if err != nil {
538+
return nil, nil, nil, err
539+
}
540+
if !slices.Contains(crsstrings, bbox.CRS) {
541+
crsstrings = append(crsstrings, bbox.CRS)
542+
}
543+
bboxMap[bbox.CRS] = &wms130.LayerBoundingBox{
544+
CRS: bbox.CRS,
545+
Minx: minX,
546+
Miny: minY,
547+
Maxx: maxX,
548+
Maxy: maxY,
549+
}
550+
}
551+
552+
var exBbox *wms130.EXGeographicBoundingBox
553+
bboxes := []*wms130.LayerBoundingBox{}
554+
crsses := []wms130.CRS{}
555+
556+
for _, crs := range crsstrings {
557+
crsSplit := strings.Split(crs, ":")
558+
code, err := strconv.Atoi(crsSplit[1])
559+
if err != nil {
560+
return nil, nil, nil, err
561+
}
562+
crsses = append(crsses, wms130.CRS{
563+
Namespace: crsSplit[0],
564+
Code: code,
565+
})
566+
567+
bbox := bboxMap[crs]
568+
bboxes = append(bboxes, bbox)
569+
570+
if crs == "CRS:84" {
571+
exBbox = &wms130.EXGeographicBoundingBox{
572+
WestBoundLongitude: bbox.Minx,
573+
EastBoundLongitude: bbox.Maxx,
574+
SouthBoundLatitude: bbox.Miny,
575+
NorthBoundLatitude: bbox.Maxy,
576+
}
577+
}
578+
579+
}
580+
return crsses, exBbox, bboxes, nil
497581
}
498582

499583
func getLayerStyles(layer pdoknlv3.Layer, canonicalURL string, parentStyleNames []string) (styles []*wms130.Style) {

internal/controller/capabilitiesgenerator/test_data/wfs_input.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ global:
33
namespace: http://prefix.geonovum.nl
44
onlineResourceUrl: http://localhost
55
path: /datasetOwner/dataset/theme/wfs/v1_0
6-
version: v1_0
76
additionalSchemaLocations: http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 http://inspire.ec.europa.eu/schemas/inspire_dls/1.0/inspire_dls.xsd
87
services:
98
wfs200:

0 commit comments

Comments
 (0)