package uk.ac.leeds.ccg.geotools; import java.util.*; import java.util.Collection; import java.util.Iterator; /** * Shape layer is holds all of the common code used by layers that contain GeoShape features * Much of the code in this class used to be duplicated multiple times by a number of classes * @since 0.7.0 * @author James Macgill */ public abstract class ShapeLayer extends SimpleLayer implements Layer { /** * The list of shape featurs that make up the layer. */ protected Vector shapeList; protected Quadtree shapeTree; //TODO JM when Quadtree is fixed, remove this option protected boolean useQuadtree = false; /** * The bounding rectangle that will contain all of the features in this layer */ protected GeoRectangle bbox = new GeoRectangle(); /** * Switch to turn the scale buffer on and off */ protected boolean bufferScale = true; /** * The last scaler used to scale this map */ protected Scaler lastScale = null; protected transient GeoRectangle lastExtent = null; /** * default constructor for an empty layer */ public ShapeLayer(){ shapeList = new Vector(); shapeTree = new Quadtree(); } /** * tempory constructor constructor for an empty layer with switch for using quadtree * TODO JM remove method once quadtree is fixed, and therefore, always used. */ public ShapeLayer(boolean quadtreeEnabled){ useQuadtree = quadtreeEnabled; shapeList = new Vector(); shapeTree = new Quadtree(); } /** * Constructs an empty layer, but with an inital expected bounds set * @param bounds A GeoRectangle that describes the initial bounds of this layer */ public ShapeLayer(GeoRectangle bounds){ this(); bbox = bounds; } /** * Adds the specified shape to the list of features in this layer * Each layer type should implement a specific version of this for their own type * @param shape The GeoShape to add to the layer */ protected void addGeoShape(GeoShape shape){ this.addGeoShape(shape,false); } /** * Adds the specified shape to the list of features in this layer * Each layer type should implement a specific version of this for their own type * @param shape The GeoShape to add to the layer * @param keepQuiet Tell the method not to fire a LayerChangedEvent. this * more or less implies that you will to this yourselve. */ protected void addGeoShape(GeoShape shape, boolean keepQuiet){ bbox.add(shape.getMultiPartBounds()); shapeList.addElement(shape); //TODO JM remove if block when quadtree is fixed if(useQuadtree){shapeTree.add(shape);} if(!keepQuiet) this.notifyLayerChangedListeners(LayerChangedEvent.GEOGRAPHY); } /** * Gets the bounding box that will contain all of the features in this layer * @return GeoRectanle that defines the bounding rectangle */ public GeoRectangle getBounds(){ return (GeoRectangle)bbox.clone(); } /** * Gets the bounding box of the specified feature * @since 0.6.5 * @param id The ID of the feature to find the bounding box for * @return GeoRectangle the bounds of the specified feature */ public GeoRectangle getBoundsOf(int id){ for(int i = 0;i < shapeList.size();i++) { GeoShape temp = (GeoShape)shapeList.elementAt(i); if(temp.getID()==id){ return temp.getMultiPartBounds(); } } return new GeoRectangle(); //empty rect, should this be null? } /** * Gets the bounding box that contains all of the given features * @since 0.6.5 * @param id[] The IDs of the features to find a bounding box for * @return GeoRectangle the bounds of the specified features */ public GeoRectangle getBoundsOf(int[] ids){ //needs optimizing! GeoRectangle bounds = new GeoRectangle(); for(int i=0;i