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

org.jgrasstools.gears.io.las.LasFileDataManager Maven / Gradle / Ivy

The newest version!
/*
 * 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.gears.io.las;

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

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope3D;
import org.jgrasstools.gears.io.las.core.ALasReader;
import org.jgrasstools.gears.io.las.core.ILasHeader;
import org.jgrasstools.gears.io.las.core.LasRecord;
import org.jgrasstools.gears.io.las.index.LasIndexer;
import org.jgrasstools.gears.io.las.index.OmsLasIndexReader;
import org.jgrasstools.gears.libs.modules.JGTConstants;
import org.jgrasstools.gears.utils.CrsUtilities;
import org.jgrasstools.gears.utils.coverage.CoverageUtilities;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
import com.vividsolutions.jts.index.strtree.STRtree;

/**
 * A class that manages las folder data.
 * 
 * @author Andrea Antonello (www.hydrologis.com)
 */
class LasFileDataManager extends ALasDataManager {
    private File lasFile;
    private GridCoverage2D inDem;
    private double elevThreshold;

    private SimpleFeatureCollection overviewFeatures;
    private ReferencedEnvelope referencedEnvelope2D;
    private List referencedEnvelope2DList = new ArrayList();
    private List fileNamesList = new ArrayList();
    private ReferencedEnvelope3D referencedEnvelope3D;
    private ALasReader lasReader;
    private ILasHeader lasHeader;
    private boolean isOpen;
    private STRtree pointsTree;

    /**
     * Constructor.
     * 
     * @param lasFile the las folder index file.
     * @param inDem a dem to normalize the elevation. If null, the original las elevation is used.
     * @param elevThreshold a threshold to use for the elevation normalization.
     * @param inCrs the data {@link org.opengis.referencing.crs.CoordinateReferenceSystem}. if null, the one of the dem is read, if available.
     */
    LasFileDataManager( File lasFile, GridCoverage2D inDem, double elevThreshold, CoordinateReferenceSystem inCrs ) {
        this.lasFile = lasFile;
        this.inDem = inDem;
        this.elevThreshold = elevThreshold;

        fileNamesList.add(lasFile.getName());

        try {
            // prj file rules if available
            inCrs = CrsUtilities.readProjectionFile(lasFile.getAbsolutePath(), "las");
        } catch (Exception e) {
            // ignore and try to read
        }
        if (inCrs != null) {
            crs = inCrs;
        } else if (inDem != null) {
            crs = inDem.getCoordinateReferenceSystem();
        } else {
            throw new IllegalArgumentException("The Crs can't be null.");
        }
    }

    @Override
    public File getFile() {
        return lasFile;
    }

    /**
     * Open the main folder file and read the main index.
     *
     * @throws Exception
     */
    @Override
    public void open() throws Exception {
        lasReader = ALasReader.getReader(lasFile, crs);
        lasReader.open();
        lasHeader = lasReader.getHeader();
        isOpen = true;
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized List getPointsInGeometry( Geometry checkGeom, boolean doOnlyEnvelope ) throws Exception {
        checkOpen();

        ArrayList pointsListForTile = new ArrayList();
        Envelope checkEnvelope = checkGeom.getEnvelopeInternal();
        if (pointsTree != null) {
            List pointsList = pointsTree.query(checkEnvelope);
            PreparedGeometry preparedGeometry = null;
            if (!doOnlyEnvelope) {
                preparedGeometry = PreparedGeometryFactory.prepare(checkGeom);
            }
            for( LasRecord lasDot : pointsList ) {
                Coordinate c = new Coordinate(lasDot.x, lasDot.y);
                if (!checkEnvelope.contains(c)) {
                    continue;
                }
                if (!doOnlyEnvelope && !preparedGeometry.contains(gf.createPoint(c))) {
                    continue;
                }
                pointsListForTile.add(lasDot);
            }
        } else {
            pointsTree = new STRtree();
            ReferencedEnvelope overallEnvelope = getOverallEnvelope();
            if (doOnlyEnvelope && checkEnvelope.covers(overallEnvelope)) {
                // read it straight
                while( lasReader.hasNextPoint() ) {
                    LasRecord lasDot = lasReader.getNextPoint();
                    if (!doAccept(lasDot)) {
                        continue;
                    }
                    pointsTree.insert(new Envelope(new Coordinate(lasDot.x, lasDot.y)), lasDot);
                    pointsListForTile.add(lasDot);
                }
            } else {

                Envelope env = checkGeom.getEnvelopeInternal();
                PreparedGeometry preparedGeometry = null;
                if (!doOnlyEnvelope) {
                    preparedGeometry = PreparedGeometryFactory.prepare(checkGeom);
                }

                while( lasReader.hasNextPoint() ) {
                    LasRecord lasDot = lasReader.getNextPoint();
                    if (!doAccept(lasDot)) {
                        continue;
                    }
                    Coordinate c = new Coordinate(lasDot.x, lasDot.y);
                    pointsTree.insert(new Envelope(c), lasDot);
                    if (!env.contains(c)) {
                        continue;
                    }

                    if (inDem != null) {
                        // check geom instead of only envelope?
                        if (!doOnlyEnvelope && !preparedGeometry.contains(gf.createPoint(c))) {
                            continue;
                        }
                        double value = CoverageUtilities.getValue(inDem, lasDot.x, lasDot.y);
                        if (JGTConstants.isNovalue(value)) {
                            continue;
                        }
                        double height = lasDot.z - value;
                        if (height > elevThreshold) {
                            lasDot.groundElevation = height;
                            pointsListForTile.add(lasDot);
                        }
                    } else {
                        if (!doOnlyEnvelope && !preparedGeometry.contains(gf.createPoint(c))) {
                            continue;
                        }
                        pointsListForTile.add(lasDot);
                    }
                }

            }
            close();
        }
        return pointsListForTile;
    }

    @Override
    public synchronized List getEnvelopesInGeometry( Geometry checkGeom, boolean doOnlyEnvelope, double[] minMaxZ )
            throws Exception {
        checkOpen();

        ReferencedEnvelope3D dataEnvelope = lasHeader.getDataEnvelope();
        Polygon envelopePolygon = LasIndexer.envelopeToPolygon(dataEnvelope);
        ArrayList envelopeList = new ArrayList();
        envelopeList.add(envelopePolygon);
        return envelopeList;
    }

    @Override
    public synchronized ReferencedEnvelope getOverallEnvelope() throws Exception {
        if (referencedEnvelope2D == null) {
            checkOpen();
            ReferencedEnvelope3D dataEnvelope = lasHeader.getDataEnvelope();
            referencedEnvelope2D = new ReferencedEnvelope(dataEnvelope, crs);
            referencedEnvelope2DList.add(referencedEnvelope2D);
        }
        return referencedEnvelope2D;
    }

    @Override
    public List getEnvelopeList() throws Exception {
        getOverallEnvelope();
        return referencedEnvelope2DList;
    }

    @Override
    public synchronized ReferencedEnvelope3D getEnvelope3D() throws Exception {
        if (referencedEnvelope3D == null) {
            checkOpen();
            ReferencedEnvelope3D dataEnvelope = lasHeader.getDataEnvelope();
            referencedEnvelope3D = new ReferencedEnvelope3D(dataEnvelope, crs);
        }
        return referencedEnvelope3D;
    }

    @Override
    public synchronized SimpleFeatureCollection getOverviewFeatures() throws Exception {
        if (overviewFeatures == null) {
            List envelopeList = getEnvelopeList();

            SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
            b.setName("overview");
            b.setCRS(crs);
            b.add("the_geom", Polygon.class);
            b.add("name", String.class);
            SimpleFeatureType type = b.buildFeatureType();
            SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);

            overviewFeatures = new DefaultFeatureCollection();

            for( int i = 0; i < envelopeList.size(); i++ ) {
                String name = fileNamesList.get(i);
                ReferencedEnvelope envelope = envelopeList.get(i);
                Polygon polygon = OmsLasIndexReader.envelopeToPolygon(envelope);
                Object[] objs = new Object[]{polygon, name};
                builder.addAll(objs);
                SimpleFeature feature = builder.buildFeature(null);
                ((DefaultFeatureCollection) overviewFeatures).add(feature);
            }
        }
        return overviewFeatures;
    }

    private void checkOpen() throws Exception {
        if (!isOpen) {
            open();
        }
    }

    @Override
    public void close() throws Exception {
        isOpen = false;
        if (lasReader != null)
            lasReader.close();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy