surfaceimagelayer.java
来自「world wind java sdk 源码」· Java 代码 · 共 372 行
JAVA
372 行
/*Copyright (C) 2001, 2006 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.layers;import gov.nasa.worldwind.avlist.*;import gov.nasa.worldwind.exception.WWRuntimeException;import gov.nasa.worldwind.geom.*;import gov.nasa.worldwind.render.*;import gov.nasa.worldwind.util.*;import javax.imageio.ImageIO;import java.awt.image.*;import java.io.*;import java.util.*;import java.util.concurrent.ConcurrentHashMap;/** * Displays a collecion of local images on the globe. * * @author tag * @version $Id: SurfaceImageLayer.java 8767 2009-02-05 11:28:34Z tgaskins $ */public class SurfaceImageLayer extends RenderableLayer{ protected ImageTiler imageTiler = new ImageTiler(); protected ConcurrentHashMap<String, ArrayList<SurfaceImage>> imageTable = new ConcurrentHashMap<String, ArrayList<SurfaceImage>>(); /** * Add an image to the collection, reprojecting it to geographic (latitude & longitude) coordinates if necessary. * The image's location is determined from metadata files co-located with the image file. The number, names and * contents of these files are governed by the type of the specified image. Location metadata must be available. * <p/> * If projection information is available and reprojection of the image's projection type is supported, the image * will be reprojected to geographic coordinates. If projection information is not available then it's assumed that * the image is already in geographic projection. * <p/> * Only reprojection from UTM is currently provided. * * @param imagePath the path to the image file. * * @throws IllegalArgumentException if the image path is null. * @throws IOException if an error occurs reading the image file. * @throws IllegalStateException if an error occurs while reprojecting or otherwise processing the image. * @throws WWRuntimeException if the image type is unsupported. */ public void addImage(final String imagePath) throws IOException { if (imagePath == null) { String message = Logging.getMessage("nullValue.ImageSource"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } final File imageFile = new File(imagePath); if (!imageFile.exists()) { String message = Logging.getMessage("generic.FileNotFound", imagePath); Logging.logger().severe(message); throw new IllegalArgumentException(message); } AVList values = ImageUtil.openSpatialImage(imageFile); final BufferedImage image = (BufferedImage) values.getValue(AVKey.IMAGE); Sector sector = (Sector) values.getValue(AVKey.SECTOR); if (image == null || sector == null) { String key = image == null ? "ImageUtil.ImageNotAvailable" : "ImageUtil.SectorNotAvailable"; String message = Logging.getMessage(key, imagePath); Logging.logger().severe(message); throw new IllegalStateException(message); } addImage(imagePath, image, sector); } /** * Add an image to the collection at an explicitly specified location. The image is assumed to be in geographic * projection (latitude & longitude). * * @param imagePath the path to the image file. * @param sector the geographic location of the image. * * @throws IllegalArgumentException if the image path or sector is null. * @throws IOException if an error occurs reading the image file. * @throws WWRuntimeException if the image type is unsupported. */ public void addImage(String imagePath, Sector sector) throws IOException { if (imagePath == null) { String message = Logging.getMessage("nullValue.ImageSource"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } File imageFile = new File(imagePath); if (!imageFile.exists()) { String message = Logging.getMessage("generic.FileNotFound", imagePath); Logging.logger().severe(message); throw new IllegalArgumentException(message); } BufferedImage image = ImageIO.read(imageFile); if (image == null) { String message = Logging.getMessage("generic.ImageReadFailed", imageFile); Logging.logger().severe(message); throw new WWRuntimeException(message); } this.addImage(imagePath, image, sector); } /** * Add a {@link BufferedImage} to the collection at an explicitly specified location. The image is assumed to be in * geographic projection (latitude & longitude). * * @param name a unique name to associate with the image so that it can be subsequently referred to without having * to keep a reference to the image itself. Use this name in calls to {@link #removeImage}. * @param image the image to add. * @param sector the geographic location of the image. * * @throws IllegalArgumentException if the image path or sector is null. * @throws WWRuntimeException if the image type is unsupported. */ public void addImage(String name, BufferedImage image, Sector sector) { if (name == null) { String message = Logging.getMessage("nullValue.NameIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (image == null) { String message = Logging.getMessage("nullValue.ImageSource"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (this.imageTable.contains(name)) this.removeImage(name); final ArrayList<SurfaceImage> surfaceImages = new ArrayList<SurfaceImage>(); this.imageTable.put(name, surfaceImages); this.imageTiler.tileImage(image, sector, new ImageTiler.ImageTilerListener() { public void newTile(BufferedImage tileImage, Sector tileSector) { SurfaceImage si = new SurfaceImage(tileImage, tileSector); surfaceImages.add(si); si.setOpacity(SurfaceImageLayer.this.getOpacity()); SurfaceImageLayer.this.addRenderable(si); } public void newTile(BufferedImage tileImage, List<? extends LatLon> corners) { } }); } /** * Add an image to the collection at an explicitly specified location. The image is assumed to be in geographic * projection (latitude & longitude). * * @param imagePath the path to the image file. * @param corners the geographic location of the image's corners, specified in order of lower-left, lower-right, * upper-right, lower-left. * * @throws IllegalArgumentException if the image path or sector is null. * @throws IOException if an error occurs reading the image file. * @throws WWRuntimeException if the image type is unsupported. */ public void addImage(String imagePath, List<? extends LatLon> corners) throws IOException { if (imagePath == null) { String message = Logging.getMessage("nullValue.ImageSource"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } File imageFile = new File(imagePath); if (!imageFile.exists()) { String message = Logging.getMessage("generic.FileNotFound", imagePath); Logging.logger().severe(message); throw new IllegalArgumentException(message); } BufferedImage image = ImageIO.read(imageFile); if (image == null) { String message = Logging.getMessage("generic.ImageReadFailed", imageFile); Logging.logger().severe(message); throw new WWRuntimeException(message); } this.addImage(imagePath, image, corners); } /** * Add a {@link BufferedImage} to the collection at an explicitly specified location. The image is assumed to be in * geographic projection (latitude & longitude). * * @param name a unique name to associate with the image so that it can be subsequently referred to without * having to keep a reference to the image itself. Use this name in calls to {@link #removeImage}. * @param image the image to add. * @param corners the geographic location of the image's corners, specified in order of lower-left, lower-right, * upper-right, lower-left. * * @throws IllegalArgumentException if the image path is null, the corners list is null, contains null values or * fewer than four locations. * @throws WWRuntimeException if the image type is unsupported. */ public void addImage(String name, BufferedImage image, List<? extends LatLon> corners) { if (name == null) { String message = Logging.getMessage("nullValue.NameIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (image == null) { String message = Logging.getMessage("nullValue.ImageSource"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (corners == null) { String message = Logging.getMessage("nullValue.LocationsListIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (this.imageTable.contains(name)) this.removeImage(name); final ArrayList<SurfaceImage> surfaceImages = new ArrayList<SurfaceImage>(); this.imageTable.put(name, surfaceImages); this.imageTiler.tileImage(image, corners, new ImageTiler.ImageTilerListener() { public void newTile(BufferedImage tileImage, Sector tileSector) { } public void newTile(BufferedImage tileImage, List<? extends LatLon> corners) { SurfaceImage si = new SurfaceImage(tileImage, corners); surfaceImages.add(si); si.setOpacity(SurfaceImageLayer.this.getOpacity()); SurfaceImageLayer.this.addRenderable(si); } }); } public void removeImage(String imagePath) { ArrayList<SurfaceImage> images = this.imageTable.get(imagePath); if (images == null) return; this.imageTable.remove(imagePath); for (SurfaceImage si : images) { if (si != null) this.removeRenderable(si); } } @Override public void setOpacity(double opacity) { super.setOpacity(opacity); for (Map.Entry<String, ArrayList<SurfaceImage>> entry : this.imageTable.entrySet()) { for (SurfaceImage si : entry.getValue()) { if (si != null) si.setOpacity(opacity); } } } public int getNumImages() { int count = 0; for (ArrayList<SurfaceImage> images : this.imageTable.values()) { count += images.size(); } return count; } /** * Create an image for the portion of this layer lying within a specified sector. The image is created at a * specified aspect ratio within a canvas of a specified size. * * @param sector the sector of interest. * @param canvasWidth the width of the canvas. * @param canvasHeight the height of the canvas. * @param aspectRatio the aspect ratio, width/height, of the window. If the aspect ratio is greater or equal to * one, the full width of the canvas is used for the image; the height used is proportional to * the inverse of the aspect ratio. If the aspect ratio is less than one, the full height of the * canvas is used, and the width used is proportional to the aspect ratio. * @param image if non-null, a {@link BufferedImage} in which to place the image. If null, a new buffered * image of type {@link BufferedImage#TYPE_INT_RGB} is created. The image must be the width and * height specified in the <code>canvasWidth</code> and <code>canvasHeight</code> arguments. * * @return image the assembelled image, of size indicated by the <code>canvasWidth</code> and * <code>canvasHeight</code>. If the specified aspect ratio is one, all pixels contain values. If the aspect * ratio is greater than one, a full-width segment along the top of the canvas is blank. If the aspect ratio * is less than one, a full-height segment along the right side of the canvase is blank. If the * <code>image</code> argument was non-null, that buffered image is returned. * * @see ImageUtil#mergeImage */ public BufferedImage composeImageForSector(Sector sector, int canvasWidth, int canvasHeight, double aspectRatio, BufferedImage image) { if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (!this.getRenderables().iterator().hasNext()) { Logging.logger().severe(Logging.getMessage("generic.NoImagesAvailable")); return null; } if (image == null) image = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB); for (Renderable r : this.getRenderables()) { SurfaceImage si = (SurfaceImage) r; if (si.getImageSource() == null) continue; ImageUtil.mergeImage(sector, si.getSector(), aspectRatio, (BufferedImage) si.getImageSource(), image); } return image; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?