All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgrasstools.lesto.modules.utilities.LasFromFaroTlsXyz Maven / Gradle / Ivy

/*
 * This file is part of JGrasstools (http://www.jgrasstools.org)
 * (C) HydroloGIS - www.hydrologis.com 
 * 
 * JGrasstools 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.jgrasstools.lesto.modules.utilities;
import static java.lang.Math.max;
import static java.lang.Math.min;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import oms3.annotations.Author;
import oms3.annotations.Description;
import oms3.annotations.Execute;
import oms3.annotations.In;
import oms3.annotations.Keywords;
import oms3.annotations.Label;
import oms3.annotations.License;
import oms3.annotations.Name;
import oms3.annotations.Status;
import oms3.annotations.UI;
import oms3.annotations.Unit;

import org.geotools.referencing.CRS;
import org.jgrasstools.gears.io.las.core.ALasWriter;
import org.jgrasstools.gears.io.las.core.LasRecord;
import org.jgrasstools.gears.io.las.core.v_1_0.LasWriterEachPoint;
import org.jgrasstools.gears.io.las.index.LasIndexer;
import org.jgrasstools.gears.libs.exceptions.ModelsIllegalargumentException;
import org.jgrasstools.gears.libs.modules.JGTConstants;
import org.jgrasstools.gears.libs.modules.JGTModel;
import org.jgrasstools.gears.libs.monitor.IJGTProgressMonitor;
import org.jgrasstools.gears.utils.CrsUtilities;
import org.jgrasstools.gears.utils.math.NumericsUtilities;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

@Description("Converts XYZ data exported from FARO TLS to las.")
@Author(name = "Andrea Antonello", contact = "www.hydrologis.com")
@Keywords("las, tls, convert")
@Label(JGTConstants.LESTO + "/utilities")
@Name("lasfromfarotlsxyz")
@Status(Status.EXPERIMENTAL)
@License(JGTConstants.GPL3_LICENSE)
public class LasFromFaroTlsXyz extends JGTModel {
    @Description("The xyz file to convert.")
    @UI(JGTConstants.FILEIN_UI_HINT)
    @In
    public String inFile;

    @Description("The reference longitude in a metric projection.")
    @In
    public Double pLongitude;

    @Description("The reference latitude in a metric projection.")
    @In
    public Double pLatitude;

    @Description("The maximum allowed distance from the center.")
    @Unit("m")
    @In
    public Double pMaxDistance;

    @Description("The code defining the data coordinate reference system.")
    @UI(JGTConstants.CRS_UI_HINT)
    @In
    public String pCode;

    @Description("The converted las output file.")
    @UI(JGTConstants.FILEOUT_UI_HINT)
    @In
    public String outLas;

    @Execute
    public void process() throws Exception {
        checkNull(inFile, outLas, pCode, pLatitude, pLongitude);
        CoordinateReferenceSystem crs = CrsUtilities.getCrsFromEpsg(pCode);

        double latitude = pLatitude;
        double longitude = pLongitude;

        List readRecords = new ArrayList();

        File inXyzFile = new File(inFile);

        double xMin = Double.POSITIVE_INFINITY;
        double yMin = Double.POSITIVE_INFINITY;
        double zMin = Double.POSITIVE_INFINITY;
        double xMax = Double.NEGATIVE_INFINITY;
        double yMax = Double.NEGATIVE_INFINITY;
        double zMax = Double.NEGATIVE_INFINITY;

        double maxDistance = Double.POSITIVE_INFINITY;
        if (pMaxDistance != null) {
            maxDistance = pMaxDistance;
        }

        /*
         * Lines are of type:
         * -7.41840000 0.39450000 1190.87950000 254 254 254
         * rownum, colnum, xDeltaMeters, yDeltaMeters, Elev, R, G, B 
         * 
         * Export scan points
         * 
         */
        int ignoredCount = 0;
        pm.beginTask("Reading xyz and creating bounds...", IJGTProgressMonitor.UNKNOWN);
        try (BufferedReader xyzReader = new BufferedReader(new FileReader(inXyzFile))) {
            String line;
            int count = 0;
            while( (line = xyzReader.readLine()) != null ) {
                if (count++ % 1000000 == 0) {
                    pm.message("processed lines: " + (count - 1) + " of which ignored: " + ignoredCount);
                }
                line = line.trim();
                if (line.length() == 0) {
                    continue;
                }
                String[] lineSplit = line.split("\\s+");

                if (lineSplit.length != 8) {
                    String msg = "Wrong data format. The data are supposed to be exported from the SCENE software as scan points.\nThe data format in the XYZ file is: rowNum, colNum, xDeltaMeters, yDeltaMeters, elev, R, G, B";
                    throw new ModelsIllegalargumentException(msg, this);
                }

                int index = 2;
                double deltaX = Double.parseDouble(lineSplit[index++]);
                double deltaY = Double.parseDouble(lineSplit[index++]);

                double distanceFromCenter = NumericsUtilities.pythagoras(deltaX, deltaY);
                if (distanceFromCenter > maxDistance) {
                    ignoredCount++;
                    continue;
                }

                double x = longitude + deltaX;
                double y = latitude + deltaY;

                double elev = Double.parseDouble(lineSplit[index++]);
                int r = Integer.parseInt(lineSplit[index++]);
                int g = Integer.parseInt(lineSplit[index++]);
                int b = Integer.parseInt(lineSplit[index++]);
                xMin = min(xMin, x);
                yMin = min(yMin, y);
                zMin = min(zMin, elev);
                xMax = max(xMax, x);
                yMax = max(yMax, y);
                zMax = max(zMax, elev);

                LasRecord dot = new LasRecord();
                dot.x = x;
                dot.y = y;
                dot.z = elev;
                dot.color = new short[]{(short) r, (short) g, (short) b};
                dot.gpsTime = System.currentTimeMillis();
                readRecords.add(dot);
            }
        }
        pm.done();

        pm.message("Keeping point: " + readRecords.size());

        File outFile = new File(outLas);
        try (ALasWriter writer = ALasWriter.getWriter(outFile, crs)) {
            writer.setBounds(xMin, xMax, yMin, yMax, zMin, zMax);
            writer.setPointFormat(3);
            writer.open();
            pm.beginTask("Writing las...", readRecords.size());
            for( LasRecord dot : readRecords ) {
                writer.addPoint(dot);
                pm.worked(1);
            }
            pm.done();
        }
    }

    public static void main( String[] args ) throws Exception {
        // String inFile = "/home/hydrologis/data/rilievo_tls/capriana_punti_scansione_avgres.xyz";
        // double lon = 681274.363;
        // double lat = 5127118.3962;
        // String outFile = "/home/hydrologis/data/rilievo_tls/capriana_avgres.las";
        // double maxDistance = 15;

        String inFile = "/home/hydrologis/data/rilievo_tls/capriana_punti_scansione_lowres.xyz";
        double lon = 681269.8905;
        double lat = 5127117.2439;
        String outFolder = "/home/hydrologis/data/rilievo_tls/lowres/";
        String outFile = outFolder + "capriana_lowres.las";
        double maxDistance = 16;

        LasFromFaroTlsXyz x = new LasFromFaroTlsXyz();
        x.inFile = inFile;
        x.pLongitude = lon;
        x.pLatitude = lat;
        x.pMaxDistance = maxDistance;
        x.pCode = "EPSG:32632";
        x.outLas = outFile;
        x.process();

        LasIndexer in = new LasIndexer();
        in.inFolder = outFolder;
        in.pCellsize = 0.5;
        in.process();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy