/** * OrbisGIS is a java GIS application dedicated to research in GIScience. * OrbisGIS is developed by the GIS group of the DECIDE team of the * Lab-STICC CNRS laboratory, see <http://www.lab-sticc.fr/>. * * The GIS group of the DECIDE team is located at : * * Laboratoire Lab-STICC – CNRS UMR 6285 * Equipe DECIDE * UNIVERSITÉ DE BRETAGNE-SUD * Institut Universitaire de Technologie de Vannes * 8, Rue Montaigne - BP 561 56017 Vannes Cedex * * OrbisGIS is distributed under GPL 3 license. * * Copyright (C) 2007-2014 CNRS (IRSTV FR CNRS 2488) * Copyright (C) 2015-2017 CNRS (Lab-STICC UMR CNRS 6285) * * This file is part of OrbisGIS. * * OrbisGIS is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * OrbisGIS is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * OrbisGIS. If not, see <http://www.gnu.org/licenses/>. * * For more information, please consult: <http://www.orbisgis.org/> * or contact directly: * info_at_ orbisgis.org */ package com.vividsolutions.wms; import biz.source_code.base64Coder.Base64Coder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static java.net.URLEncoder.encode; import java.awt.Image; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import javax.imageio.ImageIO; /** * Represents all of the parameters of a getMap request from a WMS server. * @author Chris Hodgson chodgson@refractions.net */ public class MapRequest { private static Logger LOG = LoggerFactory.getLogger(MapRequest.class); private WMService service; private int imgWidth; private int imgHeight; private List<String> layerNames; private BoundingBox bbox; private boolean transparent; private String format; private String version = WMService.WMS_1_1_1; /** * Creates a new MapRequest. * @param service the WMService which this MapRequest will use */ public MapRequest(WMService service) { this.service = service; imgWidth = 100; imgHeight = 100; layerNames = new ArrayList<String>(); bbox = service.getCapabilities().getTopLayer().getBoundingBox(); transparent = false; format = null; } /** * Gets the WMService that this object will make requests from. * @return the WMService that this object will make requests from */ public WMService getService() { return service; } /** * Returns the format of this request. * This may be a string such as GIF, JPEG, or PNG for a WMS 1.0 server, or * a mime-type string in the case of a WMS 1.1 server. It may also be null if * the format has not yet been set. * @return the string representing the format of this request */ public String getFormat() { return format; } /** * Gets the width of the requested image, in pixels. * The default image width is 100. * @return the width of the requested image */ public int getImageWidth() { return imgWidth; } /** * Gets the height of the requested image, in pixels. * The default image height is 100. * @return the height of the requested image */ public int getImageHeight() { return imgHeight; } /** * Returns the list of layers to be requested. Each item in the * list should be a String which is the name of a layer. * @return the list of layer names to be requested */ public List getLayerNames() { return Collections.unmodifiableList(layerNames); } /** * Gets the BoundingBox of the image being requested. * @return the BoundingBox of the image being requested */ public BoundingBox getBoundingBox() { return bbox; } /** * Gets whether or not a transparent image is being requested. * @return true if a transparent image is being requested, false otherwise */ public boolean getTransparent() { return transparent; } /** * Sets the format of this request. The format must be a string which is in * the list of supported formats as provided by getSupportedFormatList() * (not necessarily the same String object, but the same sequence of characters). * This will be an unformatted string for a WMS 1.0 server (GIF, JPEG, PNG) or * a mime-type string for a WMS 1.1 server (image/gif, image/jpeg, image/png). * If the format specified is not in the list, an IllegalArgumentException * will be thrown. * * @param format a format string which is in the list of supported formats * @throws IllegalArgumentException if the specified format isn't in the list of supported formats * @see MapImageFormatChooser * */ public void setFormat( String format ) throws IllegalArgumentException { // <<TODO:UNCOMMENT>> Temporarily commented out, until mapserver is fixed [Chris Hodgson] // Temporarily removing the requirement that the requested format // be in the list of supported formats, in order to work around a Mapserver bug. // String[] formats = service.getCapabilities().getMapFormats(); // for( int i = 0; i < formats.length; i++ ) { // if( formats[i].equals( format ) ) { this.format = format; return; // } //throw new IllegalArgumentException(); } /** * Sets the width of the image being requested. * @param imageWidth the width of the image being requested */ public void setImageWidth( int imageWidth ) { this.imgWidth = imageWidth; } /** * Sets the height of the image being requested. * @param imageHeight the height of the image being requested */ public void setImageHeight( int imageHeight ) { this.imgHeight = imageHeight; } /** * Sets the width and height of the image being requested. * @param imageWidth the width of the image being requested * @param imageHeight the height of the image being requested */ public void setImageSize( int imageWidth, int imageHeight ) { this.imgWidth = imageWidth; this.imgHeight = imageHeight; } /** * Sets the layers to be requested. Each item in the list should be a string * which corresponds to the name of a layer. The order of the list is * important as the layers are rendered in the same order they are listed. * @param layerNames an ordered List of the names of layers to be displayed */ public void setLayerNames( List<String> layerNames ) { this.layerNames = layerNames; } /** * Sets the BoundingBox of the image being requested. * @param bbox the BoundingBox of the image being requested */ public void setBoundingBox( BoundingBox bbox ) { this.bbox = bbox; } /** * Sets whether or not to request an image with a transparent background. * Requesting a transparent background doesn't guarantee that the resulting * image will actually have a transparent background. Not all servers * support transparency, and not all formats support transparency. * @param transparent true to request a transparent background, false otherwise. */ public void setTransparent( boolean transparent ) { this.transparent = transparent; } /** * Returns a String containing the string representations of each item in the * list (as provided by toString()), separated by commas. * @param list the list to be returned as a coma-separated String * @return a comma-separted String of the items in the list */ //[UT] 02.05.2005 made static and public public static String listToString( List<String> list ) { Iterator<String> it = list.iterator(); StringBuilder buf = new StringBuilder(); while( it.hasNext() ) { String layer = it.next(); buf.append( layer ); if( it.hasNext() ) { buf.append( "," ); } } return buf.toString(); } /** * @return the URL for this request * @throws MalformedURLException if there is a problem building the URL for some reason */ //[UT] changed to accept WMS 1.1.1 //[MM] changed to accept WMS 1.3.0 public URL getURL() throws MalformedURLException { StringBuilder urlBuf = new StringBuilder(); String ver = "REQUEST=map&WMTVER=1.0"; if ( WMService.WMS_1_1_0.equals( version )){ ver = "REQUEST=GetMap&SERVICE=WMS&VERSION=1.1.0"; } else if ( WMService.WMS_1_1_1.equals( version ) ){ ver = "REQUEST=GetMap&SERVICE=WMS&VERSION=1.1.1"; } else if ( WMService.WMS_1_3_0.equals( version ) ){ ver = "REQUEST=GetMap&SERVICE=WMS&VERSION=1.3.0"; } urlBuf.append(service.getCapabilities().getGetMapURL()).append(ver).append("&WIDTH="); urlBuf.append(imgWidth).append("&HEIGHT=").append(imgHeight ); try { urlBuf.append("&LAYERS=").append(encode(listToString(layerNames), "UTF-8")); } catch (UnsupportedEncodingException e1) { LOG.debug("UTF8 not supported by Java version", e1); } if( transparent ) { urlBuf.append( "&TRANSPARENT=TRUE" ); } if( format != null ) { try { urlBuf.append("&FORMAT=").append(encode(format, "UTF-8") ); } catch (UnsupportedEncodingException e) { LOG.debug("UTF8 not supported by Java version", e); } } if( bbox != null ) { urlBuf.append("&").append(bbox.getBBox(version)); if( bbox.getSRS() != null && !bbox.getSRS().equals( "LatLon" ) ) { if (version.compareTo(WMService.WMS_1_3_0) < 0) { urlBuf.append("&SRS=").append(bbox.getSRS()); } else { urlBuf.append("&CRS=").append(bbox.getSRS()); } } } // [UT] some style info is *required*, so add this to be spec conform urlBuf.append( "&STYLES=" ); LOG.info(urlBuf.toString()); return new URL( urlBuf.toString() ); } /** * Connect to the service and get an Image of the map. * @return the retrieved map Image */ public Image getImage() throws IOException { return getImage(0); } /** * Connect to the service and get an Image of the map. * @param timeOutMs connect timeout value in milliseconds * @return the retrieved map Image */ public Image getImage(int timeOutMs) throws IOException { URL requestUrl = getURL(); URLConnection con = requestUrl.openConnection(); if(requestUrl.getUserInfo() != null) { con.setRequestProperty("Authorization", "Basic " + Arrays.toString(Base64Coder.encode(requestUrl.getUserInfo().getBytes()))); } con.setReadTimeout(timeOutMs); return ImageIO.read(con.getInputStream()); } //UT public void setVersion( String ver ){ this.version = ver; } }