Fassung 0.6.0 und ein Bauskript fuer das Plugin-Paket
tools/baue_paket.py schnuert aus dem Arbeitsstand das ZIP (genau ein Ordner vln_karten/, ohne __pycache__) und schreibt die passende plugins.xml. Beides gehoert danach in den Manager nach api/qgis/; von dort liefert der Server es unter /v2/qgis/ aus, und QGIS bietet neue Fassungen von selbst an. metadata.txt: Fassung 0.6.0, Beschreibung und Changelog auf den heutigen Stand (Widmungen und Verkehrszeichen, Palette, Werkzeuge, Rollbalken). dist/ bleibt aus dem Git heraus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.DS_Store
|
||||
dist/
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Aus dem Arbeitsstand ein QGIS-Plugin-Paket bauen (ZIP + plugins.xml).
|
||||
|
||||
QGIS installiert Erweiterungen aus einem ZIP, das genau einen Ordner enthält — hier
|
||||
``vln_karten/``. Ein eigenes Plugin-Verzeichnis ist nichts weiter als eine ``plugins.xml``
|
||||
neben diesen ZIPs; trägt man ihre Adresse in QGIS ein (Erweiterungen → Einstellungen →
|
||||
Hinzufügen), bietet QGIS Aktualisierungen von selbst an.
|
||||
|
||||
Aufruf::
|
||||
|
||||
python3 tools/baue_paket.py [Zielordner]
|
||||
|
||||
Ohne Zielordner landet alles unter ``dist/``. Die beiden Dateien gehören danach in den
|
||||
Manager (``api/qgis/``); von dort liefert der Server sie unter ``/v2/qgis/`` aus.
|
||||
|
||||
Nichts an QGIS gebunden — läuft mit jedem Python 3.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
WURZEL = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
PAKET = "vln_karten"
|
||||
#: Was nicht ins Paket gehört (Laufzeitkram und Eigenes der Arbeitskopie).
|
||||
AUS = (".pyc", ".pyo", ".DS_Store")
|
||||
AUS_ORDNER = ("__pycache__", ".git")
|
||||
#: Adresse, unter der der Manager die Pakete ausliefert.
|
||||
BASIS = "https://api.flurneuordnung-sachsen.de/v2/qgis"
|
||||
|
||||
|
||||
def metadaten():
|
||||
"""``metadata.txt`` als dict (nur ``[general]``, mehrzeilige Werte zusammengefasst)."""
|
||||
pfad = os.path.join(WURZEL, PAKET, "metadata.txt")
|
||||
daten, schluessel = {}, None
|
||||
with open(pfad, "r", encoding="utf-8") as fh:
|
||||
for zeile in fh:
|
||||
if zeile.startswith("[") or not zeile.strip():
|
||||
continue
|
||||
if "=" in zeile and not zeile.startswith((" ", "\t")):
|
||||
schluessel, wert = zeile.split("=", 1)
|
||||
schluessel = schluessel.strip()
|
||||
daten[schluessel] = wert.strip()
|
||||
elif schluessel:
|
||||
daten[schluessel] += " " + zeile.strip()
|
||||
return daten
|
||||
|
||||
|
||||
def baue_zip(ziel, version):
|
||||
"""Das Paket schreiben und seinen Pfad zurückgeben."""
|
||||
name = "%s-%s.zip" % (PAKET, version)
|
||||
pfad = os.path.join(ziel, name)
|
||||
mit = 0
|
||||
with zipfile.ZipFile(pfad, "w", zipfile.ZIP_DEFLATED) as z:
|
||||
for ordner, unter, dateien in os.walk(os.path.join(WURZEL, PAKET)):
|
||||
unter[:] = [u for u in unter if u not in AUS_ORDNER]
|
||||
for datei in sorted(dateien):
|
||||
if datei.endswith(AUS) or datei in AUS:
|
||||
continue
|
||||
voll = os.path.join(ordner, datei)
|
||||
z.write(voll, os.path.relpath(voll, WURZEL))
|
||||
mit += 1
|
||||
return pfad, mit
|
||||
|
||||
|
||||
def _xml(text):
|
||||
return (str(text).replace("&", "&").replace("<", "<").replace(">", ">")
|
||||
.replace('"', """))
|
||||
|
||||
|
||||
def baue_xml(ziel, daten, zipname):
|
||||
"""``plugins.xml`` schreiben — das Verzeichnis, das QGIS abfragt."""
|
||||
pfad = os.path.join(ziel, "plugins.xml")
|
||||
inhalt = (
|
||||
'<?xml version="1.0"?>\n<plugins>\n'
|
||||
' <pyqgis_plugin name="%s" version="%s">\n'
|
||||
' <description>%s</description>\n'
|
||||
' <about>%s</about>\n'
|
||||
' <version>%s</version>\n'
|
||||
' <qgis_minimum_version>%s</qgis_minimum_version>\n'
|
||||
' <qgis_maximum_version>%s</qgis_maximum_version>\n'
|
||||
' <homepage>%s</homepage>\n'
|
||||
' <file_name>%s</file_name>\n'
|
||||
' <download_url>%s/%s</download_url>\n'
|
||||
' <author_name>%s</author_name>\n'
|
||||
' <tracker>%s</tracker>\n'
|
||||
' <repository>%s</repository>\n'
|
||||
' <tags>%s</tags>\n'
|
||||
' <experimental>%s</experimental>\n'
|
||||
' <deprecated>False</deprecated>\n'
|
||||
' </pyqgis_plugin>\n</plugins>\n'
|
||||
% (_xml(daten.get("name")), _xml(daten.get("version")),
|
||||
_xml(daten.get("description")), _xml(daten.get("about")),
|
||||
_xml(daten.get("version")), _xml(daten.get("qgisMinimumVersion", "3.22")),
|
||||
_xml(daten.get("qgisMaximumVersion", "3.99")), _xml(daten.get("repository", "")),
|
||||
_xml(zipname), BASIS, _xml(zipname), _xml(daten.get("author", "")),
|
||||
_xml(daten.get("tracker", "")), _xml(daten.get("repository", "")),
|
||||
_xml(daten.get("tags", "")), _xml(daten.get("experimental", "False"))))
|
||||
with open(pfad, "w", encoding="utf-8") as fh:
|
||||
fh.write(inhalt)
|
||||
return pfad
|
||||
|
||||
|
||||
def main():
|
||||
ziel = sys.argv[1] if len(sys.argv) > 1 else os.path.join(WURZEL, "dist")
|
||||
os.makedirs(ziel, exist_ok=True)
|
||||
daten = metadaten()
|
||||
zippfad, anzahl = baue_zip(ziel, daten["version"])
|
||||
xmlpfad = baue_xml(ziel, daten, os.path.basename(zippfad))
|
||||
print("Paket: %s (%d Dateien, %.0f KB)"
|
||||
% (zippfad, anzahl, os.path.getsize(zippfad) / 1024))
|
||||
print("Katalog: %s" % xmlpfad)
|
||||
print("Beides nach VLNManager/api/qgis/ kopieren; der Server liefert es unter %s/" % BASIS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -3,9 +3,9 @@ name=VLN Karten
|
||||
qgisMinimumVersion=3.22
|
||||
qgisMaximumVersion=4.99
|
||||
supportsQt6=True
|
||||
description=Beispiel: Karten-API des VLN Managers aus QGIS ansteuern — OGC API Features, alle Layer editierbar, von der Vorerhebung bis zum Maßnahmenblatt.
|
||||
about=Referenz-Implementierung für die VLN-Manager-Karten-API: Login (mail/password -> userauth-API-Key), vollständiges Laden je VKZ mit Paging (EPSG:25833), Splitten gemischter Geometrietypen in Memory-Layer und vereintes Zurückschreiben per PUT.
|
||||
version=0.5.0
|
||||
description=Karten des VLN Managers in QGIS: OGC API Features, alle Layer editierbar — von der Vorerhebung über das Maßnahmenblatt bis zu Widmungen und Verkehrszeichen.
|
||||
about=Anmeldung mit der Manager-Kennung (der API-Key wird gemerkt), Verfahrenslayer über die OGC API laden und bearbeiten (jede Änderung geht einzeln zurück), Geodienste aus der Linkliste, Stile vom Server. Verkehrszeichen und Widmungen lassen sich wie im Web setzen: Schild aus der Palette wählen, erster Klick Standort, zweiter Klick Blickrichtung; die Schildgrafiken kommen von der API und liegen danach lokal.
|
||||
version=0.6.0
|
||||
author=Erik
|
||||
email=phpwelt@gmail.com
|
||||
tracker=https://entwicklung.flurneuordnung-sachsen.de/VLN_SN/API_Karte_QGISDemo/issues
|
||||
@@ -15,3 +15,5 @@ category=Web
|
||||
icon=
|
||||
experimental=True
|
||||
deprecated=False
|
||||
changelog=0.6.0 Widmungen und Verkehrszeichen: eigene Layergruppe, Schildgrafiken vom Server (lokal abgelegt), Palette mit Suche, Werkzeuge „Schild setzen" und „Zusatzzeichen"; Seitenleiste rollt statt das QGIS-Fenster zu strecken (Issue #1).
|
||||
0.5.0 Geodienste aus der Linkliste, Stile speichern, Seitenleiste statt Werkzeugleiste.
|
||||
|
||||
Reference in New Issue
Block a user