⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getmapresponse.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
 * This code is licensed under the GPL 2.0 license, availible at the root
 * application directory.
 */
package org.vfny.geoserver.wms.responses;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geoserver.platform.GeoServerExtensions;
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
import org.geotools.data.DefaultQuery;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.factory.FactoryConfigurationError;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.map.DefaultMapLayer;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.resources.coverage.FeatureUtilities;
import org.geotools.styling.Style;
import org.opengis.filter.Filter;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterNotFoundException;
import org.opengis.parameter.ParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import org.springframework.context.ApplicationContext;
import org.vfny.geoserver.Request;
import org.vfny.geoserver.Response;
import org.vfny.geoserver.ServiceException;
import org.vfny.geoserver.global.GeoServer;
import org.vfny.geoserver.global.MapLayerInfo;
import org.vfny.geoserver.global.Service;
import org.vfny.geoserver.global.WMS;
import org.vfny.geoserver.util.CoverageUtils;
import org.vfny.geoserver.wms.GetLegendGraphicProducerSpi;
import org.vfny.geoserver.wms.GetMapProducer;
import org.vfny.geoserver.wms.GetMapProducerFactorySpi;
import org.vfny.geoserver.wms.RasterMapProducer;
import org.vfny.geoserver.wms.WMSMapContext;
import org.vfny.geoserver.wms.WmsException;
import org.vfny.geoserver.wms.requests.GetMapRequest;
import org.vfny.geoserver.wms.responses.map.metatile.MetatileMapProducer;

import com.vividsolutions.jts.geom.Envelope;

/**
 * A GetMapResponse object is responsible of generating a map based on a GetMap
 * request. The way the map is generated is independent of this class, wich will
 * use a delegate object based on the output format requested
 * 
 * @author Gabriel Roldan, Axios Engineering
 * @author Simone Giannecchini - GeoSolutions SAS
 * @version $Id: GetMapResponse.java 7746 2007-11-13 15:38:35Z aaime $
 */
public class GetMapResponse implements Response {
	/** DOCUMENT ME! */
	private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(GetMapResponse.class
			.getPackage().getName());

	/**
	 * The map producer that will be used for the production of a map in the
	 * requested format.
	 */
	private GetMapProducer delegate;

	/**
	 * The map context
	 */
	private WMSMapContext map;

	/**
	 * WMS module
	 */
	private WMS wms;

	/**
	 * custom response headers
	 */
	private HashMap responseHeaders;

	String headerContentDisposition;

	private ApplicationContext applicationContext;

	/**
	 * Creates a new GetMapResponse object.
	 * 
	 * @param applicationContext
	 */
	public GetMapResponse(WMS wms, ApplicationContext applicationContext) {
		this.wms = wms;
		this.applicationContext = applicationContext;
		responseHeaders = new HashMap(10);
	}

	/**
	 * Returns any extra headers that this service might want to set in the HTTP
	 * response object.
	 */
	public HashMap getResponseHeaders() {
		return responseHeaders;
	}

	/**
	 * DOCUMENT ME!
	 * 
	 * @param req
	 *            DOCUMENT ME!
	 * 
	 * @throws ServiceException
	 *             DOCUMENT ME!
	 * @throws WmsException
	 *             DOCUMENT ME!
	 */
	public void execute(Request req) throws ServiceException {
		GetMapRequest request = (GetMapRequest) req;

		final String outputFormat = request.getFormat();

		this.delegate = getDelegate(outputFormat, wms);
		// JD:make instance variable in order to release resources later
		// final WMSMapContext map = new WMSMapContext();
		map = new WMSMapContext(request);
		this.delegate.setMapContext(map);

		// enable on the fly meta tiling if request looks like a tiled one
		if (MetatileMapProducer.isRequestTiled(request, delegate)) {
			if (LOGGER.isLoggable(Level.FINER)) {
				LOGGER
						.finer("Tiled request detected, activating on the fly meta tiler");
			}

			this.delegate = new MetatileMapProducer(request,
					(RasterMapProducer) delegate);
			this.delegate.setMapContext(map);
		}

		final MapLayerInfo[] layers = request.getLayers();
		final Style[] styles = (Style[]) request.getStyles().toArray(
				new Style[] {});
		final Filter[] filters = ((request.getFilter() != null) ? (Filter[]) request
				.getFilter().toArray(new Filter[] {})
				: null);



		// DJB: the WMS spec says that the request must not be 0 area
		// if it is, throw a service exception!
		final Envelope env = request.getBbox();
		if (env == null) {
		    throw new WmsException("GetMap requests must include a BBOX parameter.");
		}
		if (env.isNull() || (env.getWidth() <= 0) || (env.getHeight() <= 0)) {
			throw new WmsException(new StringBuffer(
					"The request bounding box has zero area: ").append(env)
					.toString());
		}

		// DJB DONE: replace by setAreaOfInterest(Envelope,
		// CoordinateReferenceSystem)
		// with the user supplied SRS parameter

		// if there's a crs in the request, use that. If not, assume its 4326
		final CoordinateReferenceSystem mapcrs = request.getCrs();

		// DJB: added this to be nicer about the "NONE" srs.
		if (mapcrs != null) {
			map.setAreaOfInterest(env, mapcrs);
		} else {
			map.setAreaOfInterest(env, DefaultGeographicCRS.WGS84);
		}

		map.setMapWidth(request.getWidth());
		map.setMapHeight(request.getHeight());
		map.setBgColor(request.getBgColor());
		map.setTransparent(request.isTransparent());
		map.setBuffer(request.getBuffer());
		map.setPaletteInverter(request.getPalette());

		// //
		//
		// Check to see if we really have something to display. Sometimes width
		// or height or both are non positivie or the requested area is null.
		//
		// ///
		if ((request.getWidth() <= 0) || (request.getHeight() <= 0)
				|| (map.getAreaOfInterest().getLength(0) <= 0)
				|| (map.getAreaOfInterest().getLength(1) <= 0)) {
			if (LOGGER.isLoggable(Level.FINE)) {
				LOGGER
						.fine("We are not going to render anything because either the are is null ar the dimensions are not positive.");
			}

			return;
		}

		if (LOGGER.isLoggable(Level.FINE)) {
			LOGGER.fine("setting up map");
		}

		try { // mapcontext can leak memory -- we make sure we done (see
			// finally block)


			// track the external caching strategy for any map layers
			boolean cachingPossible = request.getHttpServletRequest()
					.getMethod().equals("GET");
			String featureVersion = request.getFeatureVersion();
			int maxAge = Integer.MAX_VALUE;

			final int length = layers.length;

			for (int i = 0; i < length; i++) {
				final Style style = styles[i];
				Filter optionalFilter;
				try {
					optionalFilter = filters[i];
				} catch (Exception e) {
					optionalFilter = null;
				}

				final DefaultMapLayer layer;
				if(layers[i].getType() == MapLayerInfo.TYPE_REMOTE_VECTOR) {
				    cachingPossible = false;
				    
				    final FeatureSource source = layers[i].getRemoteFeatureSource();
                    layer = new DefaultMapLayer(source, style);
                    layer.setTitle(layers[i].getName());
                    
                    final DefaultQuery definitionQuery;
                    if (optionalFilter != null) {
                        definitionQuery = new DefaultQuery(source.getSchema()
                                .getTypeName(), optionalFilter);
                        definitionQuery.setVersion(featureVersion);

                        layer.setQuery(definitionQuery);
                    } else if (featureVersion != null) {
                        definitionQuery = new DefaultQuery(source.getSchema()
                                .getTypeName());
                        definitionQuery.setVersion(featureVersion);

                        layer.setQuery(definitionQuery);
                    }

                    map.addLayer(layer);
				} else if (layers[i].getType() == MapLayerInfo.TYPE_VECTOR) {
					if (cachingPossible) {
						if (layers[i].getFeature().isCachingEnabled()) {
							int nma = Integer.parseInt(layers[i].getFeature()
									.getCacheMaxAge());

							// suppose the map contains multiple cachable
							// layers...we can only cache the combined map for
							// the
							// time specified by the shortest-cached layer.
							if (nma < maxAge) {
								maxAge = nma;
							}
						} else {
							// if one layer isn't cachable, then we can't cache
							// any of them. Disable caching.
							cachingPossible = false;
						}
					}

					final FeatureSource source;
					// /////////////////////////////////////////////////////////
					//
					// Adding a feature layer
					//
					// /////////////////////////////////////////////////////////
					try {
						source = layers[i].getFeature().getFeatureSource(true);

						// NOTE for the feature. Here there was some code that
						// sounded like:
						// * get the bounding box from feature source
						// * eventually reproject it to the actual CRS used for
						// map
						// * if no intersection, don't bother adding the feature
						// source to the map
						// This is not an optimization, on the contrary,
						// computing the bbox may be
						// very expensive depending on the data size. Using
						// sigma.openplans.org data
						// and a tiled client like OpenLayers, it dragged the
						// server to his knees
						// and the client simply timed out
					} catch (IOException exp) {
						if (LOGGER.isLoggable(Level.SEVERE)) {
							LOGGER.log(Level.SEVERE, new StringBuffer(
									"Getting feature source: ").append(
									exp.getMessage()).toString(), exp);
						}

						throw new WmsException(null, new StringBuffer(
								"Internal error : ").append(exp.getMessage())
								.toString());
					}

					layer = new DefaultMapLayer(source, style);
					layer.setTitle(layers[i].getName());

					final Filter definitionFilter = layers[i].getFeature()
							.getDefinitionQuery();
					final DefaultQuery definitionQuery;
					if (definitionFilter != null) {
						definitionQuery = new DefaultQuery(source.getSchema()
								.getTypeName(), definitionFilter);
						definitionQuery.setVersion(featureVersion);

						layer.setQuery(definitionQuery);
					} else if (optionalFilter != null) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -