Skip to content

Commit e4f212e

Browse files
committed
Implement mechanism to generate survey items from geometries
1 parent e111a14 commit e4f212e

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

xlsformconverter/XLSFormConverter.py

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
QgsEditorWidgetSetup,
1919
QgsExpression,
2020
QgsFeature,
21+
QgsFeatureRequest,
22+
QgsFeatureSink,
2123
QgsField,
2224
QgsFieldConstraints,
2325
QgsFields,
@@ -33,6 +35,8 @@
3335
QgsRelationContext,
3436
QgsVectorFileWriter,
3537
QgsVectorLayer,
38+
QgsVectorLayerUtils,
39+
QgsWkbTypes,
3640
)
3741
from qgis.PyQt.QtCore import QMetaType, QObject, QSize, pyqtSignal
3842

@@ -690,13 +694,13 @@ def detect_geometry(self, child_name=None):
690694
" "
691695
)[0]
692696
if type_details == "geopoint" or type_details == "start-geopoint":
693-
geometry = Qgis.WkbType.Point
697+
geometry = Qgis.WkbType.MultiPoint
694698
break
695699
if type_details == "geotrace" or type_details == "start-geotrace":
696-
geometry = Qgis.WkbType.LineString
700+
geometry = Qgis.WkbType.MultiLineString
697701
break
698702
if type_details == "geoshape" or type_details == "start-geoshape":
699-
geometry = Qgis.WkbType.Polygon
703+
geometry = Qgis.WkbType.MultiPolygon
700704
break
701705

702706
return geometry
@@ -990,7 +994,12 @@ def process_project_write(self, document):
990994
ms.writeXml(mapcanvasNode, document)
991995

992996
def convert(
993-
self, output_directory, title=None, language=None, basemap="OpenStreetMap"
997+
self,
998+
output_directory,
999+
title=None,
1000+
language=None,
1001+
basemap="OpenStreetMap",
1002+
geometries=None,
9941003
):
9951004
if not self.survey_layer:
9961005
return ""
@@ -1494,4 +1503,39 @@ def convert(
14941503
)
14951504
self.output_project.writeProject.connect(self.process_project_write)
14961505
self.output_project.write(output_project_file)
1506+
1507+
if (
1508+
geometries
1509+
and current_layer[0].geometryType() != Qgis.GeometryType.Null
1510+
and current_layer[0].geometryType() != Qgis.GeometryType.Unknown
1511+
):
1512+
if current_layer[0].geometryType() == QgsWkbTypes.geometryType(
1513+
geometries.wkbType()
1514+
):
1515+
current_layer[0].startEditing()
1516+
1517+
request = QgsFeatureRequest()
1518+
request.setDestinationCrs(
1519+
current_layer[0].crs(), self.output_project.transformContext()
1520+
)
1521+
geometries_iterator = geometries.getFeatures(request)
1522+
for feature in geometries_iterator:
1523+
output_features = QgsVectorLayerUtils.makeFeatureCompatible(
1524+
feature,
1525+
current_layer[0],
1526+
QgsFeatureSink.SinkFlag.RegeneratePrimaryKey,
1527+
)
1528+
if output_features:
1529+
current_layer[0].addFeature(
1530+
output_features[0], QgsFeatureSink.Flag.FastInsert
1531+
)
1532+
1533+
current_layer[0].commitChanges()
1534+
else:
1535+
self.warning.emit(
1536+
self.tr(
1537+
"The geometries' type does not match the output survey layer, skipping"
1538+
)
1539+
)
1540+
14971541
return output_project_file

xlsformconverter/XLSFormConverterAlgorithms.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import os
22

33
from qgis.core import (
4+
QgsProcessing,
45
QgsProcessingAlgorithm,
56
QgsProcessingParameterBoolean,
7+
QgsProcessingParameterDefinition,
68
QgsProcessingParameterEnum,
9+
QgsProcessingParameterFeatureSource,
710
QgsProcessingParameterFile,
811
QgsProcessingParameterFolderDestination,
912
QgsProcessingParameterString,
@@ -31,6 +34,7 @@ class XLSFormConverterAlgorithm(QgsProcessingAlgorithm):
3134
LANGUAGE = "LANGUAGE"
3235
BASEMAP = "BASEMAP"
3336
UPLOAD_TO_QFIELDCLOUD = "UPLOAD_TO_QFIELDCLOUD"
37+
GEOMETRIES = "GEOMETRIES"
3438
OUTPUT = "OUTPUT"
3539

3640
def tr(self, string):
@@ -110,6 +114,17 @@ def initAlgorithm(self, config=None):
110114
)
111115
)
112116

117+
param = QgsProcessingParameterFeatureSource(
118+
self.GEOMETRIES,
119+
self.tr(
120+
"Pre-fill project with features' geometries and matching attributes"
121+
),
122+
types=[QgsProcessing.SourceType.VectorAnyGeometry],
123+
optional=True,
124+
)
125+
param.setFlags(param.flags() | QgsProcessingParameterDefinition.Flag.Advanced)
126+
self.addParameter(param)
127+
113128
self.addParameter(
114129
QgsProcessingParameterFolderDestination(
115130
self.OUTPUT,
@@ -121,6 +136,7 @@ def processAlgorithm(self, parameters, context, feedback):
121136
xlsform_file = self.parameterAsString(parameters, self.INPUT, context)
122137
title = self.parameterAsString(parameters, self.TITLE, context)
123138
language = self.parameterAsString(parameters, self.LANGUAGE, context)
139+
geometries = self.parameterAsSource(parameters, self.GEOMETRIES, context)
124140

125141
basemap = "OpenStreetMap"
126142
basemap_index = self.parameterAsEnum(parameters, self.BASEMAP, context)
@@ -141,7 +157,9 @@ def processAlgorithm(self, parameters, context, feedback):
141157
converter.warning.connect(lambda message: feedback.pushWarning(message))
142158
converter.error.connect(lambda message: feedback.reportError(message))
143159

144-
project_file = converter.convert(output_directory, title, language, basemap)
160+
project_file = converter.convert(
161+
output_directory, title, language, basemap, geometries
162+
)
145163

146164
if project_file and upload_to_qfieldcloud:
147165
for root, dirs, files in os.walk(output_directory):

0 commit comments

Comments
 (0)