[PYTHON] Erstellen Sie mit QGIS Part 2 ein tky2jgd-Plug-In ohne praktische Anwendbarkeit

Dieses Thema

Teil 1 Wenn Sie auf die Schaltfläche im Plug-In klicken Ich habe ein Plug-In erstellt, mit dem die Koordinaten der EPSG: 4301-Multipolygon-Ebene in EPSG: 4612 konvertiert werden können.

Es ist jedoch nur für Multi-Polygon-Ebenen nutzlos. Da es keine Schichten im ebenen orthogonalen Koordinatensystem unterstützt Dieses Mal möchte ich diesen Bereich stärken und etwas praktischer gestalten.

・ Alle Geometrietypen können konvertiert werden ・ Kann unabhängig von Breite / Länge und Ebenenwinkel konvertiert werden Es kann eine Nachkonvertierungsschicht erstellt werden, die den Attributwert erbt. ~~ ・ Sie können mehrere Ebenen auswählen und gleichzeitig konvertieren ~~ ・ Behandeln Sie keine Ausnahmen

Da das Konvertieren mehrerer Ebenen gleichzeitig eine Frage der Benutzeroberfläche ist, habe ich beschlossen, sie zu trennen. Geben wir unser Bestes.

Letzter Zielpunkt

・ Vorwärtskonvertierung (japanisches Geografiesystem → Weltgeografiesystem) Was Sie tun können (fertig) </ font> ・ Kann unabhängig von Breite / Länge und Ebenenwinkel konvertiert werden ・ Alle Geometrietypen können konvertiert werden Es kann eine Nachkonvertierungsschicht erstellt werden, die den Attributwert erbt. ・ Interpolieren Sie den Korrekturwert der Parameterdatei, um die Genauigkeit zu verbessern. * Schwierigkeitsgrad: Mittel ・ Es können mehrere Ebenen gleichzeitig ausgewählt und konvertiert werden ・ Reverse Conversion (Weltvermessungssystem → Japanisches Vermessungssystem) ist ebenfalls möglich. * Schwierigkeitsgrad: Hoch

Fang an zu arbeiten

Wenn Sie die Quelle nicht in Teil 1 erstellt haben, löschen Sie sie aus dem Repository. https://github.com/ozo360/tky2jgd/releases/tag/ddbc2ba

Kompatibel mit allen Geometrietypen

Ich sage nicht, dass es allen entspricht. Der Geometrietyp der Vektorebene, die QGIS verarbeiten kann, ist QgsWkbTypes ::ometryType. Ein anderer Typ ist QgsWkbTypes :: Type.

Das Ziel dieses Plug-Ins ist auf 2D-Daten mit Punkten, Linien und Polygonen beschränkt. Dies sollte die meisten Daten abdecken. Ich weiß nicht, ob es mit Kurven- und Dreiecksdaten richtig konvertiert werden kann, daher werde ich es nach dem Erstellen testen. Wenn es nicht funktioniert, ändern Sie es, um es auszuschließen.

Gehen Sie wie folgt vor, um die Konvertierungsquellenebene wkbType abzurufen und in die URL der neuen Ebene einzubetten. Die Ausnahmeverarbeitung wird nicht ausgeführt, aber ein Zweig ist enthalten, um das Ziel zu begrenzen.

layer = self.iface.activeLayer()
wkbType = layer.wkbType()
#Ziellinienpolygon
if not QgsWkbTypes.geometryType(wkbType) in [
        QgsWkbTypes.PointGeometry, 
        QgsWkbTypes.LineGeometry, 
        QgsWkbTypes.PolygonGeometry]:
    #Nicht zutreffender GeometryType
    self.iface.messageBar().pushMessage("tky2jgd <b>{}</b>".format('activeLayer is out of scope geometryType'), Qgis.Warning)

#Targeting von 2D-Ebenen
if QgsWkbTypes.hasZ(wkbType) or QgsWkbTypes.hasM(wkbType):
    #Nicht zutreffend wkbType
    self.iface.messageBar().pushMessage("tky2jgd <b>{}</b>".format('activeLayer is out of scope wkbType'), Qgis.Warning)

self.wkbType = QgsWkbTypes.displayString(wkbType)

layerUri = self.wkbType +"?crs=postgis:4612"
newlayer = QgsVectorLayer(layerUri, "exchange", "memory")

Ich habe lange gebraucht, weil ich nicht wusste, wie ich die Enum-Zeichenfolge (displayString) erhalten soll, aber ich habe es geschafft, eine Ebene zu erstellen, die dem Geometrietyp der Zielebene entspricht.

