/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2010, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * 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 * Lesser General Public License for more details. */ package org.geotoolkit.data.shapefile.shp; import java.nio.ByteBuffer; import java.nio.DoubleBuffer; import org.apache.sis.storage.DataStoreException; /** * Decimation while reading * * @author Johann Sorel (Geomatys) * @module */ public class DecimateMultiPointHandler extends MultiPointHandler { private final double resX; private final double resY; public DecimateMultiPointHandler(final boolean read3D, final double[] res){ super(read3D); this.resX = res[0]; this.resY = res[1]; } public DecimateMultiPointHandler(final ShapeType type, final boolean read3D, final double[] res) throws DataStoreException{ super(type,read3D); this.resX = res[0]; this.resY = res[1]; } @Override public Object read(final ByteBuffer buffer, final ShapeType type) { if (type == ShapeType.NULL) { return createNull(); } final int dimensions = (read3D && shapeType == ShapeType.MULTIPOINTZ)? 3 : 2; // read bounding box (not needed) buffer.position(buffer.position() + 32); final int numpoints = buffer.getInt(); final DoubleBuffer dbuffer = buffer.asDoubleBuffer(); final double[] coords = new double[numpoints*dimensions]; final int xySize = numpoints*2; dbuffer.get(coords,0,xySize); if(dimensions==2){ return GEOMETRY_FACTORY.createMultiPoint( new ShapeCoordinateSequence2D(coords,decimatePoint2D(coords))); } else { // z min, max dbuffer.position(dbuffer.position() + 2); dbuffer.get(coords,xySize,numpoints); return GEOMETRY_FACTORY.createMultiPoint( new ShapeCoordinateSequence3D(coords)); } } private int decimatePoint2D(final double[] coords){ int lenght = 1; for(int i=2,j=0; i<coords.length; i+=2){ final double distX = Math.abs(coords[j] - coords[i]); if(distX > resX){ lenght++; j+=2; coords[j] = coords[i]; coords[j+1] = coords[i+1]; continue; } final double distY = Math.abs(coords[j+1] - coords[i+1]); if(distY > resY){ lenght++; j+=2; coords[j] = coords[i]; coords[j+1] = coords[i+1]; continue; } } return lenght; } }