Wikipedia:WikiProjekt Österreich/Checkliste bei Gebietsreformen/Wikidata

Diese Seite beschreibt den bisherigen Erfahrungsstand zu den notwendigen Änderungen auf WD im Zuge von Gebietsreformen (Gemeinde-, Bezirksebene), vornehmlich in Österreich. Die Umsetzung erfolgt halbautomatisch wie hier beschrieben.

Auf WD werden die Daten mithilfe der Properties P580 und P582 historisiert. Am Beispiel der GKZ heißt das, dass die alte GKZ in einer Gemeinde mit dem Endedatum der letzten Gültigkeit versehen wird und die neue GKZ mit dem Startdatum der ersten neuen Gütigkeit zusätzlich eingetragen wird. Alte Daten werden also nicht gelöscht oder geändert, sondern bleiben historisiert erhalten. Durch die Historisierung ist es möglich, die Änderung auf WD bereits vor dem Gültigwerden der administrativen Änderung durchzuführen.

Die Beispiele hier beziehen sich auf die Auflösung des Bezirks Wien-Umgebung und müssen für neue Aufgaben angepasst werden.

Properties Bearbeiten

Dies betrifft die folgenden Properties:

Übersicht Bearbeiten

Der Prozess besteht aus den folgenden Schritten, die auch mehrfach ausgeführt werden können, da die verwendeten Tools bereits existierende Properties nicht ändern.

  1. Manuelle Definition der Quelle in WD, etwa: Statistik Austria: Auflösung des Politischen Bezirks Wien-Umgebung mit 1.1.2017 (Q27906384)
  2. Manuelle Zusammenstellung der Daten wie in passender amtlicher Quelle vorgegeben
  3. Scriptbasierte Erzeugung der Kommandos für das WD-Tool quick_statements mittels python (z.B. mit paws)
  4. Ausführung der Kommandos in quick_statements (copy paste aus dem Ergebnis des Python-Scripts)
  5. Manuelle Kontrolle und Nacharbeit

Implementierung Bearbeiten

Inputdaten Bearbeiten

  • municipality: Lemma
  • WP article: Artikel, wird aktuell nicht verwendet
municipality	WP article	GKZ old	GKZ new	district old	district new
Ebergassing		32401	30729	Bezirk Wien-Umgebung	Bezirk Bruck an der Leitha
Fischamend		32402	30730	Bezirk Wien-Umgebung	Bezirk Bruck an der Leitha
Gablitz		32403	31949	Bezirk Wien-Umgebung	Bezirk St. Pölten-Land
Gerasdorf bei Wien		32404	31235	Bezirk Wien-Umgebung	Bezirk Korneuburg
Gramatneusiedl		32405	30731	Bezirk Wien-Umgebung	Bezirk Bruck an der Leitha
Himberg		32406	30732	Bezirk Wien-Umgebung	Bezirk Bruck an der Leitha
Klein-Neusiedl		32407	30733	Bezirk Wien-Umgebung	Bezirk Bruck an der Leitha
Klosterneuburg		32408	32144	Bezirk Wien-Umgebung	Bezirk Tulln
Lanzendorf (Niederösterreich)		32409	30734	Bezirk Wien-Umgebung	Bezirk Bruck an der Leitha
…

python script Bearbeiten

Anzupassen sind die folgenden Variablen:

  • dataRef
  • requestedChangesInputCSV
  • dueDate
# ----------
# TODO
# whenever acessing WD, get the valid snak for, it there are multiple snaks with different start & end dates
# Setting an end date seems not to work, if there is already a source set (different from the one passing)
# WA: retrieve the source and use it again to simulate identical values
# change the Kfz when moving municipalities to different districts
# is using quick_statements smart enough?
# ----------

# This script creates the imput for https://tools.wmflabs.org/wikidata-todo/quick_statements.php
# to change administrative structure as defined by legal changes in Austria
#
# the script creates commands for municipalites and districts to reflect the legal change in WD
# * for each municipality:
# ** assigns new GKZs (Gemeindekennziffer, P964) by due date and terminates the old GKZ
# ** assigns municipality objects a new parent administrative unit, i.e. district (P131) with the due date
#    and terminates the old municipality assignment
# ** change the Kfz-Kennzeichen from the old district's to the new district's
# ** for the old district terminate the municipality assignment by due date -1 (P150)
# ** for the new district create a municipality assignment by due date (P150)
#

# preconditions:
# * the target district must exist in WD (create manually if the district is new)
# * the source district, if it ceases to exist, has to be terminated manually
# * municipalities are identified by their articles on the German WP
# * define the data reference for the changes as a WD object manually. This is the source for all the changes needed
#   see https://www.wikidata.org/wiki/Q27906384 as an example
#
dataRef = "Q27906384"

import pywikibot
import re
import math
import time
import csv
from datetime import date, datetime, timedelta
from enum import Enum
from pywikibot import pagegenerators, data

# define the data
# due date
dueDate = datetime(2017,1,1)
termDate = dueDate-timedelta(days=1)

# input data as tab separated csv entries with heading in first row
# see data/WU-change.csv as the primary example
# heading:
# municipality	WP article	GKZ old	GKZ new	district old	district new
requestedChangesInputCSV = "data/WU-change.csv"

dewiki   = pywikibot.Site('de')
wikidata = pywikibot.Site('wikidata', fam='wikidata')
repo     = wikidata.data_repository()

# WD properties
P_Gemeindekennziffer = "P964" # Gemeindekennziffer in Österreich
P_Untereinheit = "P150" # Untereinheit (administrative Einheit)
P_Verwaltungseinheit = "P131" # liegt in der Verwaltungseinheit
P_KfzKennzeichen = "P395" # Kfz-Kennzeichen; data not complete, skip this
P_Startzeitpunkt = "P580"# Qualifier Startzeitpunkt
P_Endezeitpunkt = "P582" # Qualifier Endezeitpunkt
S_nachgewiesenIn = "S248" # nachgewiesen in

# the main data structure, read from csv file and augmented from various sources
requestedChanges = []
with open(requestedChangesInputCSV, 'r') as csvfile:
    reader = csv.DictReader(csvfile, delimiter='\t', quotechar='"')
    for row in reader:
        requestedChanges.append(row)

# as a performance optimization extract all the discticts and get information only once
districts = {} # a set of k=name, v={Q id, Kfz}
for r in requestedChanges:
    districts[r['district old']]={}
    districts[r['district new']]={}
#print (districts)

allObjectsFound = True # we will not continue otherwise
# get the WD Q ids for all the districts involved
for pageName in districts.keys():
    page = pywikibot.Page(dewiki, pageName) # get page

    if page.exists():
        if page.isDisambig():
            print ("*** %s is disambiguation" % page.title())
            allObjectsFound = False
            continue

        if page.isRedirectPage():
            print (">>> %s is redirect" % page.title())
            page = page.getRedirectTarget()

        item = pywikibot.ItemPage.fromPage(page)
        print (">>> %s: %s" % (page.title(),item.title()))
        districts[pageName]={'Qid':item.title()}
        item.get()
        if item.claims and P_KfzKennzeichen in item.claims:
            for v in item.claims[P_KfzKennzeichen]:
                districts[pageName]['Kfz']=v.target
    else:
        print ("*** %s not found" % page.title())
        allObjectsFound = False

#print (districts)

# get the WD Q ids for all the municipalities involved
for r in requestedChanges:
    pageName = r['municipality']
    page = pywikibot.Page(dewiki, pageName) # get page
    if page.exists():
        if page.isDisambig():
            print ("*** %s is disambiguation" % page.title())
            allObjectsFound = False
            continue

        if page.isRedirectPage():
            print (">>> %s is redirect" % page.title())
            page = page.getRedirectTarget()

        item = pywikibot.ItemPage.fromPage(page)
        print (">>> %s: %s" % (page.title(),item.title()))
        r['Qid'] = item.title()
    else:
        print ("*** %s not found" % page.title())
        allObjectsFound = False

#print (requestedChanges)

assert (allObjectsFound)

# +1967-01-17T00:00:00Z/11 # WD format, precision 1 day
dueDateFormatted = dueDate.strftime(r"+%Y-%m-%dT00:00:00Z/11")
termDateFormatted = termDate.strftime(r"+%Y-%m-%dT00:00:00Z/11")

# create data for quick_statements
print ("\nCommands for https://tools.wmflabs.org/wikidata-todo/quick_statements.php\n\n")
# Q4115189 TAB P31 TAB Q1 TAB P580 TAB +1840-01-01T00:00:00Z/09 TAB S143 TAB Q48183
for r in requestedChanges:
    # new GKZ
    print ("%s\t%s\t\"%s\"\t%s\t%s\t%s\t%s" % (r['Qid'], P_Gemeindekennziffer, r['GKZ new'],
                                               P_Startzeitpunkt, dueDateFormatted,
                                               S_nachgewiesenIn, dataRef
                                              ))
    # terminate old GKZ
    print ("%s\t%s\t\"%s\"\t%s\t%s\t%s\t%s" % (r['Qid'], P_Gemeindekennziffer, r['GKZ old'],
                                               P_Endezeitpunkt, termDateFormatted,
                                               S_nachgewiesenIn, dataRef
                                              ))

# ** assigns municipality objects a new parent administrative unit, i.e. district (P131) with the due date
#    and terminates the old municipality assignment
    print ("%s\t%s\t%s\t%s\t%s\t%s\t%s" % (r['Qid'], P_Verwaltungseinheit, districts[r['district old']]['Qid'],
                                               P_Endezeitpunkt, termDateFormatted,
                                               S_nachgewiesenIn, dataRef
                                              ))
    print ("%s\t%s\t%s\t%s\t%s\t%s\t%s" % (r['Qid'], P_Verwaltungseinheit, districts[r['district new']]['Qid'],
                                               P_Startzeitpunkt, dueDateFormatted,
                                               S_nachgewiesenIn, dataRef
                                              ))
    print ("%s\t%s\t%s\t%s\t%s\t%s\t%s" % (districts[r['district old']]['Qid'], P_Untereinheit, r['Qid'],
                                               P_Endezeitpunkt, termDateFormatted,
                                               S_nachgewiesenIn, dataRef
                                              ))
    print ("%s\t%s\t%s\t%s\t%s\t%s\t%s" % (districts[r['district new']]['Qid'], P_Untereinheit, r['Qid'],
                                               P_Startzeitpunkt, dueDateFormatted,
                                               S_nachgewiesenIn, dataRef
                                              ))


    print ("\n")

print ("\nfinished")

Das ergibt für eine Gemeinde (hier Ebergassing (Q674130)), die mit 1.1.2017 den Bezirk ändert und eine neue GKZ bekommt, folgende quick_statements Kommandos:

Q674130	P964	"30729"	P580	+2017-01-01T00:00:00Z/11	S248	Q27906384
Q674130	P964	"32401"	P582	+2016-12-31T00:00:00Z/11	S248	Q27906384
Q674130	P131	Q521869	P582	+2016-12-31T00:00:00Z/11	S248	Q27906384
Q674130	P131	Q584543	P580	+2017-01-01T00:00:00Z/11	S248	Q27906384
Q521869	P150	Q674130	P582	+2016-12-31T00:00:00Z/11	S248	Q27906384
Q584543	P150	Q674130	P580	+2017-01-01T00:00:00Z/11	S248	Q27906384

Das Ergebnis ist die folgende Änderung in WD: wikidata.org