def __init__(self, parent): wx.Dialog.__init__(self, parent, -1, 'Logging', size=(900, 600)) database = Database() rows = database.select('SELECT * FROM nlx_bag_log') table = wx.grid.Grid(self) table.CreateGrid(len(rows), 5) table.HideRowLabels() table.SetColLabelValue(0, "Tijd") table.SetColSize(0, 150) table.SetColLabelValue(1, "Actie") table.SetColSize(1, 140) table.SetColLabelValue(2, "Bestand") table.SetColSize(2, 340) table.SetColLabelValue(3, "Bericht") table.SetColSize(3, 160) table.SetColLabelValue(4, "Error") table.SetColSize(4, 80) index = 0 for log_rec in rows: # Skip overvloed logging if 'INFO' in log_rec[4]: continue table.SetCellValue(index, 0, str(log_rec[1]).split('.')[0]) table.SetCellValue(index, 1, str(log_rec[2])) table.SetCellValue(index, 2, str(log_rec[3])) table.SetCellValue(index, 3, str(log_rec[4])) table.SetCellValue(index, 4, str(log_rec[5])) index += 1
def worker(): # Print start time Log.log.time("Start") # Extracts any data from any source files/dirs/zips/xml/csv etc Database().log_actie('start_extract', file_or_dir_path) reader = BAGFileReader(file_or_dir_path) reader.process() Database().log_actie('stop_extract', file_or_dir_path) # Print end time Log.log.time("End")
def worker(): # Print start time Log.log.time("Start") sql_script = 'adres-tabel.sql' # Extracts any data from any source files/dirs/zips/xml/csv etc Database().log_actie('start_maak_adressen', sql_script) processor = Processor() processor.processSQLScript(sql_script) Database().log_actie('stop_maak_adressen', sql_script) # Print end time Log.log.time("End")
def parseXML(self, file, naam): Log.log.startTimer("parseXML") xml = None try: xml = etree.parse(file) bericht = Log.log.endTimer("parseXML") Database().log_actie('xml_parse', naam, bericht) except (Exception), e: bericht = Log.log.error("fout %s in XML parsen, bestand=%s" % (str(e), str(naam))) Database().log_actie('xml_parse', naam, bericht, True)
def get_database(self): if self.soort == "postgres": from postgresdb import Database return Database() elif self.soort == "sqlite": from sqlitedb import Database return Database() else: #ga voorlopig uit van "postgres" from postgresdb import Database return Database()
def __init__(self, raadpleegScherm, positie, afmeting): wx.Panel.__init__(self, raadpleegScherm, -1, positie, afmeting) self.raadpleegScherm = raadpleegScherm self.logScherm = raadpleegScherm.logScherm self.gebruikHuidigeKaart = False self.minX = 0.0 self.minY = 0.0 self.maxX = 0.0 self.maxY = 0.0 self.centerX = 0.0 self.centerY = 0.0 self.schaal = 0.0 self.zoom = 0.5 self.polygonen = [] # Verzameling van alle polygonen die worden getoond in de kaart self.bagObject = None # Het huidige bagObject dat wordt getoond in de kaart self.highlightPolygonen = [] # Polygoon(en) van het huidige bagObject self.PNDpolygonen = [] # Lijst van Pand-polygonen self.LPLpolygonen = [] # Lijst van Ligplaats-polygonen self.SPLpolygonen = [] # Lijst van Standplaats-polygonen self.WPLpolygonen = [] # Lijst van Woonplaats-polygonen self.NBpolygonen = [] # 'NB' betekent Niet Bestaand, voor bijv. gesloopte panden self.coordinaten = wx.TextCtrl(self, -1, "", pos=(self.GetSize().GetWidth() - 90, self.GetSize().GetHeight() - 20), size=(90, 20), style=wx.TE_READONLY) self.SetBackgroundColour(self.coordinaten.GetBackgroundColour()) self.Bind(wx.EVT_PAINT, self._tekenKaart) # self.Bind(wx.EVT_MOTION, self._beweegCursor) self.Bind(wx.EVT_LEFT_DOWN, self._klikOpPunt) self.Bind(wx.EVT_LEFT_DCLICK, self._dubbelklikOpPunt) self.zoomUitKnop = wx.Button(self, label="-", pos=(self.GetSize().GetWidth() - 20, 0), size=(20, 20)) self.zoomInKnop = wx.Button(self, label="+", pos=(self.GetSize().GetWidth() - 20, 20), size=(20, 20)) self.Bind(wx.EVT_BUTTON, self._zoomUit, self.zoomUitKnop) self.Bind(wx.EVT_BUTTON, self._zoomIn, self.zoomInKnop) self.database = Database()
def processXML(self, naam, xml): if not xml: Database().log_actie('xml_processing', naam, 'geen xml document', True) return try: Log.log.info("processXML: " + naam) xmldoc = xml.getroot() # de processor bepaalt of het een extract of een mutatie is self.processor.processDOM(xmldoc) #Log.log.info(document) except (Exception), e: bericht = Log.log.error("fout %s in DOM processing, bestand=%s" % (str(e), str(naam))) Database().log_actie('xml_processing', naam, bericht, True)
def __init__(self, app): wx.Frame.__init__(self, None, -1, 'NLExtract-BAG', size=(1000, 500)) Log() self.app = app self.hoofdScherm() # Find homedir: we may have been started within .app or .exe!! bagextract_home = os.path.dirname(os.path.realpath(__file__)) if not os.path.isdir(os.path.join(bagextract_home, 'db')): bagextract_home = None # Init globale configuratie BAGConfig(None, home_path=bagextract_home) self.database = Database()
def __init__(self, raadpleegScherm, positie, afmeting): wx.TreeCtrl.__init__(self, raadpleegScherm, -1, positie, afmeting, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.HSCROLL | wx.VSCROLL) self.raadpleegScherm = raadpleegScherm self.logScherm = raadpleegScherm.logScherm self.root = self.AddRoot("Zoekresultaat") self.font = wx.Font(8, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self.SetFont(self.font) self.plaatjes = wx.ImageList(16, 16) self.plaatjeFolder = self.plaatjes.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))) self.plaatjeFolderOpen = self.plaatjes.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16, 16))) self.SetImageList(self.plaatjes) self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self._openItem, self) self.Bind(wx.EVT_TREE_SEL_CHANGED, self._toonItem, self) self.database = Database()
def processCSV(self, csvreader, naam='onbekend'): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: obj = BestuurlijkObjectFabriek(cols, record) if obj: objecten.append(obj) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database bericht = "Insert objectCount=" + str(len(objecten)) Log.log.info(bericht) self.database.verbind() # We gaan er even vanuit dat de encoding van de CSVs UTF-8 is self.database.connection.set_client_encoding('UTF8') for obj in objecten: obj.insert() self.database.uitvoeren(obj.sql, obj.valuelist) self.database.commit() Database().log_actie('insert_database', naam, bericht)
class Processor: def __init__(self): self.database = Database() self.naam = 'onbekend' self.script_template = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/%s') def dbInit(self): # Print start time Log.log.time("Start") # Dumps all tables and recreates them db_script = self.script_template % 'bag-db.sql' Log.log.info("alle tabellen weggooien en opnieuw aanmaken in database '%s', schema '%s'..." % (BAGConfig.config.database, BAGConfig.config.schema)) try: self.database.initialiseer(db_script) except Exception: Log.log.fatal("Kan geen verbinding maken met de database") sys.exit() Log.log.info("Initieele data (bijv. gemeenten/provincies) inlezen...") from bagfilereader import BAGFileReader myreader = BAGFileReader(BAGConfig.config.bagextract_home + '/db/data') myreader.process() Log.log.info("Views aanmaken...") self.processSQLScript('bag-view-actueel-bestaand.sql') # Print end time Log.log.time("End") def processSQLScript(self, sql_file): db_script = self.script_template % sql_file self.database.file_uitvoeren(db_script) def processCSV(self, csvreader, naam='onbekend'): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: obj = BestuurlijkObjectFabriek(cols, record) if obj: objecten.append(obj) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database bericht = "Insert objectCount=" + str(len(objecten)) Log.log.info(bericht) self.database.verbind() # We gaan er even vanuit dat de encoding van de CSVs UTF-8 is self.database.connection.set_client_encoding('UTF8') for obj in objecten: obj.insert() self.database.uitvoeren(obj.sql, obj.valuelist) self.database.commit() Database().log_actie('insert_database', naam, bericht) def processGemeentelijkeIndeling(self, node, naam='onbekend'): objecten = [] provincie_gemeente = defaultdict(dict) doc_tag = stripschema(node.tag) # XML schema: # <gemeentelijke_indeling # xmlns="http://nlextract.nl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" # xsi:schemaLocation="http://nlextract.nl gemeentelijke-indeling.xsd"> # ... # <indeling jaar="2016"> # ... # <provincie code="27" naam="Noord-Holland"> # <gemeente code="358" naam="Aalsmeer" begindatum="1970-01-01" /> # ... # <gemeente code="381" naam="Bussum" begindatum="1970-01-01" einddatum="2016-01-01" /> # ... # <gemeente code="1942" naam="Gooise Meren" begindatum="2016-01-01" /> # </provincie> # ... # </indeling> # ... # </gemeentelijke_indeling> if doc_tag == 'gemeentelijke_indeling': for indelingNode in node: if stripschema(indelingNode.tag) == 'indeling': # Ongebruikt: # jaar = indelingNode.get('jaar') for provincieNode in indelingNode: if stripschema(provincieNode.tag) == 'provincie': provinciecode = provincieNode.get('code') provincienaam = provincieNode.get('naam') for gemeenteNode in provincieNode: if stripschema(gemeenteNode.tag) == 'gemeente': gemeentecode = gemeenteNode.get('code') gemeentenaam = gemeenteNode.get('naam') begindatum = gemeenteNode.get('begindatum') einddatum = gemeenteNode.get('einddatum') provincie_gemeente[provinciecode][gemeentecode] = { 'provinciecode': provinciecode, 'provincienaam': provincienaam, 'gemeentecode': gemeentecode, 'gemeentenaam': gemeentenaam, 'begindatum': begindatum, 'einddatum': einddatum, } for provinciecode in sorted(provincie_gemeente.keys()): for gemeentecode in sorted(provincie_gemeente[provinciecode].keys()): obj = GemeentelijkeIndelingFabriek(provincie_gemeente[provinciecode][gemeentecode]) if obj: objecten.append(obj) else: Log.log.warn("Geen object gevonden voor provinciecode %s en gemeentecode %s" % (provinciecode, gemeentecode)) bericht = "Processed objectCount=" + str(len(objecten)) Log.log.info(bericht) self.database.verbind() updated = 0 inserted = 0 unchanged = 0 self.database.connection.set_client_encoding('UTF8') for obj in objecten: obj.exists() if self.database.uitvoeren(obj.sql, obj.valuelist): obj.unchanged() if self.database.uitvoeren(obj.sql, obj.valuelist): unchanged += 1 else: obj.update() self.database.uitvoeren(obj.sql, obj.valuelist) updated += 1 else: obj.insert() self.database.uitvoeren(obj.sql, obj.valuelist) inserted += 1 self.database.commit() log_bericht = "Objects inserted=" + str(inserted) + " updated=" + str(updated) + " unchanged=" + str(unchanged) Log.log.info(log_bericht) Database().log_actie('insert_database', naam, bericht + " " + log_bericht) else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', self.naam, bericht) def processDOM(self, node, naam='onbekend'): self.bagObjecten = [] self.naam = naam mode = "Onbekend" doc_tag = stripschema(node.tag) # 'BAG-Extract-Deelbestand-LVC': standaard BAG Element, VBO etc # 'BAG-GWR-Deelbestand-LVC': Koppeltabel Gemeente-Woonplaats-Relatie (alleen in BAG na plm aug 2012) if doc_tag == 'BAG-Extract-Deelbestand-LVC' or doc_tag == 'BAG-GWR-Deelbestand-LVC': mode = 'Nieuw' # firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child if doc_tag == 'BAG-GWR-Deelbestand-LVC': # Noteer ook de standdatum van de gemeente_woonplaats koppel tabel # zodat we weten welke datum/versie is gebruikt... # Probeer BAG extract datum uit XML te vinden vraag = stripNS(vraag) gwr_datum = vraag.xpath("StandTechnischeDatum/text()") if len(gwr_datum) > 0: # Gevonden ! gwr_datum = str(gwr_datum[0]) else: gwr_datum = "onbekend" # Opslaan (evt vervangen) als meta info self.database.log_meta("gem_woonplaats_rel_datum", gwr_datum) elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: product_tag = stripschema(productnode.tag) if product_tag == 'LVC-product' or product_tag == 'GemeenteWoonplaatsRelatieProduct': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML(productnode) if product_tag == 'GemeenteWoonplaatsRelatieProduct': # Altijd de vorige weggooien self.database.log_actie('truncate_table', 'gemeente_woonplaats', 'altijd eerst leeg maken') self.database.tx_uitvoeren('truncate gemeente_woonplaats') bericht = Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) self.database.log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' # firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema(productnode.tag) == 'Mutatie-product': origineelObj = None # Gebruik als sorteersleutel (datum+volgnr) tbv volgorde verwerking verwerkings_id = '' for mutatienode in productnode: if stripschema(mutatienode.tag) == 'Verwerking': # Verkijgen verwerkings_datum en volgnummer tbv sorteren mutatienode = stripNS(mutatienode) # Maak uniek vewerkings id string uit datum-tijd + volgnr verwerkings_tijdstip = str(mutatienode.xpath("TijdstipVerwerking/text()")[0]) verwerkings_volgnr = str(mutatienode.xpath("VolgnrVerwerking/text()")[0]) verwerkings_id = verwerkings_tijdstip + '.' + verwerkings_volgnr # print('verwerkings_id=%s' % verwerkings_id) elif stripschema(mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") bag_objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) for bag_obj in bag_objs: bag_obj.verwerkings_id = verwerkings_id self.bagObjecten.extend(bag_objs) elif stripschema(mutatienode.tag) == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag) == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.verwerkings_id = verwerkings_id nieuwObj.origineelObj = origineelObj self.bagObjecten.append(nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None # Zie http://www.pythoncentral.io/how-to-sort-a-list-tuple-or-object-with-sorted-in-python # Tbv sorteren self.bagObjecten array op verwerkings volgorde def get_verwerkings_id(bag_obj): return bag_obj.verwerkings_id # Sorteer te muteren objecten op verwerkings_id self.bagObjecten = sorted(self.bagObjecten, key=get_verwerkings_id) bericht = Log.log.endTimer("objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Extract-Levering': # Meta data: info over levering # Sla hele file op self.database.log_meta("levering_xml", etree.tostring(node, pretty_print=True).decode()) # Extraheer BAG lever datum # <v202:LVC-Extract> # <v202:gegVarLevenscyclus>true</v202:gegVarLevenscyclus> # <v202:productcode>DNLDLXAE02</v202:productcode> # <v202:StandTechnischeDatum>20120308</v202:StandTechnischeDatum> # </v202:LVC-Extract> node = stripNS(node) # Probeer BAG extract datum uit XML te vinden extract_datum = node.xpath("//LVC-Extract/StandTechnischeDatum/text()") if len(extract_datum) > 0: # Gevonden ! extract_datum = str(extract_datum[0]) else: extract_datum = "onbekend" # Opslaan als meta info self.database.log_meta("extract_datum", extract_datum) Database().log_actie('verwerkt', self.naam, 'verwerken Leverings doc') else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', self.naam, bericht) return Log.log.startTimer("dbStart mode = " + mode) # Experimenteel: dbStoreCopy() gebruikt COPY ipv INSERT # maar moet nog gefinetuned if mode == 'Mutatie': # Voor mutaties voorlopig nog even ouderwetse INSERT/UPDATE # Hier speelt performance ook niet zo'n rol als bij hele BAG inlezen... bericht = self.dbStoreInsert(mode) else: bericht = self.dbStoreCopy(mode) Database().log_actie('insert_database', self.naam, bericht) def dbStoreInsert(self, mode): self.database.verbind() rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 else: # Mutatie: nieuw object bagObject.maakInsertSQL() try: self.database.uitvoeren(bagObject.sql, bagObject.inhoud) except Exception: # Heeft geen zin om door te gaan Log.log.error("database fout bij insert, ik stop met dit bestand") break for relatie in bagObject.relaties: i = 0 for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) i += 1 rels += 1 self.database.commit() bericht = Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------") return bericht # Experimenteel: inlezen via COPY ipv INSERT: fikse snelheidswinst def dbStoreCopy(self, mode): from io import StringIO Log.log.startTimer("dbStart mode = " + mode) self.database.verbind() # BAG Objecten en Relaties hebben verschillende tabellen/kolommen # Houd deze bij in dictionaries # TODO: maak 1 object voor combinatie buffer/kolommen buffers = {} columns = {} rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging, doe nog even traditioneel want heeft wat SQL logica bagObject.maakUpdateSQL() wijzigingen += 1 self.database.uitvoeren(bagObject.sql, bagObject.inhoud) else: # Maak buffer eenmalig aan per tabel if bagObject.naam() not in buffers: buffer = StringIO() buffers[bagObject.naam()] = buffer # Voeg de inhoud aan buffer toe bagObject.maakCopySQL(buffers[bagObject.naam()]) # Kolom namen # TODO dit hoeft natuurlijk maar 1x columns[bagObject.naam()] = bagObject.velden for relatie in bagObject.relaties: # Maak buffer eenmalig aan per relatietabel if relatie.relatieNaam() not in buffers: buffer = StringIO() buffers[relatie.relatieNaam()] = buffer buffers[relatie.relatieNaam()].write(relatie.sql) # Kolom namen # TODO dit hoeft natuurlijk maar 1x columns[relatie.relatieNaam()] = relatie.velden rels += 1 # Doe DB COPY operaties for table in buffers: buf = buffers[table] buf.seek(0) self.database.cursor.copy_from(buf, table, sep='~', null=r'\N', columns=columns[table]) buf.close() self.database.commit(True) bericht = Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------") return bericht
def __init__(self): self.database = Database() self.naam = 'onbekend'
def processDOM(self, node, naam='onbekend'): self.bagObjecten = [] self.naam = naam mode = "Onbekend" doc_tag = stripschema(node.tag) # 'BAG-Extract-Deelbestand-LVC': standaard BAG Element, VBO etc # 'BAG-GWR-Deelbestand-LVC': Koppeltabel Gemeente-Woonplaats-Relatie (alleen in BAG na plm aug 2012) if doc_tag == 'BAG-Extract-Deelbestand-LVC' or doc_tag == 'BAG-GWR-Deelbestand-LVC': mode = 'Nieuw' # firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child if doc_tag == 'BAG-GWR-Deelbestand-LVC': # Noteer ook de standdatum van de gemeente_woonplaats koppel tabel # zodat we weten welke datum/versie is gebruikt... # Probeer BAG extract datum uit XML te vinden vraag = stripNS(vraag) gwr_datum = vraag.xpath("StandTechnischeDatum/text()") if len(gwr_datum) > 0: # Gevonden ! gwr_datum = str(gwr_datum[0]) else: gwr_datum = "onbekend" # Opslaan (evt vervangen) als meta info self.database.log_meta("gem_woonplaats_rel_datum", gwr_datum) elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: product_tag = stripschema(productnode.tag) if product_tag == 'LVC-product' or product_tag == 'GemeenteWoonplaatsRelatieProduct': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML(productnode) if product_tag == 'GemeenteWoonplaatsRelatieProduct': # Altijd de vorige weggooien self.database.log_actie('truncate_table', 'gemeente_woonplaats', 'altijd eerst leeg maken') self.database.tx_uitvoeren('truncate gemeente_woonplaats') bericht = Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) self.database.log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' # firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema(productnode.tag) == 'Mutatie-product': origineelObj = None # Gebruik als sorteersleutel (datum+volgnr) tbv volgorde verwerking verwerkings_id = '' for mutatienode in productnode: if stripschema(mutatienode.tag) == 'Verwerking': # Verkijgen verwerkings_datum en volgnummer tbv sorteren mutatienode = stripNS(mutatienode) # Maak uniek vewerkings id string uit datum-tijd + volgnr verwerkings_tijdstip = str(mutatienode.xpath("TijdstipVerwerking/text()")[0]) verwerkings_volgnr = str(mutatienode.xpath("VolgnrVerwerking/text()")[0]) verwerkings_id = verwerkings_tijdstip + '.' + verwerkings_volgnr # print('verwerkings_id=%s' % verwerkings_id) elif stripschema(mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") bag_objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) for bag_obj in bag_objs: bag_obj.verwerkings_id = verwerkings_id self.bagObjecten.extend(bag_objs) elif stripschema(mutatienode.tag) == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag) == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.verwerkings_id = verwerkings_id nieuwObj.origineelObj = origineelObj self.bagObjecten.append(nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None # Zie http://www.pythoncentral.io/how-to-sort-a-list-tuple-or-object-with-sorted-in-python # Tbv sorteren self.bagObjecten array op verwerkings volgorde def get_verwerkings_id(bag_obj): return bag_obj.verwerkings_id # Sorteer te muteren objecten op verwerkings_id self.bagObjecten = sorted(self.bagObjecten, key=get_verwerkings_id) bericht = Log.log.endTimer("objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Extract-Levering': # Meta data: info over levering # Sla hele file op self.database.log_meta("levering_xml", etree.tostring(node, pretty_print=True).decode()) # Extraheer BAG lever datum # <v202:LVC-Extract> # <v202:gegVarLevenscyclus>true</v202:gegVarLevenscyclus> # <v202:productcode>DNLDLXAE02</v202:productcode> # <v202:StandTechnischeDatum>20120308</v202:StandTechnischeDatum> # </v202:LVC-Extract> node = stripNS(node) # Probeer BAG extract datum uit XML te vinden extract_datum = node.xpath("//LVC-Extract/StandTechnischeDatum/text()") if len(extract_datum) > 0: # Gevonden ! extract_datum = str(extract_datum[0]) else: extract_datum = "onbekend" # Opslaan als meta info self.database.log_meta("extract_datum", extract_datum) Database().log_actie('verwerkt', self.naam, 'verwerken Leverings doc') else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', self.naam, bericht) return Log.log.startTimer("dbStart mode = " + mode) # Experimenteel: dbStoreCopy() gebruikt COPY ipv INSERT # maar moet nog gefinetuned if mode == 'Mutatie': # Voor mutaties voorlopig nog even ouderwetse INSERT/UPDATE # Hier speelt performance ook niet zo'n rol als bij hele BAG inlezen... bericht = self.dbStoreInsert(mode) else: bericht = self.dbStoreCopy(mode) Database().log_actie('insert_database', self.naam, bericht)
def processDOM(self, node): self.bagObjecten = [] mode = "Onbekend" doc_tag = stripschema(node.tag) # 'BAG-Extract-Deelbestand-LVC': standaard BAG Element, VBO etc # 'BAG-GWR-Deelbestand-LVC': Koppeltabel Gemeente-Woonplaats-Relatie (alleen in BAG na plm aug 2012) if doc_tag == 'BAG-Extract-Deelbestand-LVC' or doc_tag == 'BAG-GWR-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child if doc_tag == 'BAG-GWR-Deelbestand-LVC': # Noteer ook de standdatum van de gemeente_woonplaats koppel tabel # zodat we weten welke datum/versie is gebruikt... # Probeer BAG extract datum uit XML te vinden vraag = stripNS(vraag) gwr_datum = vraag.xpath( "StandTechnischeDatum/text()") if len(gwr_datum) > 0: # Gevonden ! gwr_datum = str(gwr_datum[0]) else: gwr_datum = "onbekend" # Opslaan (evt vervangen) als meta info self.database.log_meta( "gem_woonplaats_rel_datum", gwr_datum) elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: product_tag = stripschema(productnode.tag) if product_tag == 'LVC-product' or product_tag == 'GemeenteWoonplaatsRelatieProduct': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML( productnode) if product_tag == 'GemeenteWoonplaatsRelatieProduct': # Altijd de vorige weggooien Database().log_actie( 'truncate_table', 'gemeente_woonplaats', 'altijd eerst leeg maken') Database().tx_uitvoeren( 'truncate gemeente_woonplaats') bericht = Log.log.endTimer( "objCreate - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', 'idem', bericht) elif doc_tag == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema( productnode.tag) == 'Mutatie-product': origineelObj = None nieuwObj = None for mutatienode in productnode: if stripschema( mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") self.bagObjecten.extend( BAGObjectFabriek.bof. BAGObjectArrayBijXML( mutatienode)) elif stripschema(mutatienode.tag ) == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML( mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag ) == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML( mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.origineelObj = origineelObj self.bagObjecten.append( nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None nieuwObj = None bericht = Log.log.endTimer( "objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', 'idem', bericht) elif doc_tag == 'BAG-Extract-Levering': # Meta data: info over levering # Sla hele file op self.database.log_meta("levering_xml", etree.tostring(node, pretty_print=True)) # Extraheer BAG lever datum # <v202:LVC-Extract> # <v202:gegVarLevenscyclus>true</v202:gegVarLevenscyclus> # <v202:productcode>DNLDLXAE02</v202:productcode> # <v202:StandTechnischeDatum>20120308</v202:StandTechnischeDatum> # </v202:LVC-Extract> node = stripNS(node) # Probeer BAG extract datum uit XML te vinden extract_datum = node.xpath( "//LVC-Extract/StandTechnischeDatum/text()") if len(extract_datum) > 0: # Gevonden ! extract_datum = str(extract_datum[0]) else: extract_datum = "onbekend" # Opslaan als meta info self.database.log_meta("extract_datum", extract_datum) else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', 'n.v.t', bericht) return Log.log.startTimer("dbStart mode = " + mode) # Experimenteel: dbStoreCopy() gebruikt COPY ipv INSERT # maar moet nog gefinetuned if mode == 'Mutatie': # Voor mutaties voorlopig nog even ouderwetse INSERT/UPDATE # Hier speelt performance ook niet zo'n rol als bij hele BAG inlezen... bericht = self.dbStoreInsert(mode) else: bericht = self.dbStoreCopy(mode) Database().log_actie('insert_database', 'idem', bericht)
class Processor: def __init__(self): self.database = Database() self.naam = 'onbekend' def processCSV(self, csvreader, naam='onbekend'): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: obj = BestuurlijkObjectFabriek(cols, record) if obj: objecten.append(obj) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database bericht = "Insert objectCount=" + str(len(objecten)) Log.log.info(bericht) self.database.verbind() # We gaan er even vanuit dat de encoding van de CSVs UTF-8 is self.database.connection.set_client_encoding('UTF8') for obj in objecten: obj.insert() self.database.uitvoeren(obj.sql, obj.valuelist) self.database.commit() Database().log_actie('insert_database', naam, bericht) def processDOM(self, node, naam='onbekend'): self.bagObjecten = [] self.naam = naam mode = "Onbekend" doc_tag = stripschema(node.tag) # 'BAG-Extract-Deelbestand-LVC': standaard BAG Element, VBO etc # 'BAG-GWR-Deelbestand-LVC': Koppeltabel Gemeente-Woonplaats-Relatie (alleen in BAG na plm aug 2012) if doc_tag == 'BAG-Extract-Deelbestand-LVC' or doc_tag == 'BAG-GWR-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child if doc_tag == 'BAG-GWR-Deelbestand-LVC': # Noteer ook de standdatum van de gemeente_woonplaats koppel tabel # zodat we weten welke datum/versie is gebruikt... # Probeer BAG extract datum uit XML te vinden vraag = stripNS(vraag) gwr_datum = vraag.xpath( "StandTechnischeDatum/text()") if len(gwr_datum) > 0: # Gevonden ! gwr_datum = str(gwr_datum[0]) else: gwr_datum = "onbekend" # Opslaan (evt vervangen) als meta info self.database.log_meta( "gem_woonplaats_rel_datum", gwr_datum) elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: product_tag = stripschema(productnode.tag) if product_tag == 'LVC-product' or product_tag == 'GemeenteWoonplaatsRelatieProduct': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML( productnode) if product_tag == 'GemeenteWoonplaatsRelatieProduct': # Altijd de vorige weggooien self.database.log_actie( 'truncate_table', 'gemeente_woonplaats', 'altijd eerst leeg maken') self.database.tx_uitvoeren( 'truncate gemeente_woonplaats') bericht = Log.log.endTimer( "objCreate - objs=" + str(len(self.bagObjecten))) self.database.log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema( productnode.tag) == 'Mutatie-product': origineelObj = None # Gebruik als sorteersleutel (datum+volgnr) tbv volgorde verwerking verwerkings_id = '' for mutatienode in productnode: if stripschema(mutatienode.tag ) == 'Verwerking': # Verkijgen verwerkings_datum en volgnummer tbv sorteren mutatienode = stripNS(mutatienode) # Maak uniek vewerkings id string uit datum-tijd + volgnr verwerkings_tijdstip = str( mutatienode.xpath( "TijdstipVerwerking/text()" )[0]) verwerkings_volgnr = str( mutatienode.xpath( "VolgnrVerwerking/text()") [0]) verwerkings_id = verwerkings_tijdstip + '.' + verwerkings_volgnr # print('verwerkings_id=%s' % verwerkings_id) elif stripschema( mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") bag_objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML( mutatienode) for bag_obj in bag_objs: bag_obj.verwerkings_id = verwerkings_id self.bagObjecten.extend(bag_objs) elif stripschema(mutatienode.tag ) == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML( mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag ) == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML( mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.verwerkings_id = verwerkings_id nieuwObj.origineelObj = origineelObj self.bagObjecten.append( nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None # Zie http://www.pythoncentral.io/how-to-sort-a-list-tuple-or-object-with-sorted-in-python # Tbv sorteren self.bagObjecten array op verwerkings volgorde def get_verwerkings_id(bag_obj): return bag_obj.verwerkings_id # Sorteer te muteren objecten op verwerkings_id self.bagObjecten = sorted(self.bagObjecten, key=get_verwerkings_id) bericht = Log.log.endTimer( "objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Extract-Levering': # Meta data: info over levering # Sla hele file op self.database.log_meta("levering_xml", etree.tostring(node, pretty_print=True)) # Extraheer BAG lever datum # <v202:LVC-Extract> # <v202:gegVarLevenscyclus>true</v202:gegVarLevenscyclus> # <v202:productcode>DNLDLXAE02</v202:productcode> # <v202:StandTechnischeDatum>20120308</v202:StandTechnischeDatum> # </v202:LVC-Extract> node = stripNS(node) # Probeer BAG extract datum uit XML te vinden extract_datum = node.xpath( "//LVC-Extract/StandTechnischeDatum/text()") if len(extract_datum) > 0: # Gevonden ! extract_datum = str(extract_datum[0]) else: extract_datum = "onbekend" # Opslaan als meta info self.database.log_meta("extract_datum", extract_datum) Database().log_actie('verwerkt', self.naam, 'verwerken Leverings doc') else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', self.naam, bericht) return Log.log.startTimer("dbStart mode = " + mode) # Experimenteel: dbStoreCopy() gebruikt COPY ipv INSERT # maar moet nog gefinetuned if mode == 'Mutatie': # Voor mutaties voorlopig nog even ouderwetse INSERT/UPDATE # Hier speelt performance ook niet zo'n rol als bij hele BAG inlezen... bericht = self.dbStoreInsert(mode) else: bericht = self.dbStoreCopy(mode) Database().log_actie('insert_database', self.naam, bericht) def dbStoreInsert(self, mode): self.database.verbind() rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 else: # Mutatie: nieuw object bagObject.maakInsertSQL() try: self.database.uitvoeren(bagObject.sql, bagObject.inhoud) except (Exception), e: # Heeft geen zin om door te gaan Log.log.error( "database fout bij insert, ik stop met dit bestand") break for relatie in bagObject.relaties: i = 0 for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) i += 1 rels += 1 self.database.commit() bericht = Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------") return bericht
class BAGBoom(wx.TreeCtrl): # Constructor def __init__(self, raadpleegScherm, positie, afmeting): wx.TreeCtrl.__init__(self, raadpleegScherm, -1, positie, afmeting, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.HSCROLL | wx.VSCROLL) self.raadpleegScherm = raadpleegScherm self.logScherm = raadpleegScherm.logScherm self.root = self.AddRoot("Zoekresultaat") self.font = wx.Font(8, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self.SetFont(self.font) self.plaatjes = wx.ImageList(16, 16) self.plaatjeFolder = self.plaatjes.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))) self.plaatjeFolderOpen = self.plaatjes.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16, 16))) self.SetImageList(self.plaatjes) self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self._openItem, self) self.Bind(wx.EVT_TREE_SEL_CHANGED, self._toonItem, self) self.database = Database() # Private functie voor het toevoegen van een item in de boom, onder een gegeven vader def _initItem(self, vader, objectType, identificatie, obj=None): item = self.AppendItem(vader, "%s %s" % (objectType, identificatie)) self.SetPyData(item, obj) self.SetItemImage(item, self.plaatjeFolder, wx.TreeItemIcon_Normal) self.SetItemImage(item, self.plaatjeFolderOpen, wx.TreeItemIcon_Expanded) if objectType != "WPL": self.SetItemHasChildren(item, True) return item # Private functie voor het initialiseren van een object bij een item in de boom. # Bij het item in de boom wordt het BAG-object als PyData opgeslagen in de boom. # De gerelateerde objecten van dat BAG-object worden toegevoegd aan de boom als # child-elementen van het item. def _initObject(self, item): if not self.GetPyData(item): # Initialiseer het BAG-object bagObject = BAGObjectFabriek.bof.getBAGObjectBijIdentificatie(self.GetItemText(item).partition(" ")[2]) sql = bagObject.maakSelectSQL() rows = self.database.select(sql) if len(rows) > 0: vals = rows[0] bagObject.zetWaarden(vals) self.SetPyData(item, bagObject) if bagObject.objectType() == "OPR": if bagObject.attribuut('gerelateerdeWoonplaats').waarde() is not None: self._initItem(item, "WPL", bagObject.attribuut('gerelateerdeWoonplaats').waarde()) if bagObject.objectType() == "NUM": if bagObject.attribuut('gerelateerdeWoonplaats').waarde() is not None: self._initItem(item, "WPL", bagObject.attribuut('gerelateerdeWoonplaats').waarde()) self._initItem(item, "OPR", bagObject.attribuut('gerelateerdeOpenbareRuimte').waarde()) ao = bagObject.getAdresseerbaarObject() if ao: sql = bagObject.maakSelectAdresseerbaarObjectSQL() ao_rows = self.database.select(sql) if len(ao_rows) > 0 and len(ao_rows[0]) > 0: identificatie = ao_rows[0][0] ao.zetWaarde('identificatie', identificatie) self._initItem(item, ao.objectType(), ao.identificatie()) if bagObject.objectType() in ["LPL", "SPL", "VBO"]: self._initItem(item, "NUM", bagObject.attribuut('hoofdadres').waarde()) nevenadressen = bagObject.getRelaties('nevenadres') for nevenadres in nevenadressen: self._initItem(item, "NUM", nevenadres.waarde()) if bagObject.objectType() == "VBO": panden = bagObject.getRelaties('gerelateerdPand') for pand in panden: self._initItem(item, "PND", pand.waarde()) if bagObject.objectType() == "PND": vbos = bagObject.getRelaties('gerelateerdverblijfsObject') for vbo in vbos: self._initItem(item, "VBO", vbo.waarde()) return self.GetPyData(item) # Private functie voor het openen van een item. Deze functie wordt uitgevoerd wanneer # een item in de boom wordt geopend. def _openItem(self, event): # Bij het sluiten van het scherm wordt ook nog een event EVT_TREE_SEL_CHANGED gegenereerd. # Sommige delen van het scherm zijn dan echter al ongeldig geworden. Daarom controleren # we eerst of het scherm nog wel getoond (IsShownOnScreen) is. if self.raadpleegScherm.IsShownOnScreen(): item = event.GetItem() if item: self._initObject(item) # Private functie voor het tonen van een item. Deze functie wordt uitgevoerd wanneer # een item in de boom wordt geselecteerd. def _toonItem(self, event): # Bij het sluiten van het scherm wordt ook nog een event EVT_TREE_SEL_CHANGED gegenereerd. # Sommige delen van het scherm zijn dan echter al ongeldig geworden. Daarom controleren # we eerst of het scherm nog wel getoond (IsShownOnScreen) is. if self.raadpleegScherm.IsShownOnScreen(): item = event.GetItem() if item: self.toonItem(item) # Toon het gegeven item. Eerst wordt het object geinitialiseerd in de boom zodat de # gerelateerde objecten zichtbaar worden. Vervolgens wordt het object getoond in de # view in het rechterdeel van het scherm. def toonItem(self, item): bagObject = self._initObject(item) self.raadpleegScherm.view.toonObject(bagObject) self.raadpleegScherm.kaart.toonGeometrie(bagObject) # Maak de hele boom leeg def maakLeeg(self): self.DeleteAllItems() self.root = self.AddRoot("Zoekresultaat") self.raadpleegScherm.view.maakLeeg() # Voeg een object met de gegeven identificatie toe aan de boom def voegToe(self, identificatie): bagObject = BAGObjectFabriek.bof.getBAGObjectBijIdentificatie(identificatie) if bagObject: return self._initItem(self.GetRootItem(), bagObject.objectType(), bagObject.identificatie()) else: return None
class Processor: def __init__(self): self.database = Database() def processCSV(self, csvreader): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: object = BestuurlijkObjectFabriek(cols, record) if object: objecten.append(object) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database Log.log.info("Insert objectCount=" + str(len(objecten))) self.database.verbind() # We gaan er even vanuit dat de encoding van de CSVs UTF-8 is self.database.connection.set_client_encoding('UTF8') for object in objecten: object.insert() self.database.uitvoeren(object.sql, object.valuelist) self.database.connection.commit() def processDOM(self, node): self.bagObjecten = [] self.bagObjectenNieuw = [] self.bagObjectenMutatie = [] mode = "Onbekend" doc_tag = stripschema(node.tag) # 'BAG-Extract-Deelbestand-LVC': standaard BAG Element, VBO etc # 'BAG-GWR-Deelbestand-LVC': Koppeltabel Gemeente-Woonplaats-Relatie (alleen in BAG na plm aug 2012) if doc_tag == 'BAG-Extract-Deelbestand-LVC' or doc_tag == 'BAG-GWR-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child if doc_tag == 'BAG-GWR-Deelbestand-LVC': # Noteer ook de standdatum van de gemeente_woonplaats koppel tabel # zodat we weten welke datum/versie is gebruikt... # Probeer BAG extract datum uit XML te vinden vraag = stripNS(vraag) gwr_datum = vraag.xpath("StandTechnischeDatum/text()") if len(gwr_datum) > 0: # Gevonden ! gwr_datum = str(gwr_datum[0]) else: gwr_datum = "onbekend" # Opslaan (evt vervangen) als meta info self.database.log_meta("gem_woonplaats_rel_datum", gwr_datum) elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: product_tag = stripschema(productnode.tag) if product_tag == 'LVC-product' or product_tag == 'GemeenteWoonplaatsRelatieProduct': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML(productnode) if product_tag == 'GemeenteWoonplaatsRelatieProduct': # Altijd de vorige weggooien Database().log_actie('truncate_table', 'gemeente_woonplaats', 'altijd eerst leeg maken') Database().tx_uitvoeren('truncate gemeente_woonplaats') bericht = Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', 'idem', bericht) elif doc_tag == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema(productnode.tag) == 'Mutatie-product': origineelObj = None nieuwObj = None for mutatienode in productnode: if stripschema(mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") self.bagObjectenNieuw.extend( BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode)) elif stripschema(mutatienode.tag) == 'Origineel': # Orgineel deel van object objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag) == 'Wijziging': # Mutatie deel van object objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: # Neem nieuw en orgineel object op in lijst nieuwObj.origineelObj = origineelObj self.bagObjectenMutatie.append(nieuwObj) origineelObj = None nieuwObj = None bericht = Log.log.endTimer("objCreate (mutaties, gemuteerde objecten) - objs=" + str(len(self.bagObjectenMutatie))) bericht = Log.log.endTimer("objCreate (mutaties, nieuwe objecten) - objs=" + str(len(self.bagObjectenNieuw))) Database().log_actie('create_objects', 'idem', bericht) elif doc_tag == 'BAG-Extract-Levering': # Meta data: info over levering # Sla hele file op self.database.log_meta("levering_xml", etree.tostring(node, pretty_print=True)) # Extraheer BAG lever datum # <v202:LVC-Extract> # <v202:gegVarLevenscyclus>true</v202:gegVarLevenscyclus> # <v202:productcode>DNLDLXAE02</v202:productcode> # <v202:StandTechnischeDatum>20120308</v202:StandTechnischeDatum> # </v202:LVC-Extract> node = stripNS(node) # Probeer BAG extract datum uit XML te vinden extract_datum = node.xpath("//LVC-Extract/StandTechnischeDatum/text()") if len(extract_datum) > 0: # Gevonden ! extract_datum = str(extract_datum[0]) else: extract_datum = "onbekend" # Opslaan als meta info self.database.log_meta("extract_datum", extract_datum) else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', 'n.v.t', bericht) return Log.log.startTimer("dbStart mode = " + mode) # Experimenteel: dbStoreCopy() gebruikt COPY ipv INSERT # maar moet nog gefinetuned if mode == 'Mutatie': # Voor mutaties voorlopig nog even ouderwetse INSERT/UPDATE # Hier speelt performance ook niet zo'n rol als bij hele BAG inlezen... bericht = self.dbStoreInsert(mode) else: bericht = self.dbStoreCopy(mode) Database().log_actie('insert_database', 'idem', bericht) def dbStoreInsert(self, mode): self.database.verbind() rels = 0 wijzigingen = 0 # In het orginele NLExtract wordt de lijst bagObjecten doorlopen en voor ieder element # insert of update gedaan. # Gevolg is dat er eerst een insert wordt gedaan dat daarna ten onrechte ge-update wordt # Immers: de id gebruikt bij update om record te bepalen is gelijk ! # # Hier geimplementeerde oplossing is om eerst alle updates uit te voeren en pas # daarna de nieuwe te inserten. # Omdat dbStoreInsert() alleen bij mutaties gebruikt wordt zijn er twee lijsten aangemaakt: # bagObjectenNieuw en bagObjectenMutatie # # Andere manieren om het op te lossen is: in 1 lijst en de lijst eenmaal doorlopen en bij ieder nieuw obj te # testen of er in de lijst ook een mutatie is, deze eerst uit te voeren. Nadeel is de extra administratie bij # doorlopen van de lijst # # Nog een andere manier is om bij het aanmaken van het update statement niet alleen de id te gebruiken maar # alle velden # # Eerst updates dan inserts for bagObject in self.bagObjectenMutatie: if bagObject.origineelObj: try: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 self.database.uitvoeren(bagObject.sql, bagObject.inhoud) for relatie in bagObject.relaties: for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) rels += 1 except (Exception), e: # Heeft geen zin om door te gaan Log.log.error("database fout bij insert, ik stop met dit bestand") break else: Log.log.error("Geen origineelObj gevonden !") for bagObject in self.bagObjectenNieuw: # Nieuw object try: bagObject.maakInsertSQL() self.database.uitvoeren(bagObject.sql, bagObject.inhoud) for relatie in bagObject.relaties: for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) rels += 1 except (Exception), e: # Heeft geen zin om door te gaan Log.log.error("database fout bij insert, ik stop met dit bestand") break
def __init__(self): self.database = Database()
def __init__(self, file_path): self.file_path = file_path self.processor = Processor() self.database = Database()
def main(): """ Voorbeelden: 1. Initialiseer een database: python bagextract.py -H localhost -d bag -U postgres -W postgres -c 2. Importeer een extract in de database: python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011-000002.xml of python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011.zip Importeer gemeente_woonplaats informatie van het kadaster http://www.kadaster.nl/bag/docs/BAG_Overzicht_aangesloten_gemeenten.zip python bagextract.py -H localhost -d bag -U postgres -W postgres -e BAG_Overzicht_aangesloten_gemeenten.zip Theoretisch is het mogelijk de hele bag in te lezen vanuit de "hoofd" zip, maar dit is nog niet getest op geheugen-problemen. """ parser = ArgParser( description= 'bag-extract, commandline tool voor het extraheren en inlezen van BAG bestanden', epilog= "Configureer de database in extract.conf of geef eigen versie van extract.conf via -f of geef parameters via commando regel expliciet op" ) parser.add_argument( '-c', '--dbinit', action='store_true', help= 'verwijdert (DROP TABLE) alle tabellen en maakt (CREATE TABLE) nieuwe tabellen aan' ) parser.add_argument('-d', '--database', metavar='<naam>', help='geef naam van de database') parser.add_argument('-s', '--schema', metavar='<naam>', help='geef naam van het database schema') parser.add_argument( '-f', '--config', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument( '-q', '--query', metavar='<bestand>', help='voer database bewerkingen uit met opgegeven SQL bestand') parser.add_argument( '-e', '--extract', metavar='<naam>', help= 'importeert of muteert de database met gegeven BAG-bestand of -directory' ) parser.add_argument('-H', '--host', metavar='<hostnaam of -adres>', help='verbind met de database op deze host') parser.add_argument('-U', '--username', metavar='<naam>', help='verbind met database met deze gebruikersnaam') parser.add_argument('-p', '--port', metavar='<poort>', help='verbind met database naar deze poort') parser.add_argument('-W', '--password', metavar='<paswoord>', help='gebruikt dit wachtwoord voor database gebruiker') parser.add_argument( '-w', '--no-password', action='store_true', help='gebruik geen wachtwoord voor de database verbinding') parser.add_argument( '-v', '--verbose', action='store_true', help='toon uitgebreide informatie tijdens het verwerken') parser.add_argument( '-D', '--dbinitcode', action='store_true', help='createert een lijst met statements om het DB script aan te passen' ) # Initialiseer args = parser.parse_args() # Initialize singleton Log object so we can use one global instance Log(args) # Init globale configuratie BAGConfig(args) # Database database = Database() if args.dbinit: if confirm( 'Waarschuwing! met dit commando worden database tabellen opnieuw aangemaakt. Doorgaan?', False): # Print start time Log.log.time("Start") # Dumps all tables and recreates them db_script = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/bag-db.sql') Log.log.info( "alle database tabellen weggooien en opnieuw aanmaken...") try: database.initialiseer(db_script) except Exception as e: Log.log.fatal("Kan geen verbinding maken met de database") sys.exit() Log.log.info( "Initieele data (bijv. gemeenten/provincies) inlezen...") from bagfilereader import BAGFileReader # from bagobject import VerblijfsObjectPand, AdresseerbaarObjectNevenAdres, VerblijfsObjectGebruiksdoel, Woonplaats, OpenbareRuimte, Nummeraanduiding, Ligplaats, Standplaats, Verblijfsobject, Pand myreader = BAGFileReader(BAGConfig.config.bagextract_home + '/db/data') myreader.process() Log.log.info("Views aanmaken...") db_script = os.path.realpath( BAGConfig.config.bagextract_home + '/db/script/bag-view-actueel-bestaand.sql') database.file_uitvoeren(db_script) # Print end time Log.log.time("End") else: exit() elif args.dbinitcode: # Print start time Log.log.time("Start") # Creates the insert statements from the code, and prints them bagObjecten = [] bagObjecten.append(VerblijfsObjectPand()) bagObjecten.append(AdresseerbaarObjectNevenAdres()) bagObjecten.append(VerblijfsObjectGebruiksdoel()) bagObjecten.append(Woonplaats()) bagObjecten.append(OpenbareRuimte()) bagObjecten.append(Nummeraanduiding()) bagObjecten.append(Ligplaats()) bagObjecten.append(Standplaats()) bagObjecten.append(Verblijfsobject()) bagObjecten.append(Pand()) for bagObject in bagObjecten: print(bagObject.maakTabel()) # Print end time Log.log.time("End") elif args.extract: from bagfilereader import BAGFileReader from bagobject import VerblijfsObjectPand, AdresseerbaarObjectNevenAdres, VerblijfsObjectGebruiksdoel, Woonplaats, OpenbareRuimte, Nummeraanduiding, Ligplaats, Standplaats, Verblijfsobject, Pand # Print start time Log.log.time("Start") # Extracts any data from any source files/dirs/zips/xml/csv etc Database().log_actie('start_extract', args.extract) myreader = BAGFileReader(args.extract) myreader.process() Database().log_actie('stop_extract', args.extract) # Print end time Log.log.time("End") elif args.query: # Print start time Log.log.time("Start") # Voer willekeurig SQL script uit uit Database().log_actie('start_query', args.query) database = Database() database.file_uitvoeren(args.query) Database().log_actie('stop_query', args.query) # Print end time Log.log.time("End") else: parser.error("Command line parameters niet herkend") sys.exit()
def processGemeentelijkeIndeling(self, node, naam='onbekend'): objecten = [] provincie_gemeente = defaultdict(dict) doc_tag = stripschema(node.tag) # XML schema: # <gemeentelijke_indeling # xmlns="http://nlextract.nl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" # xsi:schemaLocation="http://nlextract.nl gemeentelijke-indeling.xsd"> # ... # <indeling jaar="2016"> # ... # <provincie code="27" naam="Noord-Holland"> # <gemeente code="358" naam="Aalsmeer" begindatum="1970-01-01" /> # ... # <gemeente code="381" naam="Bussum" begindatum="1970-01-01" einddatum="2016-01-01" /> # ... # <gemeente code="1942" naam="Gooise Meren" begindatum="2016-01-01" /> # </provincie> # ... # </indeling> # ... # </gemeentelijke_indeling> if doc_tag == 'gemeentelijke_indeling': for indelingNode in node: if stripschema(indelingNode.tag) == 'indeling': # Ongebruikt: # jaar = indelingNode.get('jaar') for provincieNode in indelingNode: if stripschema(provincieNode.tag) == 'provincie': provinciecode = provincieNode.get('code') provincienaam = provincieNode.get('naam') for gemeenteNode in provincieNode: if stripschema(gemeenteNode.tag) == 'gemeente': gemeentecode = gemeenteNode.get('code') gemeentenaam = gemeenteNode.get('naam') begindatum = gemeenteNode.get('begindatum') einddatum = gemeenteNode.get('einddatum') provincie_gemeente[provinciecode][gemeentecode] = { 'provinciecode': provinciecode, 'provincienaam': provincienaam, 'gemeentecode': gemeentecode, 'gemeentenaam': gemeentenaam, 'begindatum': begindatum, 'einddatum': einddatum, } for provinciecode in sorted(provincie_gemeente.keys()): for gemeentecode in sorted(provincie_gemeente[provinciecode].keys()): obj = GemeentelijkeIndelingFabriek(provincie_gemeente[provinciecode][gemeentecode]) if obj: objecten.append(obj) else: Log.log.warn("Geen object gevonden voor provinciecode %s en gemeentecode %s" % (provinciecode, gemeentecode)) bericht = "Processed objectCount=" + str(len(objecten)) Log.log.info(bericht) self.database.verbind() updated = 0 inserted = 0 unchanged = 0 self.database.connection.set_client_encoding('UTF8') for obj in objecten: obj.exists() if self.database.uitvoeren(obj.sql, obj.valuelist): obj.unchanged() if self.database.uitvoeren(obj.sql, obj.valuelist): unchanged += 1 else: obj.update() self.database.uitvoeren(obj.sql, obj.valuelist) updated += 1 else: obj.insert() self.database.uitvoeren(obj.sql, obj.valuelist) inserted += 1 self.database.commit() log_bericht = "Objects inserted=" + str(inserted) + " updated=" + str(updated) + " unchanged=" + str(unchanged) Log.log.info(log_bericht) Database().log_actie('insert_database', naam, bericht + " " + log_bericht) else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', self.naam, bericht)
class Processor: # TODO: # Ben tot hier gekomen met etree. node.localName kent alleen een representatief # in de vorm van element.tag # Maar hier zitten de namespaces in: # # print xml.getroot().tag # {http://www.kadaster.nl/schemas/bag-verstrekkingen/extract-deelbestand-lvc/v20090901}BAG-Extract-Deelbestand-LVC # # Deze moeten of gestript worden, of de functie die dit automatisch doet moet worden gevonden. def __init__(self): self.database = Database() def processCSV(self, csvreader): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: object = BestuurlijkObjectFabriek(cols, record) if object: objecten.append(object) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database Log.log.info("Insert objectCount=" + str(len(objecten))) self.database.verbind() self.database.connection.set_client_encoding('LATIN1') for object in objecten: object.insert() self.database.uitvoeren(object.sql, object.valuelist) self.database.connection.commit() def processDOM(self, node): self.bagObjecten = [] mode = "Onbekend" if node.localName == 'BAG-Extract-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node.childNodes: if childNode.localName == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord.childNodes: if child.localName == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child elif child.localName == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten.childNodes: if productnode.localName == 'LVC-product' and productnode.childNodes: self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML(productnode.childNodes) Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) elif node.localName == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node.childNodes: if childNode.localName == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord.childNodes: if child.localName == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten.childNodes: if productnode.localName == 'Mutatie-product' and productnode.childNodes: origineelObj = None nieuwObj = None for mutatienode in productnode.childNodes: if mutatienode.localName == 'Nieuw': # Log.log.info("Nieuw Object") self.bagObjecten.extend( BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode.childNodes)) elif mutatienode.localName == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode.childNodes) if len(objs) > 0: origineelObj = objs[0] elif mutatienode.localName == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode.childNodes) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.origineelObj = origineelObj self.bagObjecten.append(nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None nieuwObj = None Log.log.endTimer("objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) else: Log.log.info("Niet-verwerkbare XML node: " + node.localName) return Log.log.startTimer("dbStart mode = " + mode) self.database.verbind() rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 else: # Mutatie: nieuw object bagObject.maakInsertSQL() self.database.uitvoeren(bagObject.sql, bagObject.inhoud) for relatie in bagObject.relaties: i = 0 for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) i += 1 rels += 1 self.database.connection.commit() Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------")
class BAGKaart(wx.Panel): # Constructor def __init__(self, raadpleegScherm, positie, afmeting): wx.Panel.__init__(self, raadpleegScherm, -1, positie, afmeting) self.raadpleegScherm = raadpleegScherm self.logScherm = raadpleegScherm.logScherm self.gebruikHuidigeKaart = False self.minX = 0.0 self.minY = 0.0 self.maxX = 0.0 self.maxY = 0.0 self.centerX = 0.0 self.centerY = 0.0 self.schaal = 0.0 self.zoom = 0.5 self.polygonen = [] # Verzameling van alle polygonen die worden getoond in de kaart self.bagObject = None # Het huidige bagObject dat wordt getoond in de kaart self.highlightPolygonen = [] # Polygoon(en) van het huidige bagObject self.PNDpolygonen = [] # Lijst van Pand-polygonen self.LPLpolygonen = [] # Lijst van Ligplaats-polygonen self.SPLpolygonen = [] # Lijst van Standplaats-polygonen self.WPLpolygonen = [] # Lijst van Woonplaats-polygonen self.NBpolygonen = [] # 'NB' betekent Niet Bestaand, voor bijv. gesloopte panden self.coordinaten = wx.TextCtrl(self, -1, "", pos=(self.GetSize().GetWidth() - 90, self.GetSize().GetHeight() - 20), size=(90, 20), style=wx.TE_READONLY) self.SetBackgroundColour(self.coordinaten.GetBackgroundColour()) self.Bind(wx.EVT_PAINT, self._tekenKaart) # self.Bind(wx.EVT_MOTION, self._beweegCursor) self.Bind(wx.EVT_LEFT_DOWN, self._klikOpPunt) self.Bind(wx.EVT_LEFT_DCLICK, self._dubbelklikOpPunt) self.zoomUitKnop = wx.Button(self, label="-", pos=(self.GetSize().GetWidth() - 20, 0), size=(20, 20)) self.zoomInKnop = wx.Button(self, label="+", pos=(self.GetSize().GetWidth() - 20, 20), size=(20, 20)) self.Bind(wx.EVT_BUTTON, self._zoomUit, self.zoomUitKnop) self.Bind(wx.EVT_BUTTON, self._zoomIn, self.zoomInKnop) self.database = Database() # Maak de kaart leeg def maakLeeg(self): self.minX = 0.0 self.minY = 0.0 self.maxX = 0.0 self.maxY = 0.0 self.centerX = 0.0 self.centerY = 0.0 self.schaal = 0.0 self.zoom = 0.5 self.polygonen = [] self.bagObject = None self.highlightPolygonen = [] self.PNDpolygonen = [] self.LPLpolygonen = [] self.SPLpolygonen = [] self.WPLpolygonen = [] self.NBpolygonen = [] self.coordinaten.Clear() self.Refresh() # Teken de kaart op basis van de polygonen die in de kaart zijn opgeslagen. # Deze functie wordt aangeroepen naar een EVT_PAINT event. def _tekenKaart(self, event=None): dc = wx.PaintDC(self) gc = wx.GraphicsContext.Create(dc) # Toon woonplaatsen in bruin gc.SetPen(wx.Pen("brown", 1)) for polygoon in self.WPLpolygonen: gc.DrawLines(polygoon) # Toon niet (meer) bestaand objecten zonder opvulkleur gc.SetPen(wx.Pen("grey", 1)) gc.SetBrush(wx.Brush("grey", wx.CROSSDIAG_HATCH)) for polygoon in self.NBpolygonen: gc.DrawLines(polygoon) # Toon panden in blauw gc.SetPen(wx.Pen("navy", 1)) gc.SetBrush(wx.Brush("light grey")) for polygoon in self.PNDpolygonen: gc.DrawLines(polygoon) # Toon ligplaatsen in groen gc.SetPen(wx.Pen("pale green", 1)) gc.SetBrush(wx.Brush("green")) for polygoon in self.LPLpolygonen: gc.DrawLines(polygoon) # Toon standplaatsen in paars gc.SetPen(wx.Pen("purple", 1)) gc.SetBrush(wx.Brush("pink")) for polygoon in self.SPLpolygonen: gc.DrawLines(polygoon) # Het geselecteerde BAG-object wordt vetgedrukt in rood getoond gc.SetPen(wx.Pen("red", 2)) gc.SetBrush(wx.Brush("salmon")) for polygoon in self.highlightPolygonen: if len(polygoon) == 1: # Verblijfsobjecten hebben maar 1 punt in de geometrie. Toon deze als een cirkel gc.DrawEllipse(polygoon[0].x, polygoon[0].y, 5, 5) else: gc.DrawLines(polygoon) self.zoomInKnop.Refresh() self.zoomUitKnop.Refresh() # Toon bij het bewegen van de cursor de coordinaten op de kaart def _beweegCursor(self, event): self.coordinaten.Clear() self.coordinaten.WriteText("%d,%d" % (self.cursorPositieX(), self.cursorPositieY())) # Bij een enkele klik op de kaart wordt, zonder de kaart te verschuiven of te veranderen, # het object op het aangeklikte punt geselecteerd, gehighlight en getoond in de view. # Dit werkt door de coordinaten van het aangeklikte punt in te vullen in de functie voor # het zoeken op coordinaten, en deze zoekfunctie uit te voeren. Door hierbij eerst de # vlag 'gebruikHuidigeKaart' aan te zetten, wordt voorkomen dat de hele kaart rondom het # gevonden object opnieuw wordt opgebouwd. def _klikOpPunt(self, event): self.coordinaten.Clear() self.gebruikHuidigeKaart = True self.raadpleegScherm.zoekOpCoordinaten.klapOpen() self.raadpleegScherm.zoekOpCoordinaten.xText.Clear() self.raadpleegScherm.zoekOpCoordinaten.xText.WriteText(str(int(self.cursorPositieX()))) self.raadpleegScherm.zoekOpCoordinaten.yText.Clear() self.raadpleegScherm.zoekOpCoordinaten.yText.WriteText(str(int(self.cursorPositieY()))) self.raadpleegScherm.zoekOpCoordinaten.Refresh() self.raadpleegScherm.zoekOpCoordinaten.zoek() self.gebruikHuidigeKaart = False # Bij een dubbelklik op de kaart, wordt het object gezocht op het aangeklikte punt, wordt # dit object gecentreerd in de kaart en de kaart rondom dit object opnieuw opgebouwd. def _dubbelklikOpPunt(self, event): self.coordinaten.Clear() self.raadpleegScherm.zoekOpCoordinaten.klapOpen() self.raadpleegScherm.zoekOpCoordinaten.xText.Clear() self.raadpleegScherm.zoekOpCoordinaten.xText.WriteText(str(int(self.cursorPositieX()))) self.raadpleegScherm.zoekOpCoordinaten.yText.Clear() self.raadpleegScherm.zoekOpCoordinaten.yText.WriteText(str(int(self.cursorPositieY()))) self.raadpleegScherm.zoekOpCoordinaten.Refresh() self.raadpleegScherm.zoekOpCoordinaten.zoek() # Zoom in op de kaart door de zoomfactor te halveren def _zoomIn(self, event): self.zoom = self.zoom / 2.0 self.toonGeometrie(self.bagObject) # Zoom uit op de kaart door de zoomfactor te verdubbelen def _zoomUit(self, event): self.zoom = self.zoom * 2.0 self.toonGeometrie(self.bagObject) # Reken de X-coordinaat om naar een positie op de kaart op het scherm. def schermCoordinaatX(self, x): return self.GetSize().GetWidth() / 2 + (x - self.centerX) / self.schaal # Reken de Y-coordinaat om naar een positie op de kaart op het scherm. def schermCoordinaatY(self, y): return (self.GetSize().GetHeight() / 2 + (y - self.centerY) / self.schaal) * -1 + self.GetSize().GetHeight() # Geef de X-coordinaat op de kaart die overeenkomt met de cursor positie. def cursorPositieX(self): return self.centerX + (wx.GetMousePosition().x - self.GetScreenPosition().x - self.GetSize().GetWidth() / 2) * self.schaal # Geef de Y-coordinaat op de kaart die overeenkomt met de cursor positie. def cursorPositieY(self): height = self.GetSize().GetHeight() return self.centerY + (((wx.GetMousePosition().y - self.GetScreenPosition().y - height) * -1) - height / 2) * self.schaal # Toon van een gevonden BAG-object de geometrie in de kaart, tezamen met de geometrieen van # omliggende objecten. def toonGeometrie(self, bagObject): if bagObject.objectType() == "WPL": return # Initialiseer eerst het huidige, geselecteerde BAG object en stop de geometrie hiervan in de verzameling # highlightPolygonen. self.bagObject = bagObject self.highlightPolygonen = [] if self.bagObject.objectType() == "NUM": # In geval van een nummeraanduiding, wordt het adresseerbare object bij de nummeraanduiding gebruikt # als uitgangspunt voor weergave op de kaart. ao = self.bagObject.getAdresseerbaarObject() if ao: sql = self.bagObject.maakSelectAdresseerbaarObjectSQL() ao_rows = self.database.select(sql) if len(ao_rows) > 0 and len(ao_rows[0]) > 0: ao.zetWaarde('identificatie', ao_rows[0][0]) sql = ao.maakSelectSQL() ao_rows = self.database.select(sql) if len(ao_rows) > 0 and len(ao_rows[0]) > 0: ao.zetWaarden(ao_rows[0]) self.bagObject = ao else: return if self.bagObject.objectType() in ["PND", "LPL", "SPL", "VBO"]: if self.bagObject.objectType() in ["PND", "LPL", "SPL"]: geometrie = self.bagObject.attribuut('geovlak').waarde() else: geometrie = self.bagObject.attribuut('geopunt').waarde() # Lees de geometrie uit het bagObject en stel de BAGpolygoon samen als een lijst van # coordinatenparen. if geometrie[:7].upper() == "POLYGON" or geometrie[:5].upper() == "POINT": polygoon = [] if geometrie[:7].upper() == "POLYGON": geometrie = geometrie[7:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() if geometrie[:5].upper() == "POINT": geometrie = geometrie[5:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) self.highlightPolygonen.append(polygoon) self.polygonen.append(polygoon) if self.bagObject.objectType() == "OPR": # In geval van een openbare ruimte, wordt de verzameling gevuld met geometrieen van de adresseerbare objecten # met een hoofdadres aan de openbare ruimte. sql = "SELECT vbo.geopunt " sql += " FROM verblijfsobjectactueelbestaand vbo" sql += " , nummeraanduidingactueelbestaand num" sql += " WHERE num.gerelateerdeopenbareruimte = " + str(self.bagObject.identificatie()) sql += " AND vbo.hoofdadres = num.identificatie" verblijfsobjecten = self.database.select(sql) for verblijfsobject in verblijfsobjecten: geometrie = verblijfsobject[0] if geometrie[:5].upper() == "POINT": geometrie = geometrie[5:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() polygoon = [] for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) self.highlightPolygonen.append(polygoon) self.polygonen.append(polygoon) # Zoek de ligplaatsen aan de openbare ruimte sql = "SELECT lpl.geovlak " sql += " FROM ligplaatsactueelbestaand lpl" sql += " , nummeraanduidingactueelbestaand num" sql += " WHERE num.gerelateerdeopenbareruimte = " + str(self.bagObject.identificatie()) sql += " AND lpl.hoofdadres = num.identificatie" ligplaatsen = self.database.select(sql) for ligplaats in ligplaatsen: geometrie = ligplaats[0] if geometrie[:7].upper() == "POLYGON": geometrie = geometrie[7:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() polygoon = [] for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) self.highlightPolygonen.append(polygoon) self.polygonen.append(polygoon) # Zoek de standplaatsen aan de openbare ruimte sql = "SELECT spl.geovlak " sql += " FROM standplaatsactueelbestaand spl" sql += " , nummeraanduidingactueelbestaand num" sql += " WHERE num.gerelateerdeopenbareruimte = " + str(self.bagObject.identificatie()) sql += " AND spl.hoofdadres = num.identificatie" standplaatsen = self.database.select(sql) for standplaats in standplaatsen: geometrie = standplaats[0] if geometrie[:7].upper() == "POLYGON": geometrie = geometrie[7:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() polygoon = [] for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) self.highlightPolygonen.append(polygoon) self.polygonen.append(polygoon) if self.gebruikHuidigeKaart: # Gebruik de huidige kaart zonder te verschuiven. Alleen het geselecteerde BAG-object(en) wordt opnieuw getekend. # Reken de XY-coordinaten in de polygoon om naar punten in het scherm. for polygoon in self.highlightPolygonen: for punt in polygoon: punt.x = self.schermCoordinaatX(punt.x) punt.y = self.schermCoordinaatY(punt.y) else: # Bouw een nieuwe kaart op rondom het geselecteerde object self.minX = 999999.0 self.minY = 999999.0 self.maxX = 0.0 self.maxY = 0.0 self.schaal = self.zoom self.polygonen = [] for polygoon in self.highlightPolygonen: self.polygonen.append(polygoon) self.PNDpolygonen = [] self.LPLpolygonen = [] self.SPLpolygonen = [] self.WPLpolygonen = [] self.NBpolygonen = [] # Bepaal de uiterste hoekpunten van de rechthoek waarin de BAGpolygoon past. for polygoon in self.highlightPolygonen: for punt in polygoon: self.minX = min(self.minX, punt.x) self.minY = min(self.minY, punt.y) self.maxX = max(self.maxX, punt.x) self.maxY = max(self.maxY, punt.y) self.centerX = (self.minX + self.maxX) / 2.0 self.centerY = (self.minY + self.maxY) / 2.0 # Bepaal de rechthoek rondom het object waarin naar omliggende objecten wordt gezocht. lX = self.minX - 600 * self.schaal lY = self.minY - 400 * self.schaal rX = self.maxX + 600 * self.schaal rY = self.maxY + 400 * self.schaal rechthoek = "POLYGON((%f %f 0.0, %f %f 0.0, %f %f 0.0, %f %f 0.0, %f %f 0.0))" % ( lX, lY, rX, lY, rX, rY, lX, rY, lX, lY) # Zoek panden in de omgeving sql = "SELECT geovlak, pandstatus" sql += " FROM pandactueelbestaand" sql += " WHERE geovlak && GeomFromEWKT('SRID=28992;" + rechthoek + "')" panden = self.database.select(sql) for pand in panden: geometrie = pand[0] status = pand[1] if geometrie[:7].upper() == "POLYGON": geometrie = geometrie[7:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() polygoon = [] for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) if status.upper() in ["BOUWVERGUNNING VERLEEND", "NIET GEREALISEERD PAND", "PAND GESLOOPT"]: self.NBpolygonen.append(polygoon) else: self.PNDpolygonen.append(polygoon) self.polygonen.append(polygoon) # Zoek ligplaatsen in de omgeving sql = "SELECT geovlak, ligplaatsstatus" sql += " FROM ligplaatsActueel" sql += " WHERE geovlak && GeomFromEWKT('SRID=28992;" + rechthoek + "')" ligplaatsen = self.database.select(sql) for ligplaats in ligplaatsen: geometrie = ligplaats[0] status = ligplaats[1] if geometrie[:7].upper() == "POLYGON": geometrie = geometrie[7:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() polygoon = [] for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) if status.upper() == "LIGPLAATS INGETROKKEN": self.NBpolygonen.append(polygoon) else: self.LPLpolygonen.append(polygoon) self.polygonen.append(polygoon) # Zoek standplaatsen in de omgeving sql = "SELECT geovlak, standplaatsstatus" sql += " FROM standplaatsActueel" sql += " WHERE geovlak && GeomFromEWKT('SRID=28992;" + rechthoek + "')" standplaatsen = self.database.select(sql) for standplaats in standplaatsen: geometrie = standplaats[0] status = standplaats[1] if geometrie[:7].upper() == "POLYGON": geometrie = geometrie[7:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() polygoon = [] for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) if status.upper() == "STANDPLAATS INGETROKKEN": self.NBpolygonen.append(polygoon) else: self.SPLpolygonen.append(polygoon) self.polygonen.append(polygoon) # Zoek woonplaatsen in de omgeving sql = "SELECT geovlak" sql += " FROM woonplaatsActueel" sql += " WHERE geovlak && GeomFromEWKT('SRID=28992;" + rechthoek + "')" woonplaatsen = self.database.select(sql) for woonplaats in woonplaatsen: geometrie = woonplaats[0] if geometrie[:12].upper() == "MULTIPOLYGON": geometrie = geometrie[12:].replace('(', ' ').replace(')', ' ').lstrip().rstrip() polygoon = [] for punt in geometrie.lstrip().rstrip().split(','): coordinaten = punt.lstrip().rstrip().split(' ') polygoon.append(wx.Point2D(float(coordinaten[0]), float(coordinaten[1]))) self.WPLpolygonen.append(polygoon) self.polygonen.append(polygoon) # Reken de XY-coordinaten in de polygoon om naar punten in het scherm for polygoon in self.polygonen: for punt in polygoon: punt.x = self.schermCoordinaatX(punt.x) punt.y = self.schermCoordinaatY(punt.y) # Refresh genereert een EVT_PAINT event, waarna de polygonen op de kaart getekend worden. self.Refresh()
class BagFilter(): def __init__(self): # All arguments required to be able to run configure configreader parser = ArgParser(description='bag-extract, commandline tool voor het extraheren en inlezen van BAG bestanden', epilog="Configureer de database in extract.conf of geef eigen versie van extract.conf via -f of geef parameters via commando regel expliciet op") parser.add_argument('-f', '--config', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument('-a', '--config2', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument('-c', '--dbinit', action='store_true', help='verwijdert (DROP TABLE) alle tabellen en maakt (CREATE TABLE) nieuwe tabellen aan') parser.add_argument('-d', '--database', metavar='<naam>', help='geef naam van de database') parser.add_argument('-s', '--schema', metavar='<naam>', help='geef naam van het database schema') parser.add_argument('-q', '--query', metavar='<bestand>', help='voer database bewerkingen uit met opgegeven SQL bestand') parser.add_argument('-e', '--extract', metavar='<naam>', help='importeert of muteert de database met gegeven BAG-bestand of -directory') parser.add_argument('-H', '--host', metavar='<hostnaam of -adres>', help='verbind met de database op deze host') parser.add_argument('-U', '--username', metavar='<naam>', help='verbind met database met deze gebruikersnaam') parser.add_argument('-p', '--port', metavar='<poort>', help='verbind met database naar deze poort') parser.add_argument('-W', '--password', metavar='<paswoord>', help='gebruikt dit wachtwoord voor database gebruiker') parser.add_argument('-w', '--no-password', action='store_true', help='gebruik geen wachtwoord voor de database verbinding') parser.add_argument('-v', '--verbose', action='store_true', help='toon uitgebreide informatie tijdens het verwerken') parser.add_argument('-D', '--dbinitcode', action='store_true', help='createert een lijst met statements om het DB script aan te passen') # Initialiseer self.args = parser.parse_args() # Initialize singleton Log object so we can use one global instance Log(self.args) self.database = None def filterBagData(self): self.connectDatabase() # Get list of addresses of VBOs in Eindhoven adressen = self.getEindhovenAdressen(True) print "Retrieved Adressen" # List of all VBO ids idsVBO = [row[0] for row in adressen] # Get vbo's and panden eindhoven vbos = self.getVBOByIdentificationList(idsVBO) vboPanden = self.getVBOPandenByIdentificationList(idsVBO) # Clear idsVBO for memory space idsVBO = [] print "Retrieved VBOs" panden = [row[6] for row in vboPanden] panden = self.getPandenByIdentificationList(panden) print "Retrieved Panden" self.database.close() self.connectDatabase(True) #database.insertMultiple("adres", adressen) self.database.insertMultiple("verblijfsobject", vbos) self.database.insertMultiple("verblijfsobjectpand", vboPanden) self.database.insertMultiple("pand", panden) self.database.close() def connectDatabase(self, bag2=False): BAGConfig(self.args, bag2) self.database = Database() self.database.verbind() def getEindhovenAdressen(self, vboIdsOnly=False): # Get list adressen of VBOs in Eindhoven if vboIdsOnly: sql = "SELECT adresseerbaarobject " \ "FROM adres " \ "WHERE woonplaatsnaam LIKE 'Eindhoven'" else: sql = "SELECT * " \ "FROM adres " \ "WHERE woonplaatsnaam LIKE 'Eindhoven'" return self.database.selectQuery(sql) def getVBOByIdentificationList(self, idsVBO): sql = "Select * " \ "FROM verblijfsobjectactuuelalles " \ "WHERE identificatie IN %s" return self.database.selectQuery(sql, [tuple(idsVBO)]) def getVBOPandenByIdentificationList(self, idsVBO): sql = "Select * " \ "FROM verblijfsobjectpandactueel " \ "WHERE identificatie IN %s" return self.database.selectQuery(sql, [tuple(idsVBO)]) def getPandenByIdentificationList(self, pandIds): sql = "Select * " \ "FROM pandactueelalles " \ "WHERE identificatie IN %s" return self.database.selectQuery(sql, [tuple(pandIds)])
def __init__(self): self.database = Database() self.naam = 'onbekend' self.script_template = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/%s')
class Processor: # TODO: # Ben tot hier gekomen met etree. node.localName kent alleen een representatief # in de vorm van element.tag # Maar hier zitten de namespaces in: # # print xml.getroot().tag # {http://www.kadaster.nl/schemas/bag-verstrekkingen/extract-deelbestand-lvc/v20090901}BAG-Extract-Deelbestand-LVC # # Deze moeten of gestript worden, of de functie die dit automatisch doet moet worden gevonden. def __init__(self): self.database = Database() def processCSV(self, csvreader): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: object = BestuurlijkObjectFabriek(cols, record) if object: objecten.append(object) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database Log.log.info("Insert objectCount=" + str(len(objecten))) self.database.verbind() self.database.connection.set_client_encoding('LATIN1') for object in objecten: object.insert() self.database.uitvoeren(object.sql, object.valuelist) self.database.connection.commit() def processDOM(self, node): self.bagObjecten = [] mode = "Onbekend" if node.localName == 'BAG-Extract-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node.childNodes: if childNode.localName == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord.childNodes: if child.localName == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child elif child.localName == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten.childNodes: if productnode.localName == 'LVC-product' and productnode.childNodes: self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML( productnode.childNodes) Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) elif node.localName == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node.childNodes: if childNode.localName == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord.childNodes: if child.localName == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten.childNodes: if productnode.localName == 'Mutatie-product' and productnode.childNodes: origineelObj = None nieuwObj = None for mutatienode in productnode.childNodes: if mutatienode.localName == 'Nieuw': # Log.log.info("Nieuw Object") self.bagObjecten.extend( BAGObjectFabriek.bof. BAGObjectArrayBijXML( mutatienode.childNodes)) elif mutatienode.localName == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML( mutatienode.childNodes) if len(objs) > 0: origineelObj = objs[0] elif mutatienode.localName == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML( mutatienode.childNodes) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.origineelObj = origineelObj self.bagObjecten.append( nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None nieuwObj = None Log.log.endTimer("objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) else: Log.log.info("Niet-verwerkbare XML node: " + node.localName) return Log.log.startTimer("dbStart mode = " + mode) self.database.verbind() rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 else: # Mutatie: nieuw object bagObject.maakInsertSQL() self.database.uitvoeren(bagObject.sql, bagObject.inhoud) for relatie in bagObject.relaties: i = 0 for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) i += 1 rels += 1 self.database.connection.commit() Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------")
class Processor: def __init__(self): self.database = Database() def processCSV(self, csvreader): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: object = BestuurlijkObjectFabriek(cols, record) if object: objecten.append(object) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database Log.log.info("Insert objectCount=" + str(len(objecten))) self.database.verbind() # We gaan er even vanuit dat de encoding van de CSVs UTF-8 is self.database.connection.set_client_encoding('UTF8') for object in objecten: object.insert() self.database.uitvoeren(object.sql, object.valuelist) self.database.connection.commit() def processDOM(self, node): self.bagObjecten = [] mode = "Onbekend" if stripschema(node.tag) == 'BAG-Extract-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: if stripschema(productnode.tag) == 'LVC-product': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML(productnode) Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) elif stripschema(node.tag) == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema(productnode.tag) == 'Mutatie-product': origineelObj = None nieuwObj = None for mutatienode in productnode: if stripschema(mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") self.bagObjecten.extend( BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode)) elif stripschema(mutatienode.tag) == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag) == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.origineelObj = origineelObj self.bagObjecten.append(nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None nieuwObj = None Log.log.endTimer("objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) else: Log.log.info("Niet-verwerkbare XML node: " + stripschema(node.tag)) return Log.log.startTimer("dbStart mode = " + mode) self.database.verbind() rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 else: # Mutatie: nieuw object bagObject.maakInsertSQL() self.database.uitvoeren(bagObject.sql, bagObject.inhoud) for relatie in bagObject.relaties: i = 0 for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) i += 1 rels += 1 self.database.connection.commit() Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------")
class Processor: def __init__(self): self.database = Database() def processCSV(self, csvreader): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: object = BestuurlijkObjectFabriek(cols, record) if object: objecten.append(object) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database Log.log.info("Insert objectCount=" + str(len(objecten))) self.database.verbind() # We gaan er even vanuit dat de encoding van de CSVs UTF-8 is self.database.connection.set_client_encoding('UTF8') for object in objecten: object.insert() self.database.uitvoeren(object.sql, object.valuelist) self.database.commit() def processDOM(self, node): self.bagObjecten = [] mode = "Onbekend" doc_tag = stripschema(node.tag) # 'BAG-Extract-Deelbestand-LVC': standaard BAG Element, VBO etc # 'BAG-GWR-Deelbestand-LVC': Koppeltabel Gemeente-Woonplaats-Relatie (alleen in BAG na plm aug 2012) if doc_tag == 'BAG-Extract-Deelbestand-LVC' or doc_tag == 'BAG-GWR-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child if doc_tag == 'BAG-GWR-Deelbestand-LVC': # Noteer ook de standdatum van de gemeente_woonplaats koppel tabel # zodat we weten welke datum/versie is gebruikt... # Probeer BAG extract datum uit XML te vinden vraag = stripNS(vraag) gwr_datum = vraag.xpath("StandTechnischeDatum/text()") if len(gwr_datum) > 0: # Gevonden ! gwr_datum = str(gwr_datum[0]) else: gwr_datum = "onbekend" # Opslaan (evt vervangen) als meta info self.database.log_meta("gem_woonplaats_rel_datum", gwr_datum) elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: product_tag = stripschema(productnode.tag) if product_tag == 'LVC-product' or product_tag == 'GemeenteWoonplaatsRelatieProduct': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML(productnode) if product_tag == 'GemeenteWoonplaatsRelatieProduct': # Altijd de vorige weggooien self.database.log_actie('truncate_table', 'gemeente_woonplaats', 'altijd eerst leeg maken') self.database.tx_uitvoeren('truncate gemeente_woonplaats') bericht = Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) self.database.log_actie('create_objects', 'idem', bericht) elif doc_tag == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema(productnode.tag) == 'Mutatie-product': origineelObj = None nieuwObj = None for mutatienode in productnode: if stripschema(mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") self.bagObjecten.extend( BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode)) elif stripschema(mutatienode.tag) == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag) == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.origineelObj = origineelObj self.bagObjecten.append(nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None nieuwObj = None bericht = Log.log.endTimer("objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', 'idem', bericht) elif doc_tag == 'BAG-Extract-Levering': # Meta data: info over levering # Sla hele file op self.database.log_meta("levering_xml", etree.tostring(node, pretty_print=True)) # Extraheer BAG lever datum # <v202:LVC-Extract> # <v202:gegVarLevenscyclus>true</v202:gegVarLevenscyclus> # <v202:productcode>DNLDLXAE02</v202:productcode> # <v202:StandTechnischeDatum>20120308</v202:StandTechnischeDatum> # </v202:LVC-Extract> node = stripNS(node) # Probeer BAG extract datum uit XML te vinden extract_datum = node.xpath("//LVC-Extract/StandTechnischeDatum/text()") if len(extract_datum) > 0: # Gevonden ! extract_datum = str(extract_datum[0]) else: extract_datum = "onbekend" # Opslaan als meta info self.database.log_meta("extract_datum", extract_datum) else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', 'n.v.t', bericht) return Log.log.startTimer("dbStart mode = " + mode) # Experimenteel: dbStoreCopy() gebruikt COPY ipv INSERT # maar moet nog gefinetuned if mode == 'Mutatie': # Voor mutaties voorlopig nog even ouderwetse INSERT/UPDATE # Hier speelt performance ook niet zo'n rol als bij hele BAG inlezen... bericht = self.dbStoreInsert(mode) else: bericht = self.dbStoreCopy(mode) Database().log_actie('insert_database', 'idem', bericht) def dbStoreInsert(self, mode): self.database.verbind() rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 else: # Mutatie: nieuw object bagObject.maakInsertSQL() try: self.database.uitvoeren(bagObject.sql, bagObject.inhoud) except (Exception), e: # Heeft geen zin om door te gaan Log.log.error("database fout bij insert, ik stop met dit bestand") break for relatie in bagObject.relaties: i = 0 for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) i += 1 rels += 1 self.database.commit() bericht = Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------") return bericht
class BAGFileReader: def __init__(self, file_path): self.file_path = file_path self.processor = Processor() self.database = Database() def process(self): Log.log.info("process: verwerk %s" % self.file_path) if not os.path.exists(self.file_path): Log.log.fatal("kan BAG-bestand of -directory: '%s' niet vinden" % self.file_path) return if os.path.isdir(self.file_path): # Verwerk een directory self.process_dir(self.file_path) else: # Verwerk een "gewone" file: alleen ZIP, CSV of XML self.process_file(self.file_path) def process_dir(self, file_path): Log.log.info("process_dir: verwerk %s" % file_path) # Loop door op naam (datum) gesorteerde bestanden (m.n. i.v.m. mutatie-volgorde) for each in sorted(os.listdir(file_path), key=fname_key): # Volledig pad naar ieder bestand in dir nest_file_path = os.path.join(file_path, each) # Verwerk alleen file-bestanden (ZIP, CSV, XML) # Subdirectories worden dus niet verwerkt! if not os.path.isdir(nest_file_path): self.process_file(nest_file_path) def process_file(self, file_path, file_buf=None): filenaam = os.path.basename(file_path) # Overslaan als bestand al (succesvol) verwerkt is: bijv bij herstart of reeds verwerkte mutaties if self.database.has_log_actie("verwerkt", filenaam, False): Log.log.info("bestand %s is reeds verwerkt ==> overslaan" % filenaam) self.database.log_actie("overgeslagen", filenaam, "reeds verwerkt", True) return # Mutatie-bestand overslaan indien datum eerder dan stand-datum BAG if filenaam.startswith("9999MUT"): # Draai eerste datum veld om naar YYYYMMDD, bijv: # 9999MUT14122014-15122014.zip wordt 20141214 # 9999MUT02012015-03012015-000002.xml wordt 20150102 mutatie_start_datum = filenaam[11:15] + filenaam[9:11] + filenaam[7:9] mutatie_eind_datum = filenaam[20:24] + filenaam[18:20] + filenaam[16:18] # stand datum BAG moet voor of op start-datum mutatie bestand liggen EN # voor mutatie einddatum sql = "SELECT * FROM nlx_bag_info WHERE sleutel = 'extract_datum' AND waarde <= '%s' AND waarde < '%s'" % ( mutatie_start_datum, mutatie_eind_datum, ) if self.database.tx_uitvoeren(sql) != 1: Log.log.info("mutatiebestand %s is van eerdere datum-range dan BAG ==> overslaan" % filenaam) self.database.log_actie("overgeslagen", filenaam, "mutatie datum-range voor BAG datum", True) return # Verkrijg file-extensie (niet alle files, e.g. README bestand hebben die) ext = None filenaam_arr = filenaam.split(".") if len(filenaam_arr) > 1: ext = filenaam_arr[-1].lower() # file_buf kan StringIO (stream/buffer) zijn uit zipfile file_resource = file_path if file_buf: file_resource = file_buf # Verwerk naar file-extensie/type if ext == "xml": self.process_xml(file_resource, filenaam) elif ext == "csv": self.process_csv(file_resource, filenaam) elif ext == "zip": self.process_zip(file_resource, filenaam) else: Log.log.info("Negeer bestand: %s" % file_path) def process_xml(self, file_resource, filenaam): Log.log.info("process_xml: verwerk %s " % filenaam) try: # XML doc parsen naar etree object Log.log.startTimer("parseXML") parsed_xml = etree.parse(file_resource) bericht = Log.log.endTimer("parseXML") self.database.log_actie("xml_parse", filenaam, bericht) except (Exception), e: bericht = Log.log.error("fout %s in XML parsen, bestand=%s" % (str(e), filenaam)) self.database.log_actie("xml_parse", filenaam, bericht, True) return if filenaam == "gemeentelijke-indeling.xml": try: self.processor.processGemeentelijkeIndeling(parsed_xml.getroot(), filenaam) self.database.log_actie("xml_processing", filenaam, "verwerkt OK") except (Exception), e: bericht = Log.log.error("fout %s in XML DOM processing, bestand=%s" % (str(e), filenaam)) self.database.log_actie("xml_processing", filenaam, bericht, True)
class BAGFileReader: def __init__(self, file_path): self.file_path = file_path self.processor = Processor() self.database = Database() def process(self): Log.log.info("process: verwerk %s" % self.file_path) if not os.path.exists(self.file_path): Log.log.fatal("kan BAG-bestand of -directory: '%s' niet vinden" % self.file_path) return if os.path.isdir(self.file_path): # Verwerk een directory self.process_dir(self.file_path) else: # Verwerk een "gewone" file: alleen ZIP, CSV of XML self.process_file(self.file_path) def process_dir(self, file_path): Log.log.info("process_dir: verwerk %s" % file_path) # Loop door op naam (datum) gesorteerde bestanden (m.n. i.v.m. mutatie-volgorde) for each in sorted(os.listdir(file_path), key=fname_key): # Volledig pad naar ieder bestand in dir nest_file_path = os.path.join(file_path, each) # Verwerk alleen file-bestanden (ZIP, CSV, XML) # Subdirectories worden dus niet verwerkt! if not os.path.isdir(nest_file_path): self.process_file(nest_file_path) def process_file(self, file_path, file_buf=None): filenaam = os.path.basename(file_path) # Overslaan als bestand al (succesvol) verwerkt is: bijv bij herstart of reeds verwerkte mutaties if self.database.has_log_actie('verwerkt', filenaam, False): Log.log.info("bestand %s is reeds verwerkt ==> overslaan" % filenaam) self.database.log_actie('overgeslagen', filenaam, 'reeds verwerkt', True) return # Mutatie-bestand overslaan indien datum eerder dan stand-datum BAG if filenaam.startswith('9999MUT'): # Draai eerste datum veld om naar YYYYMMDD, bijv: # 9999MUT14122014-15122014.zip wordt 20141214 # 9999MUT02012015-03012015-000002.xml wordt 20150102 mutatie_start_datum = filenaam[11:15] + filenaam[9:11] + filenaam[7:9] mutatie_eind_datum = filenaam[20:24] + filenaam[18:20] + filenaam[16:18] # stand datum BAG moet voor of op start-datum mutatie bestand liggen EN # voor mutatie einddatum sql = "SELECT * FROM nlx_bag_info WHERE sleutel = 'extract_datum' AND waarde <= '%s' AND waarde < '%s'" % (mutatie_start_datum, mutatie_eind_datum) if self.database.tx_uitvoeren(sql) != 1: Log.log.info("mutatiebestand %s is van eerdere datum-range dan BAG ==> overslaan" % filenaam) self.database.log_actie('overgeslagen', filenaam, 'mutatie datum-range voor BAG datum', True) return # Verkrijg file-extensie (niet alle files, e.g. README bestand hebben die) ext = None filenaam_arr = filenaam.split('.') if len(filenaam_arr) > 1: ext = filenaam_arr[-1].lower() # file_buf kan StringIO (stream/buffer) zijn uit zipfile file_resource = file_path if file_buf: file_resource = file_buf # Verwerk naar file-extensie/type if ext == 'xml': self.process_xml(file_resource, filenaam) elif ext == 'csv': self.process_csv(file_resource, filenaam) elif ext == 'zip': self.process_zip(file_resource, filenaam) else: Log.log.info("Negeer bestand: %s" % file_path) def process_xml(self, file_resource, filenaam): Log.log.info("process_xml: verwerk %s " % filenaam) try: # XML doc parsen naar etree object Log.log.startTimer("parseXML") parsed_xml = etree.parse(file_resource) bericht = Log.log.endTimer("parseXML") self.database.log_actie('xml_parse', filenaam, bericht) except (Exception), e: bericht = Log.log.error("fout %s in XML parsen, bestand=%s" % (str(e), filenaam)) self.database.log_actie('xml_parse', filenaam, bericht, True) return try: # Verwerken parsed xml: de Processor bepaalt of het een extract of een mutatie is self.processor.processDOM(parsed_xml.getroot(), filenaam) self.database.log_actie('verwerkt', filenaam, 'verwerkt OK') except (Exception), e: bericht = Log.log.error("fout %s in XML DOM processing, bestand=%s" % (str(e), filenaam)) self.database.log_actie('xml_processing', filenaam, bericht, True)
class Processor: def __init__(self): self.database = Database() self.naam = 'onbekend' self.script_template = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/%s') def dbInit(self): # Print start time Log.log.time("Start") # Dumps all tables and recreates them db_script = self.script_template % 'bag-db.sql' Log.log.info("alle tabellen weggooien en opnieuw aanmaken in database '%s', schema '%s'..." % (BAGConfig.config.database, BAGConfig.config.schema)) try: self.database.initialiseer(db_script) except Exception as e: Log.log.fatal("Kan geen verbinding maken met de database") sys.exit() Log.log.info("Initieele data (bijv. gemeenten/provincies) inlezen...") from bagfilereader import BAGFileReader # from bagobject import VerblijfsObjectPand, AdresseerbaarObjectNevenAdres, VerblijfsObjectGebruiksdoel, Woonplaats, OpenbareRuimte, Nummeraanduiding, Ligplaats, Standplaats, Verblijfsobject, Pand myreader = BAGFileReader(BAGConfig.config.bagextract_home + '/db/data') myreader.process() Log.log.info("Views aanmaken...") self.processSQLScript('bag-view-actueel-bestaand.sql') # Print end time Log.log.time("End") def processSQLScript(self, sql_file): db_script = self.script_template % sql_file self.database.file_uitvoeren(db_script) def processCSV(self, csvreader, naam='onbekend'): objecten = [] cols = csvreader.next() for record in csvreader: if record[0]: obj = BestuurlijkObjectFabriek(cols, record) if obj: objecten.append(obj) else: Log.log.warn("Geen object gevonden voor " + str(record)) # Verwerk het bestand, lees gemeente_woonplaatsen in de database bericht = "Insert objectCount=" + str(len(objecten)) Log.log.info(bericht) self.database.verbind() # We gaan er even vanuit dat de encoding van de CSVs UTF-8 is self.database.connection.set_client_encoding('UTF8') for obj in objecten: obj.insert() self.database.uitvoeren(obj.sql, obj.valuelist) self.database.commit() Database().log_actie('insert_database', naam, bericht) def processGemeentelijkeIndeling(self, node, naam='onbekend'): objecten = [] provincie_gemeente = defaultdict(dict) doc_tag = stripschema(node.tag) # XML schema: # <gemeentelijke_indeling xmlns="http://nlextract.nl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://nlextract.nl gemeentelijke-indeling.xsd"> # ... # <indeling jaar="2016"> # ... # <provincie code="27" naam="Noord-Holland"> # <gemeente code="358" naam="Aalsmeer" begindatum="1970-01-01" /> # ... # <gemeente code="381" naam="Bussum" begindatum="1970-01-01" einddatum="2016-01-01" /> # ... # <gemeente code="1942" naam="Gooise Meren" begindatum="2016-01-01" /> # </provincie> # ... # </indeling> # ... # </gemeentelijke_indeling> if doc_tag == 'gemeentelijke_indeling': for indelingNode in node: if stripschema(indelingNode.tag) == 'indeling': jaar = indelingNode.get('jaar') for provincieNode in indelingNode: if stripschema(provincieNode.tag) == 'provincie': provinciecode = provincieNode.get('code') provincienaam = provincieNode.get('naam') for gemeenteNode in provincieNode: if stripschema(gemeenteNode.tag) == 'gemeente': gemeentecode = gemeenteNode.get('code') gemeentenaam = gemeenteNode.get('naam') begindatum = gemeenteNode.get('begindatum') einddatum = gemeenteNode.get('einddatum') provincie_gemeente[provinciecode][gemeentecode] = { 'provinciecode' : provinciecode, 'provincienaam' : provincienaam, 'gemeentecode' : gemeentecode, 'gemeentenaam' : gemeentenaam, 'begindatum' : begindatum, 'einddatum' : einddatum, } for provinciecode in sorted(provincie_gemeente.keys()): for gemeentecode in sorted(provincie_gemeente[provinciecode].keys()): obj = GemeentelijkeIndelingFabriek(provincie_gemeente[provinciecode][gemeentecode]) if obj: objecten.append(obj) else: Log.log.warn("Geen object gevonden voor provinciecode %s en gemeentecode %s" % (provinciecode, gemeentecode)) bericht = "Processed objectCount=" + str(len(objecten)) Log.log.info(bericht) self.database.verbind() updated = 0 inserted = 0 unchanged = 0 self.database.connection.set_client_encoding('UTF8') for obj in objecten: obj.exists() if self.database.uitvoeren(obj.sql, obj.valuelist): obj.unchanged() if self.database.uitvoeren(obj.sql, obj.valuelist): unchanged += 1 else: obj.update() self.database.uitvoeren(obj.sql, obj.valuelist) updated += 1 else: obj.insert() self.database.uitvoeren(obj.sql, obj.valuelist) inserted += 1 self.database.commit() log_bericht = "Objects inserted=" + str(inserted) + " updated=" + str(updated) + " unchanged=" + str(unchanged) Log.log.info(log_bericht) Database().log_actie('insert_database', naam, bericht + " " + log_bericht) else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', self.naam, bericht) def processDOM(self, node, naam='onbekend'): self.bagObjecten = [] self.naam = naam mode = "Onbekend" doc_tag = stripschema(node.tag) # 'BAG-Extract-Deelbestand-LVC': standaard BAG Element, VBO etc # 'BAG-GWR-Deelbestand-LVC': Koppeltabel Gemeente-Woonplaats-Relatie (alleen in BAG na plm aug 2012) if doc_tag == 'BAG-Extract-Deelbestand-LVC' or doc_tag == 'BAG-GWR-Deelbestand-LVC': mode = 'Nieuw' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "vraag": # TODO: Is het een idee om vraag als object ook af te # handelen en op te slaan vraag = child if doc_tag == 'BAG-GWR-Deelbestand-LVC': # Noteer ook de standdatum van de gemeente_woonplaats koppel tabel # zodat we weten welke datum/versie is gebruikt... # Probeer BAG extract datum uit XML te vinden vraag = stripNS(vraag) gwr_datum = vraag.xpath("StandTechnischeDatum/text()") if len(gwr_datum) > 0: # Gevonden ! gwr_datum = str(gwr_datum[0]) else: gwr_datum = "onbekend" # Opslaan (evt vervangen) als meta info self.database.log_meta("gem_woonplaats_rel_datum", gwr_datum) elif stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate") for productnode in producten: product_tag = stripschema(productnode.tag) if product_tag == 'LVC-product' or product_tag == 'GemeenteWoonplaatsRelatieProduct': self.bagObjecten = BAGObjectFabriek.bof.BAGObjectArrayBijXML(productnode) if product_tag == 'GemeenteWoonplaatsRelatieProduct': # Altijd de vorige weggooien self.database.log_actie('truncate_table', 'gemeente_woonplaats', 'altijd eerst leeg maken') self.database.tx_uitvoeren('truncate gemeente_woonplaats') bericht = Log.log.endTimer("objCreate - objs=" + str(len(self.bagObjecten))) self.database.log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Mutaties-Deelbestand-LVC': mode = 'Mutatie' #firstchild moet zijn 'antwoord' for childNode in node: if stripschema(childNode.tag) == 'antwoord': # Antwoord bevat twee childs: vraag en producten antwoord = childNode for child in antwoord: if stripschema(child.tag) == "producten": producten = child Log.log.startTimer("objCreate (mutaties)") for productnode in producten: if stripschema(productnode.tag) == 'Mutatie-product': origineelObj = None # Gebruik als sorteersleutel (datum+volgnr) tbv volgorde verwerking verwerkings_id = '' for mutatienode in productnode: if stripschema(mutatienode.tag) == 'Verwerking': # Verkijgen verwerkings_datum en volgnummer tbv sorteren mutatienode = stripNS(mutatienode) # Maak uniek vewerkings id string uit datum-tijd + volgnr verwerkings_tijdstip = str(mutatienode.xpath("TijdstipVerwerking/text()")[0]) verwerkings_volgnr = str(mutatienode.xpath("VolgnrVerwerking/text()")[0]) verwerkings_id = verwerkings_tijdstip + '.' + verwerkings_volgnr # print('verwerkings_id=%s' % verwerkings_id) elif stripschema(mutatienode.tag) == 'Nieuw': # Log.log.info("Nieuw Object") bag_objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) for bag_obj in bag_objs: bag_obj.verwerkings_id = verwerkings_id self.bagObjecten.extend(bag_objs) elif stripschema(mutatienode.tag) == 'Origineel': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: origineelObj = objs[0] elif stripschema(mutatienode.tag) == 'Wijziging': objs = BAGObjectFabriek.bof.BAGObjectArrayBijXML(mutatienode) if len(objs) > 0: nieuwObj = objs[0] if nieuwObj and origineelObj: nieuwObj.verwerkings_id = verwerkings_id nieuwObj.origineelObj = origineelObj self.bagObjecten.append(nieuwObj) # Log.log.info("Wijziging Object") origineelObj = None # Zie http://www.pythoncentral.io/how-to-sort-a-list-tuple-or-object-with-sorted-in-python # Tbv sorteren self.bagObjecten array op verwerkings volgorde def get_verwerkings_id(bag_obj): return bag_obj.verwerkings_id # Sorteer te muteren objecten op verwerkings_id self.bagObjecten = sorted(self.bagObjecten, key=get_verwerkings_id) bericht = Log.log.endTimer("objCreate (mutaties) - objs=" + str(len(self.bagObjecten))) Database().log_actie('create_objects', self.naam, bericht) elif doc_tag == 'BAG-Extract-Levering': # Meta data: info over levering # Sla hele file op self.database.log_meta("levering_xml", etree.tostring(node, pretty_print=True)) # Extraheer BAG lever datum # <v202:LVC-Extract> # <v202:gegVarLevenscyclus>true</v202:gegVarLevenscyclus> # <v202:productcode>DNLDLXAE02</v202:productcode> # <v202:StandTechnischeDatum>20120308</v202:StandTechnischeDatum> # </v202:LVC-Extract> node = stripNS(node) # Probeer BAG extract datum uit XML te vinden extract_datum = node.xpath("//LVC-Extract/StandTechnischeDatum/text()") if len(extract_datum) > 0: # Gevonden ! extract_datum = str(extract_datum[0]) else: extract_datum = "onbekend" # Opslaan als meta info self.database.log_meta("extract_datum", extract_datum) Database().log_actie('verwerkt', self.naam, 'verwerken Leverings doc') else: bericht = Log.log.info("Niet-verwerkbare XML node: " + doc_tag) Database().log_actie('n.v.t', self.naam, bericht) return Log.log.startTimer("dbStart mode = " + mode) # Experimenteel: dbStoreCopy() gebruikt COPY ipv INSERT # maar moet nog gefinetuned if mode == 'Mutatie': # Voor mutaties voorlopig nog even ouderwetse INSERT/UPDATE # Hier speelt performance ook niet zo'n rol als bij hele BAG inlezen... bericht = self.dbStoreInsert(mode) else: bericht = self.dbStoreCopy(mode) Database().log_actie('insert_database', self.naam, bericht) def dbStoreInsert(self, mode): self.database.verbind() rels = 0 wijzigingen = 0 for bagObject in self.bagObjecten: if bagObject.origineelObj: # Mutatie: wijziging bagObject.maakUpdateSQL() wijzigingen += 1 else: # Mutatie: nieuw object bagObject.maakInsertSQL() try: self.database.uitvoeren(bagObject.sql, bagObject.inhoud) except (Exception), e: # Heeft geen zin om door te gaan Log.log.error("database fout bij insert, ik stop met dit bestand") break for relatie in bagObject.relaties: i = 0 for sql in relatie.sql: self.database.uitvoeren(sql, relatie.inhoud[i]) i += 1 rels += 1 self.database.commit() bericht = Log.log.endTimer("dbEnd - nieuw=" + str(len(self.bagObjecten) - wijzigingen) + " gewijzigd=" + str(wijzigingen) + " rels=" + str(rels)) Log.log.info("------") return bericht
def main(): """ Voorbeelden: 1. Initialiseer een database: python bagextract.py -H localhost -d bag -U postgres -W postgres -c 2. Importeer een extract in de database: python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011-000002.xml of python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011.zip Importeer gemeente_woonplaats informatie van het kadaster http://www.kadaster.nl/bag/docs/BAG_Overzicht_aangesloten_gemeenten.zip python bagextract.py -H localhost -d bag -U postgres -W postgres -e BAG_Overzicht_aangesloten_gemeenten.zip Theoretisch is het mogelijk de hele bag in te lezen vanuit de "hoofd" zip, maar dit is nog niet getest op geheugen-problemen. """ parser = ArgParser( description= 'bag-extract, commandline tool voor het extraheren en inlezen van BAG bestanden', epilog= "Configureer de database in extract.conf of geef eigen versie van extract.conf via -f of geef parameters via commando regel expliciet op" ) parser.add_argument( '-c', '--dbinit', action='store_true', help= 'verwijdert (DROP TABLE) alle tabellen en maakt (CREATE TABLE) nieuwe tabellen aan' ) parser.add_argument('-d', '--database', metavar='<naam>', help='geef naam van de database') parser.add_argument('-s', '--schema', metavar='<naam>', help='geef naam van het database schema') parser.add_argument( '-f', '--config', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument( '-q', '--query', metavar='<bestand>', help='voer database bewerkingen uit met opgegeven SQL bestand') parser.add_argument( '-e', '--extract', metavar='<naam>', help= 'importeert of muteert de database met gegeven BAG-bestand of -directory' ) parser.add_argument('-H', '--host', metavar='<hostnaam of -adres>', help='verbind met de database op deze host') parser.add_argument('-U', '--username', metavar='<naam>', help='verbind met database met deze gebruikersnaam') parser.add_argument('-p', '--port', metavar='<poort>', help='verbind met database naar deze poort') parser.add_argument('-W', '--password', metavar='<paswoord>', help='gebruikt dit wachtwoord voor database gebruiker') parser.add_argument( '-w', '--no-password', action='store_true', help='gebruik geen wachtwoord voor de database verbinding') parser.add_argument( '-v', '--verbose', action='store_true', help='toon uitgebreide informatie tijdens het verwerken') # Initialiseer args = parser.parse_args() # Initialize singleton Log object so we can use one global instance Log(args) # Init globale configuratie BAGConfig(args) # Database database = Database() # Print start time Log.log.time("Start") if args.dbinit: # Dumps all tables and recreates them db_script = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/bag-db.sql') Log.log.info("alle database tabellen weggooien en opnieuw aanmaken...") database.initialiseer(db_script) Log.log.info("Initieele data (bijv. gemeenten/provincies) inlezen...") myreader = BAGFileReader(BAGConfig.config.bagextract_home + '/db/data') myreader.process() Log.log.info("Views aanmaken...") db_script = os.path.realpath( BAGConfig.config.bagextract_home + '/db/script/bag-view-actueel-bestaand.sql') database.file_uitvoeren(db_script) elif args.extract: # Extracts any data from any source files/dirs/zips/xml/csv etc myreader = BAGFileReader(args.extract) myreader.process() elif args.query: # Voer willekeurig SQL script uit uit database = Database() database.file_uitvoeren(args.query) else: Log.log.fatal( "je geeft een niet-ondersteunde optie. Tip: probeer -h optie") # Print end time Log.log.time("End") sys.exit()
def main(): """ Voorbeelden: 1. Initialiseer een database: python bagextract.py -H localhost -d bag -U postgres -W postgres -c 2. Importeer een extract in de database: python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011-000002.xml of python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011.zip Importeer gemeente_woonplaats informatie van het kadaster http://www.kadaster.nl/bag/docs/BAG_Overzicht_aangesloten_gemeenten.zip python bagextract.py -H localhost -d bag -U postgres -W postgres -e BAG_Overzicht_aangesloten_gemeenten.zip Theoretisch is het mogelijk de hele bag in te lezen vanuit de "hoofd" zip, maar dit is nog niet getest op geheugen-problemen. """ parser = ArgParser(description='bag-extract, commandline tool voor het extraheren en inlezen van BAG bestanden', epilog="Configureer de database in extract.conf of geef eigen versie van extract.conf via -f of geef parameters via commando regel expliciet op") parser.add_argument('-c', '--dbinit', action='store_true', help='verwijdert (DROP TABLE) alle tabellen en maakt (CREATE TABLE) nieuwe tabellen aan') parser.add_argument('-j', '--ja', action='store_true', help='bevestig alle prompts') parser.add_argument('-d', '--database', metavar='<naam>', help='geef naam van de database') parser.add_argument('-s', '--schema', metavar='<naam>', help='geef naam van het database schema') parser.add_argument('-f', '--config', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument('-q', '--query', metavar='<bestand>', help='voer database bewerkingen uit met opgegeven SQL bestand') parser.add_argument('-e', '--extract', metavar='<naam>', help='importeert of muteert de database met gegeven BAG-bestand of -directory') parser.add_argument('-H', '--host', metavar='<hostnaam of -adres>', help='verbind met de database op deze host') parser.add_argument('-U', '--username', metavar='<naam>', help='verbind met database met deze gebruikersnaam') parser.add_argument('-p', '--port', metavar='<poort>', help='verbind met database naar deze poort') parser.add_argument('-W', '--password', metavar='<paswoord>', help='gebruikt dit wachtwoord voor database gebruiker') parser.add_argument('-w', '--no-password', action='store_true', help='gebruik geen wachtwoord voor de database verbinding') parser.add_argument('-v', '--verbose', action='store_true', help='toon uitgebreide informatie tijdens het verwerken') parser.add_argument('-D', '--dbinitcode', action='store_true', help='createert een lijst met statements om het DB script aan te passen') # Initialiseer args = parser.parse_args() # Initialize singleton Log object so we can use one global instance Log(args) # Init globale configuratie BAGConfig(args) # Database database = Database() if args.dbinit: if args.ja or confirm('Waarschuwing! met dit commando worden database tabellen opnieuw aangemaakt. Doorgaan?', False): # Print start time Log.log.time("Start") # Dumps all tables and recreates them db_script = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/bag-db.sql') Log.log.info("alle database tabellen weggooien en opnieuw aanmaken...") try: database.initialiseer(db_script) except Exception: Log.log.fatal("Kan geen verbinding maken met de database") sys.exit() Log.log.info("Initieele data (bijv. gemeenten/provincies) inlezen...") from bagfilereader import BAGFileReader # from bagobject import VerblijfsObjectPand, AdresseerbaarObjectNevenAdres, VerblijfsObjectGebruiksdoel, Woonplaats, OpenbareRuimte, Nummeraanduiding, Ligplaats, Standplaats, Verblijfsobject, Pand myreader = BAGFileReader(BAGConfig.config.bagextract_home + '/db/data') myreader.process() Log.log.info("Post processing en views aanmaken...") db_script = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/bag-gemeentecode-postprocess.sql') database.file_uitvoeren(db_script) db_script = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/bag-view-actueel-bestaand.sql') database.file_uitvoeren(db_script) # Print end time Log.log.time("End") else: exit() elif args.dbinitcode: # Print start time Log.log.time("Start") # Creates the insert statements from the code, and prints them bagObjecten = [] bagObjecten.append(VerblijfsObjectPand()) bagObjecten.append(AdresseerbaarObjectNevenAdres()) bagObjecten.append(VerblijfsObjectGebruiksdoel()) bagObjecten.append(Woonplaats()) bagObjecten.append(OpenbareRuimte()) bagObjecten.append(Nummeraanduiding()) bagObjecten.append(Ligplaats()) bagObjecten.append(Standplaats()) bagObjecten.append(Verblijfsobject()) bagObjecten.append(Pand()) for bagObject in bagObjecten: print (bagObject.maakTabel()) # Print end time Log.log.time("End") elif args.extract: from bagfilereader import BAGFileReader from bagobject import VerblijfsObjectPand, AdresseerbaarObjectNevenAdres, VerblijfsObjectGebruiksdoel, Woonplaats, OpenbareRuimte, Nummeraanduiding, Ligplaats, Standplaats, Verblijfsobject, Pand # Print start time Log.log.time("Start") # Extracts any data from any source files/dirs/zips/xml/csv etc Database().log_actie('start_extract', args.extract) myreader = BAGFileReader(args.extract) myreader.process() Database().log_actie('stop_extract', args.extract) # Print end time Log.log.time("End") elif args.query: # Print start time Log.log.time("Start") # Voer willekeurig SQL script uit uit Database().log_actie('start_query', args.query) database = Database() database.file_uitvoeren(args.query) Database().log_actie('stop_query', args.query) # Print end time Log.log.time("End") else: parser.error("Command line parameters niet herkend") sys.exit()
def main(): """ Voorbeelden: 1. Initialiseer een database: python bagextract.py -H localhost -d bag -U postgres -W postgres -c 2. Importeer een extract in de database: python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011-000002.xml of python bagextract.py -H localhost -d bag -U postgres -W postgres -e 9999STA01052011.zip Importeer gemeente_woonplaats informatie van het kadaster http://www.kadaster.nl/bag/docs/BAG_Overzicht_aangesloten_gemeenten.zip python bagextract.py -H localhost -d bag -U postgres -W postgres -e BAG_Overzicht_aangesloten_gemeenten.zip Theoretisch is het mogelijk de hele bag in te lezen vanuit de "hoofd" zip, maar dit is nog niet getest op geheugen-problemen. """ parser = ArgParser(description='bag-extract, commandline tool voor het extraheren en inlezen van BAG bestanden', epilog="Configureer de database in extract.conf of geef eigen versie van extract.conf via -f of geef parameters via commando regel expliciet op") parser.add_argument('-c', '--dbinit', action='store_true', help='verwijdert (DROP TABLE) alle tabellen en maakt (CREATE TABLE) nieuwe tabellen aan') parser.add_argument('-d', '--database', metavar='<naam>', help='geef naam van de database') parser.add_argument('-s', '--schema', metavar='<naam>', help='geef naam van het database schema') parser.add_argument('-f', '--config', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument('-q', '--query', metavar='<bestand>', help='voer database bewerkingen uit met opgegeven SQL bestand') parser.add_argument('-e', '--extract', metavar='<naam>', help='importeert of muteert de database met gegeven BAG-bestand of -directory') parser.add_argument('-H', '--host', metavar='<hostnaam of -adres>', help='verbind met de database op deze host') parser.add_argument('-U', '--username', metavar='<naam>', help='verbind met database met deze gebruikersnaam') parser.add_argument('-p', '--port', metavar='<poort>', help='verbind met database naar deze poort') parser.add_argument('-W', '--password', metavar='<paswoord>', help='gebruikt dit wachtwoord voor database gebruiker') parser.add_argument('-w', '--no-password', action='store_true', help='gebruik geen wachtwoord voor de database verbinding') parser.add_argument('-v', '--verbose', action='store_true', help='toon uitgebreide informatie tijdens het verwerken') # Initialiseer args = parser.parse_args() # Initialize singleton Log object so we can use one global instance Log(args) # Init globale configuratie BAGConfig(args) # Database database = Database() # Print start time Log.log.time("Start") if args.dbinit: # Dumps all tables and recreates them db_script = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/bag-db.sql') Log.log.info("alle database tabellen weggooien en opnieuw aanmaken...") database.initialiseer(db_script) Log.log.info("Initieele data (bijv. gemeenten/provincies) inlezen...") myreader = BAGFileReader(BAGConfig.config.bagextract_home + '/db/data') myreader.process() Log.log.info("Views aanmaken...") db_script = os.path.realpath(BAGConfig.config.bagextract_home + '/db/script/bag-view-actueel-bestaand.sql') database.file_uitvoeren(db_script) elif args.extract: # Extracts any data from any source files/dirs/zips/xml/csv etc myreader = BAGFileReader(args.extract) myreader.process() elif args.query: # Voer willekeurig SQL script uit uit database = Database() database.file_uitvoeren(args.query) else: Log.log.fatal("je geeft een niet-ondersteunde optie. Tip: probeer -h optie") # Print end time Log.log.time("End") sys.exit()
class BagPreprocessor(): def __init__(self): # All arguments required to be able to run configure configreader parser = ArgParser(description='bag-extract, commandline tool voor het extraheren en inlezen van BAG bestanden', epilog="Configureer de database in extract.conf of geef eigen versie van extract.conf via -f of geef parameters via commando regel expliciet op") parser.add_argument('-f', '--config', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument('-a', '--config2', metavar='<bestand>', help='gebruik dit configuratiebestand i.p.v. extract.conf') parser.add_argument('-c', '--dbinit', action='store_true', help='verwijdert (DROP TABLE) alle tabellen en maakt (CREATE TABLE) nieuwe tabellen aan') parser.add_argument('-d', '--database', metavar='<naam>', help='geef naam van de database') parser.add_argument('-s', '--schema', metavar='<naam>', help='geef naam van het database schema') parser.add_argument('-q', '--query', metavar='<bestand>', help='voer database bewerkingen uit met opgegeven SQL bestand') parser.add_argument('-e', '--extract', metavar='<naam>', help='importeert of muteert de database met gegeven BAG-bestand of -directory') parser.add_argument('-H', '--host', metavar='<hostnaam of -adres>', help='verbind met de database op deze host') parser.add_argument('-U', '--username', metavar='<naam>', help='verbind met database met deze gebruikersnaam') parser.add_argument('-p', '--port', metavar='<poort>', help='verbind met database naar deze poort') parser.add_argument('-W', '--password', metavar='<paswoord>', help='gebruikt dit wachtwoord voor database gebruiker') parser.add_argument('-w', '--no-password', action='store_true', help='gebruik geen wachtwoord voor de database verbinding') parser.add_argument('-v', '--verbose', action='store_true', help='toon uitgebreide informatie tijdens het verwerken') parser.add_argument('-D', '--dbinitcode', action='store_true', help='createert een lijst met statements om het DB script aan te passen') # Initialiseer self.args = parser.parse_args() # Initialize singleton Log object so we can use one global instance Log(self.args) self.database = None def processData(self): self.connectDatabase(True); vbos = self.getVBOs() vboHeightDict = {} vbosIds = [] for vbo in vbos: vbosIds.append(vbo[0]) vboHeightDict[vbo[0]] = vbo[1] buildingVBOs = self.getVBOPandenByIdentificationList(vbosIds) buildingIds = [] totalAreaDict = {} for vboBuilding in buildingVBOs: if totalAreaDict.has_key(vboBuilding[1]): totalAreaDict[vboBuilding[1]] += vboHeightDict[vboBuilding[0]] else: totalAreaDict[vboBuilding[1]] = vboHeightDict[vboBuilding[0]] buildingIds.append(vboBuilding[1]) buildings = self.getPandenByIdentificationList(buildingIds); buildingObjectList = [] for building in buildings: gmlBase64String = building[1].encode('base64') buildingObjectList.append(BuildingInfo(building[0], gmlBase64String, building[2], totalAreaDict[building[0]], building[3])) # Write mode creates a new file or overwrites the existing content of the file. # Write mode will _always_ destroy the existing contents of a file. try: # This will create a new file or **overwrite an existing file**. f = open("buildings.xml", "w") try: xml = "<?xml version='1.0' encoding='UTF-8'?>\n"; xml += "<buildings>\n" for building in buildingObjectList: xml += building.toXML() xml += "</buildings>" f.write(xml) # Write a string to a file finally: f.close() except IOError: pass def connectDatabase(self, bag2=False): BAGConfig(self.args, bag2) self.database = Database() self.database.verbind() def getVBOs(self): sql = "Select identificatie, oppervlakteverblijfsobject " \ "FROM verblijfsObject" return self.database.selectQuery(sql) def getVBOPandenByIdentificationList(self, idsVBO): sql = "Select identificatie, gerelateerdpand " \ "FROM verblijfsobjectpandactueel " \ "WHERE identificatie IN %s" return self.database.selectQuery(sql, [tuple(idsVBO)]) def getPandenByIdentificationList(self, pandIds): sql = "Select identificatie, st_asgml(geovlak), st_area(geovlak), st_npoints(geovlak) " \ "FROM pand " \ "WHERE identificatie IN %s" return self.database.selectQuery(sql, [tuple(pandIds)])
def connectDatabase(self, bag2=False): BAGConfig(self.args, bag2) self.database = Database() self.database.verbind()