[PYTHON] Deshalb kann ich von meinem aktuellen Standort aus nach kleinen Wahlkreisen suchen

Ein Jahr nach Aufhebung des Verbots von Online-Wahlen wurde die Online-Übermittlung offizieller Parteibeamter zu einem extremen Spiel, das den SAN-Wert von Unterstützern wie ein Bonito weiter senkt. Wie geht es Ihnen heute? Lassen Sie uns nun darüber nachdenken, wie Sie Informationen über den kleinen Wahlkreis von Ihrem aktuellen Standort erhalten.

Ergebnis

http://needtec.sakura.ne.jp/analyze_election/page/ElectionArea/shuin_47

Auf dieser Seite können Sie Kandidaten für kleine Wahlkreise anzeigen, indem Sie eine Präfektur auswählen oder Ihren aktuellen Standort ermitteln. Durch Auswahl eines kleinen Wahlkreises werden außerdem der ungefähre Standort des Wahlkreises und eine Liste der Kandidaten angezeigt.

Quellcode

https://github.com/mima3/analyze_election

Abhängige Bibliotheken lxml-3.4.0-py2.7-freebsd-9.1-RELEASE-p15-amd64.egg rdp-0.5-py2.7.egg numpy-1.9.1-py2.7-freebsd-9.1-RELEASE-p15-amd64.egg sympy-0.7.5-py2.7.egg Beaker-1.6.4-py2.7.egg

Sympy funktioniert nur mit 0.7.5

Nutzungsdaten

** Nationale Landnummerninformationen Verwaltungsgebietsdaten ** http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03.html

** Wahlbezirk der Mitglieder des Repräsentantenhauses kleiner Wahlbezirk (nach Präfektur) ** http://www.soumu.go.jp/senkyo/senkyo_s/news/senkyo/shu_kuwari/

Daten, die durch manuelles Konvertieren der oben genannten Daten in CSV erhalten wurden https://github.com/mima3/analyze_election/blob/master/election_area.csv

** Asahi Shimbun Digital> Wahl zum Repräsentantenhaus 2014> Kandidat ** http://www.asahi.com/senkyo/sousenkyo47/kouho/

Daten von oben in CSV konvertiert https://github.com/mima3/analyze_election/blob/master/script/candidate_shuin_47.csv

Datenerstellungsverfahren

#Datenbank erstellen
python create_db.py election.sqlite

#Nationale Landnummerninformationen Import von Verwaltungsgebietsdaten Es wird in wenigen Stunden abgeschlossen sein!
python import_administrative_boundary.py election.sqlite area\N03-14_140401.xml

#Konvertieren von Verwaltungsbereichsdaten in Sympy-Polygon Es dauert ungefähr 24 Stunden!
python convert_poly.py election.sqlite

#Registrieren Sie Informationen zu kleinen Wahlkreisen
python import_election_area.py election.sqlite election_area.csv

#Registrieren Sie Kandidateninformationen für kleine Wahlkreise
python import_candidate.py election.sqlite shuin_47 script\candidate_shuin_47.csv
 

Kommentar

Verwaltungsbereichsdaten

Verwaltungsbereichsdaten werden in XML für nationale numerische Landinformationen bereitgestellt. Wenn Sie dies verwenden, können Sie die Verwaltungsbezirksabteilung auf Google Map anzeigen. Da diese Daten jedoch enorm sind, müssen beim Umgang mit ihnen einige Vorsichtsmaßnahmen getroffen werden.

Analysieren Sie großes XML

Wenn Sie beim Parsen einer großen XML-Datei die XML-Datei in Zeichen konvertieren und analysieren, steigt die Speichernutzung dramatisch an und Sie können sie nicht verarbeiten.

Verwenden Sie daher lxml.etree.iterparse, um nacheinander zu verarbeiten. Lassen Sie uns die tatsächliche Verarbeitung sehen.

election_db.py


    def ImportAdministrativeBoundary(self, xml):
        f = None
        contents = None
        namespaces = {
            'ksj': 'http://nlftp.mlit.go.jp/ksj/schemas/ksj-app',
            'gml': 'http://www.opengis.net/gml/3.2',
            'xlink': 'http://www.w3.org/1999/xlink',
            'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
        }
        self._conn.execute('begin')

        print ('admins....')
        context = etree.iterparse(xml, events=('end',), tag='{http://nlftp.mlit.go.jp/ksj/schemas/ksj-app}AdministrativeBoundary')
        for event, admin in context:
            adminId = admin.get('{http://www.opengis.net/gml/3.2}id')
            print (adminId)
            bounds = admin.find('ksj:bounds', namespaces=namespaces).get('{http://www.w3.org/1999/xlink}href')[1:]
            prefectureName = admin.find('ksj:prefectureName', namespaces=namespaces).text
            subPrefectureName = admin.find('ksj:subPrefectureName', namespaces=namespaces).text
            countyName = admin.find('ksj:countyName', namespaces=namespaces).text
            cityName = admin.find('ksj:cityName', namespaces=namespaces).text
            areaCode = admin.find('ksj:administrativeAreaCode', namespaces=namespaces).text
            sql = '''INSERT INTO administrative_boundary
                     (gml_id, bounds, prefecture_name, sub_prefecture_name, county_name, city_name, area_code)
                     VALUES(?, ?, ?, ?, ?, ?, ?);'''
            self._conn.execute(sql, [adminId, bounds, prefectureName, subPrefectureName, countyName, cityName, areaCode ])

            admin.clear()
            # Also eliminate now-empty references from the root node to <Title> 
            while admin.getprevious() is not None:
                del admin.getparent()[0]
        del context

Der obige Code ist Teil des Prozesses, der die nationalen Landnummerninformationen analysiert und in der DB speichert. In diesem Beispiel wird etree.iterparse verwendet, um jedes Mal zu verarbeiten, wenn das Tag "Administrative Grenze" erkannt wird.

Weitere Informationen finden Sie auf der folgenden Seite. ** Verwenden Sie lxml für eine leistungsstarke XML-Syntaxanalyse in Python ** http://www.ibm.com/developerworks/jp/xml/library/x-hiperfparse/

Koordinateninformationen ausdünnen

Die nationalen numerischen Landdaten sind groß, da sie genaue Koordinateninformationen speichern. Dieses Mal müssen wir nur die groben Koordinaten kennen, damit wir diese Informationen ausdünnen können.

Es gibt einen Algorithmus namens Ramer-Douglas-Peucker als Algorithmus zum Ausdünnen von Linien. Auf der folgenden Seite finden Sie eine Beschreibung dieses Algorithmus.

** [Mathematica] verdünne die Faltlinie ** http://www.330k.info/essay/oresenwomabiku

Das Folgende ist als Modul des Ramer-Douglas-Peucker-Algorithmus von Python verfügbar. https://pypi.python.org/pypi/rdp

Informationsregistrierung für kleine Wahlkreise

Wie üblich veröffentlicht das Ministerium für innere Angelegenheiten und Kommunikation Informationen zu kleinen Wahlkreisen nur im PDF-Format. Sie müssen also Ihr Bestes geben, um es manuell einzugeben oder eine andere Methode auszuprobieren.

Auch die Informationen zu den kleinen Wahlkreisen sind überraschend unscharf. Nehmen Sie zum Beispiel die erste und zweite Abteilung der Präfektur Iwate. http://www.soumu.go.jp/main_content/000240041.pdf

  1. Bezirk Morioka City (Hauptbüro Zuständigkeit, Morioka City Hall Aoyama Zweiggerichtsbarkeit, Morioka City Hall Yanagawa Zweigstelle Gerichtsbarkeit, Morioka City Hall Ota Zweigstelle Gerichtsbarkeit, Morioka City Hall Zweigstelle Gerichtsbarkeit, Morioka City Tonan General Branch Gerichtsbarkeit)

Zweiter Bezirk Morioka Stadt (Bereich, der nicht zum ersten Bezirk gehört)

Es gibt. Selbstverständlich werden hier keine Informationen darüber gegeben, wo die Zuständigkeit des Hauptbüros vertreten ist. Daher werden diesmal im Fall von Morioka City die erste und die zweite Gemeinde als Kandidaten für den kleinen Wahlbezirk aufgeführt.

Die CSV, die erstellt wurde, als das Ministerium für innere Angelegenheiten und Kommunikation verflucht wurde und die nachdrücklich die Absicht hat, Daten nicht auf diese Weise zu analysieren, lautet wie folgt. https://github.com/mima3/analyze_election/blob/master/election_area.csv

Da ich hier so beeindruckt war, ziehe ich auch Informationen über Kandidaten aus dem Asahi Shimbun. Das folgende Skript entfernt diese Art von Daten, daher verwende ich sie bei Bedarf von Hand.

https://github.com/mima3/analyze_election/blob/master/script/analyze_asahi.py

Holen Sie sich einen kleinen Wahlkreis von Ihrem aktuellen Standort.

Holen Sie sich Ihren aktuellen Standort in Ihren Browser.

Verwenden Sie navigator.geolocation, um Ihren aktuellen Standort in Ihrem Browser zu verwenden. Sie können den Längen- und Breitengrad mit dem folgenden Code ermitteln.

if (!navigator.geolocation) {
  //Verarbeitung für Umgebungen, in denen die Geolocation-API nicht verwendet werden kann
  alert('Die Geolocate-API ist nicht verfügbar');
}
navigator.geolocation.getCurrentPosition(function(position) {
  console.log(position)
}

Im Fall von IE ist die aktuelle Position stark verschoben. Dies liegt wahrscheinlich daran, dass die von Microsoft verwendete Standortnutzungsdatenbank weniger genau ist als die von Chrome und Firefox verwendete Standortinformationsdatenbank. (Ich bin nicht schlecht! Ich bin nicht schlecht!) https://social.technet.microsoft.com/Forums/ie/en-US/aea4db4e-0720-44fe-a9b8-09917e345080/geolocation-wrong-in-ie9-but-not-other-browsers

Finden Sie heraus, ob eine bestimmte Koordinate im Verwaltungsbereich enthalten ist.

Das Herausfinden, ob eine bestimmte Koordinate in einem Verwaltungsbereich enthalten ist, hat dieselbe Bedeutung wie das Überprüfen, ob ein Punkt in einem Polygon enthalten ist. Im Fall von Python ist es gut für ** basic **, wenn Sie SymPy verwenden, um das Innere und Äußere des Punktes zu beurteilen.

** [Python] Verwenden Sie SymPy, um innerhalb und außerhalb von Punkten zu beurteilen ** http://d.hatena.ne.jp/factal/20121013

Grundsätzlich habe ich das gesagt, weil dieser Prozess so langsam ist. Es würde zu viel Zeit in Anspruch nehmen, nacheinander an Zehntausenden von Verwaltungsbezirken zu arbeiten.

Aus diesem Grund haben wir hier zwei Maßnahmen ergriffen.

Grenzen Sie zunächst die Anzahl der Zielpolygone ein, bevor Sie einen Punkt innerhalb / außerhalb des Urteils treffen. Dies wird nur gesucht, wenn der Abstand zwischen den Eckpunkten des Polygons und dem angegebenen Punkt innerhalb eines bestimmten Bereichs liegt.

Insbesondere lautet der Code wie folgt.

election_db.py


    def GetPos(self, lat, long):
        """
Abrufen von Kurvendaten zum aktuellen Längen- und Breitengrad
        """
        m =0.005
        while 1:
            rows = self._getCurveId(lat, long, m).fetchall()
            if rows:
              break
            m = m * 2
            if m > 0.1:
              return None

        dict = {}
        pt = Point(lat, long)

        for r in rows:
            key = r[0]
            ret = self._isCrossCurveId(pt, key)
            if ret:
                return ret
        return None

Die zweite besteht darin, ein Polygon-Objekt im Voraus zu erstellen und es in der Datenbank zu registrieren. Insbesondere ist die Implementierung wie folgt.

    def ConvertPoly(self):
        """
Erstellen eines Polygons aus der Kurventabelle
        """
        #gc.enable()
        #gc.set_debug(gc.DEBUG_LEAK)
        sql = '''DELETE FROM polygon'''
        self._conn.execute(sql)

        sql = '''select curve_id,lat,lng from curve order by curve_id'''
        rows = self._conn.execute(sql)
        dict = {}
        for r in rows:
            key = r[0]
            if dict.get(key) is None:
                dict[key] = []
            dict[key].append((r[1], r[2]))
        i = 0
        self.Commit()

        self._conn.execute('begin')
        for key in dict:
            print (key + ":" + str(i))
            #b = len(gc.get_objects())
            self._createPoly(key, dict[key])
            i = i + 1
            #gc.collect()
            #print str(b) + ":" + str(len(gc.get_objects()))
            if i % 100 == 0:
                clear_cache()
                self.Commit()

    def _createPoly(self, key, list):
        poly = Polygon(*list)
        obj = pickle.dumps(poly)
        sql = '''INSERT INTO polygon
                       (curve_id, object)
                     VALUES(?, ?);'''
        self._conn.execute(sql, [key, obj ])
        del poly
        del obj

Verwenden Sie pickle.dumps, um das Objekt zu serialisieren. Da Sympy einen Caching-Mechanismus verwendet, verbraucht das Erstellen einer großen Anzahl von Objekten schnell mehrere GByte Speicher. Um dies zu vermeiden, wird zum Erstellen von 100 clear_chache verwendet, um den Cache zu löschen.

Außerdem gelten die Bedingungen für die Ausgabe einer Ausnahme "Polygon hat sich überschneidende Seiten". In der neuesten Sympathie unterscheiden sich Polygon zwischen 0,7,5 und 0,7,6. Die Bedingungen sind in 0.7.6 strenger und diese Daten können nicht normal erstellt werden. Verwenden Sie daher 0.7.5 für Sympy.

Recommended Posts

Deshalb kann ich von meinem aktuellen Standort aus nach kleinen Wahlkreisen suchen
Alles für Anfänger, um maschinelles Lernen zu können