/* * Copyright (c) 2016 Vivid Solutions. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * * http://www.eclipse.org/org/documents/edl-v10.php. */ package org.locationtech.jts.generator; import java.util.NoSuchElementException; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; /** * This class should be used to generate a grid of bounding boxes, * most useful when creating multiple geometries. * * Successive calls to create() will walk the user though the grid. * Use canCreate() and reset() to control the walk through the grid. * * @see #canCreate() * @see #reset() * * @author David Zwiers, Vivid Solutions. */ public class GridGenerator extends GeometryGenerator { protected int numberColumns = 1; protected int numberRows = 1; protected int index = 0; /** * Sets some default values. */ public GridGenerator(){ dimensions = 2; } /** * * @see org.locationtech.jts.generator.GeometryGenerator#create() * * @throws NoSuchElementException when all the grids have been created (@see #create()) * @throws NullPointerException when either the Geometry Factory, or the Bounding Box are undefined. */ public Geometry create() { return geometryFactory.toGeometry(createEnv()); } /** * * @return Envelope * * @see org.locationtech.jts.generator.GeometryGenerator#create() * * @throws NoSuchElementException when all the grids have been created (@see #create()) * @throws NullPointerException when either the Geometry Factory, or the Bounding Box are undefined. */ public Envelope createEnv() { if(!canCreate()){ throw new NoSuchElementException("There are not any grids left to create."); } if(geometryFactory == null){ throw new NullPointerException("GeometryFactory is not declared"); } if(boundingBox == null || boundingBox.isNull()){ throw new NullPointerException("Bounding Box is not declared"); } double x = boundingBox.getMinX(); // base x double dx = boundingBox.getMaxX()-x; double y = boundingBox.getMinY(); // base y double dy = boundingBox.getMaxY()-y; int row = numberRows==1?0:index / numberRows; int col = numberColumns==1?0:index % numberColumns; double sx,sy; // size of a step sx = dx/numberColumns; sy = dy/numberRows; double minx, miny; minx = x+col*sx; miny = y+row*sy; Envelope box = new Envelope(geometryFactory.getPrecisionModel().makePrecise(minx), geometryFactory.getPrecisionModel().makePrecise(minx+sx), geometryFactory.getPrecisionModel().makePrecise(miny), geometryFactory.getPrecisionModel().makePrecise(miny+sy)); index++; return box; } /** * @return true when more grids exist */ public boolean canCreate(){ return (numberColumns*numberRows)>index; } /** * Resets the grid counter */ public void reset(){ index = 0; } /** * @see org.locationtech.jts.generator.GeometryGenerator#setDimensions(int) */ public void setDimensions(int dimensions) { if(dimensions!=2) throw new IllegalStateException("MAY NOT CHANGE GridGenerator's Dimensions"); } /** * @return Returns the numberColumns. */ public int getNumberColumns() { return numberColumns; } /** * @param numberColumns The numberColumns to set. */ public void setNumberColumns(int numberColumns) { if(numberColumns<=0) throw new IndexOutOfBoundsException("Index sizes must be positive, non zero"); this.numberColumns = numberColumns; } /** * @return Returns the numberRows. */ public int getNumberRows() { return numberRows; } /** * @param numberRows The numberRows to set. */ public void setNumberRows(int numberRows) { if(numberRows<=0) throw new IndexOutOfBoundsException("Index sizes must be positive, non zero"); this.numberRows = numberRows; } }