[processing] fixes and new tools for LiDAR processing

courtesy of Niccolò Marchi
This commit is contained in:
Alexander Bruy 2017-01-25 11:41:34 +02:00
parent ecf1f5a576
commit f40fb9c4d2
30 changed files with 1074 additions and 87 deletions

View File

@ -140,6 +140,15 @@ from .fusion.FilterData import FilterData
from .fusion.PolyClipData import PolyClipData
from .fusion.ImageCreate import ImageCreate
from .fusion.IntensityImage import IntensityImage
from .fusion.DensityMetrics import DensityMetrics
from .fusion.MergeDTM import MergeDTM
from .fusion.TopoMetrics import TopoMetrics
from .fusion.TreeSeg import TreeSeg
from .fusion.SplitDTM import SplitDTM
from .fusion.MergeRaster import MergeRaster
from .fusion.SurfaceStats import SurfaceStats
from .fusion.ReturnDensity import ReturnDensity # spellok
from .fusion.GridSurfaceStats import GridSurfaceStats
from .fusion.FusionUtils import FusionUtils
@ -213,7 +222,8 @@ class LidarToolsAlgorithmProvider(AlgorithmProvider):
Csv2Grid(), Cover(), FilterData(), GridMetrics(), GroundFilter(),
GridSurfaceCreate(), MergeData(), TinSurfaceCreate(), PolyClipData(),
DTM2TIF(), DTM2ASCII(), FirstLastReturn(), ASCII2DTM(), ImageCreate(),
IntensityImage()
IntensityImage(), DensityMetrics(), MergeDTM(), TopoMetrics(), TreeSeg(),
SplitDTM(), MergeRaster(), SurfaceStats(), ReturnDensity(), GridSurfaceStats() # spellok
]
for alg in fusiontools:
alg.group, alg.i18n_group = alg.trAlgorithm('Fusion')

View File

@ -51,7 +51,7 @@ class ASCII2DTM(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('ASCII to DTM')
self.group, self.i18n_group = self.trAlgorithm('Conversion')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input ESRI ASCII layer')))
self.INPUT, self.tr('Input ESRI ASCII layer'), optional=False))
self.addParameter(ParameterSelection(
self.XYUNITS, self.tr('XY Units'), self.UNITS))
self.addParameter(ParameterSelection(

View File

@ -32,7 +32,7 @@ import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterBoolean
from processing.core.outputs import OutputTable
from processing.core.outputs import OutputFile
from .FusionUtils import FusionUtils
from .FusionAlgorithm import FusionAlgorithm
@ -46,43 +46,53 @@ class CanopyMaxima(FusionAlgorithm):
SUMMARY = 'SUMMARY'
PARAM_A = 'PARAM_A'
PARAM_C = 'PARAM_C'
SHAPE = 'SHAPE'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Canopy Maxima')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input FUSION canopy height model')))
self.INPUT, self.tr('Input PLANS DTM canopy height model'),
optional=False))
self.addParameter(ParameterFile(
self.GROUND, self.tr('Input ground .dtm layer [optional]')))
self.GROUND, self.tr('Input ground PLANS DTM layer [optional]')))
self.addParameter(ParameterNumber(
self.THRESHOLD, self.tr('Height threshold'), 0, None, 10.0))
# begin
self.THRESHOLD, self.tr('Limit analysis to areas above this height threshold'), 0, None, 10.0))
self.addParameter(ParameterNumber(
self.PARAM_A, self.tr('Variable window size: parameter A'), 0, None, 2.51503))
self.addParameter(ParameterNumber(
self.PARAM_C, self.tr('Parameter C'), 0, None, 0.00901))
self.addParameter(ParameterBoolean(
self.SUMMARY, self.tr('Summary (tree height summary statistics)'), False))
# end
self.addOutput(OutputTable(
self.OUTPUT, self.tr('Output file with maxima')))
summary = ParameterBoolean(
self.SUMMARY, self.tr('Tree height summary statistics'), False)
summary.isAdvanced = True
self.addParameter(summary)
shape = ParameterBoolean(
self.SHAPE, self.tr('Create output shapefiles'), False)
shape.isAdvanced = True
self.addParameter(shape)
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output file with maxima'), 'csv'))
self.addAdvancedModifiers()
def processAlgorithm(self, feedback):
commands = [os.path.join(FusionUtils.FusionPath(), 'CanopyMaxima.exe')]
commands.append('/verbose')
### begin
commands.append('/wse:' + str(self.getParameterValue(self.PARAM_A)) + ',0,' + str(self.getParameterValue(self.PARAM_C)) + ',0')
commands.append('/wse:' + unicode(self.getParameterValue(self.PARAM_A)) + ',0,' + unicode(self.getParameterValue(self.PARAM_C)) + ',0')
ground = self.getParameterValue(self.GROUND)
if ground:
gfiles = self.getParameterValue(self.GROUND).split(';')
if len(gfiles) == 1:
commands.append('/ground:' + str(ground))
else:
FusionUtils.createGroundList(gfiles)
commands.append('/ground:' + str(FusionUtils.tempGroundListFilepath()))
commands.append('/threshold:' + str(self.getParameterValue(self.THRESHOLD)))
if self.getParameterValue(self.SUMMARY):
commands.append('/summary')
### end
self.addAdvancedModifiersToCommand(commands)
ground = self.getParameterValue(self.GROUND)
## here it's necessary to have the support for multiple files like for INPUT.
if str(ground).strip():
commands.append('/ground:' + str(ground))
commands.append('/threshold:'
+ str(self.getParameterValue(self.THRESHOLD)))
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))

View File

