Skip to content

Commit 9583c4d

Browse files
authored
ILI: Add support for INTERLIS 2.4
1 parent ca4066a commit 9583c4d

File tree

10 files changed

+3471
-127
lines changed

10 files changed

+3471
-127
lines changed

autotest/ogr/data/ili/KGKCGC_FPDS2_V1_1.imd

Lines changed: 2878 additions & 0 deletions
Large diffs are not rendered by default.

autotest/ogr/data/ili/fpds2_v1_1.xtf

Lines changed: 306 additions & 0 deletions
Large diffs are not rendered by default.

autotest/ogr/ogr_ili.py

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -790,8 +790,7 @@ def test_ogr_interlis2_2():
790790
# Ili2 Oereb model
791791

792792

793-
def test_ogr_interlis2_4():
794-
793+
def test_ogr_interlis2_3():
795794
ds = ogr.Open(
796795
"data/ili/ch.bazl.sicherheitszonenplan.oereb_20131118.xtf,data/ili/ch.bazl.sicherheitszonenplan.oereb_20131118.imd"
797796
)
@@ -872,6 +871,80 @@ def test_ogr_interlis2_4():
872871
ogrtest.check_feature_geometry(geom, val)
873872

874873

874+
###############################################################################
875+
# Ili 2.4 model
876+
877+
878+
def test_ogr_interlis2_4():
879+
ds = gdal.OpenEx(
880+
"data/ili/fpds2_v1_1.xtf", open_options=["MODEL=data/ili/KGKCGC_FPDS2_V1_1.imd"]
881+
)
882+
assert ds is not None
883+
884+
layers = [
885+
"UebersichtGeodienst",
886+
"UebersichtMassstab",
887+
"Zustaendigkeit",
888+
"Fixpunkt",
889+
"FixpunktAktion",
890+
"FixpunkteNachfuehrung",
891+
"FixpunktVersion",
892+
]
893+
894+
assert ds.GetLayerCount() == len(layers), "layer count wrong."
895+
896+
for i in range(ds.GetLayerCount()):
897+
assert ds.GetLayer(i).GetName() in layers, "Did not get right layers"
898+
899+
lyr = ds.GetLayerByName("FixpunktVersion")
900+
assert lyr.GetFeatureCount() == 7, "feature count wrong."
901+
902+
feat = lyr.GetNextFeature()
903+
904+
field_values = [
905+
"1667a884-a4a8-461f-8db1-4fbb395b0e57",
906+
"2006-11-13",
907+
0.05,
908+
535.36,
909+
"ja",
910+
"transformiert",
911+
0.02,
912+
"ja",
913+
"Stein",
914+
"Nr.reservieren",
915+
"",
916+
"",
917+
"",
918+
"72b72689-85cb-411a-9022-7de6fbd3277b",
919+
"ba10bace-1efc-4abb-8a59-ebd40a006c9e",
920+
]
921+
922+
if feat.GetFieldCount() != len(field_values):
923+
feat.DumpReadable()
924+
pytest.fail("field count wrong.")
925+
926+
for i in range(feat.GetFieldCount()):
927+
if feat.GetFieldAsString(i) != str(field_values[i]):
928+
feat.DumpReadable()
929+
print(
930+
lyr.GetLayerDefn().GetFieldDefn(i).GetName(), feat.GetFieldAsString(i)
931+
)
932+
pytest.fail("field value wrong.")
933+
934+
geom_field_values = [
935+
"POINT (2761075.728 1198812.021)",
936+
]
937+
assert feat.GetGeomFieldCount() == len(geom_field_values), "geom field count wrong."
938+
939+
for i in range(feat.GetGeomFieldCount()):
940+
geom = feat.GetGeomFieldRef(i)
941+
val = geom_field_values[i]
942+
if val is None:
943+
assert geom is None
944+
else:
945+
ogrtest.check_feature_geometry(geom, val)
946+
947+
875948
###############################################################################
876949
# Check arc segmentation
877950

doc/source/drivers/vector/ili.rst

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
- the long term data storage
2525
- the contract-proof security and the availability of the software
2626

27-
OGR supports INTERLIS 1 and INTERLIS 2 (2.2 and 2.3) with the following
27+
OGR supports INTERLIS 1 and INTERLIS 2 (2.2 and newer) with the following
2828
limitations:
2929

3030
- Curves in Interlis 1 area polygons are converted to line segments
@@ -41,12 +41,22 @@ Driver capabilities
4141

4242
.. supports_virtualio::
4343

44+
Dataset open options
45+
--------------------
46+
47+
|about-open-options|
48+
The following open options are available:
49+
50+
- .. oo:: MODEL
51+
52+
Path to IlisMeta model file.
53+
4454
Model support
4555
-------------
4656

