Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
134 lines (102 sloc) 4.52 KB
# -*- coding: utf-8 -*-
# Filter that prepares a GFS file which can be used to load with ogr2ogr.
# Author: Frank Steggink
import os
from copy import deepcopy
# We need specifically lxml, because of the incremental XML generation
from lxml import etree
from stetl.component import Config
from stetl.filter import Filter
from stetl.packet import FORMAT
from stetl.util import Util
log = Util.get_log("orlhandler")
class OrlHandler(Filter):
This filter checks whether the data file contains openbareruimtelabels. If this is the case, the positions are split
into different features.
# Start attribute config meta
# Applying Decorator pattern with the Config class to provide
# read-only config values from the configured properties.
@Config(ptype=str, default=None, required=True)
def temp_file(self):
Name of the temporary file.
# End attribute config meta
# Constructor
def __init__(self, configdict, section, consumes=FORMAT.string, produces=FORMAT.string):
Filter.__init__(self, configdict, section, consumes, produces)
def init(self):'Init: ORL handler')
if self.temp_file is None:
# If no temp_file is present:
err_s = 'The temp_file needs to be configured'
raise ValueError(err_s)
def exit(self):'Exit: ORL handler')
def invoke(self, packet):
input_gml =
if input_gml is None:
return packet'In OrlHandler.invoke')
if not os.path.exists(input_gml):
msg = "The given XML file doesn't exist"
raise ValueError(msg)
if not self.checkOrlFile(input_gml):
return packet
nsmap = {None: ""}
with etree.xmlfile(self.temp_file) as xf:
with xf.element('{}CityModel', nsmap=nsmap):
with open(input_gml) as f:
context = etree.iterparse(f)
for action, elem in context:
if action == 'end' and elem.tag == '{}cityObjectMember':
# Duplicate openbareruimtelabel
self.duplicateOrl(xf, elem)
# Clean up the original element and the node of its previous sibling
# (
while elem.getprevious() is not None:
del elem.getparent()[0]
del context
# Delete the old file and rename the new file
# Return the original packet, since this contains the name of the GML file which is being loaded
return packet
def checkOrlFile(self, input_gml):
result = False
with open(input_gml) as f:
prevTag = ''
context = etree.iterparse(f)
for action, elem in context:
if action == 'end' and elem.tag == '{}cityObjectMember':
if prevTag == '{}OpenbareRuimteLabel':
# We're processing a document with openbareruimtelabels, quit
result = True
prevTag = elem.tag
del context
return result
def duplicateOrl(self, xf, elem):
# The element to be written needs to be deepcopied first, otherwise the counts are off somehow...
out_elem = deepcopy(elem)
ns = {'imgeo': ''}
count = int(out_elem.xpath('count(//imgeo:positie)', namespaces=ns))
for i in range(0, count):
out_elem = deepcopy(elem)
# Remove all position elements except for the i'th. This is done by first collecting all positions into
# a list, then remove the position from that list which should be kept, and then remove all other positions
# from the XML element.
positions = out_elem.xpath('//imgeo:positie', namespaces=ns)
del positions[i]
for pos in positions: