/src/gdal/apps/gdalalg_vector_grid.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: GDAL |
4 | | * Purpose: gdal "vector grid" subcommand |
5 | | * Author: Even Rouault <even dot rouault at spatialys.com> |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #include "gdalalg_vector_grid.h" |
14 | | #include "gdalalg_vector_grid_average.h" |
15 | | #include "gdalalg_vector_grid_data_metrics.h" |
16 | | #include "gdalalg_vector_grid_invdist.h" |
17 | | #include "gdalalg_vector_grid_invdistnn.h" |
18 | | #include "gdalalg_vector_grid_linear.h" |
19 | | #include "gdalalg_vector_grid_nearest.h" |
20 | | |
21 | | #include "cpl_conv.h" |
22 | | #include "gdal_priv.h" |
23 | | #include "gdal_utils.h" |
24 | | #include "ogrsf_frmts.h" |
25 | | |
26 | | //! @cond Doxygen_Suppress |
27 | | |
28 | | #ifndef _ |
29 | 0 | #define _(x) (x) |
30 | | #endif |
31 | | |
32 | | /************************************************************************/ |
33 | | /* GDALVectorGridAlgorithm::GDALVectorGridAlgorithm() */ |
34 | | /************************************************************************/ |
35 | | |
36 | | GDALVectorGridAlgorithm::GDALVectorGridAlgorithm(bool standaloneStep) |
37 | 0 | : GDALPipelineStepAlgorithm( |
38 | 0 | NAME, DESCRIPTION, HELP_URL, |
39 | 0 | ConstructorOptions() |
40 | 0 | .SetStandaloneStep(standaloneStep) |
41 | 0 | .SetOutputFormatCreateCapability(GDAL_DCAP_CREATE)) |
42 | 0 | { |
43 | 0 | if (standaloneStep) |
44 | 0 | { |
45 | 0 | RegisterSubAlgorithm<GDALVectorGridAverageAlgorithmStandalone>(); |
46 | 0 | RegisterSubAlgorithm<GDALVectorGridInvdistAlgorithmStandalone>(); |
47 | 0 | RegisterSubAlgorithm<GDALVectorGridInvdistNNAlgorithmStandalone>(); |
48 | 0 | RegisterSubAlgorithm<GDALVectorGridLinearAlgorithmStandalone>(); |
49 | 0 | RegisterSubAlgorithm<GDALVectorGridNearestAlgorithmStandalone>(); |
50 | 0 | RegisterSubAlgorithm<GDALVectorGridMinimumAlgorithmStandalone>(); |
51 | 0 | RegisterSubAlgorithm<GDALVectorGridMaximumAlgorithmStandalone>(); |
52 | 0 | RegisterSubAlgorithm<GDALVectorGridRangeAlgorithmStandalone>(); |
53 | 0 | RegisterSubAlgorithm<GDALVectorGridCountAlgorithmStandalone>(); |
54 | 0 | RegisterSubAlgorithm< |
55 | 0 | GDALVectorGridAverageDistanceAlgorithmStandalone>(); |
56 | 0 | RegisterSubAlgorithm< |
57 | 0 | GDALVectorGridAverageDistancePointsAlgorithmStandalone>(); |
58 | 0 | } |
59 | 0 | else |
60 | 0 | { |
61 | 0 | RegisterSubAlgorithm<GDALVectorGridAverageAlgorithm>(); |
62 | 0 | RegisterSubAlgorithm<GDALVectorGridInvdistAlgorithm>(); |
63 | 0 | RegisterSubAlgorithm<GDALVectorGridInvdistNNAlgorithm>(); |
64 | 0 | RegisterSubAlgorithm<GDALVectorGridLinearAlgorithm>(); |
65 | 0 | RegisterSubAlgorithm<GDALVectorGridNearestAlgorithm>(); |
66 | 0 | RegisterSubAlgorithm<GDALVectorGridMinimumAlgorithm>(); |
67 | 0 | RegisterSubAlgorithm<GDALVectorGridMaximumAlgorithm>(); |
68 | 0 | RegisterSubAlgorithm<GDALVectorGridRangeAlgorithm>(); |
69 | 0 | RegisterSubAlgorithm<GDALVectorGridCountAlgorithm>(); |
70 | 0 | RegisterSubAlgorithm<GDALVectorGridAverageDistanceAlgorithm>(); |
71 | 0 | RegisterSubAlgorithm<GDALVectorGridAverageDistancePointsAlgorithm>(); |
72 | 0 | } |
73 | 0 | } |
74 | | |
75 | | /************************************************************************/ |
76 | | /* GDALVectorGridAlgorithm::RunStep() */ |
77 | | /************************************************************************/ |
78 | | |
79 | | bool GDALVectorGridAlgorithm::RunStep(GDALPipelineStepRunContext &) |
80 | 0 | { |
81 | 0 | CPLError(CE_Failure, CPLE_AppDefined, |
82 | 0 | "The Run() method should not be called directly on the \"gdal " |
83 | 0 | "vector grid\" program."); |
84 | 0 | return false; |
85 | 0 | } |
86 | | |
87 | | /************************************************************************/ |
88 | | /* GDALVectorGeomAlgorithm::RunImpl() */ |
89 | | /************************************************************************/ |
90 | | |
91 | | bool GDALVectorGridAlgorithm::RunImpl(GDALProgressFunc, void *) |
92 | 0 | { |
93 | 0 | CPLError(CE_Failure, CPLE_AppDefined, |
94 | 0 | "The Run() method should not be called directly on the \"gdal " |
95 | 0 | "vector grid\" program."); |
96 | 0 | return false; |
97 | 0 | } |
98 | | |
99 | | /************************************************************************/ |
100 | | /* GDALVectorGridAbstractAlgorithm() */ |
101 | | /************************************************************************/ |
102 | | |
103 | | GDALVectorGridAbstractAlgorithm::GDALVectorGridAbstractAlgorithm( |
104 | | const std::string &name, const std::string &description, |
105 | | const std::string &helpURL, bool standaloneStep) |
106 | 0 | : GDALPipelineStepAlgorithm( |
107 | 0 | name, description, helpURL, |
108 | 0 | ConstructorOptions() |
109 | 0 | .SetStandaloneStep(standaloneStep) |
110 | 0 | .SetOutputFormatCreateCapability(GDAL_DCAP_CREATE)) |
111 | 0 | { |
112 | 0 | AddProgressArg(); |
113 | 0 | if (standaloneStep) |
114 | 0 | { |
115 | 0 | AddOutputFormatArg(&m_format).AddMetadataItem( |
116 | 0 | GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_RASTER, GDAL_DCAP_CREATE}); |
117 | 0 | AddOpenOptionsArg(&m_openOptions); |
118 | 0 | AddInputFormatsArg(&m_inputFormats) |
119 | 0 | .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR}); |
120 | 0 | AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR); |
121 | 0 | AddOutputDatasetArg(&m_outputDataset, GDAL_OF_RASTER); |
122 | 0 | AddCreationOptionsArg(&m_creationOptions); |
123 | 0 | } |
124 | 0 | else |
125 | 0 | { |
126 | 0 | AddVectorHiddenInputDatasetArg(); |
127 | 0 | } |
128 | 0 | AddArg("extent", 0, _("Set the target georeferenced extent"), |
129 | 0 | &m_targetExtent) |
130 | 0 | .SetMinCount(4) |
131 | 0 | .SetMaxCount(4) |
132 | 0 | .SetRepeatedArgAllowed(false) |
133 | 0 | .SetMetaVar("<xmin>,<ymin>,<xmax>,<ymax>"); |
134 | 0 | AddArg("resolution", 0, _("Set the target resolution"), &m_targetResolution) |
135 | 0 | .SetMinCount(2) |
136 | 0 | .SetMaxCount(2) |
137 | 0 | .SetRepeatedArgAllowed(false) |
138 | 0 | .SetMetaVar("<xres>,<yres>") |
139 | 0 | .SetMutualExclusionGroup("size-or-resolution"); |
140 | 0 | AddArg("size", 0, _("Set the target size in pixels and lines"), |
141 | 0 | &m_targetSize) |
142 | 0 | .SetMinCount(2) |
143 | 0 | .SetMaxCount(2) |
144 | 0 | .SetRepeatedArgAllowed(false) |
145 | 0 | .SetMetaVar("<xsize>,<ysize>") |
146 | 0 | .SetMutualExclusionGroup("size-or-resolution"); |
147 | 0 | AddOutputDataTypeArg(&m_outputType).SetDefault(m_outputType); |
148 | 0 | AddArg("crs", 0, _("Override the projection for the output file"), &m_crs) |
149 | 0 | .AddHiddenAlias("srs") |
150 | 0 | .SetIsCRSArg(/*noneAllowed=*/false); |
151 | 0 | AddOverwriteArg(&m_overwrite); |
152 | 0 | AddLayerNameArg(&m_layers) |
153 | 0 | .SetMutualExclusionGroup("layer-sql") |
154 | 0 | .AddAlias("layer"); |
155 | 0 | AddArg("sql", 0, _("SQL statement"), &m_sql) |
156 | 0 | .SetReadFromFileAtSyntaxAllowed() |
157 | 0 | .SetMetaVar("<statement>|@<filename>") |
158 | 0 | .SetRemoveSQLCommentsEnabled() |
159 | 0 | .SetMutualExclusionGroup("layer-sql"); |
160 | 0 | AddBBOXArg( |
161 | 0 | &m_bbox, |
162 | 0 | _("Select only points contained within the specified bounding box")); |
163 | 0 | AddArg("zfield", 0, _("Field name from which to get Z values."), &m_zField) |
164 | 0 | .AddHiddenAlias("z-field"); |
165 | 0 | AddArg("zoffset", 0, |
166 | 0 | _("Value to add to the Z field value (applied before zmultiply)"), |
167 | 0 | &m_zOffset) |
168 | 0 | .SetDefault(m_zOffset) |
169 | 0 | .AddHiddenAlias("z-offset"); |
170 | 0 | AddArg("zmultiply", 0, |
171 | 0 | _("Multiplication factor for the Z field value (applied after " |
172 | 0 | "zoffset)"), |
173 | 0 | &m_zMultiply) |
174 | 0 | .SetDefault(m_zMultiply) |
175 | 0 | .AddHiddenAlias("z-multiply"); |
176 | |
|
177 | 0 | AddValidationAction( |
178 | 0 | [this]() |
179 | 0 | { |
180 | 0 | bool ret = true; |
181 | 0 | if (!m_targetResolution.empty() && m_targetExtent.empty()) |
182 | 0 | { |
183 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
184 | 0 | "'resolution' should be defined when 'extent' is."); |
185 | 0 | ret = false; |
186 | 0 | } |
187 | 0 | return ret; |
188 | 0 | }); |
189 | 0 | } |
190 | | |
191 | | /************************************************************************/ |
192 | | /* GDALVectorGridAbstractAlgorithm::RunStep() */ |
193 | | /************************************************************************/ |
194 | | |
195 | | bool GDALVectorGridAbstractAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt) |
196 | 0 | { |
197 | 0 | auto poSrcDS = m_inputDataset[0].GetDatasetRef(); |
198 | 0 | CPLAssert(poSrcDS); |
199 | 0 | CPLAssert(!m_outputDataset.GetDatasetRef()); |
200 | |
|
201 | 0 | CPLStringList aosOptions; |
202 | |
|
203 | 0 | std::string outputFilename; |
204 | 0 | if (m_standaloneStep) |
205 | 0 | { |
206 | 0 | outputFilename = m_outputDataset.GetName(); |
207 | 0 | if (!m_format.empty()) |
208 | 0 | { |
209 | 0 | aosOptions.AddString("-of"); |
210 | 0 | aosOptions.AddString(m_format.c_str()); |
211 | 0 | } |
212 | |
|
213 | 0 | for (const std::string &co : m_creationOptions) |
214 | 0 | { |
215 | 0 | aosOptions.AddString("-co"); |
216 | 0 | aosOptions.AddString(co.c_str()); |
217 | 0 | } |
218 | 0 | } |
219 | 0 | else |
220 | 0 | { |
221 | 0 | outputFilename = CPLGenerateTempFilenameSafe("_grid.tif"); |
222 | |
|
223 | 0 | aosOptions.AddString("-of"); |
224 | 0 | aosOptions.AddString("GTiff"); |
225 | |
|
226 | 0 | aosOptions.AddString("-co"); |
227 | 0 | aosOptions.AddString("TILED=YES"); |
228 | 0 | } |
229 | |
|
230 | 0 | if (!m_targetExtent.empty()) |
231 | 0 | { |
232 | 0 | aosOptions.AddString("-txe"); |
233 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", m_targetExtent[0])); |
234 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", m_targetExtent[2])); |
235 | 0 | aosOptions.AddString("-tye"); |
236 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", m_targetExtent[1])); |
237 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", m_targetExtent[3])); |
238 | 0 | } |
239 | |
|
240 | 0 | if (!m_bbox.empty()) |
241 | 0 | { |
242 | 0 | aosOptions.AddString("-clipsrc"); |
243 | 0 | for (double v : m_bbox) |
244 | 0 | { |
245 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", v)); |
246 | 0 | } |
247 | 0 | } |
248 | |
|
249 | 0 | if (!m_targetResolution.empty()) |
250 | 0 | { |
251 | 0 | aosOptions.AddString("-tr"); |
252 | 0 | for (double targetResolution : m_targetResolution) |
253 | 0 | { |
254 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", targetResolution)); |
255 | 0 | } |
256 | 0 | } |
257 | |
|
258 | 0 | if (!m_targetSize.empty()) |
259 | 0 | { |
260 | 0 | aosOptions.AddString("-outsize"); |
261 | 0 | for (int targetSize : m_targetSize) |
262 | 0 | { |
263 | 0 | aosOptions.AddString(CPLSPrintf("%d", targetSize)); |
264 | 0 | } |
265 | 0 | } |
266 | |
|
267 | 0 | if (!m_outputType.empty()) |
268 | 0 | { |
269 | 0 | aosOptions.AddString("-ot"); |
270 | 0 | aosOptions.AddString(m_outputType.c_str()); |
271 | 0 | } |
272 | |
|
273 | 0 | if (!m_crs.empty()) |
274 | 0 | { |
275 | 0 | aosOptions.AddString("-a_srs"); |
276 | 0 | aosOptions.AddString(m_crs.c_str()); |
277 | 0 | } |
278 | |
|
279 | 0 | if (m_sql.empty()) |
280 | 0 | { |
281 | 0 | for (const std::string &layer : m_layers) |
282 | 0 | { |
283 | 0 | aosOptions.AddString("-l"); |
284 | 0 | aosOptions.AddString(layer.c_str()); |
285 | 0 | } |
286 | 0 | } |
287 | 0 | else |
288 | 0 | { |
289 | 0 | aosOptions.AddString("-sql"); |
290 | 0 | aosOptions.AddString(m_sql.c_str()); |
291 | 0 | } |
292 | |
|
293 | 0 | if (m_zOffset != 0) |
294 | 0 | { |
295 | 0 | aosOptions.AddString("-z_increase"); |
296 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", m_zOffset)); |
297 | 0 | } |
298 | |
|
299 | 0 | if (m_zMultiply != 0) |
300 | 0 | { |
301 | 0 | aosOptions.AddString("-z_multiply"); |
302 | 0 | aosOptions.AddString(CPLSPrintf("%.17g", m_zMultiply)); |
303 | 0 | } |
304 | |
|
305 | 0 | if (!m_zField.empty()) |
306 | 0 | { |
307 | 0 | aosOptions.AddString("-zfield"); |
308 | 0 | aosOptions.AddString(m_zField.c_str()); |
309 | 0 | } |
310 | 0 | else if (m_sql.empty()) |
311 | 0 | { |
312 | 0 | const auto CheckLayer = [this](OGRLayer *poLayer) |
313 | 0 | { |
314 | 0 | auto poFeat = |
315 | 0 | std::unique_ptr<OGRFeature>(poLayer->GetNextFeature()); |
316 | 0 | poLayer->ResetReading(); |
317 | 0 | if (poFeat) |
318 | 0 | { |
319 | 0 | const auto poGeom = poFeat->GetGeometryRef(); |
320 | 0 | if (!poGeom || !poGeom->Is3D()) |
321 | 0 | { |
322 | 0 | ReportError( |
323 | 0 | CE_Warning, CPLE_AppDefined, |
324 | 0 | "At least one geometry of layer '%s' lacks a Z " |
325 | 0 | "component. You may need to set the 'zfield' argument", |
326 | 0 | poLayer->GetName()); |
327 | 0 | return false; |
328 | 0 | } |
329 | 0 | } |
330 | 0 | return true; |
331 | 0 | }; |
332 | |
|
333 | 0 | if (m_layers.empty()) |
334 | 0 | { |
335 | 0 | for (auto poLayer : poSrcDS->GetLayers()) |
336 | 0 | { |
337 | 0 | if (!CheckLayer(poLayer)) |
338 | 0 | break; |
339 | 0 | } |
340 | 0 | } |
341 | 0 | else |
342 | 0 | { |
343 | 0 | for (const std::string &layerName : m_layers) |
344 | 0 | { |
345 | 0 | auto poLayer = poSrcDS->GetLayerByName(layerName.c_str()); |
346 | 0 | if (poLayer && !CheckLayer(poLayer)) |
347 | 0 | break; |
348 | 0 | } |
349 | 0 | } |
350 | 0 | } |
351 | |
|
352 | 0 | aosOptions.AddString("-a"); |
353 | 0 | aosOptions.AddString(GetGridAlgorithm().c_str()); |
354 | |
|
355 | 0 | bool bOK = false; |
356 | 0 | std::unique_ptr<GDALGridOptions, decltype(&GDALGridOptionsFree)> psOptions{ |
357 | 0 | GDALGridOptionsNew(aosOptions.List(), nullptr), GDALGridOptionsFree}; |
358 | |
|
359 | 0 | if (psOptions) |
360 | 0 | { |
361 | 0 | GDALGridOptionsSetProgress(psOptions.get(), ctxt.m_pfnProgress, |
362 | 0 | ctxt.m_pProgressData); |
363 | |
|
364 | 0 | auto poRetDS = std::unique_ptr<GDALDataset>(GDALDataset::FromHandle( |
365 | 0 | GDALGrid(outputFilename.c_str(), GDALDataset::ToHandle(poSrcDS), |
366 | 0 | psOptions.get(), nullptr))); |
367 | |
|
368 | 0 | if (poRetDS) |
369 | 0 | { |
370 | 0 | bOK = true; |
371 | |
|
372 | 0 | if (!m_standaloneStep) |
373 | 0 | { |
374 | 0 | VSIUnlink(outputFilename.c_str()); |
375 | 0 | poRetDS->MarkSuppressOnClose(); |
376 | 0 | } |
377 | |
|
378 | 0 | m_outputDataset.Set(std::move(poRetDS)); |
379 | 0 | } |
380 | 0 | } |
381 | |
|
382 | 0 | return bOK; |
383 | 0 | } |
384 | | |
385 | | /************************************************************************/ |
386 | | /* GDALVectorGridAbstractAlgorithm::RunImpl() */ |
387 | | /************************************************************************/ |
388 | | |
389 | | bool GDALVectorGridAbstractAlgorithm::RunImpl(GDALProgressFunc pfnProgress, |
390 | | void *pProgressData) |
391 | 0 | { |
392 | 0 | GDALPipelineStepRunContext stepCtxt; |
393 | 0 | stepCtxt.m_pfnProgress = pfnProgress; |
394 | 0 | stepCtxt.m_pProgressData = pProgressData; |
395 | 0 | return RunPreStepPipelineValidations() && RunStep(stepCtxt); |
396 | 0 | } |
397 | | |
398 | | /************************************************************************/ |
399 | | /* GDALVectorGridAbstractAlgorithm::AddRadiusArg() */ |
400 | | /************************************************************************/ |
401 | | |
402 | | GDALInConstructionAlgorithmArg &GDALVectorGridAbstractAlgorithm::AddRadiusArg() |
403 | 0 | { |
404 | 0 | return AddArg("radius", 0, _("Radius of the search circle"), &m_radius) |
405 | 0 | .SetMutualExclusionGroup("radius"); |
406 | 0 | } |
407 | | |
408 | | /************************************************************************/ |
409 | | /* GDALVectorGridAbstractAlgorithm::AddRadius1AndRadius2Arg() */ |
410 | | /************************************************************************/ |
411 | | |
412 | | void GDALVectorGridAbstractAlgorithm::AddRadius1AndRadius2Arg() |
413 | 0 | { |
414 | 0 | AddArg("radius1", 0, _("First axis of the search ellipse"), &m_radius1) |
415 | 0 | .SetMutualExclusionGroup("radius"); |
416 | 0 | AddArg("radius2", 0, _("Second axis of the search ellipse"), &m_radius2); |
417 | |
|
418 | 0 | AddValidationAction( |
419 | 0 | [this]() |
420 | 0 | { |
421 | 0 | bool ret = true; |
422 | 0 | if (m_radius1 > 0 && m_radius2 == 0) |
423 | 0 | { |
424 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
425 | 0 | "'radius2' should be defined when 'radius1' is."); |
426 | 0 | ret = false; |
427 | 0 | } |
428 | 0 | else if (m_radius2 > 0 && m_radius1 == 0) |
429 | 0 | { |
430 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
431 | 0 | "'radius1' should be defined when 'radius2' is."); |
432 | 0 | ret = false; |
433 | 0 | } |
434 | 0 | return ret; |
435 | 0 | }); |
436 | 0 | } |
437 | | |
438 | | /************************************************************************/ |
439 | | /* GDALVectorGridAbstractAlgorithm::AddAngleArg() */ |
440 | | /************************************************************************/ |
441 | | |
442 | | GDALInConstructionAlgorithmArg &GDALVectorGridAbstractAlgorithm::AddAngleArg() |
443 | 0 | { |
444 | 0 | return AddArg("angle", 0, |
445 | 0 | _("Angle of search ellipse rotation in degrees (counter " |
446 | 0 | "clockwise)"), |
447 | 0 | &m_angle) |
448 | 0 | .SetDefault(m_angle); |
449 | 0 | } |
450 | | |
451 | | /************************************************************************/ |
452 | | /* GDALVectorGridAbstractAlgorithm::AddMinPointsArg() */ |
453 | | /************************************************************************/ |
454 | | |
455 | | GDALInConstructionAlgorithmArg & |
456 | | GDALVectorGridAbstractAlgorithm::AddMinPointsArg() |
457 | 0 | { |
458 | 0 | return AddArg("min-points", 0, _("Minimum number of data points to use"), |
459 | 0 | &m_minPoints) |
460 | 0 | .SetDefault(m_minPoints); |
461 | 0 | } |
462 | | |
463 | | /************************************************************************/ |
464 | | /* GDALVectorGridAbstractAlgorithm::AddMaxPointsArg() */ |
465 | | /************************************************************************/ |
466 | | |
467 | | GDALInConstructionAlgorithmArg & |
468 | | GDALVectorGridAbstractAlgorithm::AddMaxPointsArg() |
469 | 0 | { |
470 | 0 | return AddArg("max-points", 0, _("Maximum number of data points to use"), |
471 | 0 | &m_maxPoints) |
472 | 0 | .SetDefault(m_maxPoints); |
473 | 0 | } |
474 | | |
475 | | /************************************************************************/ |
476 | | /* GDALVectorGridAbstractAlgorithm::AddMinMaxPointsPerQuadrantArg() */ |
477 | | /************************************************************************/ |
478 | | |
479 | | void GDALVectorGridAbstractAlgorithm::AddMinMaxPointsPerQuadrantArg() |
480 | 0 | { |
481 | 0 | AddArg("min-points-per-quadrant", 0, |
482 | 0 | _("Minimum number of data points to use per quadrant"), |
483 | 0 | &m_minPointsPerQuadrant) |
484 | 0 | .SetDefault(m_minPointsPerQuadrant); |
485 | 0 | AddArg("max-points-per-quadrant", 0, |
486 | 0 | _("Maximum number of data points to use per quadrant"), |
487 | 0 | &m_maxPointsPerQuadrant) |
488 | 0 | .SetDefault(m_maxPointsPerQuadrant); |
489 | 0 | } |
490 | | |
491 | | /************************************************************************/ |
492 | | /* GDALVectorGridAbstractAlgorithm::AddNodataArg() */ |
493 | | /************************************************************************/ |
494 | | |
495 | | GDALInConstructionAlgorithmArg &GDALVectorGridAbstractAlgorithm::AddNodataArg() |
496 | 0 | { |
497 | 0 | return AddArg("nodata", 0, _("Target nodata value"), &m_nodata) |
498 | 0 | .SetDefault(m_nodata); |
499 | 0 | } |
500 | | |
501 | 0 | GDALVectorGridAlgorithmStandalone::~GDALVectorGridAlgorithmStandalone() = |
502 | | default; |
503 | | |
504 | | //! @endcond |