4757
Data is read from transfer files which have different
4858
formats in INTERLIS 1 (.itf) and INTERLIS 2 (.xtf). Models are passed in
49-
IlisMeta format by using "a_filename.xtf,models.imd" as a connection
59+
IlisMeta format with the open option ``MODEL`` or by using "a_filename.xtf,models.imd" as a connection
5060
string.
5161

5262
IlisMeta files can be be generated with the ili2c compiler. Command line
@@ -56,38 +66,44 @@ example:
5666

5767
java -jar ili2c.jar --ilidirs '%ILI_DIR;http://models.interlis.ch/;%JAR_DIR' -oIMD --out models.imd model1.ili [model2.ili ...]
5868

69+
or for newer models:
70+
71+
::
72+
73+
java -jar ili2c.jar --ilidirs '%ILI_DIR;http://models.interlis.ch/;%JAR_DIR' -oIMD16 --out models.imd model1.ili [model2.ili ...]
74+
5975
Some possible transformations using :ref:`ogr2ogr`.
6076

6177
- Interlis 1 -> Shape:
6278

6379
::
6480

65-
ogr2ogr -f "ESRI Shapefile" shpdir ili-bsp.itf,Beispiel.imd
81+
gdal vector convert --oo MODEL=Beispiel.imd -f "ESRI Shapefile" ili-bsp.itf shpdir
6682

67-
- Interlis 2 -> Shape:
83+
- Interlis 2 -> GeoPackage:
6884

6985
::
7086

71-
ogr2ogr -f "ESRI Shapefile" shpdir RoadsExdm2ien.xml,RoadsExdm2ien.imd
87+
gdal vector convert --oo MODEL=KGKCGC_FPDS2_V1_1.imd fpds2_v1_1.xtf fpds2_v1_1.gpkg
7288

7389
or without model:
7490

7591
::
7692

77-
ogr2ogr -f "ESRI Shapefile" shpdir RoadsExdm2ien.xml
93+
gdal vector convert -f "ESRI Shapefile" RoadsExdm2ien.xml shpdir
7894

7995
Example with curves and multiple geometries:
8096

8197
::
8298

83-
ogr2ogr --config OGR_STROKE_CURVE TRUE -SQL 'SELECT Rechtsstatus,publiziertAb,MetadatenGeobasisdaten,Eigentumsbeschraenkung,ZustaendigeStelle,Flaeche FROM "OeREBKRM09trsfr.Transferstruktur.Geometrie"' shpdir ch.bazl.sicherheitszonenplan.oereb_20131118.xtf,OeREBKRM09vs.imd OeREBKRM09trsfr.Transferstruktur.Geometrie
99+
gdal vector sql --oo MODEL=OeREBKRM09vs.imd --config OGR_STROKE_CURVE=TRUE --sql 'SELECT Rechtsstatus,publiziertAb,MetadatenGeobasisdaten,Eigentumsbeschraenkung,ZustaendigeStelle,Flaeche FROM "OeREBKRM09trsfr.Transferstruktur.Geometrie"' -f "ESRI Shapefile" ch.bazl.sicherheitszonenplan.oereb_20131118.xtf shpdir
84100

85101
- Importing multiple Interlis 1 files into PostGIS:
86102

87103
::
88104

89-
ogr2ogr -f PostgreSQL PG:dbname=warmerda av_fixpunkte_ohne_LFPNachfuehrung.itf,av.imd -lco OVERWRITE=yes
90-
ogr2ogr -f PostgreSQL PG:dbname=warmerda av_fixpunkte_mit_LFPNachfuehrung.itf,av.imd -append
105+
gdal vector convert --oo MODEL=av.imd --overwrite-layer av_fixpunkte_ohne_LFPNachfuehrung.itf PG:dbname=warmerda
106+
gdal vector convert --oo MODEL=av.imd --append av_fixpunkte_mit_LFPNachfuehrung.itf PG:dbname=warmerda
91107

92108
Arc interpolation
93109
~~~~~~~~~~~~~~~~~
@@ -102,8 +118,6 @@ Arc interpolation
102118
Other Notes
103119
-----------
104120

105-
- `ogrtools <https://github.com/sourcepole/ogrtools>`__ library
106-
includes extensions for the OGR Interlis driver
107121
- Development of the OGR INTERLIS driver was supported by `Swiss
108122
Federal Administration <http://www.kogis.ch/>`__, `Canton
109123
Solothurn <http://www.sogis.ch/>`__ and `Canton

ogr/ogrsf_frmts/ili/ili2handler.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,24 @@ void ILI2Handler::endDocument()
7474
}
7575

7676
void ILI2Handler::startElement(const XMLCh *const /* uri */,
77-
const XMLCh *const /* localname */,
78-
const XMLCh *const qname,
77+
const XMLCh *const localname,
78+
const XMLCh *const /* qname */,
7979
const Attributes &attrs)
8080
{
8181
// start to add the layers, features with the DATASECTION
8282
char *tmpC = nullptr;
8383
m_nEntityCounter = 0;
8484
if ((level >= 0) ||
85-
(cmpStr(ILI2_DATASECTION, tmpC = XMLString::transcode(qname)) == 0))
85+
(cmpStr(ILI2_DATASECTION, tmpC = XMLString::transcode(localname)) == 0))
8686
{
8787
level++;
8888

8989
if (level >= 2)
9090
{
9191

9292
// create the dom tree
93-
DOMElement *elem =
94-
reinterpret_cast<DOMElement *>(dom_doc->createElement(qname));
93+
DOMElement *elem = reinterpret_cast<DOMElement *>(
94+
dom_doc->createElement(localname));
9595

9696
// add all attributes
9797
unsigned int len = static_cast<unsigned int>(attrs.getLength());

ogr/ogrsf_frmts/ili/ili2reader.cpp

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ using namespace std;
2525
//
2626
static const char *const ILI2_TID = "TID";
2727
static const XMLCh xmlch_ILI2_TID[] = {'T', 'I', 'D', '\0'};
28+
static const XMLCh xmlch_ILI2_TID_NS[] = {'i', 'l', 'i', ':',
29+
't', 'i', 'd', '\0'};
2830
static const XMLCh ILI2_REF[] = {'R', 'E', 'F', '\0'};
31+
static const XMLCh ILI2_REF_NS[] = {'i', 'l', 'i', ':', 'r', 'e', 'f', '\0'};
2932

3033
constexpr int ILI2_STRING_TYPE = 0;
3134
constexpr int ILI2_COORD_TYPE = 1;
@@ -151,7 +154,10 @@ static char *getObjValue(DOMElement *elem)
151154

152155
static char *getREFValue(DOMElement *elem)
153156
{
154-
CPLString osREFValue(transcode(elem->getAttribute(ILI2_REF)));
157+
const XMLCh *val = elem->hasAttribute(ILI2_REF)
158+
? elem->getAttribute(ILI2_REF)
159+
: elem->getAttribute(ILI2_REF_NS);
160+
CPLString osREFValue(transcode(val));
155161
return CPLStrdup(osREFValue);
156162
}
157163

@@ -672,29 +678,9 @@ int ILI2Reader::SetupParser()
672678
m_poSAXReader->setFeature(XMLUni::fgXercesDisableDefaultEntityResolution,
673679
true);
674680

675-
/* No Validation
676-
#if (OGR_ILI2_VALIDATION)
677-
m_poSAXReader->setFeature(
678-
XMLString::transcode("http://xml.org/sax/features/validation"),
679-
true); m_poSAXReader->setFeature(
680-
XMLString::transcode("http://xml.org/sax/features/namespaces"),
681-
true);
682-
683-
m_poSAXReader->setFeature( XMLUni::fgSAX2CoreNameSpaces, true );
684-
m_poSAXReader->setFeature( XMLUni::fgXercesSchema, true );
685-
686-
// m_poSAXReader->setDoSchema(true);
687-
// m_poSAXReader->setValidationSchemaFullChecking(true);
688-
#else
689-
*/
690-
XMLCh *tmpCh =
691-
XMLString::transcode("http://xml.org/sax/features/validation");
692-
m_poSAXReader->setFeature(tmpCh, false);
693-
XMLString::release(&tmpCh);
694-
tmpCh = XMLString::transcode("http://xml.org/sax/features/namespaces");
695-
m_poSAXReader->setFeature(tmpCh, false);
696-
XMLString::release(&tmpCh);
697-
// #endif
681+
// No Validation
682+
m_poSAXReader->setFeature(XMLUni::fgSAX2CoreValidation, false);
683+
m_poSAXReader->setFeature(XMLUni::fgXercesSchema, false);
698684

699685
m_bReadStarted = FALSE;
700686

@@ -835,8 +821,10 @@ int ILI2Reader::AddFeature(DOMElement *elem)
835821
int fIndex = feature->GetFieldIndex(ILI2_TID);
836822
if (fIndex != -1)
837823
{
838-
feature->SetField(
839-
fIndex, transcode(elem->getAttribute(xmlch_ILI2_TID)).c_str());
824+
const XMLCh *val = elem->hasAttribute(xmlch_ILI2_TID)
825+
? elem->getAttribute(xmlch_ILI2_TID)
826+
: elem->getAttribute(xmlch_ILI2_TID_NS);
827+
feature->SetField(fIndex, transcode(val).c_str());
840828
}
841829
else
842830
{

0 commit comments

Comments
 (0)