Skip to content

Commit 6ea988b

Browse files
Merge pull request #115 from hamishcampbell/add-processing-support
Initial processing support for the Kart plugin
2 parents 5ba2fe4 + 04a1034 commit 6ea988b

File tree

11 files changed

+610
-10
lines changed

11 files changed

+610
-10
lines changed

kart/gui/dockwidget.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,12 @@ def _processProgressLine(bar, line):
258258
with progressBar("Clone") as bar:
259259
bar.setText("Cloning repository")
260260
repo = Repository.clone(
261-
dialog.src,
262-
dialog.dst,
263-
dialog.location,
264-
dialog.extent,
265-
dialog.username,
266-
dialog.password,
261+
src=dialog.src,
262+
dst=dialog.dst,
263+
location=dialog.location,
264+
extent=dialog.extent,
265+
username=dialog.username,
266+
password=dialog.password,
267267
output_handler=partial(_processProgressLine, bar),
268268
)
269269
RepoManager.instance().add_repo(repo)

kart/kartapi.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ def executeKart(commands, path=None, jsonoutput=False, feedback=None):
212212
# always set the use helper env var as it is long lived and the setting may have changed
213213
executeKart.env["KART_USE_HELPER"] = "1" if setting(HELPERMODE) else ""
214214

215+
# TODO - merge into Kart proper already
216+
logging.debug("Enabling VPC/VRTs generation...")
217+
executeKart.env["KART_POINT_CLOUD_VPCS"] = "1"
218+
executeKart.env["KART_RASTER_VRTS"] = "1"
219+
215220
try:
216221
encoding = locale.getdefaultlocale()[1] or "utf-8"
217222
QApplication.setOverrideCursor(Qt.WaitCursor)
@@ -293,6 +298,7 @@ def generate_clone_arguments(
293298
dst: str,
294299
location: Optional[str] = None,
295300
extent: Optional[QgsReferencedRectangle] = None,
301+
depth: Optional[int] = None,
296302
username: Optional[str] = None,
297303
password: Optional[str] = None,
298304
) -> List[str]:
@@ -313,6 +319,8 @@ def generate_clone_arguments(
313319
if extent is not None:
314320
kart_extent = f"{extent.crs().authid()};{extent.asWktPolygon()}"
315321
commands.extend(["--spatial-filter", kart_extent])
322+
if depth is not None:
323+
commands.extend(["--depth", str(depth)])
316324

317325
return commands
318326

@@ -322,6 +330,7 @@ def clone(
322330
dst: str,
323331
location: Optional[str] = None,
324332
extent: Optional[QgsReferencedRectangle] = None,
333+
depth: Optional[int] = None,
325334
username: Optional[str] = None,
326335
password: Optional[str] = None,
327336
output_handler: Callable[[str], None] = None,
@@ -330,7 +339,7 @@ def clone(
330339
Performs a (blocking, main thread only) clone operation
331340
"""
332341
commands = Repository.generate_clone_arguments(
333-
src, dst, location, extent, username, password
342+
src, dst, location, extent, depth, username, password
334343
)
335344
executeKart(commands, feedback=output_handler)
336345
return Repository(dst)
@@ -396,8 +405,11 @@ def init(self, location=None):
396405
else:
397406
self.executeKart(["init"])
398407

399-
def importIntoRepo(self, source):
400-
self.executeKart(["import", source])
408+
def importIntoRepo(self, source, dataset=None):
409+
importArgs = [source]
410+
if dataset:
411+
importArgs += ["--dataset", dataset]
412+
self.executeKart(["import"] + importArgs)
401413

402414
def checkUserConfigured(self):
403415
configDict = self._config()

kart/metadata.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ repository=https://github.com/koordinates/kart-qgis-plugin
2323
tracker=https://github.com/koordinates/kart-qgis-plugin/issues
2424
icon=img/kart.png
2525
category=Plugins
26+
hasProcessingProvider=yes

kart/plugin.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
import platform
44

5-
from qgis.core import QgsProject, Qgis, QgsMessageOutput
5+
from qgis.core import QgsApplication, QgsProject, Qgis, QgsMessageOutput
66

77
from qgis.PyQt.QtCore import Qt
88
from qgis.PyQt.QtWidgets import QAction
@@ -11,6 +11,7 @@
1111
from kart.gui.settingsdialog import SettingsDialog
1212
from kart.kartapi import checkKartInstalled, kartVersionDetails
1313
from kart.layers import LayerTracker
14+
from kart.processing import KartProvider
1415

1516

1617
pluginPath = os.path.dirname(__file__)
@@ -19,6 +20,11 @@
1920
class KartPlugin(object):
2021
def __init__(self, iface):
2122
self.iface = iface
23+
self.provider = None
24+
25+
def initProcessing(self):
26+
self.provider = KartProvider()
27+
QgsApplication.processingRegistry().addProvider(self.provider)
2228

2329
def initGui(self):
2430

@@ -43,6 +49,8 @@ def initGui(self):
4349
QgsProject.instance().layerWasAdded.connect(self.tracker.layerAdded)
4450
QgsProject.instance().crsChanged.connect(self.tracker.updateRubberBands)
4551

52+
self.initProcessing()
53+
4654
def showDock(self):
4755
if checkKartInstalled():
4856
self.dock.show()
@@ -87,3 +95,5 @@ def unload(self):
8795

8896
QgsProject.instance().layerRemoved.disconnect(self.tracker.layerRemoved)
8997
QgsProject.instance().layerWasAdded.disconnect(self.tracker.layerAdded)
98+
99+
QgsApplication.processingRegistry().removeProvider(self.provider)

kart/processing/__init__.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from qgis.core import QgsProcessingProvider
2+
3+
from kart.gui import icons
4+
5+
from .branches import RepoCreateBranch, RepoDeleteBranch, RepoSwitchBranch
6+
from .data import RepoImportData
7+
from .remotes import RepoPullFromRemote, RepoPushToRemote
8+
from .repos import RepoClone, RepoInit
9+
from .tags import RepoCreateTag
10+
11+
12+
class KartProvider(QgsProcessingProvider):
13+
def loadAlgorithms(self, *args, **kwargs):
14+
15+
self.addAlgorithm(RepoInit())
16+
self.addAlgorithm(RepoClone())
17+
self.addAlgorithm(RepoCreateTag())
18+
self.addAlgorithm(RepoSwitchBranch())
19+
self.addAlgorithm(RepoCreateBranch())
20+
self.addAlgorithm(RepoDeleteBranch())
21+
self.addAlgorithm(RepoImportData())
22+
self.addAlgorithm(RepoPullFromRemote())
23+
self.addAlgorithm(RepoPushToRemote())
24+
25+
def id(self, *args, **kwargs):
26+
return "Kart"
27+
28+
def name(self, *args, **kwargs):
29+
return self.tr("Kart")
30+
31+
def icon(self):
32+
return icons.kartIcon

kart/processing/base.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from qgis.PyQt.QtCore import QCoreApplication
2+
from qgis.core import QgsProcessingAlgorithm
3+
4+
5+
class KartAlgorithm(QgsProcessingAlgorithm):
6+
def createInstance(self):
7+
return type(self)()
8+
9+
def name(self):
10+
return f"kart_{self.__class__.__name__.lower()}"
11+
12+
def tr(self, string):
13+
return QCoreApplication.translate("Processing", string)
14+
15+
def initAlgorithm(self, config=None):
16+
return {}

kart/processing/branches.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from qgis.core import QgsProcessingParameterFile, QgsProcessingParameterString
2+
from kart.gui import icons
3+
4+
from .base import KartAlgorithm
5+
6+
7+
class RepoCreateBranch(KartAlgorithm):
8+
REPO_PATH = "REPO_PATH"
9+
REPO_BRANCH_NAME = "REPO_BRANCH_NAME"
10+
11+
def displayName(self):
12+
return self.tr("Create Branch")
13+
14+
def shortHelpString(self):
15+
return self.tr("Create a new branch")
16+
17+
def icon(self):
18+
return icons.createBranchIcon
19+
20+
def initAlgorithm(self, config=None):
21+
22+
self.addParameter(
23+
QgsProcessingParameterFile(
24+
self.REPO_PATH,
25+
self.tr("Repo Path"),
26+
behavior=QgsProcessingParameterFile.Folder,
27+
)
28+
)
29+
30+
self.addParameter(
31+
QgsProcessingParameterString(
32+
self.REPO_BRANCH_NAME,
33+
self.tr("Branch Name"),
34+
)
35+
)
36+
37+
def processAlgorithm(self, parameters, context, feedback):
38+
from kart.kartapi import Repository
39+
40+
repo_path = self.parameterAsFile(parameters, self.REPO_PATH, context)
41+
branch_name = self.parameterAsString(parameters, self.REPO_BRANCH_NAME, context)
42+
43+
repo = Repository(repo_path)
44+
repo.createBranch(branch_name)
45+
46+
return {
47+
self.REPO_PATH: repo_path,
48+
}
49+
50+
51+
class RepoSwitchBranch(KartAlgorithm):
52+
REPO_PATH = "REPO_PATH"
53+
REPO_BRANCH_NAME = "REPO_BRANCH_NAME"
54+
55+
def displayName(self):
56+
return self.tr("Switch to Branch")
57+
58+
def shortHelpString(self):
59+
return self.tr("Switches to a named branch")
60+
61+
def icon(self):
62+
return icons.checkoutIcon
63+
64+
def initAlgorithm(self, config=None):
65+
66+
self.addParameter(
67+
QgsProcessingParameterFile(
68+
self.REPO_PATH,
69+
self.tr("Repo Path"),
70+
behavior=QgsProcessingParameterFile.Folder,
71+
)
72+
)
73+
74+
self.addParameter(
75+
QgsProcessingParameterString(
76+
self.REPO_BRANCH_NAME,
77+
self.tr("Branch Name"),
78+
)
79+
)
80+
81+
def processAlgorithm(self, parameters, context, feedback):
82+
from kart.kartapi import Repository
83+
84+
repo_path = self.parameterAsFile(parameters, self.REPO_PATH, context)
85+
branch_name = self.parameterAsString(parameters, self.REPO_BRANCH_NAME, context)
86+
87+
repo = Repository(repo_path)
88+
repo.checkoutBranch(branch_name)
89+
90+
return {
91+
self.REPO_PATH: repo_path,
92+
}
93+
94+
95+
class RepoDeleteBranch(KartAlgorithm):
96+
REPO_PATH = "REPO_PATH"
97+
REPO_BRANCH_NAME = "REPO_BRANCH_NAME"
98+
99+
def displayName(self):
100+
return self.tr("Delete Branch")
101+
102+
def shortHelpString(self):
103+
return self.tr("Delete a branch")
104+
105+
def icon(self):
106+
return icons.deleteIcon
107+
108+
def initAlgorithm(self, config=None):
109+
110+
self.addParameter(
111+
QgsProcessingParameterFile(
112+
self.REPO_PATH,
113+
self.tr("Repo Path"),
114+
behavior=QgsProcessingParameterFile.Folder,
115+
)
116+
)
117+
118+
self.addParameter(
119+
QgsProcessingParameterString(
120+
self.REPO_BRANCH_NAME,
121+
self.tr("Branch Name"),
122+
)
123+
)
124+
125+
def processAlgorithm(self, parameters, context, feedback):
126+
from kart.kartapi import Repository
127+
128+
repo_path = self.parameterAsFile(parameters, self.REPO_PATH, context)
129+
branch_name = self.parameterAsString(parameters, self.REPO_BRANCH_NAME, context)
130+
131+
repo = Repository(repo_path)
132+
repo.deleteBranch(branch_name)
133+
134+
return {
135+
self.REPO_PATH: repo_path,
136+
}

kart/processing/data.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from qgis.core import (
2+
QgsProcessingParameterFile,
3+
QgsProcessingParameterString,
4+
QgsProcessingOutputFolder,
5+
)
6+
from kart.gui import icons
7+
8+
from .base import KartAlgorithm
9+
10+
11+
class RepoImportData(KartAlgorithm):
12+
REPO_PATH = "REPO_PATH"
13+
REPO_DATA_PATH = "REPO_DATA_PATH"
14+
REPO_DATASET_NAME = "REPO_DATASET_NAME"
15+
16+
def displayName(self):
17+
return self.tr("Import Data")
18+
19+
def shortHelpString(self):
20+
return self.tr("Import data into a repository")
21+
22+
def icon(self):
23+
return icons.importIcon
24+
25+
def initAlgorithm(self, config=None):
26+
27+
self.addParameter(
28+
QgsProcessingParameterFile(
29+
self.REPO_PATH,
30+
self.tr("Repo Path"),
31+
behavior=QgsProcessingParameterFile.Folder,
32+
)
33+
)
34+
35+
self.addParameter(
36+
QgsProcessingParameterFile(
37+
self.REPO_DATA_PATH,
38+
self.tr("Data Path"),
39+
behavior=QgsProcessingParameterFile.File,
40+
)
41+
)
42+
43+
self.addParameter(
44+
QgsProcessingParameterString(
45+
self.REPO_DATASET_NAME,
46+
self.tr("Dataset Name"),
47+
optional=True,
48+
)
49+
)
50+
51+
self.addOutput(
52+
QgsProcessingOutputFolder(
53+
self.REPO_PATH,
54+
self.tr("Repo Path"),
55+
)
56+
)
57+
58+
def processAlgorithm(self, parameters, context, feedback):
59+
from kart.kartapi import Repository
60+
61+
repo_path = self.parameterAsFile(parameters, self.REPO_PATH, context)
62+
data_path = self.parameterAsFile(parameters, self.REPO_DATA_PATH, context)
63+
dataset_name = self.parameterAsString(
64+
parameters, self.REPO_DATASET_NAME, context
65+
)
66+
67+
repo = Repository(repo_path)
68+
repo.importIntoRepo(data_path, dataset_name)
69+
70+
return {
71+
self.REPO_PATH: repo_path,
72+
self.REPO_DATASET_NAME: dataset_name,
73+
}

0 commit comments

Comments
 (0)