Exemple #1
0
def translate(info, infile, outfile, spatial=False, extent=None):
    """
    Does the translation between SPD V4 and .las format files.

    * Info is a fileinfo object for the input file.
    * infile and outfile are paths to the input and output files respectively.
    * spatial is True or False - dictates whether we are processing spatially or not.
        If True then spatial index will be created on the output file on the fly.
    * extent is a tuple of values specifying the extent to work with. 
        xmin ymin xmax ymax

    Currently does not take any command line scaling options so LAS scaling
    will be the same as the SPDV4 input file scaling. Not sure if this is
    a problem or not...    
    """
    # first we need to determine if the file is spatial or not
    if spatial and not info.has_Spatial_Index:
        msg = "Spatial processing requested but file does not have spatial index"
        raise generic.LiDARInvalidSetting(msg)

    # get the waveform info
    print('Getting waveform description')
    try:
        wavePacketDescr = las.getWavePacketDescriptions(infile)
    except generic.LiDARInvalidData:
        wavePacketDescr = None

    # set up the variables
    dataFiles = lidarprocessor.DataFiles()

    dataFiles.input1 = lidarprocessor.LidarFile(infile, lidarprocessor.READ)

    controls = lidarprocessor.Controls()
    progress = cuiprogress.GDALProgressBar()
    controls.setProgress(progress)
    controls.setSpatialProcessing(spatial)

    if extent is not None:
        extent = [float(x) for x in extent]
        binSize = info.header['BIN_SIZE']
        pixgrid = pixelgrid.PixelGridDefn(xMin=extent[0],
                                          yMin=extent[1],
                                          xMax=extent[2],
                                          yMax=extent[3],
                                          xRes=binSize,
                                          yRes=binSize)
        controls.setReferencePixgrid(pixgrid)
        controls.setFootprint(lidarprocessor.BOUNDS_FROM_REFERENCE)

    dataFiles.output1 = lidarprocessor.LidarFile(outfile,
                                                 lidarprocessor.CREATE)
    dataFiles.output1.setLiDARDriver('LAS')
    if wavePacketDescr is not None:
        dataFiles.output1.setLiDARDriverOption('WAVEFORM_DESCR',
                                               wavePacketDescr)

    lidarprocessor.doProcessing(transFunc, dataFiles, controls=controls)
Exemple #2
0
def run():
    """
    Main function. Looks at the command line arguments
    and calls the appropiate translation function.
    """
    cmdargs = getCmdargs()
    wktStr = None
    if cmdargs.wktfile is not None:
        wktStr = open(cmdargs.wktfile).read()

    # first determine the format of the input file
    # I'm not sure this is possible in all situations, but assume it is for now
    info = generic.getLidarFileInfo(cmdargs.input)
    inFormat = info.getDriverName()

    if inFormat == 'LAS' and cmdargs.format == 'SPDV4':
        las2spdv4.translate(info, cmdargs.input, cmdargs.output, cmdargs.range,
                            cmdargs.spatial, cmdargs.extent, cmdargs.scaling,
                            cmdargs.epsg, cmdargs.binsize, cmdargs.buildpulses,
                            cmdargs.pulseindex, cmdargs.null, cmdargs.constcol,
                            cmdargs.lasscalings)

    elif inFormat == 'SPDV3' and cmdargs.format == 'SPDV4':
        spdv32spdv4.translate(info, cmdargs.input, cmdargs.output,
                              cmdargs.range, cmdargs.spatial, cmdargs.extent,
                              cmdargs.scaling, cmdargs.null, cmdargs.constcol)

    elif inFormat == 'riegl RXP' and cmdargs.format == 'SPDV4':
        rieglrxp2spdv4.translate(info,
                                 cmdargs.input,
                                 cmdargs.output,
                                 cmdargs.range,
                                 cmdargs.scaling,
                                 cmdargs.internalrotation,
                                 cmdargs.magneticdeclination,
                                 cmdargs.externalrotationfn,
                                 cmdargs.null,
                                 cmdargs.constcol,
                                 epsg=cmdargs.epsg,
                                 wkt=wktStr)

    elif inFormat == 'riegl RDB' and cmdargs.format == 'SPDV4':
        rieglrdb2spdv4.translate(info,
                                 cmdargs.input,
                                 cmdargs.output,
                                 cmdargs.range,
                                 cmdargs.scaling,
                                 cmdargs.null,
                                 cmdargs.constcol,
                                 epsg=cmdargs.epsg,
                                 wkt=wktStr)

    elif inFormat == 'SPDV4' and cmdargs.format == 'LAS':
        spdv42las.translate(info, cmdargs.input, cmdargs.output,
                            cmdargs.spatial, cmdargs.extent)

    elif inFormat == 'ASCII' and cmdargs.format == 'SPDV4':

        if cmdargs.coltype is None:
            msg = "must pass --coltypes parameter"
            raise generic.LiDARInvalidSetting(msg)

        if cmdargs.pulsecols is not None:
            pulsecols = cmdargs.pulsecols.split(',')
        else:
            pulsecols = None

        classtrans = None
        if cmdargs.classtrans is not None:
            # translate strings to codes
            for internalCode, strLasCode in cmdargs.classtrans:
                internalCode = int(internalCode)
                strLasCodeFull = "CLASSIFICATION_%s" % strLasCode
                try:
                    lasCode = getattr(lidarprocessor, strLasCodeFull)
                except AttributeError:
                    msg = 'class %s not understood' % strLasCode
                    raise generic.LiDARInvalidSetting(msg)

                if classtrans is None:
                    classtrans = []
                classtrans.append((internalCode, lasCode))

        ascii2spdv4.translate(info, cmdargs.input, cmdargs.output,
                              cmdargs.coltype, pulsecols, cmdargs.range,
                              cmdargs.scaling, classtrans, cmdargs.null,
                              cmdargs.constcol)

    elif inFormat == 'LVIS Binary' and cmdargs.format == 'SPDV4':

        lvisbin2spdv4.translate(info, cmdargs.input, cmdargs.output,
                                cmdargs.range, cmdargs.scaling, cmdargs.null,
                                cmdargs.constcol)

    elif inFormat == 'LVIS HDF5' and cmdargs.format == 'SPDV4':

        lvishdf52spdv4.translate(info, cmdargs.input, cmdargs.output,
                                 cmdargs.range, cmdargs.scaling, cmdargs.null,
                                 cmdargs.constcol)

    elif inFormat == 'PulseWaves' and cmdargs.format == 'SPDV4':

        pulsewaves2spdv4.translate(info, cmdargs.input, cmdargs.output,
                                   cmdargs.range, cmdargs.scaling,
                                   cmdargs.null, cmdargs.constcol)

    elif inFormat == 'SPDV4' and cmdargs.format == 'PULSEWAVES':
        spdv42pulsewaves.translate(info, cmdargs.input, cmdargs.output)

    else:
        msg = 'Cannot convert between formats %s and %s'
        msg = msg % (inFormat, cmdargs.format)
        raise generic.LiDARFunctionUnsupported(msg)
Exemple #3
0
def translate(info,
              infile,
              outfile,
              expectRange=None,
              spatial=False,
              extent=None,
              scaling=None,
              nullVals=None,
              constCols=None):
    """
    Main function which does the work.

    * Info is a fileinfo object for the input file.
    * infile and outfile are paths to the input and output files respectively.
    * expectRange is a list of tuples with (type, varname, min, max).
    * spatial is True or False - dictates whether we are processing spatially or not.
        If True then spatial index will be created on the output file on the fly.
    * extent is a tuple of values specifying the extent to work with. 
        xmin ymin xmax ymax
    * scaling is a list of tuples with (type, varname, gain, offset).
    * nullVals is a list of tuples with (type, varname, value)
    * constCols is a list of tupes with (type, varname, dtype, value)
    """
    scalingsDict = translatecommon.overRideDefaultScalings(scaling)

    # first we need to determine if the file is spatial or not
    if spatial and not info.hasSpatialIndex:
        msg = "Spatial processing requested but file does not have spatial index"
        raise generic.LiDARInvalidSetting(msg)

    if extent is not None and not spatial:
        msg = 'Extent can only be set when processing spatially'
        raise generic.LiDARInvalidSetting(msg)

    dataFiles = lidarprocessor.DataFiles()

    dataFiles.input1 = lidarprocessor.LidarFile(infile, lidarprocessor.READ)
    dataFiles.output1 = lidarprocessor.LidarFile(outfile,
                                                 lidarprocessor.CREATE)
    dataFiles.output1.setLiDARDriver('SPDV4')
    dataFiles.output1.setLiDARDriverOption('SCALING_BUT_NO_DATA_WARNING',
                                           False)

    controls = lidarprocessor.Controls()
    progress = cuiprogress.GDALProgressBar()
    controls.setProgress(progress)
    controls.setSpatialProcessing(spatial)

    if extent is not None:
        extent = [float(x) for x in extent]
        binSize = info.header['BIN_SIZE']
        pixgrid = pixelgrid.PixelGridDefn(xMin=extent[0],
                                          yMin=extent[1],
                                          xMax=extent[2],
                                          yMax=extent[3],
                                          xRes=binSize,
                                          yRes=binSize)
        controls.setReferencePixgrid(pixgrid)
        controls.setFootprint(lidarprocessor.BOUNDS_FROM_REFERENCE)

    otherArgs = lidarprocessor.OtherArgs()
    otherArgs.scaling = scalingsDict
    otherArgs.expectRange = expectRange
    otherArgs.nullVals = nullVals
    otherArgs.constCols = constCols

    lidarprocessor.doProcessing(transFunc,
                                dataFiles,
                                controls=controls,
                                otherArgs=otherArgs)
