📄 imageserver.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/image/ImageServer.java,v $// $RCSfile: ImageServer.java,v $// $Revision: 1.5.2.4 $// $Date: 2005/08/09 17:59:10 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.image;import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Paint;import java.awt.RenderingHints;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.util.Hashtable;import java.util.Properties;import java.util.Vector;import com.bbn.openmap.Environment;import com.bbn.openmap.Layer;import com.bbn.openmap.MapBean;import com.bbn.openmap.PropertyConsumer;import com.bbn.openmap.plugin.PlugIn;import com.bbn.openmap.plugin.PlugInLayer;import com.bbn.openmap.proj.Mercator;import com.bbn.openmap.proj.Proj;import com.bbn.openmap.proj.Projection;import com.bbn.openmap.proj.ProjectionFactory;import com.bbn.openmap.util.ComponentFactory;import com.bbn.openmap.util.Debug;import com.bbn.openmap.util.PropUtils;/** * The image server is the class you want to deal with when creating * images from the ImageGenerator. It takes a properties file and sets * up the image generator based on those properties. It also has this * queuing thing going so that requests can stack up while the image * generator is working on requests, and it will notify the requestor * when the image is ready. * <P> * * The ImageServer generally has the layers on the map predefined at * construction, although you can change the layers that it has. When * setting the layer array, do not use the same layer in two different * slots of the array - it may not give you the expected map, and may * mess around with the timing issues that the ImageGenerator takes * care of. If you want to reorder the layers, do so before adding * your request to the ImageServer. Additionally, each request has the * option of not using certain layers in the ImageServer layer array, * by turning off the appropriate bits in the layer mask. Understand * that the image for a request will be created based on the layer * array contents and the request layer mask at the time the request * processing is started, not when it is submitted. * <P> * Right now, the ImageServer is single threaded - processing requests * one after another. The request setup was written to support * multi-threaded processing, though, where each image could be * generated in it's own thread. That code is not written - maybe * someday. * <P> * <code><pre> * * * * # If the ImageServer is created and given a prefix (in this example, * # 'imageServer') the properties file should contain the properties: * imageServer.layers=<layer1 layer2 ...> * layer1.className=<classname> * layer1.prettyName=<pretty name of layer> * # Add other attributes as required by layer1... * layer2.className=<classname> * layer2.prettyName=<pretty name of layer> * # Add other attributes as required by layer2... * # First formatter listed is default. * imageServer.formatters=<formatter1 formatter2 ...> * formatter1.class=<classname of formatter 1> * # Add other formatter1 properties * formatter2.class=<classname of formatter 2> * * * * </pre></code> * <P> * NOTE: If you simply hand the ImageServer a standard * openmap.properties file, it works with the addition of the first * two attributes except WITHOUT the 'imageServer.' prefix. * * New for 4.5: If the layers property is not defined, then the * openmap.layers property is used to define which layers are * available for the ImageServer. */public class ImageServer implements/* ImageReadyListener, ImageReceiver, */PropertyConsumer { /** The Image formatter for the output image. */ protected ImageFormatter formatter; /** * Hashtable of ImageFormatters available to be used. */ protected Hashtable imageFormatters; /** The array of layers on the map. First is on top. */ protected Layer[] layers; /** Property for space separated layers. */ public static final String ImageServerLayersProperty = "layers"; /** OpenMap prefix */ public static final String OpenMapPrefix = "openmap."; /** * Property for the image formatter list of available formats. * This propery should contain a space separated list of marker * names. */ public static final String ImageFormattersProperty = "formatters"; /** Property to turn on anti-aliasing. */ public static final String AntiAliasingProperty = "antialiasing"; /** Flag to do graphics and text anti-aliasing on the map image. */ protected boolean doAntiAliasing = false; /** * A place to hold on to a property prefix in case one is used. * Useful for ImageServer properties files where more than one * image server is defined. */ protected String propertiesPrefix = null; /** * Empty constructor that expects to be configured later. */ protected ImageServer() {} /** * To create the image server, you hand it a set of properties * that let it create an array of layers, and also to set the * properties for those layers. The properties file for the * ImageServer looks strikingly similar to the openmap.properties * file. So, all the layers get set up here... */ public ImageServer(Properties props) { setProperties(props); } /** * Same as the other constructor, except that the properties can * have a prefix in front of them. The format of the prefix has to * match how the property is specified the the properties file, * which may include the period - i.e server1.imageServer.layers, * the server1. is the prefix that should get passed in. The * ImageMaster does this. */ public ImageServer(String prefix, Properties props) { this(prefix, props, null); } /** * Create an ImageServer that should be configured with a * Properties file. The prefix given is to scope the ImageServer * properties to this instance. The Hashtable is for reusing any * layers that may already be instantiated. */ public ImageServer(String prefix, Properties props, Hashtable instantiatedLayers) { setProperties(prefix, props, instantiatedLayers); } /** * Create an ImageServer from an array of Layers and an * ImageFormatter. It's assumed that the layers are already * configured. * * @param layers the array of layers. * @param formatter the ImageFormatter to use for the output image * format. */ public ImageServer(Layer[] layers, ImageFormatter formatter) { this.layers = layers; this.formatter = formatter; } /** * Set whether anti-aliasing is used when creating the image. */ public void setDoAntiAliasing(boolean set) { doAntiAliasing = set; } /** * Find out whether anti-aliasing is used when creating the image. */ public boolean getDoAntiAliasing() { return doAntiAliasing; } /** * Set the layers used on the NEXT request that is processed. Will * not affect any image currently being created. * * @param newLayers an array of com.bbn.openmap.Layer objects, * already configured and ready to respond to a * projectionChanged method call. */ public synchronized void setLayers(Layer[] newLayers) { if (newLayers == null) { layers = new Layer[0]; } else { layers = newLayers; } } /** * Retrieve the current set of layers used for requests. * * @return Layer[] */ public synchronized Layer[] getLayers() { return layers; } /** * Use the ProjectionPainter interface of the layers to create an * image. This approach avoids some of the timing issues that the * thread model of the MapBean and Layers that seem to pop up from * time to time. They are Swing components, you know. They were * designed to be part of a GUI. So, this is a serialized, safe * way to do things. * * @param proj projection of map. * @return a byte[] representing the formatted image. */ public byte[] createImage(Projection proj) { return createImage(proj, -1, -1, 0xFFFFFFFF); } /** * Use the ProjectionPainter interface of the layers to create an * image. This approach avoids some of the timing issues that the * thread model of the MapBean and Layers that seem to pop up from * time to time. They are Swing components, you know. They were * designed to be part of a GUI. So, this is a serialized, safe * way to do things. * * @param proj projection of map. * @param scaledWidth scaled pixel width of final image. If you * don't want it scaled, use -1. * @param scaledHeight scaled pixel height of final image. If you * don't want it scaled, use -1. * @return a byte[] representing the formatted image. */ public byte[] createImage(Projection proj, int scaledWidth, int scaledHeight) { return createImage(proj, scaledWidth, scaledHeight, 0xFFFFFFFF); } /** * Use the ProjectionPainter interface of the layers to create an * image. This approach avoids some of the timing issues that the * thread model of the MapBean and Layers that seem to pop up from * time to time. They are Swing components, you know. They were * designed to be part of a GUI. So, this is a serialized, safe * way to do things. * * @param proj projection of map. * @param scaledWidth scaled pixel width of final image. If you * don't want it scaled, use -1. * @param scaledHeight scaled pixel height of final image. If you * don't want it scaled, use -1. * @param showLayers Layer marker names reflecting the layers that * should be part of this image. * @return a byte[] representing the formatted image. */ public byte[] createImage(Projection proj, int scaledWidth, int scaledHeight, Vector showLayers) { Debug.message("imageserver", "ImageServer: using the new ProjectionPainter interface! createImage with layer string array. "); if (formatter == null) { Debug.error("ImageServer.createImage: no formatter set! Can't create image."); return new byte[0]; } ImageFormatter imageFormatter = formatter.makeClone(); java.awt.Graphics graphics = createGraphics(imageFormatter, proj.getWidth(), proj.getHeight()); if (graphics == null) { return new byte[0]; } ((Proj) proj).drawBackground((Graphics2D) graphics, background); int size = showLayers.size(); if (showLayers != null) { for (int j = size - 1; j >= 0; j--) { for (int i = layers.length - 1; i >= 0; i--) { String layerName = (String) showLayers.elementAt(j); Layer layer = layers[i]; if (layerName.equals(layer.getPropertyPrefix())) { layer.renderDataForProjection(proj, graphics); if (Debug.debugging("imageserver")) { Debug.output("ImageServer: image request adding layer graphics from : " + layer.getName()); } } } } } else if (Debug.debugging("imageserver")) { Debug.output("ImageServer: no layers available for image"); } byte[] formattedImage = getFormattedImage(imageFormatter, scaledWidth, scaledHeight); graphics.dispose(); return formattedImage; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -