Skip to content

Commit

Permalink
First version of Top250Extract
Browse files Browse the repository at this point in the history
  • Loading branch information
fsteggink committed Jan 15, 2018
1 parent 1d0d8dd commit 9738fa2
Show file tree
Hide file tree
Showing 18 changed files with 3,927 additions and 0 deletions.
217 changes: 217 additions & 0 deletions brt/top250nl/doc/1.2.1/brt-algemeen.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:brt="http://register.geostandaarden.nl/gmlapplicatieschema/brt-algemeen/1.2.0" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" targetNamespace="http://register.geostandaarden.nl/gmlapplicatieschema/brt-algemeen/1.2.0" version="1.2.0">
<import namespace="http://www.opengis.net/gml/3.2" schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<!--XML Schema document created by ShapeChange - http://shapechange.net/-->
<element name="BRTHogeEnLageZijde" substitutionGroup="gml:AbstractObject" type="brt:BRTHogeEnLageZijdeType">
<annotation>
<documentation>definitie van een geometrietype van een relief object, dat bestaat uit twee verschillende lijngeometrieën, namelijk een hoge zijde en een lage zijde</documentation>
</annotation>
</element>
<complexType name="BRTHogeEnLageZijdeType">
<sequence>
<element name="hogeZijde" type="gml:CurvePropertyType"/>
<element name="lageZijde" type="gml:CurvePropertyType"/>
</sequence>
</complexType>
<complexType name="BRTHogeEnLageZijdePropertyType">
<sequence>
<element ref="brt:BRTHogeEnLageZijde"/>
</sequence>
</complexType>
<simpleType name="BRTJaNeeWaardeType">
<annotation>
<documentation>waardelijst als alternatief voor het algemene "boolean" type
-- Description--
Alleen de waarden 'ja' en 'nee' zijn toegestaan. Niet alle databases kennen het boolean datatype. Met deze waardelijst hoeven gebruikers zich niet af te vragen hoe de waarde in de database terecht moet komen.</documentation>
</annotation>
<restriction base="string">
<enumeration value="ja"/>
<enumeration value="nee"/>
</restriction>
</simpleType>
<element name="BRTLijnOfPunt" substitutionGroup="gml:AbstractObject" type="brt:BRTLijnOfPuntType">
<annotation>
<documentation>definitie van een geometrietype van een ruimtelijk object, waarbij gekozen kan worden uit lijn- of puntgeometrie</documentation>
</annotation>
</element>
<complexType name="BRTLijnOfPuntType">
<choice>
<element name="lijnGeometrie" type="gml:CurvePropertyType"/>
<element name="puntGeometrie" type="gml:PointPropertyType"/>
</choice>
</complexType>
<complexType name="BRTLijnOfPuntPropertyType">
<sequence>
<element ref="brt:BRTLijnOfPunt"/>
</sequence>
</complexType>
<element name="BRTVlakLijnOfPunt" substitutionGroup="gml:AbstractObject" type="brt:BRTVlakLijnOfPuntType">
<annotation>
<documentation>definitie van een geometrietype van een ruimtelijk object, waarbij gekozen kan worden uit vlak-, lijn- of puntgeometrie</documentation>
</annotation>
</element>
<complexType name="BRTVlakLijnOfPuntType">
<choice>
<element name="vlakGeometrie" type="gml:SurfacePropertyType"/>
<element name="lijnGeometrie" type="gml:CurvePropertyType"/>
<element name="puntGeometrie" type="gml:PointPropertyType"/>
</choice>
</complexType>
<complexType name="BRTVlakLijnOfPuntPropertyType">
<sequence>
<element ref="brt:BRTVlakLijnOfPunt"/>
</sequence>
</complexType>
<element name="BRTVlakMultivlakOfPunt" substitutionGroup="gml:AbstractObject" type="brt:BRTVlakMultivlakOfPuntType">
<annotation>
<documentation>definitie van een geometrietype van een ruimtelijk object, waarbij gekozen kan worden uit vlak-, mulitivlak- of puntgeometrie</documentation>
</annotation>
</element>
<complexType name="BRTVlakMultivlakOfPuntType">
<choice>
<element name="vlakGeometrie" type="gml:SurfacePropertyType"/>
<element name="multivlakGeometrie" type="gml:MultiSurfacePropertyType"/>
<element name="puntGeometrie" type="gml:PointPropertyType"/>
</choice>
</complexType>
<complexType name="BRTVlakMultivlakOfPuntPropertyType">
<sequence>
<element ref="brt:BRTVlakMultivlakOfPunt"/>
</sequence>
</complexType>
<element name="BRTVlakOfLijn" substitutionGroup="gml:AbstractObject" type="brt:BRTVlakOfLijnType">
<annotation>
<documentation>definitie van een geometrietype van een ruimtelijk object, waarbij gekozen kan worden uit vlak- of lijngeometrie</documentation>
</annotation>
</element>
<complexType name="BRTVlakOfLijnType">
<choice>
<element name="vlakGeometrie" type="gml:SurfacePropertyType"/>
<element name="lijnGeometrie" type="gml:CurvePropertyType"/>
</choice>
</complexType>
<complexType name="BRTVlakOfLijnPropertyType">
<sequence>
<element ref="brt:BRTVlakOfLijn"/>
</sequence>
</complexType>
<element name="BRTVlakOfMultivlak" substitutionGroup="gml:AbstractObject" type="brt:BRTVlakOfMultivlakType">
<annotation>
<documentation>definitie van een geometrietype van een ruimtelijk object, waarbij gekozen kan worden uit vlak- of multivlakgeometrie</documentation>
</annotation>
</element>
<complexType name="BRTVlakOfMultivlakType">
<choice>
<element name="vlakGeometrie" type="gml:SurfacePropertyType"/>
<element name="multivlakGeometrie" type="gml:MultiSurfacePropertyType"/>
</choice>
</complexType>
<complexType name="BRTVlakOfMultivlakPropertyType">
<sequence>
<element ref="brt:BRTVlakOfMultivlak"/>
</sequence>
</complexType>
<element name="BRTVlakOfPunt" substitutionGroup="gml:AbstractObject" type="brt:BRTVlakOfPuntType">
<annotation>
<documentation>definitie van een geometrietype van een ruimtelijk object, waarbij gekozen kan worden uit vlak- of puntgeometrie</documentation>
</annotation>
</element>
<complexType name="BRTVlakOfPuntType">
<choice>
<element name="vlakGeometrie" type="gml:SurfacePropertyType"/>
<element name="puntGeometrie" type="gml:PointPropertyType"/>
</choice>
</complexType>
<complexType name="BRTVlakOfPuntPropertyType">
<sequence>
<element ref="brt:BRTVlakOfPunt"/>
</sequence>
</complexType>
<element name="NEN3610ID" substitutionGroup="gml:AbstractObject" type="brt:NEN3610IDType">
<annotation>
<documentation>identificatiegegevens voor de universeel unieke identificatie van een object
NOTE De combinatie van ‘namespace’ van een registratie en lokale identificatie maken een object uniek identificeerbaar. Met de informatie van deze klasse kan daardoor met zekerheid worden verwezen naar het geïdentificeerde object.
-- Source --
Dit datatype is in NEN 3610:2011 gedefinieerd met optionele versie informatie. Deze versie informatie is echter niet opgenomen in IMBRT</documentation>
</annotation>
</element>
<complexType name="NEN3610IDType">
<sequence>
<element name="namespace" type="string">
<annotation>
<documentation>unieke verwijzing naar een registratie van objecten
NOTE Het attribuut &amp;lsquo;namespace&amp;rsquo; is een unieke verwijzing naar de registratie die de identificatie uitdeelt. Deze lijst van registraties wordt beheerd binnen de context van NEN 3610. Binnen Nederland zal deze namespace vrijwel altijd met &amp;lsquo;NL.&amp;rsquo; beginnen.
De volgende karakters mogen in een namespace aanduiding voorkomen: {&amp;rdquo;A&amp;rdquo;&amp;hellip;&amp;rdquo;Z&amp;rdquo;, &amp;ldquo;a&amp;rdquo;&amp;hellip;&amp;rdquo;z&amp;rdquo;, &amp;rdquo;0&amp;rdquo;&amp;hellip;&amp;rdquo;9&amp;rdquo;, &amp;ldquo;_&amp;rdquo;, &amp;ldquo;- &amp;ldquo;, &amp;ldquo;,&amp;rdquo;, &amp;rdquo;.&amp;rdquo;}
-- Source --
NEN 3610:2011</documentation>
</annotation>
</element>
<element name="lokaalID" type="string">
<annotation>
<documentation>unieke identificatiecode binnen een registratie
NOTE &amp;lsquo;LokaalId&amp;rsquo; is de identificatiecode die een object heeft binnen een (lokale) registratie.
De volgende karakters mogen in een lokaalID voorkomen: {&amp;rdquo;A&amp;rdquo;&amp;hellip;&amp;rdquo;Z&amp;rdquo;, &amp;ldquo;a&amp;rdquo;&amp;hellip;&amp;rdquo;z&amp;rdquo;, &amp;rdquo;0&amp;rdquo;&amp;hellip;&amp;rdquo;9&amp;rdquo;, &amp;ldquo;_&amp;rdquo;, &amp;ldquo;-&amp;ldquo;, &amp;ldquo;,&amp;rdquo;, &amp;rdquo;.&amp;rdquo;}.
-- Source --
NEN 3610:2011</documentation>
</annotation>
</element>
</sequence>
</complexType>
<simpleType name="VoidReasonValueType">
<annotation>
<documentation>Void reason value: reden waarom een ’void-waarde’ is ingevuld
-- Source --
NEN 3610:2011</documentation>
</annotation>
<union memberTypes="brt:VoidReasonValueEnumerationType brt:VoidReasonValueOtherType"/>
</simpleType>
<simpleType name="VoidReasonValueEnumerationType">
<annotation>
<documentation>Void reason value: reden waarom een ’void-waarde’ is ingevuld
-- Source --
NEN 3610:2011</documentation>
</annotation>
<restriction base="string">
<enumeration value="geenWaarde">
<annotation>
<documentation>element heeft in werkelijkheid geen waarde
-- Source --
NEN 3610:2011</documentation>
</annotation>
</enumeration>
<enumeration value="nietOndersteund">
<annotation>
<documentation>-- Definitie --
zender houdt in zijn registratie geen waarde voor dit attribuut bij. Geldt voor alle objecten van dit objecttype
-- Source --
NEN 3610:2011</documentation>
</annotation>
</enumeration>
<enumeration value="nogNietIngewonnen">
<annotation>
<documentation>-- Definitie --
Er is nog nog geen waarde voor dit attribuut ingewonnen. maar de bronhouder gaat dat wel doen</documentation>
</annotation>
</enumeration>
<enumeration value="vastgesteldOnbekend">
<annotation>
<documentation>er is vastgesteld dat de waarde van het attribuut onbekend is en hoogst waarschijnlijk niet meer kan worden achterhaald (bijvoorbeeld omdat het brondocument onleesbaar is of het object niet meer bestaat in de werkelijkheid)
-- Source --
NEN 3610:2011</documentation>
</annotation>
</enumeration>
<enumeration value="waardeOnbekend">
<annotation>
<documentation>element is verplicht maar de waarde is bij de zender niet bekend
-- Source --
NEN 3610:2011</documentation>
</annotation>
</enumeration>
</restriction>
</simpleType>
<simpleType name="VoidReasonValueOtherType">
<restriction base="string">
<pattern value="other: \w{2,}"/>
</restriction>
</simpleType>
</schema>
54 changes: 54 additions & 0 deletions brt/top250nl/etl/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
TOP250NL inlezen met Stetl (www.stetl.org) ETL framework.
door: Just van den Broecke,
GFS en XSLT door Frank Steggink

Deze map bevat de ETL configuratie en commando om via Stetl
TOP250NL vanuit de bron GML bestanden naar verschillende outputs weg te schrijven.
Standaard is dit PostGIS, maar omdat output via ogr2ogr verloopt kan dit
elke output zijn die ogr2ogr ondersteunt, bijv SHP, GeoJSON of GeoPackage, in theorie ook bijv Oracle.

Om gebruik te maken van Stetl moet de externe GitHub submodule externals/stetl
aanwezig zijn.

Bij het klonen van de GitHub komt Stetl als volgt mee:
git clone --recursive https://github.com/nlextract/NLExtract.git
Stetl komt dan mee, hoeft niet apart geinstalleerd, alleen de Stetl-dependencies.

Dependencies Stetl installeren:
http://www.stetl.org/en/latest/install.html

Meer over Stetl: http://stetl.org

Commando
--------

./etl-top250nl.sh
Windows: etl-top250nl.cmd

Gebruikt default opties (database params etc) uit options/default.args.

Stetl configuratie, hoeft niet gewijzigd, alleen indien bijv andere output gewenst:
conf/etl-top250nl-v1.2.1.cfg

Opties/argumenten
-----------------

Een aantal opties kunnen op 2 manieren vervangen worden:

1- Impliciet: Overrule default opties (database params etc) met een eigen lokale file gebaseerd op
lokale hostnaam: options/<jouw host naam>.args

2- Expliciet op command line via ./etl-top250nl.sh <mijn opties file>.args
etl-top250nl.cmd <mijn opties file>.args

Indien methode 2 gebruikt wordt, prevaleert deze boven 1 en de default opties!

Database mapping
----------------
gfs/top250-v1.2.1.gfs is de GDAL/OGR "GFS Template" en bepaalt de mapping van GML elementen/attributen
naar PostGIS kolom(namen). Maak eventueel een eigen GFS file en specificeer deze in je
options/<jouw host naam>.args: bijv gfs_template=gfs/mijntop250.gfs

TODO
----
* GUI
119 changes: 119 additions & 0 deletions brt/top250nl/etl/conf/etl-top250nl-v1.2.1.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Example of process-chains for extracting TOP250NL source data from GML to PostGIS.
# A Chain is a series of Components: one Input, zero or more Filters and one Output.
# The output of a Component is connected to the input of the next Component (except for
# the final Output Component, which writes to the final destination, e.g. Postgres.
#
# Currently 3 chains are executed in the following order:
# - SQL pre: DB initialization, delete tables, create schema
# - Main ETL chain, consists of the following components
# 1. input_zip_file: reads files from input ZIP file(s)
# 2. extract_zip_file: extracts a GML file from a ZIP file
# 3. parse_gml_file: parses elements from a GML file
# 4. xml_assembler: assemble feature elements into smaller (etree) docs
# 5. transformer_xslt: transform each (etree) doc
# 6. packet_writer: writes the transformed GML document to a file
# 7. output_ogr2ogr: output using ogr2ogr, input is a transformed GML file, output can be any OGR output
# - SQL post: remove duplicates
#
# Any substitutable values are specified in curly brackets e.g. {password}.
# Actual values can be passed as args to Stetl main.py or as arguments from a wrapper program
# like top250extract.py to etl.py. Here are the 3 chains:

[etl]
chains = input_sql_pre|schema_name_filter|output_postgres,
input_zip_file|extract_zip_file|parse_gml_file|xml_assembler|transformer_xslt|packet_writer|output_ogr2ogr,
input_sql_post|schema_name_filter|output_postgres

# Pre SQL file inputs to be executed
[input_sql_pre]
class = inputs.fileinput.StringFileInput
file_path = sql/drop-tables-v1.2.1.sql,sql/create-schema.sql

# Post SQL file inputs to be executed
[input_sql_post]
class = inputs.fileinput.StringFileInput
file_path = sql/delete-duplicates-v1.2.1.sql,sql/update-multiattributes-v1.2.1.sql

# Generic filter to substitute Python-format string values like {schema} in string
[schema_name_filter]
class = filters.stringfilter.StringSubstitutionFilter
# format args {schema} is schema name
format_args = schema:{schema}

[output_postgres]
class = outputs.dboutput.PostgresDbOutput
database = {database}
host = {host}
port = {port}
user = {user}
password = {password}
schema = {schema}

# The source input ZIP-file(s) from dir, producing 'records' with ZIP file name and inner file names
[input_zip_file]
class=inputs.fileinput.ZipFileInput
file_path = {input_dir}
filename_pattern = *.[zZ][iI][pP]
name_filter=*.[gG][mM][lL]

# Filter to extract a ZIP file one by one to a temporary location
[extract_zip_file]
class=filters.zipfileextractor.ZipFileExtractor
file_path = {temp_dir}/fromzip-tmp.gml

# The source input file producing cityObjectMember elements
[parse_gml_file]
class = filters.xmlelementreader.XmlElementReader
element_tags = FeatureMember

# Assembles etree docs gml:featureMember elements, each with "max_elements" elements
[xml_assembler]
class = filters.xmlassembler.XmlAssembler
max_elements = {max_features}
container_doc = <?xml version="1.0" encoding="UTF-8"?>
<top250nl:FeatureCollectionT250NL
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:top250nl="http://register.geostandaarden.nl/gmlapplicatieschema/top250nl/1.2.1"
xmlns:brt="http://register.geostandaarden.nl/gmlapplicatieschema/brt-algemeen/1.2.0"
xmlns:gml="http://www.opengis.net/gml/3.2"
xsi:schemaLocation="http://register.geostandaarden.nl/gmlapplicatieschema/top250nl/1.2.1 top250nl.xsd"
gml:id="Top250NL_FC">
</top250nl:FeatureCollectionT250NL>
element_container_tag = FeatureCollectionT250NL

# Transforms into simple/flat feature data (single geometry per feature type, single attrs)
[transformer_xslt]
class = filters.xsltfilter.XsltFilter
script = xsl/top250-split_v1.2.1.xsl

# Writes the payload of a packet as a string to a file
[packet_writer]
class = filters.packetwriter.PacketWriter
file_path = {temp_dir}/top250-tmp.gml

# The ogr2ogr command-line, may use any output here, as long as
# the input is a GML file. The "temp_file" is where etree-docs
# are saved. It has to be the same file as in the ogr2ogr command.
# TODO: find a way to use a GML-stream through stdin to ogr2ogr
[output_ogr2ogr]
class = outputs.execoutput.Ogr2OgrExecOutput
# destination format: OGR vector format name
dest_format = PostgreSQL
# destination datasource: name of datasource
dest_data_source = "PG:dbname={database} host={host} port={port} user={user} password={password} active_schema={schema}"
# layer creation options will only be added to ogr2ogr on first run
lco = -lco LAUNDER=YES -lco PRECISION=NO
# spatial_extent, translates to -spat xmin ymin xmax ymax
spatial_extent = {spatial_extent}
# gfs template
gfs_template = gfs/top250-v1.2.1.gfs
# miscellaneous ogr2ogr options
options = -append -gt 65536 {multi_opts} --config PG_USE_COPY NO
# cleanup input?
cleanup_input = True

# Validator for XML
[xml_schema_validator]
class = filters.xmlvalidator.XmlSchemaValidator
xsd = http://register.geostandaarden.nl/gmlapplicatieschema/top250nl/1.2.1/top250nl.xsd
enabled = False

0 comments on commit 9738fa2

Please sign in to comment.