Skip to content

Commit

Permalink
feat(geopackage): prefer non-GML namespace on multiple candidates for…
Browse files Browse the repository at this point in the history
… property

ING-4543
  • Loading branch information
stempler committed Nov 29, 2024
1 parent 0089368 commit 9c4ecbe
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:planAtlas-="https://www.geoportal-raumordnung-bw.de/planAtlas-rp" elementFormDefault="qualified" targetNamespace="https://www.geoportal-raumordnung-bw.de/planAtlas-rp">
<import namespace="http://www.opengis.net/gml/3.2" schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<element name="ING-4543" substitutionGroup="gml:AbstractFeature" type="planAtlas-:ING-4543"/>
<complexType name="ING-4543">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element maxOccurs="1" minOccurs="0" name="bereich" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="oa_nr" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="oa_nr_t" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="klasse" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="klasse_t" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="bindung" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="bindung_t" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="status" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="status_t" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="kategorie" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="kategori_t" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="erst_id" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="erst_id_t" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="name" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="bemerkung" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="inkraft" nillable="false" type="date"/>
<element maxOccurs="1" minOccurs="0" name="massstab" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="nr" nillable="false" type="integer"/>
<element maxOccurs="1" minOccurs="0" name="id" nillable="false" type="string"/>
<element maxOccurs="1" minOccurs="0" name="geometrie" nillable="false" type="gml:MultiCurvePropertyType"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
package eu.esdihumboldt.hale.io.geopackage.internal

import static eu.esdihumboldt.hale.common.schema.SchemaConstants.GML_NAMESPACE_CORE

import groovy.transform.CompileStatic

import java.sql.SQLException
Expand Down Expand Up @@ -102,6 +104,16 @@ class TableInstanceBuilder {
cand = candidates.find { it.getConstraint(Cardinality).getMinOccurs() > 0 && !it.getConstraint(NillableFlag).isEnabled() }
}

if (cand == null && candidates.size() == 2) {
// prefer property that is not in GML namespace, if the other is in a GML namespace
if (candidates[0].name.namespaceURI.startsWith(GML_NAMESPACE_CORE)) {
cand = candidates[1]
}
else if (candidates[1].name.namespaceURI.startsWith(GML_NAMESPACE_CORE)) {
cand = candidates[0]
}
}

if (cand == null) {
// just pick the first one
cand = candidates[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import groovy.transform.TypeCheckingMode

import java.util.function.Consumer

import javax.xml.namespace.QName

import org.junit.Test
import org.locationtech.jts.geom.Geometry

Expand All @@ -36,6 +38,7 @@ import eu.esdihumboldt.hale.common.schema.geometry.GeometryProperty
import eu.esdihumboldt.hale.common.schema.model.Schema
import eu.esdihumboldt.hale.common.test.TestUtil
import eu.esdihumboldt.util.test.AbstractPlatformTest
import io.qameta.allure.Link

/**
* Tests loading GeoPackage instances.
Expand Down Expand Up @@ -261,4 +264,64 @@ class GeopackageInstanceReaderTest extends AbstractPlatformTest {
.isNotNull()
} as Consumer)
}

/**
* Test reading Geopackage data based on an XML schema (Use case: Rewrite Geopackage as GML).
*/
@CompileStatic(TypeCheckingMode.SKIP)
@Link(value = "ING-4543", type = "JIRA")
@Test
public void testReadInstancesXsdGmlConflict() {
GeopackageApiTest.withTestFile("testdata/gml-conflict.gpkg") { File file ->
Schema xmlSchema = TestUtil.loadSchema(getClass().getClassLoader().getResource("testdata/gml-conflict.xsd").toURI())

InstanceCollection instances = loadInstances(xmlSchema, file)

assertNotNull(instances)
assertTrue(instances.hasSize())

// test count
assertEquals(3, instances.size())

// check instances
def list = instances.toList()
def all = { new InstanceAccessor(list) }

def expectedNames = [
'Allgäubahn',
'Bodensee-Gürtelbahn',
'Donaubahn'
].toArray()

// verify that names are present
assertThat(all().name.values())
.containsExactlyInAnyOrder(expectedNames)

// verify that correct name property is used
def nameProperty = new QName('https://www.geoportal-raumordnung-bw.de/planAtlas-rp', 'name')
def names = list.collect { it.getProperty(nameProperty)[0] }.toList()
assertThat(names)
.containsExactlyInAnyOrder(expectedNames)

// also check for id element (which is present in the schema in addition to the GML id attribute)
def idProperty = new QName('https://www.geoportal-raumordnung-bw.de/planAtlas-rp', 'id')
def ids = list.collect { it.getProperty(idProperty)[0] }.toList()
assertThat(ids)
.containsExactlyInAnyOrder('ln_8164_843_1', 'ln_8164_843_2', 'ln_8164_843_3')

// GML id attribute should be empty
def gmlIdProperty = new QName('http://www.opengis.net/gml/3.2', 'id')
def gmlIds = list.collect {
def prop = it.getProperty(gmlIdProperty)
if (prop) {
prop[0]
}
else {
null
}
}.findAll()
assertThat(gmlIds)
.isEmpty()
}
}
}

0 comments on commit 9c4ecbe

Please sign in to comment.