@ -45,6 +45,7 @@ class CanopyModel(FusionAlgorithm):
INPUT = 'INPUT'
OUTPUT_DTM = 'OUTPUT_DTM'
ASPECT = 'ASPECT'
CELLSIZE = 'CELLSIZE'
XYUNITS = 'XYUNITS'
ZUNITS = 'ZUNITS'
@ -54,13 +55,15 @@ class CanopyModel(FusionAlgorithm):
SMOOTH = 'SMOOTH'
SLOPE = 'SLOPE'
CLASS = 'CLASS'
RETURN = 'RETURN'
ASCII = 'ASCII'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Canopy Model')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterNumber(
self.CELLSIZE, self.tr('Cell Size'), 0, None, 10.0))
self.addParameter(ParameterSelection(
@ -70,7 +73,7 @@ class CanopyModel(FusionAlgorithm):
self.addOutput(OutputFile(
self.OUTPUT_DTM, self.tr('.dtm output surface'), 'dtm'))
ground = ParameterFile(
self.GROUND, self.tr('Input ground DTM layer'), False, True)
self.GROUND, self.tr('Input ground PLANS DTM layer'), False, True)
ground.isAdvanced = True
self.addParameter(ground)
median = ParameterString(
@ -82,13 +85,21 @@ class CanopyModel(FusionAlgorithm):
smooth.isAdvanced = True
self.addParameter(smooth)
class_var = ParameterString(
self.CLASS, self.tr('Class'), '', False, True)
self.CLASS, self.tr('Select specific class'), '', False, True)
class_var.isAdvanced = True
self.addParameter(class_var)
ret_num = ParameterString(
self.RETURN, self.tr('Select specific return'), '', False, True)
ret_num.isAdvanced = True
self.addParameter(ret_num)
slope = ParameterBoolean(
self.SLOPE, self.tr('Calculate slope'), False)
slope.isAdvanced = True
self.addParameter(slope)
aspec = ParameterBoolean(
self.ASPECT, self.tr('Calculate aspect'), False)
aspec.isAdvanced = True
self.addParameter(aspect)
self.addParameter(ParameterBoolean(
self.ASCII, self.tr('Add an ASCII output'), False))
self.addAdvancedModifiers()
@ -98,7 +109,12 @@ class CanopyModel(FusionAlgorithm):
commands.append('/verbose')
ground = self.getParameterValue(self.GROUND)
if str(ground).strip():
commands.append('/ground:' + str(ground))
gfiles = self.getParameterValue(self.GROUND).split(';')
if len(gfiles) == 1:
commands.append('/ground:' + str(ground))
else:
FusionUtils.createGroundList(gfiles)
commands.append('/ground:' + str(FusionUtils.tempGroundListFilepath()))
median = self.getParameterValue(self.MEDIAN)
if str(median).strip():
commands.append('/median:' + str(median))
@ -108,11 +124,17 @@ class CanopyModel(FusionAlgorithm):
slope = self.getParameterValue(self.SLOPE)
if slope:
commands.append('/slope')
aspect = self.getParameterValue(self.ASPECT)
if aspect:
commands.append('/aspect')
class_var = self.getParameterValue(self.CLASS)
if str(class_var).strip():
commands.append('/class:' + str(class_var))
ascii = self.getParameterValue(self.ASCII)
if ascii:
ret_num = self.getParameterValue(self.RETURN)
if str(ret_num).strip():
commands.append('/return:' + str(ret_num))
use_ascii = self.getParameterValue(self.ASCII)
if use_ascii:
commands.append('/ascii')
self.addAdvancedModifiersToCommand(commands)
commands.append(self.getOutputValue(self.OUTPUT_DTM))

View File

@ -29,6 +29,7 @@ __revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterBoolean
from processing.core.outputs import OutputFile
from .FusionUtils import FusionUtils
from .FusionAlgorithm import FusionAlgorithm
@ -41,13 +42,19 @@ class Catalog(FusionAlgorithm):
DENSITY = 'DENSITY'
FIRSTDENSITY = 'FIRSTDENSITY'
INTENSITY = 'INTENSITY'
INDEX = 'INDEX'
IMAGE = 'IMAGE'
DRAWTILES = 'DRAWTILES'
COVERAGE = 'COVERAGE'
CRETURNS = 'CRETURNS'
ADVANCED_MODIFIERS = 'ADVANCED_MODIFIERS'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Catalog')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addOutput(OutputFile(self.OUTPUT, self.tr('Output files')))
density = ParameterString(
self.DENSITY,
@ -67,6 +74,16 @@ class Catalog(FusionAlgorithm):
'', False, True)
intensity.isAdvanced = True
self.addParameter(intensity)
self.addParameter(ParameterBoolean(self.INDEX,
self.tr('Create LIDAR data file indexes'), False))
self.addParameter(ParameterBoolean(self.IMAGE,
self.tr('Create image files showing the coverage area for each LIDAR file'), False))
self.addParameter(ParameterBoolean(self.DRAWTILES,
self.tr('Draw data file extents and names on the intensity image'), False))
self.addParameter(ParameterBoolean(self.COVERAGE,
self.tr('Create one image that shows the nominal coverage area'), False))
self.addParameter(ParameterBoolean(self.CRETURNS,
self.tr('Adds count return columns in the CSV and HTML output'), False))
advanced_modifiers = ParameterString(
self.ADVANCED_MODIFIERS,
self.tr('Additional modifiers'), '', False, True)
@ -85,6 +102,21 @@ class Catalog(FusionAlgorithm):
firstdensity = self.getParameterValue(self.FIRSTDENSITY)
if str(firstdensity).strip():
commands.append('/firstdensity:' + str(firstdensity))
index = self.getParameterValue(self.INDEX)
if str(index).strip():
commands.append('/index')
drawtiles = self.getParameterValue(self.IMAGE)
if str(drawtiles).strip():
commands.append('/drawtiles')
coverage = self.getParameterValue(self.DRAWTILES)
if str(coverage).strip():
commands.append('/coverage')
image = self.getParameterValue(self.COVERAGE)
if str(image).strip():
commands.append('/image')
creturns = self.getParameterValue(self.COVERAGE)
if str(creturns).strip():
commands.append('/countreturns')
advanced_modifiers = str(self.getParameterValue(self.ADVANCED_MODIFIERS)).strip()
if advanced_modifiers:
commands.append(advanced_modifiers)

View File

@ -51,10 +51,11 @@ class ClipData(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Clip Data')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterExtent(self.EXTENT, self.tr('Extent'), optional=False))
self.addParameter(ParameterSelection(
self.SHAPE, self.tr('Shape'), ['Rectangle', 'Circle']))
self.SHAPE, self.tr('Shape of the sample area'), ['Rectangle', 'Circle']))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output clipped LAS file')))
dtm = ParameterFile(
@ -74,7 +75,12 @@ class ClipData(FusionAlgorithm):
commands.append('/shape:' + str(self.getParameterValue(self.SHAPE)))
dtm = self.getParameterValue(self.DTM)
if dtm:
commands.append('/dtm:' + str(dtm))
gfiles = self.getParameterValue(self.DTM).split(';')
if len(gfiles) == 1:
commands.append('/ground:' + str(dtm))
else:
FusionUtils.createGroundList(gfiles)
commands.append('/ground:' + str(FusionUtils.tempGroundListFilepath()))
height = self.getParameterValue(self.HEIGHT)
if height:
commands.append('/height')

View File

@ -32,11 +32,11 @@ __revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterBoolean
from processing.core.outputs import OutputFile
from .FusionUtils import FusionUtils
from .FusionAlgorithm import FusionAlgorithm
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterBoolean
class CloudMetrics(FusionAlgorithm):
@ -52,10 +52,11 @@ class CloudMetrics(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Cloud Metrics')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output file with tabular metric information'), 'csv'))
above = ParameterString(self.ABOVE, self.tr('Above'), '', False)
above = ParameterNumber(self.ABOVE, self.tr('Compute cover statistics above the following heightbreak:'), 0, None, 0.0)
above.isAdvanced = True
self.addParameter(above)
firstImpulse = ParameterBoolean(
@ -66,7 +67,7 @@ class CloudMetrics(FusionAlgorithm):
self.FIRSTRETURN, self.tr('First Return'), False)
firstReturn.isAdvanced = True
self.addParameter(firstReturn)
htmin = ParameterString(self.HTMIN, self.tr('Htmin'), '', False, True)
htmin = ParameterNumber(self.HTMIN, self.tr('Use only returns above this minimum height:'), 0, None, 0)
htmin.isAdvanced = True
self.addParameter(htmin)
@ -74,7 +75,7 @@ class CloudMetrics(FusionAlgorithm):
commands = [os.path.join(FusionUtils.FusionPath(), 'CloudMetrics.exe')]
commands.append('/verbose')
above = self.getParameterValue(self.ABOVE)
if str(above).strip() != '':
if above != 0.0:
commands.append('/above:' + str(above))
firstImpulse = self.getParameterValue(self.FIRSTIMPULSE)
if firstImpulse:
@ -83,7 +84,7 @@ class CloudMetrics(FusionAlgorithm):
if firstReturn:
commands.append('/firstreturn')
htmin = self.getParameterValue(self.HTMIN)
if str(htmin).strip() != '':
if htmin != 0.0:
commands.append('/minht:' + str(htmin))
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:

View File

@ -31,6 +31,7 @@ __revision__ = '$Format:%H$'
import os
import subprocess
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterSelection
from processing.core.outputs import OutputRaster
@ -45,6 +46,8 @@ class Cover(FusionAlgorithm):
CELLSIZE = 'CELLSIZE'
HEIGHTBREAK = 'HEIGHTREAK'
GROUND = 'GROUND'
ALLRETS = 'ALLRETS'
PENETRATION = 'PENETRATION'
XYUNITS = 'XYUNITS'
ZUNITS = 'ZUNITS'
UNITS = ['Meter', 'Feet']
@ -53,27 +56,42 @@ class Cover(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Cover')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterFile(
self.GROUND, self.tr('Input ground DTM layer')))
self.GROUND, self.tr('Input ground PLANS DTM layer'),
optional=False))
self.addParameter(ParameterNumber(
self.CELLSIZE, self.tr('Cell Size'), 0, None, 10.0))
self.addParameter(ParameterNumber(
self.HEIGHTBREAK, self.tr('Heightbreak'), 0, None, 10.0))
self.HEIGHTBREAK, self.tr('Heightbreak for the cover calculation (see help)'), 0, None, 10.0))
self.addParameter(ParameterSelection(
self.XYUNITS, self.tr('XY Units'), self.UNITS))
self.addParameter(ParameterSelection(
self.ZUNITS, self.tr('Z Units'), self.UNITS))
self.addOutput(OutputRaster(self.OUTPUT, self.tr('Cover')))
self.addParameter(ParameterBoolean(
self.ALLRETS, self.tr('Use all returns instead of only first'), False))
self.addParameter(ParameterBoolean(
self.PENETRATION, self.tr('Compute the proportion of returns close to the ground surface'), False))
self.addOutput(OutputFile(self.OUTPUT, self.tr('Cover output file')))
self.addAdvancedModifiers()
def processAlgorithm(self, feedback):
commands = [os.path.join(FusionUtils.FusionPath(), 'Cover.exe')]
commands.append('/verbose')
allrets = self.getParameterValue(self.ALLRETS)
if str(allrets).strip() != '':
commands.append('/all')
penetration = self.getParameterValue(self.PENETRATION)
if penetration:
commands.append('/penetration')
self.addAdvancedModifiersToCommand(commands)
ground = self.getParameterValue(self.GROUND)
if str(ground).strip() != '':
commands.append('/ground:' + str(ground))
ground = self.getParameterValue(self.GROUND).split(';')
if len(ground) == 1:
commands.append(self.getParameterValue(self.GROUND))
else:
FusionUtils.createGroundList(ground)
commands.append(FusionUtils.tempGroundListFilepath())
outFile = self.getOutputValue(self.OUTPUT) + '.dtm'
commands.append(outFile)
commands.append(str(self.getParameterValue(self.HEIGHTBREAK)))

View File

@ -27,7 +27,7 @@ __revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
@ -42,8 +42,8 @@ class Csv2Grid(FusionAlgorithm):
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Csv2Grid')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(self.INPUT, self.tr('CSV Files')))
self.addParameter(ParameterString(self.COLUMN, self.tr('Column')))
self.addParameter(ParameterFile(self.INPUT, self.tr('CSV Files'), optional=False))
self.addParameter(ParameterNumber(self.COLUMN, self.tr('Column'), 0, None, 0z))
self.addOutput(OutputFile(self.OUTPUT, self.tr('Raster Output file'), 'asc'))
def processAlgorithm(self, feedback):

View File

@ -43,7 +43,8 @@ class DTM2ASCII(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('DTM to ASCII')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input canopy surface (.dtm)')))
self.INPUT, self.tr('Input canopy surface (.dtm)'),
optional=False))
self.addParameter(ParameterSelection(
self.SWITCH, self.tr('Output format'), ['raster (ASCII)', 'csv']))

View File

@ -44,7 +44,8 @@ class DTM2TIF(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('DTM to TIF')
self.group, self.i18n_group = self.trAlgorithm('Conversion')
self.addParameter(ParameterFile(
self.INPUT, self.tr("Input .dtm layer")))
self.INPUT, self.tr("Input .dtm layer"),
optional=False))
self.addOutput(OutputRaster(self.OUTPUT, self.tr('Output file name')))
self.addAdvancedModifiers()

View File

@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
DensityMetrics.py
---------------------
Date : August 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'August 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
import subprocess
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class DensityMetrics(FusionAlgorithm):
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
CELLSIZE = 'CELLSIZE'
SLICE = 'SLICE'
GROUND = 'GROUND'
FIRST = 'FIRST'
NOCSV = 'NOCSV'
HTLIM = 'HTLIM'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Density Metrics')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer'), optional=False))
self.addParameter(ParameterFile(
self.GROUND, self.tr('Input ground PLANS DTM layer'), optional=False))
self.addParameter(ParameterNumber(
self.CELLSIZE, self.tr('Cellsize'), 0, None, 5.0))
self.addParameter(ParameterNumber(
self.SLICE, self.tr('Slice thickness'), 0, None, 2.0))
self.addParameter(ParameterNumber(
self.HTLIM, self.tr('Maximum height limit'), 0, None, 50.0))
self.addParameter(ParameterBoolean(
self.FIRST, self.tr('Use only first returns'), False))
self.addParameter(ParameterBoolean(
self.NOCSV, self.tr('Do not create a CSV output file for cell metrics'), False))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Base name for output files')))
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'DensityMetrics.exe')]
commands.append('/verbose')
first = self.getParameterValue(self.FIRST)
if first:
commands.append('/first')
nocsv = self.getParameterValue(self.NOCSV)
if nocsv:
commands.append('/nocsv')
commands.append('/maxsliceht:' + unicode(self.getParameterValue(self.HTLIM)))
self.addAdvancedModifiersToCommand(commands)
ground = self.getParameterValue(self.GROUND).split(';')
if len(ground) == 1:
commands.append(self.getParameterValue(self.GROUND))
else:
FusionUtils.createGroundList(ground)
commands.append(FusionUtils.tempGroundListFilepath())
commands.append(unicode(self.getParameterValue(self.CELLSIZE)))
commands.append(unicode(self.getParameterValue(self.SLICE)))
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
FusionUtils.runFusion(commands, progress)

View File

@ -48,7 +48,8 @@ class FilterData(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Filter Data outliers')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterNumber(
self.VALUE, self.tr('Standard Deviation multiplier')))
self.addParameter(ParameterNumber(
@ -61,7 +62,7 @@ class FilterData(FusionAlgorithm):
commands = [os.path.join(FusionUtils.FusionPath(), 'FilterData.exe')]
commands.append('/verbose')
self.addAdvancedModifiersToCommand(commands)
commands.append('/outlier')
commands.append('outlier')
commands.append(str(self.getParameterValue(self.VALUE)))
commands.append(str(self.getParameterValue(self.WINDOWSIZE)))
outFile = self.getOutputValue(self.OUTPUT)

View File

@ -75,3 +75,15 @@ class FusionUtils(object):
for line in iter(proc.readline, ''):
loglines.append(line)
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
@staticmethod
def tempGroundListFilepath():
filename = 'fusion_groundFiles_list.txt'
filepath = os.path.join(userFolder(), filename)
return filepath
@staticmethod
def createGroundList(gfiles):
with open(FusionUtils.tempGroundListFilepath(), 'w') as outg:
for f in gfiles:
outg.write(f + '\n')

View File

@ -52,6 +52,7 @@ class GridMetrics(FusionAlgorithm):
CELLSIZE = 'CELLSIZE'
OUTLIER = 'OUTLIER'
FIRST = 'FIRST'
FUEL = 'FUEL'
MINHT = 'MINHT'
CLASS = 'CLASS'
@ -59,13 +60,19 @@ class GridMetrics(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Grid Metrics')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterFile(
self.GROUND, self.tr('Input ground DTM layer')))
self.GROUND, self.tr('Input ground PLANS DTM layer'),
optional=False))
self.addParameter(ParameterNumber(
self.HEIGHT, self.tr('Height break')))
self.addParameter(ParameterNumber(
self.CELLSIZE, self.tr('Cell Size')))
self.addParameter(ParameterBoolean(
self.FIRST, self.tr('Use only first returns'), False))
self.addParameter(ParameterBoolean(
self.FUEL, self.tr('Apply fuel parameter models (cannot be used with /first switch)'), False))
self.addOutput(OutputFile(
self.OUTPUT_CSV_ELEVATION, self.tr('Output table with grid metrics')))
@ -89,9 +96,6 @@ class GridMetrics(FusionAlgorithm):
self.OUTLIER, self.tr('Outlier:low,high'), '', False, True)
outlier.isAdvanced = True
self.addParameter(outlier)
first = ParameterBoolean(self.FIRST, self.tr('First'), False)
first.isAdvanced = True
self.addParameter(first)
minht = ParameterString(self.MINHT, self.tr('Htmin'), '', False, True)
minht.isAdvanced = True
self.addParameter(minht)
@ -99,6 +103,7 @@ class GridMetrics(FusionAlgorithm):
self.CLASS, self.tr('Class (set blank if not used)'), '', False, True)
class_var.isAdvanced = True
self.addParameter(class_var)
self.addAdvancedModifiers()
def processAlgorithm(self, feedback):
commands = [os.path.join(FusionUtils.FusionPath(), 'GridMetrics.exe')]
@ -109,15 +114,24 @@ class GridMetrics(FusionAlgorithm):
first = self.getParameterValue(self.FIRST)
if first:
commands.append('/first')
fuel = self.getParameterValue(self.FUEL)
if fuel:
commands.append('/fuel')
minht = self.getParameterValue(self.MINHT)
if str(minht).strip() != '':
commands.append('/minht:' + str(minht))
class_var = self.getParameterValue(self.CLASS)
if str(class_var).strip() != '':
commands.append('/class:' + str(class_var))
commands.append(self.getParameterValue(self.GROUND))
self.addAdvancedModifiersToCommand(commands)
ground = self.getParameterValue(self.GROUND).split(';')
if len(ground) == 1:
commands.append(self.getParameterValue(self.GROUND))
else:
FusionUtils.createGroundList(ground)
commands.append(FusionUtils.tempGroundListFilepath())
commands.append(str(self.getParameterValue(self.HEIGHT)))
commands.append(str(self.getParameterValue(self.CELLSIZE)))
commands.append(str(self.getParameterValue(self.CELLSIZE)))
commands.append(self.getOutputValue(self.OUTPUT_CSV_ELEVATION))
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:

View File

@ -61,7 +61,8 @@ class GridSurfaceCreate(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Grid Surface Create')
self.group, self.i18n_group = self.trAlgorithm('Surface')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterNumber(
self.CELLSIZE, self.tr('Cell Size'), 0, None, 10.0))
self.addParameter(ParameterSelection(
@ -70,28 +71,28 @@ class GridSurfaceCreate(FusionAlgorithm):
self.ZUNITS, self.tr('Z Units'), self.UNITS))
self.addOutput(OutputFile(
self.OUTPUT_DTM, self.tr('DTM Output Surface'), 'dtm'))
spike = ParameterString(
self.SPIKE, self.tr('Spike (set blank if not used)'), '', False, True)
spike = ParameterNumber(
self.SPIKE, self.tr('Filter final surface to remove spikes with slopes greater than # percent'), 0, None, 0.0)
spike.isAdvanced = True
self.addParameter(spike)
median = ParameterString(
self.MEDIAN, self.tr('Median'), '', False, True)
median = ParameterNumber(
self.MEDIAN, self.tr('Apply median filter to model using # by # neighbor window'), 0, None, 0.0)
median.isAdvanced = True
self.addParameter(median)
smooth = ParameterString(
self.SMOOTH, self.tr('Smooth'), '', False, True)
smooth = ParameterNumber(
self.SMOOTH, self.tr('Apply mean filter to model using # by # neighbor window'), 0, None, 0.0)
smooth.isAdvanced = True
self.addParameter(smooth)
slope = ParameterString(
self.SLOPE, self.tr('Slope'), '', False, True)
slope = ParameterNumber(
self.SLOPE, self.tr('Filter areas from the surface with slope greater than # percent'), 0, None, 0.0)
slope.isAdvanced = True
self.addParameter(slope)
minimum = ParameterBoolean(
self.MINIMUM, self.tr('Minimum (set blank if not used)'), False)
self.MINIMUM, self.tr('Use the lowest point in each cell as the surface elevation'), False)
minimum.isAdvanced = True
self.addParameter(minimum)
class_var = ParameterString(
self.CLASS, self.tr('Class(es)'), 2, False, True)
self.CLASS, self.tr('Class(es)'), '', False, True)
class_var.isAdvanced = True
self.addParameter(class_var)
advance_modifiers = ParameterString(
@ -103,16 +104,16 @@ class GridSurfaceCreate(FusionAlgorithm):
commands = [os.path.join(FusionUtils.FusionPath(), 'GridSurfaceCreate.exe')]
commands.append('/verbose')
spike = self.getParameterValue(self.SPIKE)
if str(spike).strip():
if spike != 0.0:
commands.append('/spike:' + str(spike))
median = self.getParameterValue(self.MEDIAN)
if str(median).strip():
if median != 0.0:
commands.append('/median:' + str(median))
smooth = self.getParameterValue(self.SMOOTH)
if str(smooth).strip():
if smooth != 0.0:
commands.append('/smooth:' + str(smooth))
slope = self.getParameterValue(self.SLOPE)
if str(slope).strip():
if slope != 0.0:
commands.append('/slope:' + str(slope))
minimum = self.getParameterValue(self.MINIMUM)
if str(minimum).strip():

View File

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
GridSurfaceStats.py
---------------------
Date : November 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'November 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterBoolean
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class GridSurfaceStats(FusionAlgorithm):
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
SAFACT = 'SAFACT'
AREA = 'AREA'
ASCII = 'ASCII'
SVONLY = 'SVONLY'
GROUND = 'GROUND'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Grid Surface Stats')
self.group, self.i18n_group = self.trAlgorithm('Surface')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input PLANS DTM canopy height model'), optional=False))
self.addParameter(ParameterNumber(
self.SAFACT, self.tr('Multiplier for outputfile cell size'), 0, None, 1.0))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output file')))
area = ParameterBoolean(
self.AREA, self.tr('Compute the surface area of inputfile instead of the surface area divided by the flat cell area'), False)
area.isAdvanced = True
self.addParameter(area)
ascii = ParameterBoolean(
self.ASCII, self.tr('Output all files in ASCII raster format instead of PLANS DTM ones'), False)
ascii.isAdvanced = True
self.addParameter(ascii)
svonly = ParameterBoolean(
self.SVONLY, self.tr('Output only the surface volume metric layer'), False)
svonly.isAdvanced = True
self.addParameter(svonly)
ground = ParameterFile(
self.GROUND, self.tr('Use the specified surface model to represent the ground surface'), False, True)
ground.isAdvanced = True
self.addParameter(ground)
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'GridSurfaceStats.exe')]
commands.append('/verbose')
area = self.getParameterValue(self.AREA)
if area:
commands.append('/area')
ascii = self.getParameterValue(self.ASCII)
if ascii:
commands.append('/ascii')
svonly = self.getParameterValue(self.SVONLY)
if svonly:
commands.append('/svonly')
ground = self.getParameterValue(self.GROUND)
if ground:
gfiles = self.getParameterValue(self.GROUND).split(';')
if len(gfiles) == 1:
commands.append('/ground:' + unicode(ground))
else:
FusionUtils.createGroundList(gfiles)
commands.append('/ground:' + unicode(FusionUtils.tempGroundListFilepath()))
self.addAdvancedModifiersToCommand(commands)
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
commands.append(self.getOutputValue(self.OUTPUT))
commands.append(unicode(self.getParameterValue(self.SAFACT)))
FusionUtils.runFusion(commands, progress)

View File

@ -48,7 +48,8 @@ class GroundFilter(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Ground Filter')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterNumber(self.CELLSIZE,
self.tr('Cell size for intermediate surfaces'), 0, None, 10))
self.addOutput(OutputFile(

View File

@ -52,7 +52,8 @@ class ImageCreate(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('ImageCreate')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS')))
self.INPUT, self.tr('Input LAS'),
optional=False))
self.addParameter(ParameterSelection(
self.COLOROPTION, self.tr('Method to assign color'),
['Intensity', 'Elevation', 'Height']))
@ -72,14 +73,20 @@ class ImageCreate(FusionAlgorithm):
commands.append('/verbose')
commands.append('/coloroption:' + str(self.getParameterValue(self.COLOROPTION)))
ground = self.getParameterValue(self.GROUND)
if str(ground).strip():
commands.append('/dtm:' + str(ground))
if ground:
gfiles = self.getParameterValue(self.GROUND).split(';')
if len(gfiles) == 1:
commands.append('/ground:' + str(ground))
else:
FusionUtils.createGroundList(gfiles)
commands.append('/ground:' + str(FusionUtils.tempGroundListFilepath()))
if self.getParameterValue(self.RGB):
commands.append('/rgb')
if self.getParameterValue(self.SWITCH) == 0:
commands.append('/jpg')
else:
commands.append('/bmp')
self.addAdvancedModifiersToCommand(commands)
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
commands.append(str(self.getParameterValue(self.PIXEL)))

View File

@ -46,6 +46,7 @@ class IntensityImage(FusionAlgorithm):
HIST = 'HIST'
PIXEL = 'PIXEL'
SWITCH = 'SWITCH'
FALIGN = 'FALIGN'
OUTPUT = 'OUTPUT'
def defineCharacteristics(self):
@ -53,7 +54,8 @@ class IntensityImage(FusionAlgorithm):
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input file')))
self.INPUT, self.tr('Input file'),
optional=False))
self.addParameter(ParameterBoolean(
self.ALLRET, self.tr('Use all returns instead of only first'), False))
self.addParameter(ParameterBoolean(
@ -64,6 +66,10 @@ class IntensityImage(FusionAlgorithm):
self.PIXEL, self.tr('Pixel size'), 0, None, 1.0))
self.addParameter(ParameterSelection(
self.SWITCH, self.tr('Output format'), ['Bitmap', 'JPEG']))
falign = ParameterBoolean(
self.FALIGN, self.tr('Force alignment to match other raster products'), False)
falign.isAdvanced = True
self.addParameter(falign)
self.addOutput(OutputFile(self.OUTPUT, 'Output image'))
self.addAdvancedModifiers()
@ -78,7 +84,9 @@ class IntensityImage(FusionAlgorithm):
commands.append('/hist')
if self.getParameterValue(self.SWITCH) == 1:
commands.append('/jpg')
commands.append(str(self.getParameterValue(self.PIXEL)))
if self.getParameterValue(self.FALIGN):
commands.append('/rasterorigin')
commands.append(unicode(self.getParameterValue(self.PIXEL)))
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
files = self.getParameterValue(self.INPUT).split(';')

View File

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
MergeDTM.py
---------------------
Date : August 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'August 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class MergeDTM(FusionAlgorithm):
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
CELLSIZE = 'CELLSIZE'
EXTENT = 'EXTENT'
DISK = 'DISK'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Merge PLANS DTM files')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input PLANS DTM files'), optional=False))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output merged file')))
cellsize = ParameterNumber(
self.CELLSIZE, self.tr('Resample the input DTM data to the following cellsize'), 0, None, 0.0)
cellsize.isAdvanced = True
self.addParameter(cellsize)
extent = ParameterBoolean(
self.EXTENT, self.tr('Preserve the exact extent of the input models'), False)
extent.isAdvanced = True
self.addParameter(extent)
disk = ParameterBoolean(
self.DISK, self.tr('Merge the files to a disk file. USE ONLY IF DEFAULT METHOD FAILS'), False)
disk.isAdvanced = True
self.addParameter(disk)
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'MergeDTM.exe')]
commands.append('/verbose')
cellsize = self.getParameterValue(self.CELLSIZE)
if cellsize != 0.0:
commands.append('/cellsize:' + unicode(self.getParameterValue(self.CELLSIZE)))
extent = self.getParameterValue(self.EXTENT)
if extent:
commands.append('/exactextent')
disk = self.getParameterValue(self.DISK)
if disk:
commands.append('/disk')
self.addAdvancedModifiersToCommand(commands)
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
FusionUtils.runFusion(commands, progress)

View File

@ -43,7 +43,9 @@ class MergeData(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Merge LAS Files')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS files')))
self.INPUT, self.tr('Input LAS files'),
optional=False))
self.addAdvancedModifiers()
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output merged LAS file')))

View File

@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
MergeRaster.py
---------------------
Date : November 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'November 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterString
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class MergeRaster(FusionAlgorithm):
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
OVERL = 'OVERL'
COMP = 'COMP'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Merge ASCII files')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input ASCII files'), optional=False))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output file'), 'asc'))
overl = ParameterString(
self.OVERL, self.tr('Specify how overlap areas should be treated'), '', False, True)
overl.isAdvanced = True
self.addParameter(overl)
comp = ParameterBoolean(
self.COMP, self.tr('Compare values in cells common to two or more input files'), False)
comp.isAdvanced = True
self.addParameter(comp)
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'MergeRaster.exe')]
commands.append('/verbose')
overl = self.getParameterValue(self.OVERL)
if overl:
commands.append('/overlap:' + unicode(overl))
comp = self.getParameterValue(self.COMP)
if comp:
commands.append('/compare')
self.addAdvancedModifiersToCommand(commands)
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
FusionUtils.runFusion(commands, progress)

View File

@ -45,21 +45,22 @@ class PolyClipData(FusionAlgorithm):
MASK = 'MASK'
FIELD = 'FIELD'
VALUE = 'VALUE'
MULTIFILE = 'MULTIFILE'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Poly Clip Data')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.addParameter(ParameterFile(self.MASK, self.tr('Mask layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterFile(self.MASK, self.tr('Mask layer'), optional=False))
self.addOutput(OutputFile(self.OUTPUT,
self.tr('Output clipped LAS file'), 'las'))
self.addParameter(ParameterBoolean(self.SHAPE,
self.tr('Use Shape attribute'), False))
## 'field' e 'value' box should appear or get activated if Shape attribute is switched ON
self.addParameter(ParameterString(self.SHAPE, self.tr("Use Shape attribute (shp column number,value)"), optional=True))
self.addParameter(ParameterString(self.FIELD,
self.tr('Shape field index')))
self.addParameter(ParameterString(self.VALUE, self.tr("Shape value")))
self.addParameter(ParameterBoolean(self.MULTIFILE, self.tr('Create a file per each polygon'), False))
self.addAdvancedModifiers()
def processAlgorithm(self, feedback):
@ -67,6 +68,9 @@ class PolyClipData(FusionAlgorithm):
commands.append('/verbose')
if self.getParameterValue(self.SHAPE):
commands.append('/shape:' + str(self.getParameterValue(self.FIELD)) + ',' + str(self.getParameterValue(self.VALUE)))
multiFile = self.getParameterValue(self.MULTIFILE)
if multiFile:
commands.append('/multifile')
self.addAdvancedModifiersToCommand(commands)
commands.append(self.getParameterValue(self.MASK))
outFile = self.getOutputValue(self.OUTPUT)

View File

@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
ReturnDensity.py #spellok
---------------------
Date : November 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'November 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterString
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class ReturnDensity(FusionAlgorithm): # spellok
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
CELLSIZE = 'CELLSIZE'
FIRST = 'FIRST'
ASCII = 'ASCII'
CLASS = 'CLASS'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Return Density')
self.group, self.i18n_group = self.trAlgorithm('Surface')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer'), optional=False))
self.addParameter(ParameterNumber(
self.CELLSIZE, self.tr('Cellsize'), 0, None, 10.0))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output file')))
first = ParameterBoolean(
self.FIRST, self.tr('Use only first returns when computing return counts'), False)
first.isAdvanced = True
self.addParameter(first)
ascii = ParameterBoolean(
self.ASCII, self.tr('Output raster data in ASCII raster format instead of PLANS DTM format'), False)
ascii.isAdvanced = True
self.addParameter(ascii)
class_var = ParameterString(
self.CLASS, self.tr('LAS class'), '', False, True)
class_var.isAdvanced = True
self.addParameter(class_var)
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'ReturnDensity.exe')] # spellok
commands.append('/verbose')
first = self.getParameterValue(self.FIRST)
if first:
commands.append('/first')
ascii = self.getParameterValue(self.ASCII)
if ascii:
commands.append('/ascii')
class_var = self.getParameterValue(self.CLASS)
if class_var:
commands.append('/class:' + unicode(class_var))
self.addAdvancedModifiersToCommand(commands)
commands.append(self.getOutputValue(self.OUTPUT))
commands.append(unicode(self.getParameterValue(self.CELLSIZE)))
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
FusionUtils.runFusion(commands, progress)

View File

@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
SplitDTM.py
---------------------
Date : November 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'November 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterString
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class SplitDTM(FusionAlgorithm):
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
COLUMNS = 'COLUMNS'
ROWS = 'ROWS'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Split PLANS DTM files')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input PLANS DTM file'), optional=False))
self.addParameter(ParameterNumber(
self.COLUMNS, self.tr('Number of columns of tiles'), 0, None, 1))
self.addParameter(ParameterNumber(
self.ROWS, self.tr('Number of rows of tiles'), 0, None, 1))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output files')))
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'SplitDTM.exe')]
commands.append('/verbose')
self.addAdvancedModifiersToCommand(commands)
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
commands.append(unicode(self.getParameterValue(self.COLUMNS)))
commands.append(unicode(self.getParameterValue(self.ROWS)))
FusionUtils.runFusion(commands, progress)

View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
SurfaceStats.py
---------------------
Date : November 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'November 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterFile
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class SurfaceStats(FusionAlgorithm):
INPUT = "INPUT"
OUTPUT = "OUTPUT"
GROUND = 'GROUND'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Surface Statistics')
self.group, self.i18n_group = self.trAlgorithm('Surface')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input PLANS DTM layer'), optional=False))
self.addOutput(OutputFile(self.OUTPUT, self.tr('Output file name'), 'csv'))
ground = ParameterFile(
self.GROUND, self.tr('Use the specified surface model to represent the ground surface'))
ground.isAdvanced = True
self.addParameter(ground)
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), "SurfaceStats.exe")]
commands.append('/verbose')
ground = self.getParameterValue(self.GROUND)
if ground:
gfiles = self.getParameterValue(self.GROUND).split(';')
if len(gfiles) == 1:
commands.append('/ground:' + unicode(ground))
else:
FusionUtils.createGroundList(gfiles)
commands.append('/ground:' + unicode(FusionUtils.tempGroundListFilepath()))
self.addAdvancedModifiersToCommand(commands)
files = self.getParameterValue(self.INPUT).split(";")
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
FusionUtils.runFusion(commands, progress)

View File

@ -52,7 +52,8 @@ class TinSurfaceCreate(FusionAlgorithm):
self.name, self.i18n_name = self.trAlgorithm('Tin Surface Create')
self.group, self.i18n_group = self.trAlgorithm('Surface')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input LAS layer')))
self.INPUT, self.tr('Input LAS layer'),
optional=False))
self.addParameter(ParameterNumber(self.CELLSIZE,
self.tr('Cell Size'), 0, None, 10.0))
self.addParameter(ParameterSelection(self.XYUNITS,

View File

@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
TopoMetrics.py
---------------------
Date : August 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'August 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class TopoMetrics(FusionAlgorithm):
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
CELLSIZE = 'CELLSIZE'
POINTSP = 'POINTSP'
LATITUDE = 'LATITUDE'
TPI = 'TPI'
SQUARE = 'SQUARE'
DISK = 'DISK'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Topographic Metrics')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input PLANS DTM surface files'), optional=False))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Output file')))
self.addParameter(ParameterNumber(
self.CELLSIZE, self.tr('Size of the cell used to report topographic metrics'), 0, None, 5.0))
self.addParameter(ParameterNumber(
self.POINTSP, self.tr('Spacing for the 3 by 3 array of points used to compute the metrics'), 0, None, 0.0))
self.addParameter(ParameterNumber(
self.LATITUDE, self.tr('Latitude'), 2, None, 45.0))
self.addParameter(ParameterNumber(
self.TPI, self.tr('TPI window size'), 0, None, 5.0))
square = ParameterBoolean(
self.SQUARE, self.tr('Use a square window for TPI'), False)
square.isAdvanced = True
self.addParameter(square)
disk = ParameterBoolean(
self.DISK, self.tr('Do not load ground surface models into memory'), False)
disk.isAdvanced = True
self.addParameter(disk)
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'TopoMetrics.exe')]
commands.append('/verbose')
square = self.getParameterValue(self.SQUARE)
if square:
commands.append('/square')
disk = self.getParameterValue(self.DISK)
if disk:
commands.append('/disk')
self.addAdvancedModifiersToCommand(commands)
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
commands.append(unicode(self.getParameterValue(self.CELLSIZE)))
commands.append(unicode(self.getParameterValue(self.POINTSP)))
commands.append(unicode(self.getParameterValue(self.LATITUDE)))
commands.append(unicode(self.getParameterValue(self.TPI)))
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
FusionUtils.runFusion(commands, progress)

View File

@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
TreeSeg.py
---------------------
Date : November 2016
Copyright : (C) 2016 by Niccolo' Marchi
Email : sciurusurbanus at hotmail dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Niccolo' Marchi"
__date__ = 'November 2016'
__copyright__ = "(C) 2016 by Niccolo' Marchi"
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterFile
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputFile
from .FusionAlgorithm import FusionAlgorithm
from .FusionUtils import FusionUtils
class TreeSeg(FusionAlgorithm):
INPUT = 'INPUT'
GROUND = 'GROUND'
HTTH = 'HTTH'
OUTPUT = 'OUTPUT'
HEIGHT = 'HEIGHT'
SHAPE = 'SHAPE'
ALIGN = 'ALIGN'
BUFF = 'BUFF'
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Tree Segmentation')
self.group, self.i18n_group = self.trAlgorithm('Points')
self.addParameter(ParameterFile(
self.INPUT, self.tr('Input Canopy Height Model (in PLANS DTM format)'), optional=False))
self.addParameter(ParameterNumber(
self.HTTH, self.tr('Minimum height for object segmentation'), 0, None, 2.0))
self.addOutput(OutputFile(
self.OUTPUT, self.tr('Base name for output files')))
ground = ParameterFile(
self.GROUND, self.tr('Ground file for height normalization'))
ground.isAdvanced = True
self.addParameter(ground)
height = ParameterBoolean(
self.HEIGHT, self.tr("Normalize height model using ground model (select if a ground file is provided)"), False)
height.isAdvanced = True
self.addParameter(height)
buff = ParameterNumber(
self.BUFF, self.tr('Add a buffer to the data extent when segmenting'), 0, None, 0.0)
buff.isAdvanced
self.addParameter(buff)
shape = ParameterBoolean(
self.SHAPE, self.tr('Create output shapefiles'), False)
shape.isAdvanced = True
self.addParameter(shape)
align = ParameterBoolean(
self.ALIGN, self.tr('Align output grid to the input extent'), False)
align.isAdvanced = True
self.addParameter(align)
self.addAdvancedModifiers()
def processAlgorithm(self, progress):
commands = [os.path.join(FusionUtils.FusionPath(), 'TreeSeg.exe')]
commands.append('/verbose')
ground = self.getParameterValue(self.GROUND)
if ground:
gfiles = self.getParameterValue(self.GROUND).split(';')
if len(gfiles) == 1:
commands.append('/ground:' + unicode(ground))
else:
FusionUtils.createGroundList(gfiles)
commands.append('/ground:' + unicode(FusionUtils.tempGroundListFilepath()))
height = self.getParameterValue(self.HEIGHT)
if height:
commands.append('/height')
buff = self.getParameterValue(self.BUFF)
if buff != 0.0:
commands.append('/buffer:' + unicode(self.getParameterValue(self.BUFF)))
shape = self.getParameterValue(self.SHAPE)
if shape:
commands.append('/shape')
align = self.getParameterValue(self.ALIGN)
if align:
commands.append('/align:' + unicode(self.getParameterValue(self.INPUT)))
self.addAdvancedModifiersToCommand(commands)
files = self.getParameterValue(self.INPUT).split(';')
if len(files) == 1:
commands.append(self.getParameterValue(self.INPUT))
else:
FusionUtils.createFileList(files)
commands.append(FusionUtils.tempFileListFilepath())
commands.append(unicode(self.getParameterValue(self.HTTH)))
outFile = self.getOutputValue(self.OUTPUT)
commands.append(outFile)
FusionUtils.runFusion(commands, progress)