Konvertieren Sie unabhängig von Breiten- / Längengrad und Orthogonalität der Ebene

Da das Ziel das japanische geodätische System ist, müssen die folgenden Konvertierungen durchgeführt werden können.

System Konvertierungsquelle SRID SRID des Konvertierungsziels
4301 4612
I 30161 2443
II 30162 2444
III 30163 2445
IV 30164 2446
XVIII 30178 2460
XIX 30179 2461

Außerdem zeigt die Parameterdatei den Korrekturwert in EPSG: 4301. Der rechte Winkel der Ebene muss in Breiten- und Längengrade konvertiert werden, bevor der Korrekturwert verschoben wird. Daher erfolgt die Konvertierung in die Konvertierungsziel-SRID von EPSG: 4301 für jede SRID. Generieren Sie jeweils eine Koordinatenkonvertierungsklasse.

layer = self.iface.activeLayer()
srid = layer.crs().postgisSrid()
if srid == 4301:
    self.isLonlat = True
    self.toSrid = 4612
elif (srid > 30160 and srid < 30180):
    self.isLonlat = False
    self.toSrid = 2442 + srid - 30160
else:
    #Nicht zutreffende SRID
    self.iface.messageBar().pushMessage("tky2jgd <b>{}</b>".format('activeLayer is not Tokyo Datum'), Qgis.Warning)

#Generieren Sie eine Koordinatentransformationsklasse
crs4301 = QgsCoordinateReferenceSystem(4301, QgsCoordinateReferenceSystem.EpsgCrsId)
if not self.isLonlat:
    crsFrom = QgsCoordinateReferenceSystem(fromSrid, QgsCoordinateReferenceSystem.EpsgCrsId)
    self.trans4301 = QgsCoordinateTransform(crsFrom, crs4301, QgsProject.instance())

crsTo = QgsCoordinateReferenceSystem(self.toSrid, QgsCoordinateReferenceSystem.EpsgCrsId)
self.transTo = QgsCoordinateTransform(crs4301, crsTo, QgsProject.instance())

Solange Sie eine Koordinatenkonvertierungsklasse haben und diese zum Zeitpunkt der Konvertierungsverarbeitung orthogonal ist, müssen Sie nur eine Vorverarbeitung durchführen, um sie in Breiten- und Längengrade zu konvertieren.

Attributwert erben

Sie müssen der neuen Ebene eine Spalte hinzufügen, um die Attributwerte zu erben. Kopieren Sie die Spalten von der ursprünglichen Ebene in die neue Ebene.

#Wenn newLayer eine neue Ebene ist
layer = self.iface.activeLayer()
newLayer.dataProvider().addAttributes(layer.fields())

Beim Erstellen eines Features wird der ursprüngliche Attributwert vererbt.

inFeat = QgsFeature()
feats = layer.getFeatures()
while feats.nextFeature( inFeat ):
    attributes = inFeat.attributes()
    geometry = QgsGeometry( inFeat.geometry() )
    #Tatsächlich werden hier die Koordinaten konvertiert
    feature = QgsFeature(fields)
    feature.setAttributes(attributes)
    feature.setGeometry(geometry)
    
    newLayer.addFeature(feature)

Plug-In einbetten

Nachdem jeder Prozess abgeschlossen ist, werden wir ihn in das Plug-In einbetten.

###################################
#Klicken Sie auf die Schaltfläche Prozessstart
###################################
def buttonClicked(self):
    self.layer = self.iface.activeLayer()
    if not self.isScope():
        return

    self.wkbType = QgsWkbTypes.displayString(self.layer.wkbType())

    #Generieren Sie ein Wörterbuch für die Koordinatenkonvertierungsparameter
    self.loadPar()
    #Generieren Sie eine Koordinatentransformationsklasse
    self.setCrsTrans()

    #Umwandlungsprozess
    self.execTrans()
    QMessageBox.information(self.dlg, 'tky2jgd', 'finished')
    
###################################
#Konvertierungsparameterdatei lesen
###################################
def loadPar(self):
    self.par = {}
    parfile = 'TKY2JGD.par'
    with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), parfile)) as f:
        #Überspringen Sie zwei Zeilen in der Kopfzeile
        skip = 2
        for i in range(skip):
            next(f)

        #Zeile für Zeile lesen und in Liste speichern
        while True:
            line = f.readline()
            if not line:
                # EOF
                break
            #Der Wert ist Sekunden, also teilen Sie ihn hier
            self.par[int(line[0:8])] = (float(line[8:18]) / 3600, float(line[18:28]) / 3600)

###################################
#Bestimmen Sie, ob es sich um eine Conversion-Zielebene handelt
#(Übrigens, behalten Sie die srid- und Längen- / Breitengrad-Flags vor und nach der Konvertierung bei.)
###################################
def isScope(self):
    try:
        if not isinstance(self.layer, QgsVectorLayer):
            raise ValueError("activeLayer is not QgsVectorLayer")

        self.srid = self.layer.crs().postgisSrid()
        if self.srid == 4301:
            self.isLonlat = True
            self.toSrid = 4612
        elif (self.srid > 30160 and self.srid < 30180):
            self.isLonlat = False
            self.toSrid = 2442 + self.srid - 30160
        else:
            #Nicht zutreffende SRID
            raise ValueError("activeLayer is not Tokyo Datum")

        wkbType = self.layer.wkbType()
        #Ziellinienpolygon
        if not QgsWkbTypes.geometryType(wkbType) in [
                QgsWkbTypes.PointGeometry, 
                QgsWkbTypes.LineGeometry, 
                QgsWkbTypes.PolygonGeometry]:
            #Nicht zutreffender GeometryType
            raise ValueError("activeLayer is out of scope geometryType")

        #Targeting von 2D-Ebenen
        if QgsWkbTypes.hasZ(wkbType) or QgsWkbTypes.hasM(wkbType):
            #Nicht zutreffend wkbType
            raise ValueError("activeLayer is out of scope wkbType")

    except ValueError as e:
        #Unzutreffend
        self.iface.messageBar().pushMessage("tky2jgd <b>{}</b>".format(e), Qgis.Warning)
        return False
    else:
        #Ziel
        return True

###################################
#Konvertierungsprozess koordinieren
###################################
def execTrans(self):
    #Ebene nach der Konvertierung generieren
    afterLayer = self.createAfterLayer()

    #Beginnen Sie die Bearbeitung
    afterLayer.startEditing()
    fields = afterLayer.fields()

    inFeat = QgsFeature()
    feats = self.layer.getFeatures()
    while feats.nextFeature( inFeat ):
        attributes = inFeat.attributes()
        beforeGeom = QgsGeometry( inFeat.geometry() )
        if not self.isLonlat:
            beforeGeom.transform(self.trans4301)
        afterGeom = self.moveCorrection(beforeGeom)
        if not self.isLonlat:
            afterGeom.transform(self.transTo)

        feature = QgsFeature(fields)
        feature.setAttributes(attributes)
        feature.setGeometry(afterGeom)
        
        afterLayer.addFeature(feature)

    #Ende der Bearbeitung
    afterLayer.commitChanges()
    QgsProject.instance().addMapLayer(afterLayer)

###################################
#Erstellen Sie eine konvertierte Speicherebene
###################################
def createAfterLayer(self):
    layerUri = self.wkbType +"?crs=postgis:" + str(self.toSrid)
    afterLayer = QgsVectorLayer(layerUri, "exchange", "memory")
    afterLayer.dataProvider().addAttributes(self.layer.fields())
    return afterLayer

###################################
#Verschieben des oberen Bereichs eines Features
###################################
def moveCorrection(self, geom):
    for i, v in enumerate(geom.vertices()):
        meshcode = self.Coordinate2MeshCode(v.y(), v.x())
        correction = self.par[meshcode]
        geom.moveVertex(v.x() + correction[1], v.y() + correction[0], i)
    return geom

###################################
#Generieren Sie eine Koordinatentransformationsklasse
###################################
def setCrsTrans(self):
    crs4301 = QgsCoordinateReferenceSystem(4301, QgsCoordinateReferenceSystem.EpsgCrsId)
    if not self.isLonlat:
        crsFrom = QgsCoordinateReferenceSystem(self.srid, QgsCoordinateReferenceSystem.EpsgCrsId)
        self.trans4301 = QgsCoordinateTransform(crsFrom, crs4301, QgsProject.instance())

    crsTo = QgsCoordinateReferenceSystem(self.toSrid, QgsCoordinateReferenceSystem.EpsgCrsId)
    self.transTo = QgsCoordinateTransform(crs4301, crsTo, QgsProject.instance())

Ich habe nicht richtig mit dem Klassendesign angefangen, also war es irgendwie chaotisch. Dieser Bereich wird am Ende in Klassen unterteilt und organisiert, und wir werden dem Umzug zuerst Priorität einräumen. Es ist so langweilig, dass die isScope-Funktion mich sterben lässt.

Überprüfung

Es ist mühsam, Beispieldaten nüchtern zu machen.

Lassen Sie uns überprüfen, ob die von uns erstellten Beispieldaten auch im rechten Winkel zur Ebene konvertiert werden können.

    1. Erstellt eine Linienschicht aus Japan Survey System 16. EPSG: 30176 mit Kratzschicht.
  1. Lesen Sie OSM und kritzeln Sie auf Nishi-Omotesando.
    1. Konvertiert mit dem Plugin tky2jgd.

Die SRID der konvertierten Schicht ist ordnungsgemäß 2458. © OpenStreetMap contributors image.png

  1. In Punkte konvertieren und mit Webversion TKY2JGD --Kokuritsu Ritsuin überprüfen.
Schicht X Y
Vor der Konvertierung -21165 -177520
Nach der Konvertierung -21313 -177066
Webversion TKY2JGD -21315.4052 -177083.9327

Der Fehler in Y-Richtung ist groß, aber wenn die Berechnung falsch ist, sollte dieser Fehler nicht ausreichen. Vielleicht ist er in Ordnung?

Versuchen wir es weiter in Tokio. Gleichzeitig wird der Geometrietyp überprüft.

    1. Erstellen Sie eine Mehrpunktebene mit der Kratzschicht des 9. Systems EPSG: 30169 des Japan Survey System.
  1. Schreiben Sie einen Mehrpunkt in der Nähe der kaiserlichen Residenz.
    1. Konvertiert mit dem Plugin tky2jgd.

Mehrpunktschichten können ebenfalls konvertiert werden, und die SRID dieser Schicht ist 2451. © OpenStreetMap contributors image.png

Schicht X Y
Vor der Konvertierung -6984 -34730
Nach der Konvertierung -7276 -34371
Webversion TKY2JGD -7277.1503 -34374.4408

Ich habe kein schlechtes Gefühl, aber ich schließe die Augen und gehe weiter.

Überprüfen Sie nun, ob die Attribute vererbt wurden Fügen Sie der Speicherebene Zeichen-, Ganzzahl- und Gleitkommaspalten hinzu und fügen Sie dann Features hinzu. Geben wir einen Attributwert an. Wenn die Attribute der konvertierten Ebene angezeigt werden, werden sie ordnungsgemäß beibehalten. image.png

Damit sind alle Funktionen implementiert, die Gegenstand dieser Zeit waren.

Klicken Sie hier für die bisherige Quelle

  • Es gibt jedoch einen großen Fehler https://github.com/ozo360/tky2jgd/releases/tag/sono2

Die Identität der unangenehmen Vorahnung

Versuchen Sie, die konvertierte Ebene in einem Shapefile zu speichern. Das angegebene CRS ist natürlich das der konvertierten Schicht. Wenn ich das gespeicherte Shapefile erneut in QGIS lade, verschiebt es sich. Ich muss in der Nähe der ursprünglichen Ebene fliegen, aber ich komme an den konvertierten Ort. Wenn ich die Koordinaten überprüfe, sind sie wirklich nicht ausgerichtet. Ein Wert, der dem Wert ähnlich ist, der erhalten wird, indem die alten Koordinaten in die neuen Koordinaten konvertiert und dann in die neuen Koordinaten verschoben werden.

Möglicherweise haben Sie den falschen Weg gefunden, um es Ihrem Projekt hinzuzufügen, oder Sie haben zuvor einen grundlegenden Fehler gemacht. Normalerweise denke ich, dass Sie nach der Behebung des Problems posten sollten, aber es ist in Ordnung, solche Versuche und Irrtümer zu haben. Deshalb gehe ich schlafen, daher kann ich es eine Weile nicht aktualisieren, aber das nächste Mal werde ich diesen Fehler untersuchen.

Nachtrag 2020/01/14

Nach dem Verschieben mit der Parameterdatei bei der Konvertierung von Breiten- und Längengrad war es ein Fehler, mit QgsCoordinateTransform weiter von den alten Koordinaten in die neuen Koordinaten zu konvertieren, sodass ich sie einschließlich "Teil 1" korrigierte. Infolgedessen wurde die Umrechnung von Längen- und Breitengraden normal. Es wurde festgestellt, dass der Bewegungsbetrag der Parameterdatei beim Konvertieren der Ebenenorthogonalität verdoppelt wurde. Die Ursache hierfür wurde noch nicht gefunden.

Lizenz für diesen Artikel

![Creative Commons License](https://i.creativecommons.org/l/by/4.0 /88x31.png) Dieser Artikel wird unter Creative Commons Attribution 4.0 International License bereitgestellt.

Recommended Posts

Erstellen Sie mit QGIS Part 2 ein tky2jgd-Plug-In ohne praktische Anwendbarkeit
Erstellen eines tky2jgd-Plug-Ins ohne praktische Anwendbarkeit mit QGIS Teil 1
Machen Sie Ja Nein Popup mit Kivy
So erstellen Sie ein QGIS-Plug-In (Paketerzeugung)
Erstellen Sie einen einfachen Slackbot mit einer interaktiven Schaltfläche in Python
Wie man ein Schießspiel mit toio macht (Teil 1)
Erstellen Sie ein Blueqat-Backend ~ Teil 1
Erstellen Sie ein Blueqat-Backend ~ Teil 2
Erstellen Sie ein Lesezeichen in Python
Machen Sie eine Lotterie mit Python
Machen Sie ein Feuer mit kdeplot
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 1 erstellen
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 2 erstellen
Erstellen Sie eine Spinbox, die mit Tkinter in Binär angezeigt werden kann
Machen Sie ein Thermometer mit Raspberry Pi und machen Sie es im Browser Teil 4 sichtbar
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 3 erstellen
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 4 erstellen
Erstellen Sie eine Spinbox, die mit Tkinter in HEX angezeigt werden kann
Spiele mit einer Schildkröte mit Schildkrötengrafiken (Teil 1)
Lassen Sie uns eine GUI mit Python erstellen.
Machen Sie einen Sound mit Jupyter Notebook
Machen wir einen Blockbruch mit wxPython
Erstellen Sie ein Empfehlungssystem mit Python
Schreiben Sie das Vim-Plugin in Python
[Blender] So erstellen Sie ein Blender-Plug-In
Machen Sie einen Filter mit einer Django-Vorlage
Lassen Sie uns ein Diagramm mit Python erstellen! !!
Machen wir mit xCAT einen Spacon
Erstellen Sie mit PySide einen Modelliterator
Machen Sie eine schöne Grafik mit Plotly
Machen Sie einen Vorhanggenerator mit Blender
Ich habe ein Plug-In "EZPrinter" erstellt, das Karten-PDF mit QGIS einfach ausgibt.
Spiralbuch in Python! Python mit einem Spiralbuch! (Kapitel 14 ~)
Erstellen Sie einen Videoplayer mit PySimpleGUI + OpenCV
Zeichne mit PyCall ein Herz in Ruby
Machen Sie einen seltenen Gacha-Simulator mit Flask
Erstellen Sie eine Notebook-Pipeline mit Kedro + Papermill
Mit Python Teil 2 ein Herz zeichnen (SymPy Edition)
Machen Sie mit matplotlib eine teilweise gezoomte Figur
Machen Sie ein Zeichnungsquiz mit kivy + PyTorch
Lassen Sie uns mit Python langsam sprechen
Erstellen Sie einen Kaskadenklassifizierer mit Google Colaboratory
Lassen Sie uns mit PLY 1 eine einfache Sprache erstellen
Machen Sie eine Logikschaltung mit Perceptron (Multilayer Perceptron)
Machen Sie einen Waschtrocknungs-Timer mit Raspberry Pi
Schreiben Sie ein einfaches Vim-Plugin in Python 3
Erstellen Sie eine GIF-Animation mit Ordnerüberwachung
Erstellen Sie ein Webframework mit Python! (1)
Machen wir mit Pylearn 2 eine dreiäugige KI
Lassen Sie uns eine Kombinationsberechnung mit Python durchführen
Erstellen Sie eine Desktop-App mit Python mit Electron
Machen wir einen Twitter-Bot mit Python!
Erstellen Sie ein Webframework mit Python! (2)
Zeichnen Sie ein Diagramm mit PyQtGraph Part 1-Drawing
Lassen Sie uns ein Backend-Plug-In für Errbot erstellen
Machen Sie ein Thermometer mit Raspberry Pi und machen Sie es im Browser Teil 3 sichtbar
Machen wir eine nervenschwächende App mit Vue.js und Django-Rest-Framework [Teil 3] ~ Implementierung von Nervenschwäche ~
Lassen Sie uns mit Vue.js und Django-Rest-Framework [Teil 2] ~ Vue setup ~ eine nervenschwächende App erstellen
Lassen Sie uns mit Vue.js und Django-Rest-Framework [Teil 1] ~ Django-Setup ~ eine nervenschwächende App erstellen
Machen wir eine nervenschwächende Anwendung mit Vue.js und Django-Rest-Framework [Teil 6] ~ Benutzerauthentifizierung 2 ~