Exemple #4
0
def translate(info,
              infile,
              outfile,
              expectRange=None,
              scalings=None,
              internalrotation=False,
              magneticdeclination=0.0,
              externalrotationfn=None,
              nullVals=None,
              constCols=None,
              epsg=None,
              wkt=None):
    """
    Main function which does the work.

    * Info is a fileinfo object for the input file.
    * infile and outfile are paths to the input and output files respectively.
    * expectRange is a list of tuples with (type, varname, min, max).
    * scaling is a list of tuples with (type, varname, gain, offset).
    * if internalrotation is True then the internal rotation will be applied
        to data. Overrides externalrotationfn
    * if externalrotationfn is not None then then the external rotation matrix
        will be read from this file and applied to the data
    * magneticdeclination. If not 0, then this will be applied to the data
    * nullVals is a list of tuples with (type, varname, value)
    * constCols is a list of tupes with (type, varname, dtype, value)
    """
    scalingsDict = translatecommon.overRideDefaultScalings(scalings)

    # set up the variables
    dataFiles = lidarprocessor.DataFiles()

    dataFiles.input1 = lidarprocessor.LidarFile(infile, lidarprocessor.READ)

    # first set the rotation matrix if asked for
    if internalrotation and externalrotationfn:
        msg = "Can't use both internal and external rotation"
        raise generic.LiDARInvalidSetting(msg)

    rotationMatrix = None
    if internalrotation:
        if "ROTATION_MATRIX" in info.header:
            dataFiles.input1.setLiDARDriverOption(
                "ROTATION_MATRIX", info.header["ROTATION_MATRIX"])
            rotationMatrix = info.header["ROTATION_MATRIX"]
        else:
            msg = "Internal Rotation requested but no information found in input file"
            raise generic.LiDARInvalidSetting(msg)
    elif externalrotationfn is not None:
        externalrotation = numpy.loadtxt(externalrotationfn,
                                         ndmin=2,
                                         delimiter=" ",
                                         dtype=numpy.float32)
        dataFiles.input1.setLiDARDriverOption("ROTATION_MATRIX",
                                              externalrotation)
        rotationMatrix = externalrotation

    # set the magnetic declination if not 0 (the default)
    if magneticdeclination != 0:
        dataFiles.input1.setLiDARDriverOption("MAGNETIC_DECLINATION",
                                              magneticdeclination)

    controls = lidarprocessor.Controls()
    progress = cuiprogress.GDALProgressBar()
    controls.setProgress(progress)
    controls.setSpatialProcessing(False)

    otherArgs = lidarprocessor.OtherArgs()
    # and the header so we don't collect it again
    otherArgs.rieglInfo = info.header
    # also need the default/overriden scaling
    otherArgs.scaling = scalingsDict
    # Add the rotation matrix to otherArgs
    # for updating the header
    otherArgs.rotationMatrix = rotationMatrix
    # expected range of the data
    otherArgs.expectRange = expectRange
    # null values
    otherArgs.nullVals = nullVals
    # constant columns
    otherArgs.constCols = constCols
    otherArgs.epsg = epsg
    otherArgs.wkt = wkt

    dataFiles.output1 = lidarprocessor.LidarFile(outfile,
                                                 lidarprocessor.CREATE)
    dataFiles.output1.setLiDARDriver('SPDV4')
    dataFiles.output1.setLiDARDriverOption('SCALING_BUT_NO_DATA_WARNING',
                                           False)

    lidarprocessor.doProcessing(transFunc,
                                dataFiles,
                                controls=controls,
                                otherArgs=otherArgs)
Exemple #5
0
def translate(info,
              infile,
              outfile,
              expectRange=None,
              spatial=None,
              extent=None,
              scaling=None,
              epsg=None,
              binSize=None,
              buildPulses=False,
              pulseIndex=None,
              nullVals=None,
              constCols=None,
              useLASScaling=False):
    """
    Main function which does the work.

    * Info is a fileinfo object for the input file.
    * infile and outfile are paths to the input and output files respectively.
    * expectRange is a list of tuples with (type, varname, min, max).
    * spatial is True or False - dictates whether we are processing spatially or not.
        If True then spatial index will be created on the output file on the fly.
    * extent is a tuple of values specifying the extent to work with. 
        xmin ymin xmax ymax
    * scaling is a list of tuples with (type, varname, dtype, gain, offset).
    * if epsg is not None should be a EPSG number to use as the coord system
    * binSize is the used by the LAS spatial index
    * buildPulses dictates whether to attempt to build the pulse structure
    * pulseIndex should be 'FIRST_RETURN' or 'LAST_RETURN' and determines how the
        pulses are indexed.
    * nullVals is a list of tuples with (type, varname, value)
    * constCols is a list of tupes with (type, varname, dtype, value)
    * if useLASScaling is True, then the scaling used in the LAS file
        is used for columns. Overrides anything given in 'scaling'
    
    """
    scalingsDict = translatecommon.overRideDefaultScalings(scaling)

    if epsg is None and (info.wkt is None or len(info.wkt) == 0):
        msg = 'No projection set in las file. Must set EPSG on command line'
        raise generic.LiDARInvalidSetting(msg)

    if spatial and not info.hasSpatialIndex:
        msg = 'Spatial processing requested but file does not have spatial index'
        raise generic.LiDARInvalidSetting(msg)

    if spatial and binSize is None:
        msg = "For spatial processing, the bin size must be set"
        raise generic.LiDARInvalidSetting(msg)

    if extent is not None and not spatial:
        msg = 'Extent can only be set when processing spatially'
        raise generic.LiDARInvalidSetting(msg)

    # set up the variables
    dataFiles = lidarprocessor.DataFiles()

    dataFiles.input1 = lidarprocessor.LidarFile(infile, lidarprocessor.READ)
    if pulseIndex == 'FIRST_RETURN':
        dataFiles.input1.setLiDARDriverOption('PULSE_INDEX', las.FIRST_RETURN)
    elif pulseIndex == 'LAST_RETURN':
        dataFiles.input1.setLiDARDriverOption('PULSE_INDEX', las.LAST_RETURN)
    else:
        msg = "Pulse index argument not recognised."
        raise generic.LiDARInvalidSetting(msg)

    dataFiles.input1.setLiDARDriverOption('BUILD_PULSES', buildPulses)

    if spatial:
        dataFiles.input1.setLiDARDriverOption('BIN_SIZE', float(binSize))

    controls = lidarprocessor.Controls()
    progress = cuiprogress.GDALProgressBar()
    controls.setProgress(progress)
    controls.setSpatialProcessing(spatial)

    otherArgs = lidarprocessor.OtherArgs()
    otherArgs.scaling = scalingsDict
    otherArgs.epsg = epsg
    otherArgs.expectRange = expectRange
    otherArgs.lasInfo = info
    otherArgs.nullVals = nullVals
    otherArgs.constCols = constCols
    otherArgs.useLASScaling = useLASScaling

    if extent is not None:
        extent = [float(x) for x in extent]
        pixgrid = pixelgrid.PixelGridDefn(xMin=extent[0],
                                          yMin=extent[1],
                                          xMax=extent[2],
                                          yMax=extent[3],
                                          xRes=binSize,
                                          yRes=binSize)
        controls.setReferencePixgrid(pixgrid)
        controls.setFootprint(lidarprocessor.BOUNDS_FROM_REFERENCE)

    dataFiles.output1 = lidarprocessor.LidarFile(outfile,
                                                 lidarprocessor.CREATE)
    dataFiles.output1.setLiDARDriver('SPDV4')
    dataFiles.output1.setLiDARDriverOption('SCALING_BUT_NO_DATA_WARNING',
                                           False)

    lidarprocessor.doProcessing(transFunc,
                                dataFiles,
                                controls=controls,
                                otherArgs=otherArgs)