Skip to content

Commit b3deff6

Browse files
author
anitagraser
committed
Make parallel processing optional, avoids #93
Reviewed-on: https://codeberg.org/movingpandas/trajectools/pulls/99
1 parent eba284c commit b3deff6

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

qgis_processing/extractPtsAlgorithm.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
2525
from .qgisUtils import feature_from_gdf_row
2626

2727

28-
CPU_COUNT = os.cpu_count()
29-
30-
3128
class ExtractODPtsAlgorithm(TrajectoriesAlgorithm):
3229
ORIGIN_PTS = "ORIGIN_PTS"
3330
DESTINATIONS_PTS = "DESTINATIONS_PTS"
@@ -206,7 +203,7 @@ def processTc(self, tc, parameters, context):
206203
min_duration = pd.Timedelta(min_duration).to_pytimedelta()
207204

208205
try:
209-
gdf = TrajectoryStopDetector(tc, n_processes=CPU_COUNT).get_stop_points(
206+
gdf = TrajectoryStopDetector(tc, n_processes=self.cpu_count).get_stop_points(
210207
max_diameter=max_diameter, min_duration=min_duration
211208
)
212209
except TypeError:

qgis_processing/splitTrajectoriesAlgorithm.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121
from .trajectoriesAlgorithm import TrajectoryManipulationAlgorithm, help_str_base, help_str_traj
2222

2323

24-
CPU_COUNT = os.cpu_count()
25-
26-
2724
class SplitTrajectoriesAlgorithm(TrajectoryManipulationAlgorithm):
2825
def __init__(self):
2926
super().__init__()
@@ -90,12 +87,13 @@ def processTc(self, tc, parameters, context):
9087
if td_units == "Weeks":
9188
td_units = "W"
9289
time_gap = pd.Timedelta(f"{time_gap} {td_units}").to_pytimedelta()
90+
9391
for traj in tc.trajectories:
9492
try:
9593
splits = ObservationGapSplitter(traj).split(
9694
gap=time_gap,
9795
min_length=tc.min_length,
98-
n_processes=CPU_COUNT
96+
n_processes=self.cpu_count
9997
)
10098
except TypeError:
10199
raise TypeError("TypeError: cannot pickle 'QVariant' object. This error is usually caused by None values in input layer fields. Try to remove None values or run without Add movement metrics.")
@@ -151,7 +149,7 @@ def processTc(self, tc, parameters, context):
151149
splits = TemporalSplitter(tc).split(
152150
mode=split_mode,
153151
min_length=tc.min_length,
154-
n_processes=CPU_COUNT
152+
n_processes=self.cpu_count
155153
)
156154
except TypeError:
157155
raise TypeError("TypeError: cannot pickle 'QVariant' object. This error is usually caused by None values in input layer fields. Try to remove None values or run without Add movement metrics.")
@@ -212,7 +210,7 @@ def processTc(self, tc, parameters, context):
212210
max_diameter=max_diameter,
213211
min_duration=min_duration,
214212
min_length=tc.min_length,
215-
n_processes=CPU_COUNT
213+
n_processes=self.cpu_count
216214
)
217215
except TypeError:
218216
raise TypeError("TypeError: cannot pickle 'QVariant' object. This error is usually caused by None values in input layer fields. Try to remove None values or run without Add movement metrics.")
@@ -263,7 +261,7 @@ def processTc(self, tc, parameters, context):
263261
splits = ValueChangeSplitter(traj).split(
264262
col_name=self.field,
265263
min_length=tc.min_length,
266-
n_processes=CPU_COUNT
264+
n_processes=self.cpu_count
267265
)
268266
except TypeError:
269267
raise TypeError("TypeError: cannot pickle 'QVariant' object. This error is usually caused by None values in input layer fields. Try to remove None values or run without Add movement metrics.")

qgis_processing/trajectoriesAlgorithm.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
"a": 3600 * 24 * 365,
4141
}
4242

43-
CPU_COUNT = os.cpu_count()
44-
4543
help_str_base = (
4644
"<p><b>Trajectory ID field</b> is the input layer field containing the ID "
4745
"of the moving objects. If no field is specified, all input features are "
@@ -66,6 +64,7 @@ class TrajectoriesAlgorithm(QgsProcessingAlgorithm):
6664
TRAJ_ID_FIELD = "TRAJ_ID_FIELD"
6765
TIMESTAMP_FIELD = "TIME_FIELD"
6866
ADD_METRICS = "ADD_METRICS"
67+
USE_PARALLEL_PROCESSING = "USE_PARALLEL_PROCESSING"
6968
SPEED_UNIT = "SPEED_UNIT"
7069
MIN_LENGTH = "MIN_LENGTH"
7170

@@ -143,6 +142,11 @@ def prepare_parameters(self, parameters, context):
143142
).split("/")
144143
self.min_length = self.parameterAsDouble(parameters, self.MIN_LENGTH, context)
145144
self.add_metrics = self.parameterAsBoolean(parameters, self.ADD_METRICS, context)
145+
self.use_parallel = self.parameterAsBoolean(parameters, self.USE_PARALLEL_PROCESSING, context)
146+
if self.use_parallel:
147+
self.cpu_count = os.cpu_count()
148+
else:
149+
self.cpu_count = 1
146150

147151
def create_tc(self, parameters, context):
148152
self.prepare_parameters(parameters, context)
@@ -159,8 +163,8 @@ def create_tc(self, parameters, context):
159163

160164
if self.add_metrics:
161165
try:
162-
tc.add_speed(units=tuple(self.speed_units), overwrite=True, n_processes=CPU_COUNT)
163-
tc.add_direction(overwrite=True, n_processes=CPU_COUNT)
166+
tc.add_speed(units=tuple(self.speed_units), overwrite=True, n_processes=self.cpu_count)
167+
tc.add_direction(overwrite=True, n_processes=self.cpu_count)
164168
except TypeError: # None values cause TypeError: cannot pickle 'QVariant' object, see issue #93
165169
raise TypeError("TypeError: cannot pickle 'QVariant' object. This error is usually caused by None values in input layer fields. Try to remove None values or run without Add movement metrics.")
166170

@@ -226,7 +230,15 @@ def initAlgorithm(self, config=None):
226230
defaultValue=True,
227231
optional=False,
228232
)
229-
)
233+
)
234+
self.addParameter(
235+
QgsProcessingParameterBoolean(
236+
name=self.USE_PARALLEL_PROCESSING,
237+
description=self.tr("Use parallel processing (experimental)"),
238+
defaultValue=False,
239+
optional=False,
240+
)
241+
)
230242
self.addParameter(
231243
QgsProcessingParameterString(
232244
name=self.SPEED_UNIT,

0 commit comments

Comments
 (0)