/** * Add content to this Group. The OMGraphicHandler layers that are part of the map with have their * graphics may be added with a small separation between the layers, depending on the value of * layerSeparation. * * @param mapHandler Description of the Parameter */ protected void createMap(MapHandler mapHandler) { double baselineHeight = layerSeparation; LayerHandler lh = (LayerHandler) mapHandler.get("com.bbn.openmap.LayerHandler"); if (lh != null) { Debug.message("3d", "LayerMapContent: putting layer graphics on the map."); Layer[] layers = lh.getLayers(); // Back to front makes the sea in the back, and keeps // first layers on top, to go with the OpenMap paradigm. for (int i = layers.length - 1; i >= 0; i--) { Layer layer = layers[i]; if (layer.isVisible()) { if (layer instanceof ScaleFilterLayer) { ScaleFilterLayer sfl = (ScaleFilterLayer) layer; layer = sfl.getAppropriateLayer(); } if (layer instanceof OMGraphicHandlerLayer) { addContent(this, (OMGraphicHandlerLayer) layer, baselineHeight += layerSeparation); } else { Debug.message("3d", "LayerMapContent: skipping layer " + layer.getName()); } } } } addSea(this, mapHandler); }
/** * Called when some fundamental parameters change. * * <p>Each projection will decide how to respond to this change. For instance, they may need to * recalculate "constant" parameters used in the forward() and inverse() calls. * * <p> */ protected void computeParameters() { Debug.message("proj", "Gnomonic.computeParameters()"); super.computeParameters(); // maxscale = scale at which a world hemisphere fits in the // window maxscale = (width < height) ? (float) (planetPixelRadius * 2 * hPrime) / (float) width : (float) (planetPixelRadius * 2 * hPrime) / (float) height; if (maxscale < minscale) { maxscale = minscale; } if (scale > maxscale) { scale = maxscale; } scaled_radius = planetPixelRadius / scale; // width of the world in pixels at current scale. We see only // one hemisphere. world.x = (int) ((planetPixelRadius * 2 * hPrime) / scale); // do some precomputation of stuff cosCtrLat = Math.cos(centerY); sinCtrLat = Math.sin(centerY); // compute the offsets hy = height / 2; wx = width / 2; }
/** * Inverse project x,y coordinates into a LatLonPoint. * * @param x integer x coordinate * @param y integer y coordinate * @param llp LatLonPoint * @return LatLonPoint llp * @see Proj#inverse(Point2D) */ public <T extends Point2D> T inverse(double x, double y, T llp) { if (llp == null) { llp = (T) new LatLonPoint.Double(); } // convert from screen to world coordinates x -= wx; y = hy - y; // Debug.output("Gnomonic.inverse: x,y=" + x + "," + y); double rho = Math.sqrt(x * x + y * y); if (rho == 0) { Debug.message("proj", "Gnomonic.inverse: center!"); llp.setLocation(ProjMath.radToDeg(centerX), ProjMath.radToDeg(centerY)); return llp; } double c = Math.atan2(rho, scaled_radius); double cosC = Math.cos(c); double sinC = Math.sin(c); // calculate latitude double lat = Math.asin(cosC * sinCtrLat + (y * sinC * (cosCtrLat / rho))); // calculate longitude double lon = centerX + Math.atan2((x * sinC), (rho * cosCtrLat * cosC - y * sinCtrLat * sinC)); // Debug.output("Gnomonic.inverse: lat,lon=" + // ProjMath.radToDeg(lat) + "," + // ProjMath.radToDeg(lon)); // check if point in outer space // if (MoreMath.approximately_equal(lat, ctrLat) && // MoreMath.approximately_equal(lon, ctrLon) && // (Math.abs(x-(width/2))<2) && // (Math.abs(y-(height/2))<2)) if (Double.isNaN(lat) || Double.isNaN(lon)) { Debug.message("proj", "Gnomonic.inverse(): outer space!"); lat = centerY; lon = centerX; } llp.setLocation(Math.toDegrees(wrapLongitude(lon)), Math.toDegrees(normalizeLatitude(lat))); return llp; }
/** * Paints the layer. * * @param g the Graphics context for painting */ public void paint(java.awt.Graphics g) { Debug.message("dted", getName() + "|DTEDLayer.paint()"); super.paint(g); if (location != null) location.render(g); location = null; }
/** * Use the current projection to place the graphics on the screen. Has to be called to at least * assure the graphics that they are ready for rendering. Called when the graphic position * changes. * * @param proj com.bbn.openmap.proj.Projection * @return true */ public boolean generate(Projection proj) { Debug.message("eomg", "EditableOMPoly.generate()"); if (poly != null) { poly.generate(proj); } generateGrabPoints(proj); return true; }
/** * Given a new projection, the grab points may need to be repositioned off the current position of * the graphic. Called when the projection changes. */ public void regenerate(Projection proj) { Debug.message("eomg", "EditableOMPoly.regenerate()"); if (poly != null) { poly.generate(proj); setGrabPoints(poly); } generateGrabPoints(proj); }
/** * Draw the EditableOMPoly parts into the java.awt.Graphics object. The grab points are only * rendered if the poly machine state is PolySelectedState.POLY_SELECTED. * * @param graphics java.awt.Graphics. */ public void render(java.awt.Graphics graphics) { Debug.message("eomg", "EditableOMPoly.render()"); State state = getStateMachine().getState(); if (poly != null && !(state instanceof PolyUndefinedState)) { poly.setVisible(true); poly.render(graphics); poly.setVisible(false); } else { Debug.message("eomg", "EditableOMPoly.render: null or undefined poly."); return; } // Render the points actually on the polygon if (state instanceof GraphicSelectedState || state instanceof PolyAddNodeState || state instanceof PolyDeleteNodeState) { for (GrabPoint gb : polyGrabPoints) { if (gb != null) { gb.setVisible(true); gb.render(graphics); gb.setVisible(false); } } } // In certain conditions, render the offset grab point. if (state instanceof GraphicSelectedState || state instanceof GraphicEditState /* * || * state * instanceof * PolySetOffsetState */) { if (gpo != null && poly.getRenderType() == OMGraphic.RENDERTYPE_OFFSET) { gpo.setVisible(true); gpo.render(graphics); gpo.setVisible(false); } } }
/** * Adds widgets to modify polygon. * * @param graphicAttributes the GraphicAttributes to use to get the GUI widget from to control * those parameters for this EOMG. * @return Component to use to control parameters for this EOMG. */ public Component getGUI(GraphicAttributes graphicAttributes) { Debug.message("eomg", "EditableOMPoly.getGUI"); if (graphicAttributes != null) { JMenu ahm = getArrowHeadMenu(); graphicAttributes.setLineMenuAdditions(new JMenu[] {ahm}); // JComponent gaGUI = (JComponent) graphicAttributes.getGUI(); JComponent toolbar = createAttributePanel(graphicAttributes); getPolyGUI(graphicAttributes.getOrientation(), toolbar); return toolbar; } else { return getPolyGUI(); } }
/** * Find a PoliticalArea named by the search key. If the shapefile is large, the first query will * take a little extra time on the first query to read in the files. * * @param area_key the lookup key, of which the index for the column was designated in the * properties file. */ public PoliticalArea findPoliticalArea(String area_key) { // Right now, this method gathers all the graphics in the // shape file, groups them, and then returns the PoliticalArea // for the key. In the future, it would be nice to have the // option to actually search through the data file, find the // indexes of the graphics that go to the area, and assemble a // temporary list to pass back. if (politicalAreas == null) { Debug.message("areas", "AreaHandler: initializing graphic attributes"); initialize(originalPrefix, originalProperties); if (omgraphics == null) { omgraphics = getGraphics(); if (dbfModel != null) loadDbfModelIntoGraphics(omgraphics); else infoFile.loadIntoGraphics(omgraphics); } politicalAreas = determinePoliticalAreas(omgraphics); Debug.message("areas", "AreaHandler: completed initialization"); } if (politicalAreas != null) { String key = area_key.toUpperCase().intern(); // Just to // be sure. return (PoliticalArea) politicalAreas.get(key); } else { Debug.error( "AreaHandler: initialization failed for " + originalPrefix + "\n\tNo data will be displayed"); return null; } }
/** * Read a cache of OMGeometries, given a ObjectInputStream. * * @param objstream ObjectInputStream of geometry list. */ public void readGraphics(ObjectInputStream objstream) throws IOException { Debug.message("omgraphics", "OMGeometryList: Reading cached geometries"); try { while (true) { try { OMGeometry omg = (OMGeometry) objstream.readObject(); this.add(omg); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (OptionalDataException ode) { ode.printStackTrace(); } } } catch (EOFException e) { } }
/** * Read the link and pull off the gesture, filling in the fields of this object. * * @param link the link to read from. * @return Link.END_TOTAL or Link.END_SECTION */ public String read(Link link) throws IOException { float ver = link.dis.readFloat(); if (ver != version) { if (ver == .1) { // Big differece.... throw new IOException("LinkActionRequest: Versions do not match! DANGER!"); } else { Debug.message("link", "LinkActionRequest: Versions do not match"); } } // the second thing we get is the descriptor descriptor = link.dis.readInt(); if (isClientNotification()) { // In case it is passed back later to the server - we // really don't need to know that it was a notification // mask after this, right?? descriptor = LinkUtil.unsetMask(descriptor, CLIENT_NOTIFICATION_MASK); return link.readDelimiter(false); } else if (isKeyEvent()) { // key event key = link.dis.readChar(); modifiers = link.dis.readInt(); } else { // Mouse event x = link.dis.readInt(); y = link.dis.readInt(); clickCount = link.dis.readInt(); modifiers = link.dis.readInt(); lat = link.dis.readFloat(); lon = link.dis.readFloat(); } properties = new LinkProperties(link); if (LinkUtil.isMask(descriptor, GRAPHIC_ID_MASK)) { id = properties.getProperty(LPC_GRAPHICID); } return link.readDelimiter(false); }
/** * Add the projection background color to the base level of the Java 3D map. The MapHandler * provides the MapBean and therefore the projection. * * @param bg The feature to be added to the Sea attribute * @param mh The feature to be added to the Sea attribute */ protected void addSea(Group bg, MapHandler mh) { MapBean map = (MapBean) mh.get("com.bbn.openmap.MapBean"); if (map != null) { Debug.message("3d", "LayerMapContent: putting down sea."); Color seaColor = map.getBackground(); Projection proj = map.getProjection(); // Make the background strech a screen around the current // map, all directions. int width = proj.getWidth(); int height = proj.getHeight(); java.awt.geom.GeneralPath background = // OMGraphic.createBoxShape(0, 0, width, height); OMGraphicAdapter.createBoxShape(-width, -height, width * 3, height * 3); addTo(bg, OMGraphicUtil.createShape3D(background, 0, seaColor, true)); } }
/** * Get the array of grab points used for the EditableOMGraphic. Creates the array by copying all * the grab points out of the ArrayList, and tacking the offset grab point to the end. */ public GrabPoint[] getGrabPoints() { int size = polyGrabPoints.size(); // The second half of the test is the fix to the bug that caused // OMEditablePolys to be unresponsive when the colors changed. Thanks, // Stephane! // if (gPoints.length != size + 1 // || ((size > 0) && (!gPoints[0].equals(polyGrabPoints.get(0))))) { if (gPoints.length != size + 1 || arrayCleared) { arrayCleared = false; Debug.message("eomg", "EditableOMPoly.getGrabPoints(): recreating grab points"); gPoints = new GrabPoint[size + 1]; int counter = 0; for (GrabPoint gb : polyGrabPoints) { gPoints[counter++] = gb; } gPoints[counter] = gpo; } return gPoints; }
public boolean generate(Projection proj) { if (renderType == RENDERTYPE_XY || renderType == RENDERTYPE_OFFSET) { return super.generate(proj); // generate using circle's generate } // RENDERTYPE_LATLON should go in here setShape(null); if (proj == null) { Debug.message("omgraphic", "OMEllipse: null projection in generate!"); return false; } if (rawllpts == null) { rawllpts = createLatLonPoints(); } ArrayList vector = null; // polygon/polyline project the polygon/polyline. // Vertices should already be in radians. vector = proj.forwardPoly(rawllpts, getLineType(), -1, true); int size = vector.size(); // We could call create shape, but this is more efficient. int i, j; for (i = 0, j = 0; i < size; i += 2, j++) { GeneralPath gp = createShape((int[]) vector.get(i), (int[]) vector.get(i + 1), true); if (shape == null) { setShape(gp); } else { ((GeneralPath) shape).append(gp, false); } } setNeedToRegenerate(false); return true; }
/** * Prepares the graphics for the layer. This is where the getRectangle() method call is made on * the dted. * * <p>Occasionally it is necessary to abort a prepare call. When this happens, the map will set * the cancel bit in the LayerThread, (the thread that is running the prepare). If this Layer * needs to do any cleanups during the abort, it should do so, but return out of the prepare asap. */ public synchronized OMGraphicList prepare() { if (isCancelled()) { Debug.message("dted", getName() + "|DTEDLayer.prepare(): aborted."); return null; } Projection projection = getProjection(); if (projection == null) { Debug.error("DTED Layer needs to be added to the MapBean before it can draw images!"); return new OMGraphicList(); } DTEDCacheManager cache = getCache(); if (!(projection instanceof EqualArc)) { // fireRequestInfoLine("DTED works faster with an Equal Arc projection (CADRG/LLXY)."); } Debug.message("basic", getName() + "|DTEDLayer.prepare(): doing it"); // Setting the OMGraphicsList for this layer. Remember, the // OMGraphicList is made up of OMGraphics, which are generated // (projected) when the graphics are added to the list. So, // after this call, the list is ready for painting. // call getRectangle(); if (Debug.debugging("dted")) { Debug.output( getName() + "|DTEDLayer.prepare(): " + "calling getRectangle " + " with projection: " + projection + " ul = " + projection.getUpperLeft() + " lr = " + projection.getLowerRight()); } OMGraphicList omGraphicList; if (projection.getScale() < maxScale) { omGraphicList = cache.getRectangle(projection); } else { fireRequestInfoLine(" The scale is too small for DTED viewing."); Debug.error( "DTEDLayer: scale (1:" + projection.getScale() + ") is smaller than minimum (1:" + maxScale + ") allowed."); omGraphicList = new OMGraphicList(); } // /////////////////// // safe quit int size = 0; if (omGraphicList != null) { size = omGraphicList.size(); Debug.message( "basic", getName() + "|DTEDLayer.prepare(): finished with " + size + " graphics"); // // Don't forget to project them. Since they are only // // being recalled if the projection has changed, then we // // need to force a reprojection of all of them because the // // screen position has changed. // omGraphicList.project(projection, true); } else { Debug.message("basic", getName() + "|DTEDLayer.prepare(): finished with null graphics list"); } return omGraphicList; }
/** * Called when some fundamental parameters change. * * <p>Each projection will decide how to respond to this change. For instance, they may need to * recalculate "constant" parameters used in the forward() and inverse() calls. * * <p> */ protected synchronized void computeParameters() { int w, h; if (ul == null) ul = new Point(0, 0); // HACK // quick calculate the maxscale maxscale = CADRG_calc_maxscale(); if (scale > maxscale) scale = maxscale; // Compute the "ADRG" scale, which gets used below. double adrgscale = 1000000.0 / scale; // 1 million (from // ADRG // spec) if (adrgscale > CADRG_SCALE_LIMIT) { Debug.message("proj", "CADRG: adrgscale > CADRG_SCALE_LIMIT"); adrgscale = CADRG_SCALE_LIMIT; } // Compute the y pixel constant based on scale. y_pix_constant = CADRG_y_pix_constant(adrgscale); if (Debug.debugging("proj")) { Debug.output("Y pix constant = " + y_pix_constant); } // //// /** Pixels per degree */ double ppd = y_pix_constant / 90.0; if (upper_zone_extents == null || lower_zone_extents == null) { upper_zone_extents = new double[CADRG_get_zone_old_extents.length]; lower_zone_extents = new double[CADRG_get_zone_old_extents.length + 1]; lower_zone_extents[0] = 0f; lower_zone_extents[8] = 80f; upper_zone_extents[8] = 90f; // figure out new extents - from CADRG spec for (int x = 0; x < CADRG_get_zone_old_extents.length - 1 /* 8 */; x++) { double pivot = Math.floor(ppd * CADRG_get_zone_old_extents[x] / 1536.0); lower_zone_extents[x + 1] = pivot * 1536.0 / ppd; // Can't go further than the equator. // if (x == 0) lower_zone_extents[x] = 0; pivot++; upper_zone_extents[x] = pivot * 1536.0 / ppd; Debug.message("proj", "lower_zone_extents[" + x + "] = " + lower_zone_extents[x]); Debug.message("proj", "upper_zone_extents[" + x + "] = " + upper_zone_extents[x]); } } // //// // What zone are we in? To try to reduce pixel spacing jumping when // zoomed // out, just set the zone level to one when zoomed out past 1:60M. There // aren't any charts available at those scales in this projection type. if (scale > 60000000) { zone = 1; } else { zone = getZone(ProjMath.radToDeg(centerY), y_pix_constant); } if (Debug.debugging("proj")) { Debug.output("Zone = " + zone); } // Compute the x pixel constant, based on scale and zone. x_pix_constant = CADRG_x_pix_constant(adrgscale, zone); // If the x_pix_constant, or number of pixels around the earth is less // than or equal to the width of the map window, then the corner // coordinates become equal or inverted (ul vs lr). if (width >= x_pix_constant) { x_pix_constant = width + 1; } if (Debug.debugging("proj")) { Debug.output("x_pix_constant = " + x_pix_constant); } // Now I can compute the world coordinate. if (world == null) world = new Point(0, 0); world.x = (int) ProjMath.roundAdjust(x_pix_constant); world.y = (int) ProjMath.roundAdjust(y_pix_constant * 4.0 / 2.0); Debug.message("proj", "world = " + world.x + "," + world.y); // Compute scaled pixels per RADIAN, not SCOORD spps_x = (double) x_pix_constant / MoreMath.TWO_PI /* * MoreMath.DEG_TO_SC(360 * ) */; spps_y = (double) y_pix_constant / MoreMath.HALF_PI /* * MoreMath.DEG_TO_SC( * 90 ) */; Debug.message("proj", "spps = " + spps_x + "," + spps_y); // Fix the "small world" situation, computing ox, oy. if (width > world.x) { Debug.message("proj", "CADRG: fixing small world"); w = world.x; // ox = (int) ProjMath.roundAdjust((width - w) / 2.0); } else { w = width; // ox = 0; } if (height > world.y) { h = (int) world.y; oy = (int) ProjMath.roundAdjust((height - h) / 2.0); } else { h = height; oy = 0; } // compute the "upper left" adjustment. long temp = (long) ProjMath.roundAdjust(spps_y * centerY); if (Debug.debugging("proj")) { Debug.output("CADRG.temp = " + temp); } if (ul == null) ul = new Point(0, 0); ul.x = (int) ProjMath.roundAdjust(-w / 2.0); if ((temp != 0) && (oy != 0)) { ul.y = (int) ProjMath.roundAdjust(h / 2.0); } else { ul.y = (int) temp + (int) ProjMath.roundAdjust(h / 2.0); } if (Debug.debugging("proj")) { Debug.output("CADRG: ul = " + ul.x + "," + ul.y); Debug.output(/* "ox = " + ox + */ " oy = " + oy); } // Finally compute some useful cylindrical projection // parameters // maxscale = (CADRG_ARC_A[0] * (1000000/width));// HACK!!! half_world = world.x / 2; if (scale > maxscale) { scale = maxscale; } // scaled_radius = planetPixelRadius/scale; Debug.message("proj", "CADRG.computeParameters(): maxscale: " + maxscale); }
/** * Delete a point at a certain point in the polygon coordinate list. If the position is less than * zero, the deleted point will be the starting point. If the position is greater than the list of * current points, the point will be deleted from the end of the poly. */ public void deletePoint(int position) { int renderType = poly.getRenderType(); boolean needToHookUp = false; if (position <= 0 && isEnclosed()) { // if the position is 0 and the polygon is enclosed, we // need to disengage the two points, then reattach. enclose(false); needToHookUp = true; } if (renderType == OMGraphic.RENDERTYPE_LATLON) { Debug.message("eomg", "EditableOMPoly: removing point from lat/lon poly"); if (projection != null) { double[] ll = poly.getLatLonArray(); double[] newll = new double[ll.length - 2]; int actualPosition = (position == Integer.MAX_VALUE ? ll.length : position * 2); if (actualPosition >= ll.length) { // Pull the new points off the end System.arraycopy(ll, 0, newll, 0, ll.length - 2); position = (ll.length - 2) / 2; } else if (actualPosition <= 0) { // Pull the new points off the beginning System.arraycopy(ll, 2, newll, 0, ll.length - 2); position = 0; } else { // actualPosition because there are 2 floats for // every // position. System.arraycopy(ll, 0, newll, 0, actualPosition); System.arraycopy( ll, actualPosition + 2, newll, actualPosition, ll.length - actualPosition - 2); } poly.setLocation((double[]) newll, poly.getUnits()); } } else { // Grab the projected endpoints Debug.message("eomg", "EditableOMPoly: removing point from x/y or offset poly"); int currentLength = poly.xs.length; int[] newxs = new int[currentLength - 1]; int[] newys = new int[currentLength - 1]; if (position >= currentLength) { // Pull the points from the end... System.arraycopy(poly.xs, 0, newxs, 0, currentLength - 1); System.arraycopy(poly.ys, 0, newys, 0, currentLength - 1); position = currentLength - 1; } else if (position <= 0) { // Pull the points from the beginning... System.arraycopy(poly.xs, 1, newxs, 0, currentLength - 1); System.arraycopy(poly.ys, 1, newys, 0, currentLength - 1); position = 0; } else { System.arraycopy(poly.xs, 0, newxs, 0, position); System.arraycopy(poly.xs, position + 1, newxs, position, currentLength - position - 1); System.arraycopy(poly.ys, 0, newys, 0, position); System.arraycopy(poly.ys, position + 1, newys, position, currentLength - position - 1); } if (poly.getRenderType() == OMGraphic.RENDERTYPE_OFFSET) { poly.setLocation(poly.lat, poly.lon, poly.getUnits(), newxs, newys); } else { poly.setLocation(newxs, newys); } } if (projection != null) { poly.regenerate(projection); } // Remove the GrabPoint for the deleted spot. GrabPoint gp = (GrabPoint) polyGrabPoints.remove(position); if (gpo != null && gp != null) { gpo.removeGrabPoint(gp); } if (needToHookUp) { enclose(true); } }
/** * Add a point at a certain point in the polygon coordinate list. If the position is less than * zero, the point will be the starting point. If the position is greater than the list of current * points, the point will be added to the end of the poly. This method is convenient because it * lets you define the GrabPoint object to use for the node, in case you need a special type of * GrabPoint. * * @return the index for the point in the polygon, starting with 0. */ public int addPoint(GrabPoint gp, int position) { if (gp == null) { return -1; } int x = gp.getX(); int y = gp.getY(); int renderType = poly.getRenderType(); boolean rads = (poly.getUnits() == OMGraphic.RADIANS); if (renderType == OMGraphic.RENDERTYPE_LATLON) { Debug.message("eomg", "EditableOMPoly: adding point to lat/lon poly"); if (projection != null) { double[] ll = poly.getLatLonArray(); int actualPosition = (position == Integer.MAX_VALUE ? ll.length : position * 2); LatLonPoint llpnt = projection.inverse(x, y, new LatLonPoint.Double()); if (Debug.debugging("eomp")) { Debug.output( "EditableOMPoly: adding point to lat/lon poly at " + x + ", " + y + ": " + llpnt + ", at the end of "); for (int j = 0; j < ll.length; j += 2) { Debug.output(ll[j] + ", " + ll[j + 1]); } } double[] newll = new double[ll.length + 2]; double newlat; double newlon; if (rads) { newlat = llpnt.getRadLat(); newlon = llpnt.getRadLon(); } else { newlat = llpnt.getY(); newlon = llpnt.getX(); } if (actualPosition >= ll.length) { // Put the new points at the end if (ll.length != 0) { System.arraycopy(ll, 0, newll, 0, ll.length); } newll[ll.length] = newlat; newll[ll.length + 1] = newlon; position = ll.length / 2; } else if (actualPosition <= 0) { // Put the new point at the beginning System.arraycopy(ll, 0, newll, 2, ll.length); newll[0] = newlat; newll[1] = newlon; position = 0; } else { // actualPosition because there are 2 floats for // every // position. newll[actualPosition] = newlat; newll[actualPosition + 1] = newlon; System.arraycopy(ll, 0, newll, 0, actualPosition); System.arraycopy( ll, actualPosition, newll, actualPosition + 2, ll.length - actualPosition); } poly.setLocation((double[]) newll, poly.getUnits()); } } else if (renderType == OMGraphic.RENDERTYPE_XY) { // Grab the projected endpoints Debug.message("eomg", "EditableOMPoly: adding point to x/y poly"); int currentLength = poly.xs.length; int[] newxs = new int[currentLength + 1]; int[] newys = new int[currentLength + 1]; if (position >= currentLength) { // Put the new points at the end System.arraycopy(poly.xs, 0, newxs, 0, currentLength); System.arraycopy(poly.ys, 0, newys, 0, currentLength); newxs[currentLength] = x; newys[currentLength] = y; position = currentLength; } else if (position <= 0) { // Put the new points at the beginning System.arraycopy(poly.xs, 0, newxs, 1, currentLength); System.arraycopy(poly.ys, 0, newys, 1, currentLength); newxs[0] = x; newys[0] = y; position = 0; } else { newxs[position] = x; newys[position] = y; System.arraycopy(poly.xs, 0, newxs, 0, position); System.arraycopy(poly.xs, position, newxs, position + 1, currentLength - position); System.arraycopy(poly.ys, 0, newys, 0, position); System.arraycopy(poly.ys, position, newys, position + 1, currentLength - position); } poly.setLocation(newxs, newys); } else { // Rendertype is offset... // Grab the projected endpoints Debug.message("eomg", "EditableOMPoly: adding point to offset poly"); int currentLength = poly.xs.length; int[] newxs = new int[currentLength + 1]; int[] newys = new int[currentLength + 1]; if (position >= currentLength) { // Put the new points at the end position = currentLength; System.arraycopy(poly.xs, 0, newxs, 0, currentLength); System.arraycopy(poly.ys, 0, newys, 0, currentLength); } else if (position <= 0) { // Put the new points at the beginning position = 0; System.arraycopy(poly.xs, 0, newxs, 1, currentLength); System.arraycopy(poly.ys, 0, newys, 1, currentLength); } else { System.arraycopy(poly.xs, 0, newxs, 0, position); System.arraycopy(poly.xs, position, newxs, position + 1, currentLength - position); System.arraycopy(poly.ys, 0, newys, 0, position); System.arraycopy(poly.ys, position, newys, position + 1, currentLength - position); } int offsetX; int offsetY; if (gpo.getX() == -1 && gpo.getY() == -1) { offsetX = projection.getWidth() / 2; offsetY = projection.getHeight() / 2; } else { offsetX = gpo.getX(); offsetY = gpo.getY(); } if (poly.coordMode == OMPoly.COORDMODE_ORIGIN || position == 0) { // cover // the // first // point newxs[position] = x - offsetX; newys[position] = y - offsetY; } else { // CMode Previous offset deltas newxs[position] = x - offsetX - newxs[position - 1]; newys[position] = y - offsetY - newys[position - 1]; } if (position == 0) { // Could call projection.getCenter() but that might // break if/when we make other projection // libraries/paradigms active. LatLonPoint llpnt = projection.inverse(offsetX, offsetY, new LatLonPoint.Double()); if (rads) { poly.lat = llpnt.getRadLat(); poly.lon = llpnt.getRadLon(); } else { poly.lat = llpnt.getY(); poly.lon = llpnt.getX(); } } poly.setLocation(poly.lat, poly.lon, poly.getUnits(), newxs, newys); } // Need to reset the arrowhead when an end point is added, // removing it from the shape when the point gets added. // Otherwise, you end up with a arrowhead at each junction of // the polygon. OMArrowHead omah = poly.getArrowHead(); poly.setArrowHead(null); // Reset the arrowhead so it will get drawn on the new // segment. poly.setArrowHead(omah); polyGrabPoints.add(position, gp); if (gpo != null) { gpo.addGrabPoint(gp); } // This is the standard call that needs to be made here, the // arrowhead changes are around this. poly.regenerate(projection); gp.generate(projection); return position; }
/** * Take the current location of the GrabPoints, and modify the location parameters of the OMPoly * with them. Called when you want the graphic to change according to the grab points. */ public void setGrabPoints() { int i; GrabPoint gb; // just to use a temp marker LatLonPoint llp = new LatLonPoint.Double(); int renderType = poly.getRenderType(); if (renderType == OMGraphic.RENDERTYPE_LATLON) { if (projection != null) { double[] radCoords = new double[polyGrabPoints.size() * 2]; // OK, this code resets the location of every point slightly to // the inverse location of the grab points. So if you grab one // node and move it, all of the precise values of each node // actually changes. As we go through the array of grab points, // we can check the corresponding projected location of the // current node and it matches the grab point, just use the // current poly value. double[] currentCoords = poly.getLatLonArray(); Point2D testPoint = new Point2D.Double(); for (i = 0; i < polyGrabPoints.size(); i++) { gb = (GrabPoint) polyGrabPoints.get(i); boolean useGrabPointLocation = true; try { double radLat = currentCoords[i * 2]; double lat = Math.toDegrees(radLat); double radLon = currentCoords[i * 2 + 1]; double lon = Math.toDegrees(radLon); testPoint = projection.forward(lat, lon, testPoint); if (testPoint.getX() == gb.getX() && testPoint.getY() == gb.getY()) { // The projected location of the current node is the // same as the grab point, use that location. radCoords[2 * i] = radLat; radCoords[2 * i + 1] = radLon; useGrabPointLocation = false; } } catch (Exception e) { // If anything goes wrong, don't worry about it, just // use the // projected inverse of grab point } if (useGrabPointLocation) { projection.inverse(gb.getX(), gb.getY(), llp); radCoords[2 * i] = llp.getRadLat(); radCoords[2 * i + 1] = llp.getRadLon(); } } poly.setLocation(radCoords, OMGraphic.RADIANS); } else { Debug.message( "eomg", "EditableOMPoly.setGrabPoints: projection is null, can't figure out LATLON points for poly."); } } else if (renderType == OMGraphic.RENDERTYPE_OFFSET) { // Do the offset point. if (projection != null) { projection.inverse(gpo.getX(), gpo.getY(), llp); } else { Debug.message( "eomg", "EditableOMPoly.setGrabPoints: projection is null, can't figure out LATLON points for poly offset."); } } if (renderType == OMGraphic.RENDERTYPE_XY || renderType == OMGraphic.RENDERTYPE_OFFSET) { int[] ints = new int[polyGrabPoints.size() * 2]; if (renderType == OMGraphic.RENDERTYPE_OFFSET && gpo != null) { // If offset rendertype, the x-y have to be offset // distances, not screen pixel locations. For the // polygon, you also need to take into account that // the ints can represent 2 different things: distance // from the origin (Offset) or distance from the // previous point. Need to check with the poly to // find out which to do. GrabPoint previous = gpo; for (i = 0; i < polyGrabPoints.size(); i++) { gb = (GrabPoint) polyGrabPoints.get(i); if (poly.coordMode == OMPoly.COORDMODE_PREVIOUS) { ints[2 * i] = gb.getX() - previous.getX(); ints[2 * i + 1] = gb.getY() - previous.getY(); previous = gb; } else { ints[2 * i] = gb.getX() - gpo.getX(); ints[2 * i + 1] = gb.getY() - gpo.getY(); } } double newlat = llp.getRadLat(); double newlon = llp.getRadLon(); poly.setLocation(newlat, newlon, OMGraphic.RADIANS, ints); } else { for (i = 0; i < polyGrabPoints.size(); i++) { gb = (GrabPoint) polyGrabPoints.get(i); ints[2 * i] = gb.getX(); ints[2 * i + 1] = gb.getY(); } poly.setLocation(ints); } } }
/** * Set the grab points for the graphic provided, setting them on the extents of the graphic. * Called when you want to set the grab points off the points of the graphic. */ public void setGrabPoints(OMGraphic graphic) { if (!(graphic instanceof OMPoly)) { return; } assertGrabPoints(); polyGrabPoints.clear(); arrayCleared = true; gpo.clear(); OMPoly poly = (OMPoly) graphic; boolean ntr = poly.getNeedToRegenerate(); int renderType = poly.getRenderType(); Point p = new Point(); GrabPoint gb; int i; int npts; boolean geoProj = projection instanceof GeoProj; if (ntr == false) { if (renderType == OMGraphic.RENDERTYPE_LATLON) { Debug.message("eomg", "EditableOMPoly: modifying lat/lon line"); if (projection != null) { double[] ll = poly.getLatLonArray(); boolean rads = poly.getUnits() == OMGraphic.RADIANS; gb = null; // reset for this loop for (i = 0; i < ll.length; i += 2) { if (geoProj) { ((GeoProj) projection).forward(ll[i], ll[i + 1], p, rads); } else { projection.forward(ll[i], ll[i + 1], p); } // Need to add a grab point for this // coordinate gb = new OffsetGrabPoint((int) p.getX(), (int) p.getY()); polyGrabPoints.add(gb); } } } else if (renderType == OMGraphic.RENDERTYPE_OFFSET) { // Grab the projected endpoints Debug.message("eomg", "EditableOMPoly: modifying offset poly"); int x; int y; npts = poly.xs.length; // Check to see if the poly is a offset poly, and set // the // offset grab point accordingly. if (projection != null) { if (geoProj) { ((GeoProj) projection).forward(poly.lat, poly.lon, p, true); } else { projection.forward(poly.lat, poly.lon, p); } gpo.set((int) p.getX(), (int) p.getY()); if (poly.coordMode == OMPoly.COORDMODE_ORIGIN) { for (i = 0; i < npts; i++) { x = (int) (poly.xs[i] + p.getX()); y = (int) (poly.ys[i] + p.getY()); gb = new OffsetGrabPoint(x, y); polyGrabPoints.add(gb); } } else { // CMode Previous offset deltas int lastX = (int) p.getX(); int lastY = (int) p.getY(); for (i = 0; i < npts; i++) { x = poly.xs[i] + lastX; y = poly.ys[i] + lastY; gb = new OffsetGrabPoint(x, y); polyGrabPoints.add(gb); lastX += x; lastY += y; } } } } else { npts = poly.xs.length; Debug.message("eomg", "EditableOMPoly: modifying x/y poly"); for (i = 0; i < npts; i++) { gb = new OffsetGrabPoint(poly.xs[i], poly.ys[i]); polyGrabPoints.add(gb); } } // Add the || to maintain manualEnclosed if it was // externally set before the OMPoly is actually defined, // indicating that the user wants to draw a polygon. setEnclosed(syncEnclosed() || isEnclosed()); addPolyGrabPointsToOGP(gpo); } else { Debug.message("eomg", "EditableOMPoly.setGrabPoints: graphic needs to be regenerated "); } }
public void actionPerformed(ActionEvent ae) { Debug.message("saveimage", "SaveAsImageMenuItem: actionPerformed"); if (mapHandler == null) { Debug.output("SaveAsImageMenuItem: mapHandler = null, returning"); return; } MapBean mb = (MapBean) mapHandler.get("com.bbn.openmap.MapBean"); if (mb != null) { Debug.message("saveimage", "MapBean found, creating image"); try { while (true) { SaveAsImageFileChooser chooser = new SaveAsImageFileChooser(mb.getWidth(), mb.getHeight()); int returnVal = chooser.showSaveDialog(getParent()); if (returnVal == JFileChooser.APPROVE_OPTION) { String filename = chooser.getSelectedFile().getAbsolutePath(); if (formatter == null) { break; } filename = checkFileName(filename, formatter.getFormatLabel().toLowerCase()); if (filename == null) { // This is the reason for the while // loop, the name didn't really pass // muster, so we'll try again. continue; } int imageHeight = chooser.getImageHeight(); int imageWidth = chooser.getImageWidth(); byte[] imageBytes = formatter.getImageFromMapBean(mb, imageWidth, imageHeight); FileOutputStream binFile = new FileOutputStream(filename); binFile.write(imageBytes); binFile.close(); if (Debug.debugging("saveimage")) { com.bbn.openmap.proj.Projection proj = mb.getProjection(); Debug.output( "Created image at " + filename + "where projection covers " + proj.getUpperLeft() + " to " + proj.getLowerRight()); } break; } else if (returnVal == JFileChooser.CANCEL_OPTION) { break; } } } catch (IOException e) { Debug.error("SaveAsImageMenuItem: " + e); } } return; }
/** * Prepare the spline for rendering. * * @see com.bbn.openmap.omGraphics.OMGeometry#generate(Projection) * @param proj Projection * @return true if generate was successful */ public boolean generate(Projection proj) { setNeedToRegenerate(true); if (proj == null) { Debug.message("omspline", "OMSpline: null projection in generate!"); return false; } NatCubicSpline spline = isGeometryClosed() ? natCubicClosed : natCubic; // HACK : should use something else than nsegs spline.setSteps(nsegs); float[][] splinePoints; switch (renderType) { case RENDERTYPE_XY: if (xs == null) { Debug.message("omspline", "OMSpline x/y rendertype null coordinates"); setNeedToRegenerate(true); return false; } splinePoints = spline.calc(xs, ys); xpoints = new float[1][0]; xpoints[0] = splinePoints[0]; ypoints = new float[1][0]; ypoints[0] = splinePoints[1]; break; case RENDERTYPE_OFFSET: if (xs == null) { Debug.message("omspline", "OMSpline offset rendertype null coordinates"); setNeedToRegenerate(true); return false; } int npts = xs.length; float[] _x = new float[npts]; float[] _y = new float[npts]; // forward project the radian point Point origin = new Point(); if (proj instanceof GeoProj) { ((GeoProj) proj).forward(lat, lon, origin, true); // radians } else { proj.forward(Math.toDegrees(lat), Math.toDegrees(lon), origin); } if (coordMode == COORDMODE_ORIGIN) { for (int i = 0; i < npts; i++) { _x[i] = (float) (xs[i] + origin.getX()); _y[i] = (float) (ys[i] + origin.getY()); } } else { // CModePrevious offset deltas _x[0] = xs[0] + origin.x; _y[0] = ys[0] + origin.y; for (int i = 1; i < npts; i++) { _x[i] = xs[i] + _x[i - 1]; _y[i] = ys[i] + _y[i - 1]; } } splinePoints = spline.calc(_x, _y); xpoints = new float[1][0]; xpoints[0] = splinePoints[0]; ypoints = new float[1][0]; ypoints[0] = splinePoints[1]; break; case RENDERTYPE_LATLON: if (rawllpts == null) { Debug.message("omspline", "OMSpline latlon rendertype null coordinates"); setNeedToRegenerate(true); return false; } // spline creation ; precision 1e-8 rad = 0.002" double[] splinellpts = spline.calc(rawllpts, 1e-8f); // polygon/polyline project the polygon/polyline. // Vertices should already be in radians. ArrayList<float[]> vector; if (proj instanceof GeoProj) { vector = ((GeoProj) proj).forwardPoly(splinellpts, lineType, nsegs, isPolygon); } else { vector = proj.forwardPoly(rawllpts, isPolygon); } int size = vector.size(); xpoints = new float[(int) (size / 2)][0]; ypoints = new float[xpoints.length][0]; for (int i = 0, j = 0; i < size; i += 2, j++) { xpoints[j] = vector.get(i); ypoints[j] = vector.get(i + 1); } if (!doShapes && size > 1) { setNeedToRegenerate(false); initLabelingDuringGenerate(); setLabelLocation(xpoints[0], ypoints[0]); return true; } break; case RENDERTYPE_UNKNOWN: Debug.error("OMSpline.generate: invalid RenderType"); return false; } setNeedToRegenerate(false); setShape(createShape()); setLabelLocation(getShape(), proj); return true; }
/** * Add a layer to the Group, at a specific height. * * @param bg The feature to be added to the Content attribute * @param layer The feature to be added to the Content attribute * @param baselineHeight The feature to be added to the Content attribute */ protected void addContent(Group bg, OMGraphicHandlerLayer layer, double baselineHeight) { Debug.message( "3d", "LayerMapContent: putting layer " + layer.getName() + " graphics on the map."); addTo(bg, OMGraphicUtil.createShape3D(layer.getList(), baselineHeight)); }
/** * Create and initialize the state machine that interprets the * * <p>modifying gestures/commands, as well as initialize the grab points. Also allocates the grab * point array needed by the EditableOMPoly. */ public void init() { Debug.message("eomg", "EditableOMPoly.init()"); setStateMachine(new PolyStateMachine(this)); gPoints = new GrabPoint[1]; }
/** * A simple test method to determine if a file or directory, represented by a string, can be found * by the current Java environment. Uses the same tests as BinaryFile constructor for tracking * down a file. * * @param name A path to a file, a URL, or a path to a jar file entry. */ public static boolean exists(final String name) { boolean exists = false; try { File file = null; URL url = null; if (!Environment.isApplet()) { file = new File(name); } if (file != null && file.exists()) { exists = true; } else { // url = ClassLoader.getSystemResource(name); url = Thread.currentThread().getContextClassLoader().getResource(name); // OK, now we want to look around for the file, in the // classpaths, and as a resource. It may be a file in // a classpath, available for direct access. if (url != null) { exists = true; } else if (Environment.isApplet()) { if (Debug.debugging("binaryfile")) { Debug.output(" As applet, checking codebase..."); } // Look in the codebase for applets... final URL[] cba = new URL[1]; cba[0] = Environment.getApplet().getCodeBase(); final URLClassLoader ucl = URLClassLoader.newInstance(cba); if (ucl.getResource(name) != null) { exists = true; // This has been commented out because the // AppletDataNugget has been deprecated, and // is not needed. // } else { // url = AppletDataNugget.findResource(name); // if (url != null) { // exists = true; // } } } // It's not in the classpath, so try it as a URL to a // webserver. if (!exists && name.indexOf("http:") != -1) { try { final InputStream stream = new URL(name).openStream(); stream.close(); exists = true; } catch (final java.security.AccessControlException ace) { exists = false; } } } } catch (final IOException ioe) { Debug.message("binaryfile", "BinaryFile.exists() caught IOException"); exists = false; } if (Debug.debugging("binaryfile")) { Debug.output("BinaryFile.exists(" + name + ") = " + exists); } return exists; }
/** * Get the map coverage * * @param ullat * @param ullon * @param lrlat * @param lrlon * @param proj projection for display * @param chartSeries the chart series to query for, may be null for all coverages * @param coverages The Map to be modified */ protected void getCatalogCoverage( double ullat, double ullon, double lrlat, double lrlon, Projection proj, String chartSeries, Map<RpfProductInfo, RpfCoverage.RpfCoverageControl> coverages) { Debug.message("rpfcov", "RpfCoverageManager: Getting catalog coverage from RpfFrameProvider"); if (proj == null || frameProvider == null) { return; } CADRG cadrg; if (proj instanceof CADRG) { cadrg = (CADRG) proj; } else { cadrg = new CADRG( (LatLonPoint) proj.getCenter(new LatLonPoint.Float()), proj.getScale(), proj.getWidth(), proj.getHeight()); } List<RpfCoverageBox> hemisphereData = new ArrayList<RpfCoverageBox>(); if (ProjMath.isCrossingDateline(ullon, lrlon, proj.getScale())) { hemisphereData.addAll( frameProvider.getCatalogCoverage(ullat, ullon, lrlat, 180f, cadrg, chartSeries)); hemisphereData.addAll( frameProvider.getCatalogCoverage(ullat, -180f, lrlat, lrlon, cadrg, chartSeries)); } else { hemisphereData.addAll( frameProvider.getCatalogCoverage(ullat, ullon, lrlat, lrlon, cadrg, chartSeries)); } boolean checkSeries = !(chartSeries == null || chartSeries.equals(RpfViewAttributes.ANY) || chartSeries.equals(RpfViewAttributes.ALL)); for (RpfCoverageBox box : hemisphereData) { OMRect rect = new OMRect(box.nw_lat, box.nw_lon, box.se_lat, box.se_lon, currentLineType); RpfProductInfo rpi = RpfProductInfo.get(box.chartCode); if (rpi != null) { if (checkSeries && !rpi.seriesCode.equalsIgnoreCase(chartSeries)) { continue; } RpfCoverage.RpfCoverageControl control = coverages.get(rpi); if (control != null) { control.add(rect); rect.generate(proj); } } } }