// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/omGraphics/OMAreaList.java,v $ // $RCSfile: OMAreaList.java,v $ // $Revision: 1.9 $ // $Date: 2005/01/10 16:58:33 $ // $Author: dietrick $ // // ********************************************************************** package com.bbn.openmap.omGraphics; import java.awt.geom.GeneralPath; import java.io.Serializable; import com.bbn.openmap.proj.Projection; /** * This class encapsulates a list of OMGeometries that are connected to form one * area. Different types of vector OMGeometries can be combined and used to * create a unique shape over the map. OMRasterObjects will contribute their * shape/size, but not their images. The OMGeometries should be added in a * clockwise format. * * <P> * KNOWN ISSUES: OMAreaLists that wrap around the back of the earth and showing * up on both edges of the map are not handled well - you'll end up with lines * going horizontally across the map. It's on the to-do list to fix this. */ public class OMAreaList extends OMGeometryList implements Serializable { /** * Construct an OMAreaList. */ public OMAreaList() { super(10); init(); } /** * Construct an OMAreaList with a capacity to be combined from an initial * amount of OMGeometries. * * @param initialCapacity the initial capacity of the list */ public OMAreaList(int initialCapacity) { super(initialCapacity); init(); } /** * Construct an OMAreaList around a List of OMGeometries. The OMAreaList * assumes that all the objects on the list are vector OMGeometries, and * never does checking. Live with the consequences if you put other stuff in * there. * * @param list List of vector OMGeometries. */ public OMAreaList(java.util.List<OMGeometry> list) { addAll(list); init(); } /** * Initialization that sets the OMAreaList, which is a modified * OMGraphicList, to be vague and constructed in a first added, first used * order. connectParts, a variable from OMGeometryList, is also set to true. */ protected void init() { setVague(true); setTraverseMode(LAST_ADDED_ON_TOP); setConnectParts(true); } /** * Create the GeneralPath used for the internal Shape objects held by the * OMGeometries added. With the OMAreaList, all of the components are * combined to make a single area. So updateShape, which is called from * super.generate(), calls appendShapeEdge() instead of appending each part * Shape to the main Shape. This method closes off the GeneralPath Shape, so * it will be considered a polygon. */ public synchronized boolean generate(Projection p, boolean forceProjectAll) { boolean isGenerated = super.generate(p, forceProjectAll); GeneralPath projectedShape = getShape(); if (projectedShape != null) { projectedShape.closePath(); } return isGenerated; } /** * Given a OMGeometry, it calls generate/regenerate on it, and then adds the * GeneralPath shape within it to the OMGeometryList shape object. The edges * of each part are combined to make one big polygon. */ protected void updateShape(OMGeometry geometry, Projection p, boolean forceProject) { if (forceProject) { geometry.generate(p); } else { geometry.regenerate(p); } if (geometry.isVisible()) { GeneralPath gp = geometry.getShape(); if (gp == null) { return; } setShape(appendShapeEdge(getShape(), gp, connectParts)); // save memory?? by deleting the shape in each part, since // they are each contributing to the whole. geometry.setShape((GeneralPath) null); } setLabelLocation(getShape(), p); } /** * Overrides the OMGeometryList and OMGraphicList methods to just call * _distance() on the internal shape object. * * @param x x coordinate * @param y y coordinate * @param limit the max distance that a graphic has to be within to be * returned, in pixels. * @param resetSelect deselect any OMGraphic touched. * @return OMDist */ public synchronized OMDist<OMGeometry> findClosest(double x, double y, float limit, boolean resetSelect) { OMDist<OMGeometry> omd = new OMDist<OMGeometry>(); float currentDistance = Float.MAX_VALUE; // cannot select a graphic which isn't visible if (!isVisible()) { omd.omg = null; } else { if (resetSelect) deselect(); currentDistance = _distance(x, y); } if (currentDistance < limit) { omd.omg = this; omd.d = currentDistance; } return omd; } }