?? roadfinder.java
字號(hào):
/* ********************************************************************** * * Use, duplication, or disclosure by the Government is subject to * restricted rights as set forth in the DFARS. * * BBN Technologies * A Division of * BBN Corporation * 10 Moulton Street * Cambridge, MA 02138 * (617) 873-3000 * * Copyright 1998 by BBN Technologies, A Division of * BBN Corporation, all rights reserved. * * ********************************************************************** * * $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/tools/roads/RoadFinder.java,v $ * $RCSfile: RoadFinder.java,v $ * $Revision: 1.1.2.5 $ * $Date: 2005/08/12 21:47:05 $ * $Author: dietrick $ * * ********************************************************************** */package com.bbn.openmap.tools.roads;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Point;import java.awt.Shape;import java.awt.geom.AffineTransform;import java.awt.geom.PathIterator;import java.io.PrintStream;import java.util.ArrayList;import java.util.Enumeration;import java.util.HashMap;import java.util.HashSet;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.Vector;import java.util.logging.Level;import java.util.logging.Logger;import com.bbn.openmap.LatLonPoint;import com.bbn.openmap.event.ProjectionEvent;import com.bbn.openmap.event.ProjectionListener;import com.bbn.openmap.omGraphics.OMGeometry;import com.bbn.openmap.omGraphics.OMLine;import com.bbn.openmap.omGraphics.OMPoint;import com.bbn.openmap.omGraphics.OMText;import com.bbn.openmap.proj.Projection;import com.bbn.openmap.util.quadtree.QuadTree;/** * Gives road access to a shape or vpf layer. */public class RoadFinder implements RoadServices, ProjectionListener, RoadLayer { protected RoadClasses roadClasses = new RoadClasses(); protected RoadClass defaultRoadClass; protected LayerView layer; protected Intersections intersections = new Intersections(); protected RoadVector roads = new RoadVector(); protected Vector removedRoads = new Vector(); /** * how far (in lat-lon space) from lat,lon point to look in quad * tree for nearest road * */ protected float halo; Logger logger = Logger.getLogger(this.getClass().getName()); boolean drawIntersections = false; boolean drawResults = false; boolean doLoopCheck = false; protected QuadTree interQuadTree; protected Map graphicToRoad; boolean doInterp = true; /** list of extra graphics to display */ List toDraw = new ArrayList(); boolean showLines = true; int roadsMade = 0; public RoadFinder(LayerView layer, boolean drawIntersections, boolean drawResults) { initRoadClasses(); this.drawIntersections = drawIntersections; this.drawResults = drawResults; logger.info("drawIntersections is " + drawIntersections); logger.info("drawResults is " + drawResults); this.layer = layer; } protected void initRoadClasses() { roadClasses.put(new RoadClass("1", Color.magenta, 2, 25.0f)); defaultRoadClass = findRoadClass("1"); } /** * Implemented for ProtectionListener */ public void projectionChanged(ProjectionEvent e) { try { getData(); } catch (Exception ee) { logger.warning("Got exception " + ee); ee.printStackTrace(); } } /** * Take the shape data on the layer and use it to populate our * roads and intersections. * * Clears lists of roads and intersections first, and after * calculating the roads, tells the RoadLayer what extra graphics * to display, if any. */ protected synchronized void getData() throws Exception { logger.info("get Data called."); intersections.clear(); removedRoads.setSize(0); roads.clear(); toDraw.clear(); getRoads(); checkIntegrity(); logger.info("showing " + toDraw.size() + " extra graphics."); layer.setExtraGraphics(toDraw); halo = 0.05f * (getProjection().getScale() / 20000f); } /** * Take the shape data on the layer and use it to populate our * roads and intersections. * */ protected void getRoads() throws Exception { roadsMade = 0; List rectangle = layer.getGraphicList(); int[] xPoints = new int[1024]; int[] yPoints = new int[1024]; interQuadTree = new QuadTree(); graphicToRoad = new HashMap(); int height = getProjection().getHeight(); int width = getProjection().getWidth(); int skipped = 0; synchronized (rectangle) { double[] points = new double[6]; if (logger.isLoggable(Level.INFO)) logger.info("iterating over rectangle contents."); int num = 0; int made = 0; for (Iterator iter = rectangle.iterator(); iter.hasNext();) { double lastXOff = 0; double lastYOff = 0; num++; OMGeometry graphic = (OMGeometry) iter.next(); if (logger.isLoggable(Level.FINE)) logger.fine("examining " + graphic); Shape shape = graphic.getShape(); if (shape == null) continue; PathIterator path = shape.getPathIterator(new AffineTransform()); int segment = 0; int itemsInPath = 0; boolean pathValid = true; for (; !path.isDone() && pathValid; path.next()) { int type = path.currentSegment(points); itemsInPath++; boolean offScreen = false; if (points[0] < 0 || points[0] >= width) { // logger.warning("skipping x point " + // points[0] + " b/c it's off the map."); offScreen = true; } if (points[1] < 0 || points[1] >= height) { // logger.warning("skipping y point " + // points[1] + " b/c it's off the map."); offScreen = true; } switch (type) { case PathIterator.SEG_CLOSE: logger.warning("got close"); break; case PathIterator.SEG_CUBICTO: logger.warning("got cubic to"); break; case PathIterator.SEG_LINETO: if (offScreen) { if (segment > 0) { // BOZO // should reexamine whether this is // legal - there should be // a one-to-one mapping between // graphic and road object, // but this will throw away the // original entry if (doInterp) { Point interpPt = interp(xPoints[segment - 1], yPoints[segment - 1], points[0], points[1], width, height); xPoints[segment] = interpPt.x; yPoints[segment++] = interpPt.y; makeRoad(shape, graphic, made++, xPoints, yPoints, segment); lastXOff = 0; lastYOff = 0; segment = 0; } } else { lastXOff = points[0]; lastYOff = points[1]; } } else { // onscreen if (lastXOff != 0 || lastYOff != 0) { Point interpPt = interp(points[0], points[1], lastXOff, lastYOff, width, height); xPoints[segment] = interpPt.x; yPoints[segment++] = interpPt.y; } xPoints[segment] = (int) points[0]; yPoints[segment++] = (int) points[1]; lastXOff = 0; lastYOff = 0; } if (logger.isLoggable(Level.FINE)) logger.fine(" line to " + points[0] + ", " + points[1]); break; case PathIterator.SEG_MOVETO: if (offScreen) { lastXOff = points[0]; lastYOff = points[1]; } else { if (segment == 0) { xPoints[segment] = (int) points[0]; yPoints[segment++] = (int) points[1]; } else { // we got a second move to in the list // - this is not valid pathValid = false; logger.info("got invalid path."); } lastXOff = 0; lastYOff = 0; } if (logger.isLoggable(Level.FINE)) logger.fine(" moving to " + points[0] + ", " + points[1]); break; case PathIterator.SEG_QUADTO: logger.warning("got quad to"); break; default: logger.warning("got another type : " + type); break; } } if (segment < 2) { skipped++; logger.fine("Skipping line that doesn't have an end point"); } else { if (logger.isLoggable(Level.INFO)) logger.info("items in path " + itemsInPath); makeRoad(shape, graphic, made++, xPoints, yPoints, segment); } segment = 0; } if (logger.isLoggable(Level.INFO)) logger.info("num items " + num + " skipped " + skipped); } } /** * find a point between x1,y1 and x2, y2 that is within the * visible map * * @param width of visible map * @param height of visible map * @return Point between x1,y1 and x2, y2 */ protected Point interp(double x1, double y1, double x2, double y2, int width, int height) {
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -