Skip to content
Snippets Groups Projects
Commit 181bcbb4 authored by Maximilian Loch's avatar Maximilian Loch
Browse files

added python scripts from first demo

parent 61487f38
Branches
No related tags found
No related merge requests found
# script zum updaten der adressdaten anhand der existierenden URI
from script_helper import DBTools, APITools
from configparser import ConfigParser
if __name__ == '__main__':
print("updating dataset with adresses from areg by URI")
# datenbank mit den schuldaten
conn_config = ConfigParser()
conn_config.read("db_conn.cfg")
conn_str = f"host={conn_config['connection']['host']} port={conn_config['connection']['port']} dbname={conn_config['connection']['dbname']} user={conn_config['connection']['user']} password={conn_config['connection']['pwd']}"
url = r"https://chat.gdi-sh.de/aregapi/"
my_db = DBTools(conn_str)
my_api = APITools(url)
schulen = my_db.select_uri()
lenschule = len(schulen)
i = 1
for item in schulen:
print(str(i) + "/" + str(lenschule))
if item[0] is not None:
adresse = my_api.findadresse(item[0])
my_db.update_adress(adresse, item[0])
else:
print("hat keine URI")
i += 1
my_db.closecursor()
print("update finished closing programm")
# script zum geocoden der schulen und zuweisen der URI aus dem AREG
from script_helper import DBTools, APITools
from configparser import ConfigParser
if __name__ == '__main__':
print("geocoding dataset now")
# datenbank mit den schuldaten
conn_config = ConfigParser()
conn_config.read("db_conn.cfg")
conn_str = f"host={conn_config['connection']['host']} port={conn_config['connection']['port']} dbname={conn_config['connection']['dbname']} user={conn_config['connection']['user']} password={conn_config['connection']['pwd']}"
url = r"https://chat.gdi-sh.de/aregapi/"
# logfile = r"geocoder.log"
my_db = DBTools(conn_str)
my_api = APITools(url)
schulen = my_db.select_adress()
adresse = {}
maxfeatures = len(schulen)
numfeatures = 0
errorfeatures = 0
missinfeatures = 0
log = []
for item in schulen:
adresse["hnr"] = item[1]
adresse["stn"] = item[2]
adresse["plz"] = item[3]
adresse["ort"] = item[4]
areg_response = my_api.geocode(adresse)
if areg_response.get("uri") is not None:
areg_uri = areg_response.get("uri")
my_db.update_uri(str(item[0]), areg_uri)
numfeatures += 1
else:
areg_response_key = list(areg_response.keys())
if areg_response_key[0] == "MISSING":
missinfeatures += 1
if areg_response_key[0] == "ERROR":
errorfeatures += 1
# log.append(areg_response_key[0] + ": " + areg_response.get(areg_response_key[0]) + f" | betroffene schule: {adresse['hnr']}\t{adresse['stn']}\t{adresse['plz']}\t{adresse['ort']}")
print(areg_response_key[0] + ": " + areg_response.get(areg_response_key[0]) + f" | betroffene schule: [{item[0]}]\t{adresse['hnr']}; {adresse['stn']}; {adresse['plz']}; {adresse['ort']}")
my_db.closecursor()
# sorgt auf dem cloudserver fuer fehler wegen permission
# with open(logfile, "w", encoding='utf-8') as out:
# for item in log:
# out.write(item)
percentage = round((numfeatures * 100) / maxfeatures, 2)
print(f"\nstatistics:\n {numfeatures} from {maxfeatures} geocoded >> {percentage}%\n {missinfeatures} features with missing attributes\n {errorfeatures} features with errors\n")
print("geocoding dataset finished, closing programm")
# helferscript mit klassen für den URI und adressen update
# schuldatenbank heißt in der DB "schulen"
import requests
import psycopg2
import json
class DBTools:
"""
Tools für das arbeiten mit der Datenbank, hier sind die select Funktionen zum
auslesen der Daten und zum updaten der Daten mit den Adressen.
"""
def __init__(self, data):
"""
Aufbauen der Verbindung zu der Datenbank
:param str data: Connection String mit allen Informationen für die Verbindung zur Datenbank
"""
self.db_connection = psycopg2.connect(data)
self.cursor = self.db_connection.cursor()
def select_adress(self):
"""
Funktion zum selektieren der Adressdaten der Schulen um diese zu geocoden und ihnen URI aus dem AREG zuzuweisen.
:return: Tupel mit alten Adressdaten der Schulen
:rtype: tuple
"""
self.cursor.execute("select lokaleID, adressealt_hnr, adressealt_strasse, adressealt_plz, adressealt_ort from prototyp_areg.schulen;")
query_result = self.cursor.fetchall()
return query_result
def select_uri(self):
"""
Funktion zum selektieren der URI aus dem Datensatz um diese mit aktuellen AREG Adressen anzureichern.
:return: Tupel mit den AREG URI die in der Datenbank vorhanden sind, Safeguard ist vorhanden damit keine NULL Werte kommen.
:rtype: tuple
"""
self.cursor.execute("select distinct(areg_uri) from prototyp_areg.schulen where areg_uri like 'https://%';")
query_data = self.cursor.fetchall()
return query_data
def update_uri(self, param_dbid: str, param_uri: str):
"""
Funktion zum Update der Datenbank mit den URI aus dem Geocoder.
:param str param_dbid: ID der Schule aus der Datenbank (nicht AREG URI)
:param str param_uri: AREG URI
"""
self.cursor.execute("alter table prototyp_areg.schulen add column if not exists areg_uri varchar;")
self.cursor.execute(f"update prototyp_areg.schulen set areg_uri='{param_uri}' where lokaleID='{param_dbid}';")
def update_adress(self, data, param_uri):
"""
Funktion zum Update der Datenbank mit den neuen Adressdaten aus dem AREG anhand der URI.
:param dict data: GeoJSON aus der AREG API mit den aktuellen Adressdaten
:param param_uri: AREG URI zum zuordnen der Adressdaten
"""
geometry = str(data['geometry'])
geometry = geometry.replace("'", '"')
self.cursor.execute("alter table prototyp_areg.schulen add column if not exists hnr varchar, add column if not exists strasse varchar, add column if not exists plz varchar, add column if not exists ort varchar, add column if not exists geom geometry(Point, 4326);")
self.cursor.execute(f"update prototyp_areg.schulen set hnr='{data['properties']['hnr']}' where areg_uri='{param_uri}'")
self.cursor.execute(f"update prototyp_areg.schulen set strasse='{data['properties']['stn']}' where areg_uri='{param_uri}'")
self.cursor.execute(f"update prototyp_areg.schulen set plz='{data['properties']['plz']}' where areg_uri='{param_uri}'")
self.cursor.execute(f"update prototyp_areg.schulen set ort='{data['properties']['ort']}' where areg_uri='{param_uri}'")
self.cursor.execute(f"update prototyp_areg.schulen set geom=ST_GeomFromGeoJSON('{geometry}') where areg_uri='{param_uri}'")
def closecursor(self):
"""
Funktion zum Commit und Schießen der Datenbankverbindung nachdem alle Änderungen vorgenommen wurden.
"""
# schließt den cursor
self.db_connection.commit()
self.cursor.close()
self.db_connection.close()
class APITools:
"""
Tools für das Arbeiten mit der pygeoAPI.
Hier sind die Funktionen zum aufrufen des Geocoder Prozesses und zum Finden der Adresse anhand der URI
"""
def __init__(self, param_url):
"""
Festlegen der Base URL der API für die weitere Verwendung in den Funktionen der Klasse.
:param str param_url: Base URL der API
"""
self.base_url = param_url
def geocode(self, data: dict):
"""
Funktion zum Aufrufen des Geocoder Prozesses in der API. Bereinigung finden nicht in dieser Funktion oder diesem Skript sondern im Geocoder statt!
:param data: Dictionary mit den alten Adressdaten
:type: dict
:return: Dictionary entweder mit einem "uri" Objekt oder einem "message" Objekt, wenn uri kommt ist alles gut, wenn message kommt dann ist ein fehler aufgetreten
:rtype: dict
"""
url = self.base_url + r"processes/geocoder/execution"
result = {"message": "you should not see this"}
request_body = {
"inputs": {
"hnr": data["hnr"],
"ort": data["ort"],
"plz": data["plz"],
"stn": data["stn"],
"uri": True
}
}
try:
api_result = requests.post(url, json.dumps(request_body))
api_result.raise_for_status()
result = api_result.json()
except requests.exceptions.ConnectionError as e:
result = {"message": str(e)}
except requests.exceptions.Timeout as e:
result = {"message": str(e)}
except requests.exceptions.HTTPError as e:
result = {"message": str(e)}
return result
def findadresse(self, param_uri):
"""
Funktion zum finden der Adresse im AREG anhand der vergebenen URI.
:param str param_uri: URI des Datensatzes
:return: GeoJSON des jeweiligen Items das der URI entspricht
:rtype: dict
"""
url = param_uri + r"?f=json"
response = requests.get(url)
response_json = response.json()
return response_json
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment