📄 losgenerator.java
字号:
// **********************************************************************// // <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/layer/terrain/LOSGenerator.java,v $// $RCSfile: LOSGenerator.java,v $// $Revision: 1.3.2.3 $// $Date: 2005/08/09 21:17:47 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.layer.terrain;import java.awt.*;import java.awt.event.*;import com.bbn.openmap.LatLonPoint;import com.bbn.openmap.MoreMath;import com.bbn.openmap.event.*;import com.bbn.openmap.gui.ProgressListenerGauge;import com.bbn.openmap.dataAccess.dted.DTEDFrameCache;import com.bbn.openmap.layer.util.stateMachine.*;import com.bbn.openmap.omGraphics.*;import com.bbn.openmap.proj.*;import com.bbn.openmap.util.Debug;import com.bbn.openmap.util.SwingWorker;/** * The LOSGenerator uses gestures to create a mask over the map. The * circular mask of green pixels shows what places are within the * sight of the center of the circle. Additional height can be added * to the center of the circle via the TerrainLayer palette, to * represent a tower, building, or aircraft. */public class LOSGenerator implements TerrainTool { // These are used to control the algorithm type. Right now, the // first two are eliminated, since the azimuth alogorithm is // faster // and more precise. final static int PRECISE = 0; final static int GOODENOUGH = 1; final static int AZIMUTH = 2; // RED Color toolColor = new Color(255, 0, 0); // The colors of pixels final static int INVISIBLE = 0; final static int VISIBLE = 1; final static int MAYBEVISIBLE = 2; int[] colortable; Projection proj; protected LOSStateMachine stateMachine; TerrainLayer layer; /** Lat lon of the center of hte circle. */ LatLonPoint LOScenterLLP; /** The xy of the center of the circle. */ Point LOScenterP = new Point(); /** The height of the earth at the center point. */ int LOScenterHeight; /** The height of the object at the center point. */ int LOSobjectHeight = 0; /** The diameter of the circle of interest. */ int LOSedge; protected OMGraphicList graphics = new OMGraphicList(); OMRaster LOSimage; // The image for the mask OMCircle LOScirc; // The circle modified for the image definition int LOSprecision; // The flag for the algorithm type LatLonPoint LOSOffPagell = new LatLonPoint(-79f, -170f); Point LOSOffPagep1 = new Point(-10, -10); /** The thread worker used to create the Terrain images. */ LOSWorker currentWorker; /** * Set when the projection has changed while a swing worker is * gathering graphics, and we want him to stop early. */ protected boolean cancelled = false; protected ProgressSupport progressSupport; class LOSWorker extends SwingWorker { /** Constructor used to create a worker thread. */ public LOSWorker() {} /** * Compute the value to be returned by the <code>get</code> * method. */ public Object construct() { Debug.message("terrain", layer.getName() + "|LOSWorker.construct()"); layer.fireStatusUpdate(LayerStatusEvent.START_WORKING); createLOSImage(); return null; } /** * Called on the event dispatching thread (not on the worker * thread) after the <code>construct</code> method has * returned. */ public void finished() { layer.fireStatusUpdate(LayerStatusEvent.FINISH_WORKING); workerComplete(); } } /** * Not the preferred way to create one of these. It's full of * defaults. */ private LOSGenerator() { init(); } /** * The creation of the tool starts here. The DTED data cache is * passed in, along with a path to the dted directory to get more * data if needed. */ public LOSGenerator(TerrainLayer tLayer) { layer = tLayer; init(); } public synchronized OMGraphicList getGraphics() { return graphics; } public State getState() { return stateMachine.getState(); } public void init() { progressSupport = new ProgressSupport(this); addProgressListener(new ProgressListenerGauge("LOS Mask Creation")); // colortable colortable = new int[3]; colortable[INVISIBLE] = new Color(0, 0, 0, 0).getRGB(); colortable[VISIBLE] = new Color(0, 255, 0, 255).getRGB(); colortable[MAYBEVISIBLE] = new Color(255, 255, 0, 255).getRGB(); stateMachine = new LOSStateMachine(this); // set the graphics reset(true, true); graphics.add(LOSimage); graphics.add(LOScirc); } public void doImage() { // If there isn't a worker thread working on this already, // create a thread that will do the real work. If there is // a thread working on this, then set the cancelled flag // in the layer. if (currentWorker == null) { currentWorker = new LOSWorker(); currentWorker.execute(); } else setCancelled(true); } /** * The TerrainWorker calls this method on the layer when it is * done working. If the calling worker is not the same as the * "current" worker, then a new worker is created. */ protected synchronized void workerComplete() { if (!isCancelled()) { currentWorker = null; layer.repaint(); } else { setCancelled(false); currentWorker = new LOSWorker(); currentWorker.execute(); } } /** * Used to set the cancelled flag in the layer. The swing worker * checks this once in a while to see if the projection has * changed since it started working. If this is set to true, the * swing worker quits when it is safe. */ public synchronized void setCancelled(boolean set) { cancelled = set; } /** Check to see if the cancelled flag has been set. */ public synchronized boolean isCancelled() { return cancelled; } /** * Without arguments, the reset() call makes both graphics go * offscreen in their smallest size. */ public void reset() { reset(true, true); } /** * Circ is for the circle to be reset, and image is for the image * to be reset. Sometimes you only want one to be moved. */ public void reset(boolean circ, boolean image) { graphics.clear(); if (image) { LOSimage = new OMRaster(LOSOffPagell.getLatitude(), LOSOffPagell.getLongitude(), LOSOffPagep1.x, LOSOffPagep1.y, 1, 1, new int[1]); } if (circ) { LOScirc = new OMCircle(LOSOffPagell.getLatitude(), LOSOffPagell.getLongitude(), 1, 1); LOScirc.setLinePaint(toolColor); } layer.repaint(); stateMachine.reset(); } /** * Called on every getRectangle, in order to let the cache get * sized right, and to reset the graphics if the scale changed * (since they won't make sense. */ public void setScreenParameters(Projection p) { reset(true, true); proj = p; LOSprecision = AZIMUTH; graphics.generate(proj); } /** * Takes the member settings and manages the creation of the * image. A large vector of slope values are created, depending on * the size of the circle, and how many pixels are around it. Each * entry in the vector is the value of the largest slope value in * that direction. The image is created from the inside out, pixel * by pixel. The slope from the pixel to the center is calculated, * and then compared with the value for that direction (in the * vector). If the pixel's slope is larger, the point is visible, * and is colored that way. The vector is updated, and the cycle * continues. */ public synchronized void createLOSImage() { if (Debug.debugging("los")) { Debug.output("createLOSimage: Entered with diameter = " + LOSedge); } if (layer == null || layer.frameCache == null) { Debug.error("LOSGenerator: can't access the DTED data through the terrain layer."); return; } int squareRadius = LOSedge / 2 + 1; int[] newPixels = new int[LOSedge * LOSedge]; float[] azimuthVals = new float[8 * (squareRadius - 1)]; // center point of raster newPixels[((LOSedge / 2) * LOSedge) + squareRadius] = MAYBEVISIBLE; if (Debug.debugging("los")) { Debug.output("createLOSimage: size of azimuth array = " + azimuthVals.length); } fireProgressUpdate(ProgressEvent.START, "Building LOS Image Mask...", 0, 100); int x, y; boolean mark = false; int markColor = colortable[INVISIBLE]; int range; float pix_arc_interval = (float) (2 * Math.PI / azimuthVals.length); // Do this in a spiral, around the center point. for (int round = 1; round < squareRadius; round++) { if (Debug.debugging("los")) { Debug.output("createLOSimage: round " + round); } y = LOScenterP.y - round; x = LOScenterP.x - round; if (round == 1) { mark = true; markColor = colortable[MAYBEVISIBLE];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -