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

org.jgrasstools.gears.utils.geometry.FeatureSlidingAverage Maven / Gradle / Ivy

/*
 * JGrass - Free Open Source Java GIS http://www.jgrass.org 
 * (C) HydroloGIS - www.hydrologis.com 
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Library General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 * 
 * This library 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 Library General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Library General Public License
 * along with this library; if not, write to the Free Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.jgrasstools.gears.utils.geometry;

import java.util.ArrayList;
import java.util.List;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;

/**
 * Applies a sliding average on linear geometries for smoothing.
 * 
 * @author Andrea Antonello (www.hydrologis.com)
 *
 */
public class FeatureSlidingAverage {

    private final Geometry geometry;

    public FeatureSlidingAverage( Geometry geometry ) {
        this.geometry = geometry;
    }

    public List smooth( int lookAhead, boolean considerZ, double slide ) {

        double sc;
        List res = new ArrayList();

        Coordinate[] coordinates = geometry.getCoordinates();
        int n = coordinates.length; // Points->n_points;
        int half = lookAhead / 2;

        for( int j = 0; j < n; j++ ) {
            Coordinate tmp = new Coordinate();
            res.add(tmp);
        }

        if (lookAhead % 2 == 0) {
            throw new IllegalArgumentException("Look ahead parameter must be odd, but you supplied: " + lookAhead);
        }

        if (lookAhead >= n || lookAhead == 1)
            return null;

        sc = (double) 1.0 / (double) lookAhead;

        Coordinate pCoord = new Coordinate();
        Coordinate sCoord = new Coordinate();
        pointAssign(coordinates, 0, considerZ, pCoord);
        for(int i = 1; i < lookAhead; i++ ) {
            Coordinate tmpCoord = new Coordinate();
            pointAssign(coordinates, i, considerZ, tmpCoord);
            pointAdd(pCoord, tmpCoord, pCoord);
        }

        /* and calculate the average of remaining points */
        for(int i = half; i + half < n; i++ ) {
            Coordinate tmpCoord = new Coordinate();
            pointAssign(coordinates, i, considerZ, sCoord);
            pointScalar(sCoord, 1.0 - slide, sCoord);
            pointScalar(pCoord, sc * slide, tmpCoord);
            pointAdd(tmpCoord, sCoord, res.get(i));
            if (i + half + 1 < n) {
                pointAssign(coordinates, i - half, considerZ, tmpCoord);
                pointSubtract(pCoord, tmpCoord, pCoord);
                pointAssign(coordinates, i + half + 1, considerZ, tmpCoord);
                pointAdd(pCoord, tmpCoord, pCoord);
            }
        }

        for(int i = 0; i < half; i++ ) {
            res.get(i).x = coordinates[i].x;
            res.get(i).y = coordinates[i].y;
            res.get(i).z = coordinates[i].z;
        }
        for(int i = n - half - 1; i < n; i++ ) {
            res.get(i).x = coordinates[i].x;
            res.get(i).y = coordinates[i].y;
            res.get(i).z = coordinates[i].z;
        }
        for( Coordinate coordinate : res ) {
            if (coordinate.x == 0) {
                System.out.println();
            }
        }
        // for( i = half; i + half < n; i++ ) {
        // coordinates[i].x = res.get(i).x;
        // coordinates[i].y = res.get(i).y;
        // coordinates[i].z = res.get(i).z;
        // }

        // return Points->n_points;

        return res;
    }

    private void pointAssign( Coordinate[] coordinates, int index, boolean considerZ, Coordinate newAssignedCoordinate ) {
        Coordinate coordinate = coordinates[index];
        newAssignedCoordinate.x = coordinate.x;
        newAssignedCoordinate.y = coordinate.y;
        if (considerZ) {
            newAssignedCoordinate.z = coordinate.z;
        } else {
            newAssignedCoordinate.z = 0;
        }
        return;
    }

    private void pointAdd( Coordinate a, Coordinate b, Coordinate res ) {
        res.x = a.x + b.x;
        res.y = a.y + b.y;
        res.z = a.z + b.z;
    }

    private void pointSubtract( Coordinate a, Coordinate b, Coordinate res ) {
        res.x = a.x - b.x;
        res.y = a.y - b.y;
        res.z = a.z - b.z;
    }

    private void pointScalar( Coordinate a, double k, Coordinate res ) {
        res.x = a.x * k;
        res.y = a.y * k;
        res.z = a.z * k;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy