public boolean determineLocation(MouseEvent e) { Projection projection = getProjection(); if (cache != null && projection != null) { LatLonPoint ll = projection.inverse(e.getX(), e.getY(), new LatLonPoint.Double()); location = new DTEDLocation(e.getX(), e.getY()); location.setElevation(cache.getElevation((float) ll.getY(), (float) ll.getX())); location.generate(projection); repaint(); return true; } return 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)); } }
/** * Function to add a specific message to the map * * @param message */ public void setMarker(MsiMessageExtended message) { this.message = message; this.msiLocation = message.msiMessage.getLocation().getCenter(); LatLonPoint center = (LatLonPoint) mapBean.getCenter(); GeoLocation geoCenter = new GeoLocation(center.getLatitude(), center.getLongitude()); double bearing = Calculator.bearing(geoCenter, msiLocation, Heading.RL); Projection projection = mapBean.getProjection(); Point2D projectedMSI = projection.forward(msiLocation.getLatitude(), msiLocation.getLongitude()); Point2D origin = new Point2D.Double(mapBean.getWidth() * 0.5f, mapBean.getHeight() * 0.5f); Line2D direction = new Line2D.Double(origin, projectedMSI); double boxWidth = mapBean.getWidth() - IMAGE_SIZE / 2; double boxHeight = mapBean.getHeight() - IMAGE_SIZE / 2; Line2D topFrame = new Line2D.Double(IMAGE_SIZE / 2, IMAGE_SIZE / 2, boxWidth, IMAGE_SIZE / 2); Line2D rightFrame = new Line2D.Double(boxWidth, IMAGE_SIZE / 2, boxWidth, boxHeight); Line2D bottomFrame = new Line2D.Double(IMAGE_SIZE / 2, boxHeight, boxWidth, boxHeight); Line2D leftFrame = new Line2D.Double(IMAGE_SIZE / 2, IMAGE_SIZE / 2, IMAGE_SIZE / 2, boxHeight); boolean intersects = false; if (intersects(direction, topFrame)) intersects = true; if (intersects(direction, rightFrame)) intersects = true; if (intersects(direction, bottomFrame)) intersects = true; if (intersects(direction, leftFrame)) intersects = true; if (!intersects) return; int x = Math.round((float) intersection.getX()); int y = Math.round((float) intersection.getY()); directionRaster = new CenterRaster(x, y, directionImage); directionRaster.setRotationAngle(Math.toRadians(bearing)); markerRaster = new CenterRaster(x, y, markerImage); add(markerRaster); add(directionRaster); }
/** * Called from the OMGrid.generate() method to tell the generator to create something to represent * the grid contents. */ public OMGraphic generate(OMGrid grid, Projection proj) { // Make a decision based on the last projection to see if we // should generate a new raster from the data with better // detail. // We used to keep the same OMScalingRaster here if the scale // number was larger, but I think that might be too much // memory usage, more so if the scales are pretty close and // you have two images pretty much the same size for each dted // frame. So we reuse if the scales match. if (raster != null && proj instanceof EqualArc && proj.getScale() == generatedScale && !isIncompleteImage()) { raster.generate(proj); return raster; } else { generatedScale = proj.getScale(); return super.generate(grid, proj); } }
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; }
public OMGraphicList prepare() { if (layer != null) { // setBuffer(null); Projection proj = layer.getProjection(); if (layer.isProjectionOK(proj)) { // set the offsets depending on how much the image moves Point2D ul = proj.getUpperLeft(); if (oldUL != null && !oldUL.equals(ul) && oldScale == proj.getScale() && proj.getClass().equals(oldProjType)) { Point2D currentPoint = proj.forward(ul); Point2D oldPoint = proj.forward(oldUL); offset.setLocation( oldPoint.getX() - currentPoint.getX(), oldPoint.getY() - currentPoint.getY()); layer.repaint(); } oldUL = ul; oldProjType = ((Proj) proj).getClass(); oldScale = proj.getScale(); OMGraphicList list = layer.prepare(); setBuffer(createAndPaintImageBuffer(list)); return list; } else { logger.warning("NULL projection, can't do anything."); } } else { logger.warning("NULL layer, can't do anything."); } return null; }
/** Create the query to be sent to the server, based on current settings. */ public String createQueryString(Projection p) { if (queryHeader == null) { return null; } String bbox = "undefined"; String height = "undefined"; String width = "undefined"; String sCoordParamName = WMTConstants.SRS; if (p != null) { Point2D ul = p.getUpperLeft(); Point2D lr = p.getLowerRight(); if (wmsVersion.compareTo("1.3.0") == 0) { bbox = Double.toString(lr.getY()) + "," + Double.toString(ul.getX()) + "," + Double.toString(ul.getY()) + "," + Double.toString(lr.getX()); sCoordParamName = WMTConstants.CRS; errorHandling = "INIMAGE"; } else { bbox = Double.toString(ul.getX()) + "," + Double.toString(lr.getY()) + "," + Double.toString(lr.getX()) + "," + Double.toString(ul.getY()); } height = Integer.toString(p.getHeight()); width = Integer.toString(p.getWidth()); } StringBuffer buf = new StringBuffer(queryHeader); buf.append("?") .append(WMTConstants.VERSION) .append("=") .append(wmsVersion) .append("&") .append(WMTConstants.REQUEST) .append("=") .append(mapRequestName) .append("&") .append(sCoordParamName) .append("=") .append("EPSG:4326") .append("&") .append(WMTConstants.BBOX) .append("=") .append(bbox) .append("&") .append(WMTConstants.HEIGHT) .append("=") .append(height) .append("&") .append(WMTConstants.WIDTH) .append("=") .append(width) .append("&") .append(WMTConstants.EXCEPTIONS) .append("=") .append(errorHandling); if (imageFormat != null) { buf.append("&").append(WMTConstants.FORMAT).append("=").append(imageFormat); String baseImageFormat = imageFormat; if (baseImageFormat.indexOf('/') > 0) baseImageFormat = baseImageFormat.substring(baseImageFormat.indexOf('/')); if (baseImageFormat.equals(WMTConstants.IMAGEFORMAT_JPEG)) { buf.append("&quality=").append(imageQuality); } } if (transparent != null) { buf.append("&").append(WMTConstants.TRANSPARENT).append("=").append(transparent); } if (backgroundColor != null) { buf.append("&").append(WMTConstants.BGCOLOR).append("=").append(backgroundColor); } if (layers != null) { buf.append("&").append(WMTConstants.LAYERS).append("=").append(layers); } String cStyles = styles; if (cStyles == null) { cStyles = ""; } // if (styles != null) { buf.append("&").append(WMTConstants.STYLES).append("=").append(cStyles); // } if (Debug.debugging("wms")) { Debug.output("query string: " + buf); } /* * Included to allow for one or more vendor specific parameters to be * specified such as ESRI's ArcIMS's "ServiceName" parameter. */ if (vendorSpecificNames != null) { if (vendorSpecificValues != null) { StringTokenizer nameTokenizer = new StringTokenizer(vendorSpecificNames, ","); StringTokenizer valueTokenizer = new StringTokenizer(vendorSpecificValues, ","); String paramName = null; String paramValue = null; while (nameTokenizer.hasMoreTokens()) { try { paramName = nameTokenizer.nextToken(); paramValue = valueTokenizer.nextToken(); buf.append("&").append(paramName).append("=").append(paramValue); } catch (NoSuchElementException e) { if (Debug.debugging("wms")) { Debug.output( "WMSPlugIn.getRectangle(): " + "parameter \"" + paramName + "\" has no value"); } } } } } return buf.toString(); }
/** * 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; }
/** * Get the graphics for a particular lat/lon area. * * @param ulLat upper left latitude, in decimal degrees. * @param ulLon upper left longitude, in decimal degrees. * @param lrLat lower right latitude, in decimal degrees. * @param lrLon lower right longitude, in decimal degrees. * @param proj the current map projection. * @return OMGraphicList */ public OMGraphicList getGraphics( double ulLat, double ulLon, double lrLat, double lrLon, Projection proj) { if (cacheURL != null) { return omgraphics; } if (spatialIndex == null) { return new OMGraphicList(); } if (politicalAreas == null) { initialize(originalPrefix, originalProperties); } OMGraphicList list = new OMGraphicList(); // check for dateline anomaly on the screen. we check for // ulLon >= lrLon, but we need to be careful of the check for // equality because of floating point arguments... if (ProjMath.isCrossingDateline(ulLon, lrLon, proj.getScale())) { if (Debug.debugging("areas")) { Debug.output("AreaHander.getGraphics(): Dateline is on screen"); } double ymin = Math.min(ulLat, lrLat); double ymax = Math.max(ulLat, lrLat); try { list = spatialIndex.getOMGraphics( ulLon, ymin, 180.0d, ymax, list, drawingAttributes, proj, coordTransform); list = spatialIndex.getOMGraphics( -180.0d, ymin, lrLon, ymax, list, drawingAttributes, proj, coordTransform); } catch (InterruptedIOException iioe) { // This means that the thread has been interrupted, // probably due to a projection change. Not a big // deal, just return, don't do any more work, and let // the next thread solve all problems. list = null; } catch (IOException ex) { ex.printStackTrace(); } catch (FormatException fe) { fe.printStackTrace(); } } else { double xmin = (double) Math.min(ulLon, lrLon); double xmax = (double) Math.max(ulLon, lrLon); double ymin = (double) Math.min(ulLat, lrLat); double ymax = (double) Math.max(ulLat, lrLat); try { list = spatialIndex.getOMGraphics( xmin, ymin, xmax, ymax, list, drawingAttributes, proj, coordTransform); } catch (InterruptedIOException iioe) { // This means that the thread has been interrupted, // probably due to a projection change. Not a big // deal, just return, don't do any more work, and let // the next thread solve all problems. list = null; } catch (java.io.IOException ex) { ex.printStackTrace(); } catch (FormatException fe) { fe.printStackTrace(); } } updateDrawingParameters(list); return list; }
/** * 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; }
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; }
/** * Since the image doesn't necessarily need to be regenerated when it is merely moved, raster * objects have this function, called from generate() and when a placement attribute is changed. * * @return true if enough information is in the object for proper placement. * @param proj projection of window. */ protected boolean position(Projection proj) { if (proj == null) { logger.fine("OMRasterObject: null projection in position!"); return false; } projWidth = proj.getWidth(); projHeight = proj.getHeight(); switch (renderType) { case RENDERTYPE_LATLON: if (!proj.isPlotable(lat, lon)) { if (DEBUG) { logger.fine("OMRasterObject: point is not plotable!"); } setNeedToReposition(true); // so we don't render it! return false; } point1 = (Point) proj.forward(lat, lon, new Point()); break; case RENDERTYPE_XY: point1 = new Point(x, y); break; case RENDERTYPE_OFFSET: if (!proj.isPlotable(lat, lon)) { if (DEBUG) { logger.fine("OMRasterObject: point is not plotable!"); } setNeedToReposition(true); // so we don't render it! return false; } point1 = (Point) proj.forward(lat, lon, new Point()); point1.x += x; point1.y += y; break; case RENDERTYPE_UNKNOWN: if (DEBUG) { logger.fine("OMRasterObject.position(): ignoring unknown rendertype, wingin' it"); } if (lat == 0 && lon == 0) { if (x == 0 && y == 0) { if (DEBUG) { logger.fine( "OMRasterObject.position(): Not enough info in object to place it reasonably."); } point1 = new Point(-width, -height); point2 = new Point(0, 0); return false; } else { point1 = new Point(x, y); } } else { if (!proj.isPlotable(lat, lon)) { logger.fine("OMRasterObject: point is not plotable!"); return false; } point1 = (Point) proj.forward(lat, lon, new Point()); } break; } point2 = new Point(0, 0); point2.x = point1.x + width; point2.y = point1.y + height; setNeedToReposition(false); return true; }
/** * 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); } } } }