Revision 4160

View differences:

org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19/pom.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
	<modelVersion>4.0.0</modelVersion>
4
	<artifactId>org.gvsig.raster.wms</artifactId>
5
	<packaging>pom</packaging>
6
	<version>2.2.19</version>
7
	<name>${project.artifactId}</name>
8
	<description>wms client</description>
9
	<inceptionYear>2011</inceptionYear>
10
	
11
	<parent>
12
      <groupId>org.gvsig</groupId>
13
      <artifactId>org.gvsig.desktop</artifactId>
14
      <version>2.0.111</version>
15
  </parent>
16

  
17
        <properties>
18
            <!-- El plugin versions:use-latest-versions falla con scope import -->
19
            <!-- asi que toca usar el versions:update-properties que si que funciona -->
20
            <org.gvsig.raster.version>2.2.21</org.gvsig.raster.version>
21
        </properties>
22
    
23
    <repositories>
24
      <repository>
25
        <id>gvsig-public-http-repository</id>
26
        <name>gvSIG maven public HTTP repository</name>
27
        <url>http://devel.gvsig.org/m2repo/j2se</url>
28
        <releases>
29
          <enabled>true</enabled>
30
          <updatePolicy>daily</updatePolicy>
31
          <checksumPolicy>warn</checksumPolicy>
32
        </releases>
33
        <snapshots>
34
          <enabled>true</enabled>
35
          <updatePolicy>daily</updatePolicy>
36
          <checksumPolicy>warn</checksumPolicy>
37
        </snapshots>
38
      </repository>
39
    </repositories>
40
    
41
    <scm>
42
        <connection>scm:svn:https://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19</connection>
43
        <developerConnection>scm:svn:https://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19</developerConnection>
44
        <url>https://devel.gvsig.org/redmine/projects/gvsig-raster/repository/show/org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19</url>
45
    </scm>
46
    
47
    <build>
48
        <plugins>
49
            <plugin>
50
                <groupId>org.apache.maven.plugins</groupId>
51
                <artifactId>maven-release-plugin</artifactId>
52
                <configuration>
53
                    <tagBase>https://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wms/tags/</tagBase>
54
                    <goals>deploy</goals>
55
                </configuration>
56
            </plugin>
57
        </plugins>
58
    </build>
59
    
60
    <dependencyManagement>
61
		<dependencies>
62
                        <dependency>
63
                                <groupId>org.gvsig</groupId>
64
                                <artifactId>org.gvsig.raster</artifactId>
65
                                <version>${org.gvsig.raster.version}</version>
66
                                <type>pom</type>
67
                                <scope>import</scope>
68
                        </dependency>
69

  
70
			<dependency>
71
				<groupId>org.gvsig</groupId>
72
				<artifactId>org.gvsig.raster.wms.io</artifactId>
73
				<version>2.2.19</version>
74
			</dependency>
75
			<dependency>
76
				<groupId>org.gvsig</groupId>
77
				<artifactId>org.gvsig.raster.wms.remoteclient</artifactId>
78
				<version>2.2.19</version>
79
			</dependency>
80
			<dependency>
81
				<groupId>org.gvsig</groupId>
82
				<artifactId>org.gvsig.raster.wms.app.wmsclient</artifactId>
83
				<version>2.2.19</version>
84
			</dependency>
85

  
86
		</dependencies>
87
	</dependencyManagement>
88

  
89
	<modules>
90
		<module>org.gvsig.raster.wms.remoteclient</module>
91
		<module>org.gvsig.raster.wms.io</module>
92
		<module>org.gvsig.raster.wms.app.wmsclient</module>
93
	</modules>
94
</project>
95

  
0 96

  
org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19/org.gvsig.raster.wms.app.wmsclient/src/main/assembly/gvsig-plugin-package.xml
1
<assembly>
2
    <id>gvsig-plugin-package</id>
3
    <formats>
4
        <format>zip</format>
5
    </formats>
6
    <baseDirectory>${project.artifactId}</baseDirectory>
7
    <includeBaseDirectory>true</includeBaseDirectory>
8
    <files>
9
        <file>
10
            <source>target/${project.artifactId}-${project.version}.jar</source>
11
            <outputDirectory>lib</outputDirectory>
12
        </file>
13
        <file>
14
            <source>target/package.info</source>
15
        </file>
16
    </files>
17

  
18
    <fileSets>
19
        <fileSet>
20
            <directory>src/main/resources-plugin</directory>
21
            <outputDirectory>.</outputDirectory>
22
        </fileSet>
23
    </fileSets>
24

  
25

  
26
    <dependencySets>
27
        <dependencySet>
28
            <useProjectArtifact>false</useProjectArtifact>
29
            <useTransitiveDependencies>false</useTransitiveDependencies>
30
            <outputDirectory>lib</outputDirectory>
31
            <includes> 
32
                <include>org.gvsig:org.gvsig.raster.wms.remoteclient:jar</include>
33
                <include>org.gvsig:org.gvsig.raster.wms.io:jar</include>
34
            </includes>
35
        </dependencySet>
36
    </dependencySets>
37
</assembly>
0 38

  
org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19/org.gvsig.raster.wms.app.wmsclient/src/main/java/org/gvsig/raster/wms/app/wmsclient/layer/DynObjectSetWMSInfo.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.wms.app.wmsclient.layer;
23

  
24
import org.gvsig.fmap.dal.feature.FeatureSet;
25
import org.gvsig.tools.ToolsLocator;
26
import org.gvsig.tools.dispose.DisposableIterator;
27
import org.gvsig.tools.dynobject.DynClass;
28
import org.gvsig.tools.dynobject.DynObject;
29
import org.gvsig.tools.dynobject.DynObjectManager;
30
import org.gvsig.tools.dynobject.DynObjectSet;
31
import org.gvsig.tools.exception.BaseException;
32
import org.gvsig.tools.observer.Observable;
33
import org.gvsig.tools.observer.Observer;
34
import org.gvsig.tools.observer.impl.BaseWeakReferencingObservable;
35
import org.gvsig.tools.visitor.Visitor;
36

  
37
/**
38
 * {@link DynObject} implementation to facade of a {@link FeatureSet} and allow
39
 * to be used as a {@link DynObjectSet}.
40
 * 
41
 * @author Nacho Brodin (nachobrodin@gmail.com)
42
 * @version $Id$
43
 */
44
public class DynObjectSetWMSInfo extends BaseWeakReferencingObservable
45
    implements DynObjectSet, Observer {
46
	//public static final int             TYPE_TEXT = 0;
47
	//public static final int             TYPE_HTML = 1;
48
	//public static final int             TYPE_XML  = 2;
49
	private DynObjectIteratorWMSInfo    ite       = null;
50
	private DynObject                   dynObject = null;
51
	private String                      type      = "text/plain";
52
	
53
	public static void registerDynClass() {
54
		DynObjectManager manager = ToolsLocator.getDynObjectManager();
55
    	DynClass dynClass = manager.add("WMSInfoByPoint", "WMS InfoByPoint");
56
    	dynClass.setNamespace("InfoByPoint");
57
    	dynClass.addDynFieldString("info");
58
	}
59
	
60
    /**
61
     * Creates a new facade over a given info, with fast dynobject
62
     * iteration.
63
     */
64
    public DynObjectSetWMSInfo(String txt, String type) {
65
    	DynObjectManager manager = ToolsLocator.getDynObjectManager();
66
    	dynObject = manager.createDynObject("WMSInfoByPoint");
67
    	dynObject.setDynValue("info", txt);
68
    	ite = new DynObjectIteratorWMSInfo(dynObject);
69
    	this.type = type;
70
    	/*if(type == TYPE_HTML)
71
    		this.type = "text/html";
72
    	if(type == TYPE_XML)
73
    		this.type = "text/xml";
74
    	if(type == TYPE_TEXT)
75
    		this.type = "text/plain";*/
76
    }
77

  
78
    public String getTypeInfo() {
79
    	return this.type;
80
    }
81
    
82
    public String getInfoElement() {
83
    	return (String)dynObject.getDynValue("info");
84
    }
85
    
86
    public void dispose() {
87

  
88
    }
89

  
90
    public void accept(final Visitor visitor, long firstValueIndex) throws BaseException {
91
    	while(ite.hasNext()) {
92
    		visitor.visit(ite.next());
93
    	}
94
    }
95

  
96
    public void accept(final Visitor visitor) throws BaseException {
97
    	while(ite.hasNext()) {
98
    		visitor.visit(ite.next());
99
    	}
100
    }
101

  
102
    public long getSize() throws BaseException {
103
       return ite.getSize();
104
    }
105

  
106
    public DisposableIterator iterator(long index) throws BaseException {
107
        return iterator();
108
    }
109

  
110
    public DisposableIterator iterator() throws BaseException {
111
    	return ite;
112
    }
113

  
114
    public boolean isEmpty() throws BaseException {
115
    	return (getSize() == 0);
116
    }
117

  
118
    public boolean isDeleteEnabled() {
119
    	return true;
120
    }
121

  
122
    public void delete(DynObject dynObject) throws BaseException {
123

  
124
    }
125

  
126
    public boolean isUpdateEnabled() {
127
    	return true;
128
    }
129

  
130
    public void update(DynObject dynObject) throws BaseException {
131
    	System.out.println();
132
    }
133

  
134
    public void update(Observable observable, Object notification) {
135
    	System.out.println();
136
    }
137
}
0 138

  
org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19/org.gvsig.raster.wms.app.wmsclient/src/main/java/org/gvsig/raster/wms/app/wmsclient/layer/FLyrWMS.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
 
23
package org.gvsig.raster.wms.app.wmsclient.layer;
24

  
25
import java.awt.Dimension;
26
import java.awt.Graphics2D;
27
import java.awt.Image;
28
import java.awt.Point;
29
import java.awt.Rectangle;
30
import java.awt.geom.AffineTransform;
31
import java.awt.geom.NoninvertibleTransformException;
32
import java.awt.geom.Point2D;
33
import java.awt.geom.Rectangle2D;
34
import java.awt.image.BufferedImage;
35
import java.lang.ref.WeakReference;
36
import java.util.ArrayList;
37
import java.util.HashMap;
38
import java.util.Iterator;
39
import java.util.List;
40
import java.util.Vector;
41
import java.util.prefs.Preferences;
42

  
43
import javax.print.attribute.PrintRequestAttributeSet;
44
import javax.swing.JOptionPane;
45

  
46
import org.cresques.cts.ICoordTrans;
47
import org.cresques.cts.IProjection;
48
import org.gvsig.andami.PluginServices;
49
import org.gvsig.fmap.dal.DALLocator;
50
import org.gvsig.fmap.dal.DataManager;
51
import org.gvsig.fmap.dal.DataParameters;
52
import org.gvsig.fmap.dal.DataStore;
53
import org.gvsig.fmap.dal.DataStoreParameters;
54
import org.gvsig.fmap.dal.coverage.RasterLocator;
55
import org.gvsig.fmap.dal.coverage.RasterManager;
56
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
57
import org.gvsig.fmap.dal.coverage.datastruct.ViewPortData;
58
import org.gvsig.fmap.dal.coverage.exception.FilePaletteException;
59
import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
60
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
61
import org.gvsig.fmap.dal.coverage.exception.QueryException;
62
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
63
import org.gvsig.fmap.dal.coverage.grid.RasterFilter;
64
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
65
import org.gvsig.fmap.dal.coverage.store.parameter.RasterDataParameters;
66
import org.gvsig.fmap.dal.coverage.store.parameter.RemoteStoreParameters;
67
import org.gvsig.fmap.dal.coverage.store.parameter.TileDataParameters;
68
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
69
import org.gvsig.fmap.dal.exception.DataException;
70
import org.gvsig.fmap.dal.exception.InitializeException;
71
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
72
import org.gvsig.fmap.dal.exception.ReadException;
73
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
74
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
75
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
76
import org.gvsig.fmap.geom.GeometryLocator;
77
import org.gvsig.fmap.geom.GeometryManager;
78
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
79
import org.gvsig.fmap.geom.primitive.Envelope;
80
import org.gvsig.fmap.mapcontext.ViewPort;
81
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
82
import org.gvsig.fmap.mapcontext.exceptions.UnsupportedVersionLayerException;
83
import org.gvsig.fmap.mapcontext.layers.FLayer;
84
import org.gvsig.fmap.mapcontext.layers.Tiling;
85
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
86
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
87
import org.gvsig.gui.beans.Messages;
88
import org.gvsig.raster.fmap.layers.DefaultFLyrRaster;
89
import org.gvsig.raster.fmap.layers.IRasterLayerActions;
90
import org.gvsig.raster.fmap.layers.NotAvailableStateException;
91
import org.gvsig.raster.fmap.legend.ImageLegend;
92
import org.gvsig.raster.util.CancelTaskImpl;
93
import org.gvsig.raster.wms.app.wmsclient.wmc.WebMapContextTags;
94
import org.gvsig.raster.wms.app.wmsclient.wmc.XmlBuilder;
95
import org.gvsig.raster.wms.io.RemoteWMSStyle;
96
import org.gvsig.raster.wms.io.WMSDataParameters;
97
import org.gvsig.raster.wms.io.WMSLayerNode;
98
import org.gvsig.raster.wms.io.WMSServerExplorer;
99
import org.gvsig.raster.wms.io.WMSServerExplorerParameters;
100
import org.gvsig.tools.ToolsLocator;
101
import org.gvsig.tools.dynobject.DynObjectSet;
102
import org.gvsig.tools.dynobject.DynStruct;
103
import org.gvsig.tools.persistence.PersistenceManager;
104
import org.gvsig.tools.task.Cancellable;
105
import org.gvsig.tools.task.SimpleTaskStatus;
106
import org.gvsig.tools.task.TaskStatusManager;
107
import org.slf4j.Logger;
108
import org.slf4j.LoggerFactory;
109

  
110

  
111

  
112
/**
113
 * FMap's WMS Layer class.
114
 *
115
 * Las capas WMS son tileadas para descargarlas del servidor. Esto quiere decir que
116
 * est?n formadas por multiples ficheros raster. Por esto la fuente de datos raster (IRasterDatasource)
117
 * de la capa FLyrWMS es un objeto de tipo CompositeDataset. Este objeto est? compuesto por un array
118
 * bidimensional de MultiRasterDataset. Cada uno de los MultiRasterDataset corresponde con un tile
119
 * salvado en disco. Estos MultiRasterDataset se crean cada vez que se repinta ya que en WMS a cada
120
 * zoom varian los ficheros fuente. La secuencia de creaci?n de un CompositeDataset ser?a la siguiente:
121
 * <UL>
122
 * <LI>Se hace una petici?n de dibujado por parte del usuario llamando al m?todo draw de FLyrWMS</LI>
123
 * <LI>Se tilea la petici?n</LI>
124
 * <LI>Cada tile se dibuja abriendo una FLyerRaster para ese tile</LI>
125
 * <LI>Si es el primer dibujado se guarda una referencia en la capa WMS a las propiedades de renderizado, orden de bandas,
126
 * transparencia, filtros aplicados, ...</LI>
127
 * <LI>Si no es el primer dibujado se asignan las propiedades de renderizado cuya referencia se guarda en la capa WMS</LI>
128
 * <LI>Se guarda el MultiRasterDataset de cada tile</LI>
129
 * <LI>Al acabar todos los tiles creamos un CompositeDataset con los MultiRasterDataset de todos los tiles</LI>
130
 * <LI>Asignamos a la capa la referencia de las propiedades de renderizado que tenemos almacenadas. De esta forma si hay
131
 * alguna modificaci?n desde el cuadro de propiedades ser? efectiva sobre los tiles que se dibujan.</LI>
132
 * </UL>
133
 *
134
 *
135
 * @author Jaume Dominguez Faus
136
 *
137
 */
138
@SuppressWarnings("deprecation")
139
public class FLyrWMS extends DefaultFLyrRaster {
140
	public static final String           PERSISTENT_NAME           = "FLyrWMS_Persistent";
141
	public static final String           PERSISTENT_DESCRIPTION    = "FLyrWMS Persistent Definition";
142
	
143
	private static final GeometryManager geomManager               = GeometryLocator.getGeometryManager();
144
	private static final Logger          logger                    = LoggerFactory.getLogger(FLyrWMS.class);
145
	private boolean 					 mustSplitRequest          = false;
146
	private final int 					 maxTileDrawWidth          = 1023;
147
	private final int 					 maxTileDrawHeight         = 1023;
148
	private final int 					 maxTilePrintWidth         = 1023;
149
	private final int 					 maxTilePrintHeight        = 1023;
150
	private List<WeakReference<Thread>>	 disableUpdateDrawVersion;
151
	//private Envelope					 fullEnvelope              = null;
152
	private boolean						 firstLoad                 = false;
153
	private RasterManager                rManager                  = RasterLocator.getManager();
154
	//private WMSServerExplorer            explorer                  = null;
155
	private boolean                      deleteCache               = false;
156

  
157
	public FLyrWMS() {
158
		super();
159
		this.updateDrawVersion();
160
		try {
161
			enableAwake();
162
		} catch (NotAvailableStateException e) {
163
			logger.error("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), this, e);
164
		}
165
	}
166
	
167
   public FLyrWMS(DataStoreParameters dataStoreParameters) throws Exception {
168
        this();
169
        //Create the explorer and connect
170
        DataManager dataManager = DALLocator.getDataManager();
171
        WMSServerExplorerParameters explorerParams = (WMSServerExplorerParameters) 
172
               dataManager.createServerExplorerParameters(WMSServerExplorer.NAME);
173
        explorerParams.setHost((String)dataStoreParameters.getDynValue("uri"));        
174
        WMSServerExplorer wmsServerExplorer = 
175
            (WMSServerExplorer) dataManager.openServerExplorer(WMSServerExplorer.NAME, explorerParams);
176
        wmsServerExplorer.connect(null, ((RemoteStoreParameters)dataStoreParameters).isDeletingCache());
177
        
178
        //Set the parameters
179
        setParameters((WMSDataParameters)dataStoreParameters);
180
        setExplorer(wmsServerExplorer);
181
    }
182
	
183
	public static DataStore createDataStore(String host, IProjection srs) throws InitializeException {
184
		DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
185
		RasterDataParameters params = null;
186
		try {
187
			params = (RasterDataParameters)dataman.createServerExplorerParameters(WMSServerExplorer.NAME);
188
		} catch (InitializeException e) {
189
			return null;
190
		} catch (ProviderNotRegisteredException e) {
191
			return null;
192
		}
193
		params.setURI(host);
194
		params.setSRS(srs);
195
		
196
		try {
197
			return dataman.openStore(params.getDataStoreName(), params);
198
		} catch (ValidateDataParametersException e) {
199
			throw new InitializeException(e);
200
		} catch (ProviderNotRegisteredException e) {
201
			throw new InitializeException(e);
202
		}
203
	}
204

  
205
	public void setDataStore(DataStore dataStore) throws LoadLayerException {
206
		this.dataStore = (RasterDataStore) dataStore;
207
		try {
208
			this.dataStore.isOpen();
209
			if(!isOpen())
210
				enableOpen();
211
		} catch (NotAvailableStateException e) {
212
			logger.error("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), this, e);
213
		}
214
		setProjection(this.dataStore.getProjection());
215
	}
216

  
217
	/**
218
	 * It choose the best format to load different maps if the server
219
	 * supports it. This format could be png, because it supports
220
	 * transparency.
221
	 * @param formats
222
	 * Arraywith all the formats supported by the server
223
	 * @return
224
	 */
225
	@SuppressWarnings("unused")
226
	private String getGreatFormat(Vector<String> formats){
227
		for (int i = 0 ; i < formats.size() ; i++){
228
			String format = (String) formats.get(i);
229
			if (format.equals("image/jpg")){
230
				return format;
231
			}
232
			if (format.equals("image/jpeg")){
233
				return format;
234
			}
235
		}
236
		return (String)formats.get(0);
237
	}
238
	
239
	public static void registerPersistent() {
240
		PersistenceManager manager = ToolsLocator.getPersistenceManager();
241
		DynStruct definition = manager.getDefinition("FLyrWMS_Persistent");
242
		if( definition == null ) {
243
			if (manager.getDefinition(DefaultFLyrRaster.class) == null) {
244
				DefaultFLyrRaster.registerPersistence();
245
			}
246

  
247
			definition = manager.addDefinition(
248
					FLyrWMS.class,
249
					"FLyrWMS_Persistent",
250
					"FLyrWMS Persistent Definition",
251
					null, 
252
					null
253
			);
254
			
255
			definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE, DefaultFLyrRaster.PERSISTENT_NAME);
256
		}
257

  
258
		DefaultFLyrRaster.registerPersistence(definition);
259
	}
260
	
261
	public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
262
			Cancellable cancel, double scale) throws ReadException {
263
		TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
264
		SimpleTaskStatus taskStatus = new RasterTaskStatus("Drawing " + getName() + "...", cancel);
265
		manager.add(taskStatus);
266
		taskStatus.setAutoremove(true);
267
		splitRequestCalculation(viewPort.getImageWidth(), viewPort.getImageHeight());
268
		
269
		if(!firstLoad) {
270
			try {
271
				initFilters();
272
				try {
273
					if(!isOpen())
274
						enableOpen();
275
				} catch (NotAvailableStateException e) {
276
					throw new ReadException("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), e);
277
				}
278
			} catch (FilePaletteException e) {
279
				logger.error(e.getMessage(), this, e);
280
			}
281
			firstLoad = true;
282
		}
283
		
284
		enableStopped();
285
		
286
		if(recalcLevel) {
287
			double pixelSize = viewPort.getEnvelope().getLength(0) / (double)viewPort.getImageWidth();
288
			zoomLevel = dataStore.getNearestLevel(pixelSize);
289
		}
290
		recalcLevel = true;
291

  
292
		if (isWithinScale(scale)) {
293

  
294
			if(mustSplitRequest) {
295
				Point2D p = viewPort.getOffset();
296
				Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), viewPort.getImageWidth(), viewPort.getImageHeight());
297
				Tiling tiles = new Tiling(maxTileDrawWidth, maxTileDrawHeight, r);
298
				tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
299

  
300
				for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
301
					// drawing part
302
					try {
303
						ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
304
						drawTile(g, vp, taskStatus, scale);
305
					} catch (LoadLayerException e) {
306
						throw new ReadException(e.getMessage(), e);
307
					} catch (NoninvertibleTransformException e) {
308
						throw new ReadException(e.getMessage(), e);
309
					}
310
				}
311
			} else {
312
				try {
313
					drawTile(g, viewPort, taskStatus, scale);
314
				} catch (LoadLayerException e) {
315
					setAvailable(false);
316
					logger.error("Server error:" + e.getMessage(), e);
317
				}
318
			}
319
		}
320
		disableStopped();
321
	}
322
	
323
		
324
	/**
325
	 * This is the method used to draw a tile in a WMS mosaic layer.
326
	 * @throws LoadLayerException
327
	 * @throws ReadDriverException
328
	 * @return true when a tile has been painted
329
	 */
330
	private void drawTile(Graphics2D g, ViewPort vp, SimpleTaskStatus taskStatus, double scale) throws LoadLayerException, ReadException {
331
		// Compute the query geometry
332
		// 1. Check if it is within borders
333
		Envelope layerEnv = getFullEnvelope();
334
		Envelope vpEnv = vp.getAdjustedEnvelope();
335
		if (!vpEnv.intersects(layerEnv)) {
336
			return;
337
		}
338
		try {
339
			Rectangle2D vpRect = getRectable2DFromEnvelope(vpEnv);
340
			Rectangle2D layerRect = getRectable2DFromEnvelope(layerEnv);
341
			// 2. Intersect layer and viewport extents to get the area of interest
342
			Rectangle2D requestedRect = new Rectangle2D.Double(); 
343
			Rectangle2D.intersect(layerRect, vpRect, requestedRect);
344

  
345
			// 3. Compute image size in pixels from the requested Extent
346
			double scalex = vp.getAffineTransform().getScaleX();
347
			double scaley = vp.getAffineTransform().getScaleY();
348
			int wImg = (int) Math.ceil(Math.abs(requestedRect.getWidth() * scalex));
349
			int hImg = (int) Math.ceil(Math.abs(requestedRect.getHeight() * scaley));
350
			if ((wImg <= 0) || (hImg <= 0)) {
351
				return;
352
			}
353
			
354
			// 4. compute exactly the requested extent (from the rounded image size)
355
			// ensuring we are still within the layer extent
356
			double worldWidth = Math.abs((double)wImg/scalex);
357
			double worldHeigh = Math.abs((double)hImg/scaley);
358
			double worldX;
359
			if (requestedRect.getX()+worldWidth>layerEnv.getMaximum(0)) {
360
				// we've got outside of layer extent due to rounding
361
				worldX = layerEnv.getMaximum(0)-worldWidth;
362
			}
363
			else {
364
				worldX = requestedRect.getX();
365
			}
366
			double worldY;
367
			if (requestedRect.getY()+worldHeigh>layerEnv.getMaximum(1)) {  // FIXME: test with different CRSs
368
				worldY = layerEnv.getMaximum(1)-worldHeigh;
369
			}
370
			else {
371
				worldY = requestedRect.getMinY();
372
			}
373
			
374
			requestedRect.setRect(worldX, worldY, worldWidth, worldHeigh); 
375
			Envelope requestedEnvelope = geomManager.createEnvelope(requestedRect.getMinX(),
376
					requestedRect.getMinY(),
377
					requestedRect.getMaxX(),
378
					requestedRect.getMaxY(),
379
					SUBTYPES.GEOM2D);
380
			Extent requestedExtent = rManager.getDataStructFactory().createExtent(
381
					requestedEnvelope.getMinimum(0), 
382
					requestedEnvelope.getMaximum(1), 
383
					requestedEnvelope.getMaximum(0), 
384
					requestedEnvelope.getMinimum(1));
385

  
386
			// 5. compute the new AffineTransform (ViewPort class can do it for us
387
			// if we provide the image size, extent and offset)
388
			ViewPort auxVp = (ViewPort) vp.clone();
389
			Dimension sz = new Dimension(wImg, hImg);
390
			auxVp.setImageSize(sz);
391
			auxVp.setEnvelope(requestedEnvelope);
392

  
393
			
394
			// 6. compute tile offeset. It is the sum of the original viewport offset
395
			// plus the offset introduced by intersecting layer and viewport extents
396
			double offsetX = vp.getOffset().getX();
397
			if (requestedEnvelope.getMinimum(0)-vpEnv.getMinimum(0)>0) {
398
				offsetX = offsetX + (requestedEnvelope.getMinimum(0)-vpEnv.getMinimum(0))*auxVp.getAffineTransform().getScaleX();
399
			}
400
			double offsetY = vp.getOffset().getY(); // FIXME: test with different CRSs
401
			if (requestedEnvelope.getMaximum(1)-vpEnv.getMaximum(1)<0) {
402
				offsetY = offsetY + (requestedEnvelope.getMaximum(1)-vpEnv.getMaximum(1))*auxVp.getAffineTransform().getScaleY();
403
			}
404

  
405
			// 7. Compute again the AffineTransform considering also the offset
406
			auxVp.setOffset(new Point2D.Double(offsetX, offsetY));
407
			auxVp.refreshExtent(); // necessary after updating the offset
408

  
409
			ViewPortData vpData = rManager.getDataStructFactory().createViewPortData(auxVp.getProjection(), requestedExtent, sz);
410
			vpData.setMat(auxVp.getAffineTransform());
411
			vpData.setDPI((int)auxVp.getDPI());
412
			getParameters().setExtent(requestedRect);
413
			if(getParameters().isSizeFixed()) {
414
				getParameters().setWidth((int)getParameters().getFixedSize().getWidth());
415
				getParameters().setHeight((int)getParameters().getFixedSize().getHeight());
416
			} else {
417
				getParameters().setWidth(wImg);
418
				getParameters().setHeight(hImg);
419
			}
420
			if(getDataStore().getParameters() instanceof WMSDataParameters) {
421
				getRender().draw(g, vpData, taskStatus);
422
			} else {
423
				Extent vpExtent = rManager.getDataStructFactory().createExtent(
424
						vpEnv.getMinimum(0),
425
						vpEnv.getMaximum(1),
426
						vpEnv.getMaximum(0),
427
						vpEnv.getMinimum(1));
428
				ViewPortData vp2 = rManager.getDataStructFactory().createViewPortData(vp.getProjection(), vpExtent, vp.getImageSize() );
429
				vp2.setMat(vp.getAffineTransform());
430
				vp2.setDPI((int)vp.getDPI());
431
				getParameters().setExtent(vpExtent.toRectangle2D());
432
				getRender().drawTiledService(g, vp2, vp.getImageSize(), taskStatus);
433
			}
434
		} catch (ProcessInterruptedException e) {
435
		} catch (CloneNotSupportedException e) {
436
			drawingError(e);
437
		}
438
		catch (QueryException e) {
439
			drawingError(e);
440
		} catch (CreateEnvelopeException e) {
441
			drawingError(e);
442
		} finally {
443
			taskStatus.terminate();				
444
		}
445
	}
446
	
447
	private void drawingError(Exception e) {
448
		setAvailable(false);
449
		JOptionPane.showMessageDialog(null, "Problems drawing this layer:" + e.getMessage(), Messages.getText("Error"), JOptionPane.ERROR_MESSAGE);
450
		logger.info("Problems drawing this layer:" + e.getMessage(), e);
451
	}	
452

  
453
	/**
454
	 * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
455
	 * 		com.iver.cit.gvsig.fmap.ViewPort,
456
	 * 		com.iver.cit.gvsig.fmap.operations.Cancellable)
457
	 */
458
	public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet properties)
459
	throws ReadException {
460
		TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
461
		SimpleTaskStatus taskStatus = new RasterTaskStatus("Printing " + getName() + "...", cancel);
462
		manager.add(taskStatus);
463
		taskStatus.setAutoremove(true);
464
		splitRequestCalculation(viewPort.getImageWidth(), viewPort.getImageHeight());
465

  
466
		if (isVisible() && isWithinScale(scale)){
467
			if (!mustSplitRequest) {
468
				draw(null, g, viewPort, cancel,scale);
469
			} else {
470
				Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipBounds());
471
				tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
472
				for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
473
					// Parte que dibuja
474
					try {
475
						ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
476
						drawTile(g, vp, taskStatus, scale);
477
					} catch (NoninvertibleTransformException e) {
478
						throw new ReadException(e.getMessage(), e);
479
					} catch (LoadLayerException e) {
480
						throw new ReadException(e.getMessage(), e);
481
					}
482
				}
483
			}
484
		}
485
		taskStatus.terminate();
486
	}
487

  
488
	public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
489
			double scale) throws ReadException {
490
		draw(null, g, viewPort, cancel,scale);
491
	}
492

  
493
	public HashMap<String, Object> getProperties() {
494
		HashMap<String, Object> info = new HashMap<String, Object>();
495
		String[] layerNames = getParameters().getLayerQuery().split(",");
496
		Vector<WMSLayerNode> layers = new Vector<WMSLayerNode>(layerNames.length);
497
		try {
498
			//explorer.connect(null);
499
			for (int i = 0; i < layerNames.length; i++) {
500
				layers.add(i, getExplorer().getLayer(layerNames[i]));
501
			}
502
			info.put("name", getName());
503
			info.put("selectedLayers", layers);
504
			info.put("host", getParameters().getURI());
505
			info.put("srs", getParameters().getSRSCode());
506
			info.put("format", getParameters().getFormat());
507
			info.put("infoformat", getParameters().getInfoFormat());
508
			info.put("wmsTransparency", new Boolean(getParameters().isWmsTransparent()));
509
			info.put("styles", getParameters().getStyles());
510
			info.put("dimensions", getParameters().getDimensions());
511
			info.put("fixedSize", getParameters().getFixedSize());
512
			return info;
513
		} catch (Exception e) {
514
			e.printStackTrace();
515
		}
516
		return null;
517
	}
518

  
519
	/**
520
	 * Creates the part of a OGC's MapContext document that would describe this
521
	 * layer(s).
522
	 * @param version, The desired version of the resulting document. (1.1.0)
523
	 * @return String containing the xml.
524
	 * @throws UnsupportedVersionLayerException
525
	 */
526
	@SuppressWarnings({ "unchecked", "rawtypes" })
527
	public String toMapContext(String mapContextVersion) {
528
		XmlBuilder xml = new XmlBuilder();
529
		
530
		String query = getParameters().getLayerQuery();
531
		String[] layerNames = query.split(",");
532
		List<RemoteWMSStyle> styleList = getParameters().getStyles();
533
		for (int i = 0; i < layerNames.length; i++) {
534
			WMSLayerNode layer = getExplorer().getLayer(layerNames[i]);
535
			HashMap xmlAttrs = new HashMap();
536

  
537
			// <Layer>
538
			xmlAttrs.put(WebMapContextTags.HIDDEN, !isVisible() + "");
539
			xmlAttrs.put(WebMapContextTags.QUERYABLE, getExplorer().isQueryable() + "");
540
			xml.openTag(WebMapContextTags.LAYER, xmlAttrs);
541
			xmlAttrs.clear();
542
			if (mapContextVersion.equals("1.1.0") || mapContextVersion.equals("1.0.0")) {
543
				// <Server>
544
				xmlAttrs.put(WebMapContextTags.SERVICE, WebMapContextTags.WMS);
545
				xmlAttrs.put(WebMapContextTags.VERSION, getExplorer().getVersion());
546
				xmlAttrs.put(WebMapContextTags.SERVER_TITLE, getExplorer().getServiceTitle());
547
				xml.openTag(WebMapContextTags.SERVER, xmlAttrs);
548
				xmlAttrs.clear();
549

  
550
				// <OnlineResource>
551
				xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
552
				xmlAttrs.put(WebMapContextTags.XLINK_HREF, getParameters().getURI().toString());
553
				xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
554
				xmlAttrs.clear();
555
				// </OnlineResource>
556

  
557
				xml.closeTag();
558
				// </Server>
559

  
560
				// <Name>
561
				xml.writeTag(WebMapContextTags.NAME, layer.getName().trim());
562
				// </Name>
563

  
564
				// <Title>
565
				xml.writeTag(WebMapContextTags.TITLE, layer.getTitle().trim());
566
				//?xml.writeTag(WebMapContextTags.TITLE, getName().trim());
567
				// </Title>
568

  
569
				// <Abstract>
570
				if (layer.getAbstract() != null) {
571
					xml.writeTag(WebMapContextTags.ABSTRACT, layer.getAbstract());
572
					// </Abstract>
573
				}
574

  
575
				// <SRS> (a list of available SRS for the enclosing layer)
576
				String[] strings = (String[]) layer.getAllSrs().toArray(new String[0]);
577
				String mySRS = strings[0];
578
				for (int j = 1; j < strings.length; j++) {
579
					mySRS += ","+strings[j];
580
				}
581
				xml.writeTag(WebMapContextTags.SRS, mySRS);
582
				// </SRS>
583

  
584
				// <FormatList>
585
				xml.openTag(WebMapContextTags.FORMAT_LIST);
586
				strings = getExplorer().getFormats();
587
				for (int j = 0; j < strings.length; j++) {
588
					// <Format>
589
					String str = strings[j].trim();
590
					if (str.equals(getParameters().getFormat())) {
591
						xml.writeTag(WebMapContextTags.FORMAT, str, WebMapContextTags.CURRENT, "1");
592
					} else {
593
						xml.writeTag(WebMapContextTags.FORMAT, str);
594
						// </Format>
595
					}
596
				}
597
				xml.closeTag();
598
				// </FormatList>
599

  
600
				// <StyleList>
601
				xml.openTag(WebMapContextTags.STYLE_LIST);
602

  
603
				if (layer.getStyles().size() > 0) {
604
					for (int j = 0; j < layer.getStyles().size(); j++) {
605
						// <Style>
606
						RemoteWMSStyle st = layer.getStyles().get(j);
607
						if (st.getName().equals(styleList.get(i).getName())) {
608
							xmlAttrs.put(WebMapContextTags.CURRENT, "1");
609
						}
610
						xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
611
						xmlAttrs.clear();
612

  
613
						// <Name>
614
						xml.writeTag(WebMapContextTags.NAME, st.getName());
615
						// </Name>
616

  
617
						// <Title>
618
						xml.writeTag(WebMapContextTags.TITLE, st.getTitle());
619
						// </Title>
620

  
621
						// <LegendURL width="180" format="image/gif" height="50">
622
						// <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
623
						// </OnlineResource>
624
						// </LegendURL>
625
						xml.closeTag();
626
						// </Style>
627

  
628
					}
629

  
630
				} else {
631
					// Create fake style (for compatibility issues)
632
					xmlAttrs.put(WebMapContextTags.CURRENT, "1");
633
					// <Style>
634
					xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
635
					xmlAttrs.clear();
636
					// <Name>
637
					xml.writeTag(WebMapContextTags.NAME, "default");
638
					// </Name>
639

  
640
					// <Title>
641
					xml.writeTag(WebMapContextTags.TITLE, "default");
642
					xml.closeTag();
643
				}
644
				// </StyleList>
645
				xml.closeTag();
646
				if (mapContextVersion.compareTo("1.0.0") > 0) {
647
					// <DimensionList>
648
					xml.openTag(WebMapContextTags.DIMENSION_LIST);
649
					// <Dimension>
650
					// </Dimension>
651
					xml.closeTag();
652
					// </DimensionList>
653
				}
654
			} else {
655
				xml.writeTag("ERROR", PluginServices.getText(this, "unsupported_map_context_version"));
656
			}
657
			// </Layer>
658
			xml.closeTag();
659
		}
660
		return xml.getXML();
661
	}
662

  
663
	public String getTocImageIcon() {
664
		return "icon-layer-wms";
665
	}
666

  
667
	public int[] getTileSize() {
668
		int[] size = {maxTileDrawWidth, maxTileDrawHeight};
669
		return size;
670
	}
671

  
672
	public boolean isTiled() {
673
		return mustSplitRequest;
674
	}
675
	
676
	private void splitRequestCalculation(int width, int height) {
677
            RasterDataStore store = this.getDataStore();
678
            if( store == null ) {
679
                String msg = "Can't get RasterDataStore associated to this layer ("+this.toString()+").";
680
                logger.warn(msg);
681
                throw new RuntimeException(msg);
682
            }
683
            mustSplitRequest = (!store.isTiled() && (width > maxTileDrawWidth || height > maxTileDrawHeight));
684
	}
685

  
686
	public ComposedLayer newComposedLayer() {
687
		Preferences prefs = Preferences.userRoot().node("gvsig.wms");
688

  
689
		/*
690
		 * from java.util.prefs import Preferences
691
		 * prefs = Preferences.userRoot().node("gvsig.wms")
692
		 * prefs.put("useComposedLayer","true")
693
		 */
694

  
695
		String str = prefs.get("useComposedLayer","false");
696
		Boolean useComposedLayer = Boolean.TRUE; // por defecto ya se usan
697
		try {
698
			useComposedLayer = Boolean.valueOf(str);
699
		} catch (Exception e) {
700

  
701
		}
702
		if (useComposedLayer.booleanValue()) {
703
			return new ComposedLayerWMS();
704
		} else {
705
			return null;
706
		}
707
	}
708

  
709
	/*
710
	 * Checks if can make a single petition for the two layers to the server
711
	 * @see com.iver.cit.gvsig.fmap.layers.ComposedLayerWMS#canAdd(com.iver.cit.gvsig.fmap.layers.FLayer)
712
	 */
713
	boolean isComposedLayerCompatible(FLayer layer) {
714
		FLyrWMS aLayer;
715

  
716
		if (!(layer instanceof FLyrWMS)) {
717
			return false;
718
		}
719
		aLayer = (FLyrWMS)layer;
720
		if (!getParameters().getURI().equals(aLayer.getParameters().getURI())) {
721
			return false;
722
		}
723
		
724
		WMSDataParameters p = getWMSParameters(getDataStore().getParameters()); 
725
				
726
		if (!p.getFormat().equals(aLayer.getParameters().getFormat())) {
727
			return false;
728
		}
729
		if (!p.getSRS().equals(aLayer.getParameters().getSRS())) {
730
			return false;
731
		}
732
		if (p.getInfoLayerQuery() != null) {
733
			if (!p.getInfoLayerQuery().equals(aLayer.getParameters().getInfoLayerQuery())) {
734
				return false;
735
			}
736
		}else if (p.getInfoLayerQuery() != null) {
737
			return false;
738
		}
739

  
740

  
741
		// isFixedSize es privado
742
		if ((getParameters().getFixedSize() != null) &&
743
				(aLayer.getParameters().getFixedSize() != null)) {
744
			if (getParameters().getFixedSize().equals(aLayer.getParameters().getFixedSize())) {
745
				return false;
746
			}
747
		} else if ((getParameters().getFixedSize() != null) != (aLayer.getParameters().getFixedSize() != null)) {
748
			return false;
749
		}
750

  
751
		// time elevation (dimensions)
752
		if ((p.getDimensions() != null) &&
753
				(aLayer.getParameters().getDimensions() != null)) {
754
			if (p.getDimensions().size() != aLayer.getParameters().getDimensions().size()) {
755
				return false;
756
			} else {
757
				Iterator<String> iter = p.getDimensions().iterator();
758
				while (iter.hasNext()) {
759
					if (!aLayer.getParameters().getDimensions().contains(iter.next())) {
760
						return false;
761
					}
762
				}
763
			}
764

  
765
		} else if ((p.getDimensions() != null) != (aLayer.getParameters().getDimensions() != null)) {
766
			return false;
767
		}
768

  
769
		return true;
770
	}
771

  
772
	public boolean isActionEnabled(int action) {
773
		switch (action) {
774
		case IRasterLayerActions.ZOOM_PIXEL_RESOLUTION:
775
		case IRasterLayerActions.FLYRASTER_BAR_TOOLS:
776
		case IRasterLayerActions.BANDS_FILE_LIST:
777
		case IRasterLayerActions.COLOR_TABLE:
778
		case IRasterLayerActions.GEOLOCATION:
779
		case IRasterLayerActions.PANSHARPENING:
780
		case IRasterLayerActions.SAVE_COLORINTERP:
781
		case IRasterLayerActions.SAVEAS:
782
		case IRasterLayerActions.BANDS_RGB:
783
		case IRasterLayerActions.ENHANCED:
784
		case IRasterLayerActions.STATS:
785
		case IRasterLayerActions.NODATA:
786
			return false;
787
		case IRasterLayerActions.REMOTE_ACTIONS:
788
			return true;
789
		}
790

  
791
		return super.isActionEnabled(action);
792
	}
793

  
794
	public ILegend getLegend() {
795
		if(getDataStore() != null) {
796
			Image img = getDataStore().getImageLegend();
797
			if(img != null)
798
				return new ImageLegend(img);
799
		}
800
		return null;
801
	}
802
	
803
	public boolean isRemote() {
804
		return true;
805
	}
806

  
807
	public boolean overviewsSupport() {
808
		return false;
809
	}
810

  
811
	protected void updateDrawVersion() {
812
		if (this.disableUpdateDrawVersion != null){
813

  
814
			Thread curThread = Thread.currentThread();
815

  
816
			Thread aThread;
817

  
818
			Iterator<WeakReference<Thread>> iter = this.disableUpdateDrawVersion.iterator();
819
			while (iter.hasNext()){
820
				aThread = (Thread) ((WeakReference<?>)iter.next()).get();
821
				if (aThread == null){
822
					iter.remove();
823
				} else if(aThread.equals(curThread)){
824
					return;
825
				}
826
			}
827
		}
828
		//		Exception ex = new Exception();
829
		//		ex.printStackTrace();
830
		super.updateDrawVersion();
831
	}
832

  
833
	protected void disableUpdateDrawVersion() {
834
		if (this.disableUpdateDrawVersion == null) {
835
			this.disableUpdateDrawVersion = new ArrayList<WeakReference<Thread>>();
836
		}
837
		this.disableUpdateDrawVersion.add(new WeakReference<Thread>(Thread.currentThread()));
838
	}
839

  
840
	protected void enableUpdateDrawVersion() {
841
		if (this.disableUpdateDrawVersion == null){
842
			return;
843
		}
844
		Thread curThread = Thread.currentThread();
845
		Thread aThread;
846

  
847
		Iterator<WeakReference<Thread>> iter = this.disableUpdateDrawVersion.iterator();
848
		while (iter.hasNext()) {
849
			aThread = (Thread) ((WeakReference<?>)iter.next()).get();
850
			if (aThread == null) {
851
				iter.remove();
852
			} else if(aThread.equals(curThread)) {
853
				iter.remove();
854
				break;
855
			}
856
		}
857

  
858
	}
859

  
860
	private Rectangle2D.Double getRectable2DFromEnvelope(Envelope env) {
861
		return new Rectangle2D.Double(env.getMinimum(0), env.getMinimum(1), env
862
				.getLength(0), env.getLength(1));
863
	}
864

  
865
	/*private Envelope getEnvelopeFromRectable2D(Rectangle2D rect) {
866
		try {
867
			return geomManager.createEnvelope(rect.getMinX(), rect.getMinY(),
868
					rect.getMaxX(), rect.getMaxY(),
869
					SUBTYPES.GEOM2D);
870
		} catch (CreateEnvelopeException e) {
871
			logger.error("Error creating the envelope", e);
872
		}
873
		return null;
874
	}*/
875
	
876
	@Override
877
	public String getFileFormat() {
878
		return "WMS";
879
	}
880
	
881
	@Override
882
	public FLayer getFileLayer() throws RasterDriverException {
883
		/*if(getDataStore() instanceof DefaultRemoteRasterStore) {
884
			RemoteRasterProvider prov = (RemoteRasterProvider)((DefaultRemoteRasterStore)getDataStore()).getProvider(0);
885
			File file = null;
886
			
887
			if(getParameters().isSizeFixed()) {
888
				file = prov.getFileLayer();
889
			} else {
890
				file = prov.getLastRequest();
891
			}
892
				
893
			if(file == null)
894
				return null;
895
			
896
			try {
897
				return DefaultFLyrRaster.createLayer("tmp", file);
898
			} catch (LoadLayerException e) {
899
				throw new RasterDriverException(e.getMessage(), e);
900
			}
901
		}*/
902
		return null;
903
	}
904

  
905
	/**
906
	 * Devuelve el envelope en la proyeccion de la vista
907
	 */
908
	public Envelope getFullEnvelope() {
909
		Extent e1 = getDataStore().getExtent();
910
		Envelope rAux = null;
911
		try {
912
			rAux = geomManager.createEnvelope(e1.getMin().getX(), e1.getMin().getY(), e1.getMax().getX(), e1.getMax().getY(), SUBTYPES.GEOM2D);
913
		} catch (CreateEnvelopeException exc) {
914
			logger.error("Error creating the envelope", exc);
915
		}
916

  
917
		// Esto es para cuando se crea una capa nueva con el fullExtent de ancho
918
		// y alto 0.
919
		if (rAux == null || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
920
				&& rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
921
			try {
922
				rAux = geomManager.createEnvelope(0, 0, 100, 100, SUBTYPES.GEOM2D);
923
			} catch (CreateEnvelopeException e) {
924
				logger.error("Error creating the envelope", e);
925
			}
926
		}
927
		// Si existe reproyecci?n, reproyectar el extent
928
		ICoordTrans ct = getCoordTrans();
929
		if (ct != null) {
930
			Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux
931
					.getMinimum(1));
932
			Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux
933
					.getMaximum(1));
934
			pt1 = ct.convert(pt1, null);
935
			pt2 = ct.convert(pt2, null);
936
			try {
937
				rAux = geomManager.createEnvelope(pt1.getX(), pt1.getY(), pt2
938
						.getX(), pt2.getY(), SUBTYPES.GEOM2D);
939
			} catch (CreateEnvelopeException e) {
940
				logger.error("Error creating the envelope", e);
941
			}// new
942
			// Rectangle2D.Double();
943
		}
944
		return rAux;
945

  
946
	}
947
	
948
	public Extent getFullRasterExtent() {
949
		return getExtentFromEnvelope(getFullEnvelope());
950
	}
951
	
952
	public DynObjectSet getInfo(org.gvsig.fmap.geom.primitive.Point p, double tolerance) throws LoadLayerException, DataException {
953
		Point p1 = new Point((int)p.getX(), (int)p.getY());
954
		return getInfo(p1, tolerance, null, false);
955
	}
956

  
957
	@Override
958
	public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel,
959
			boolean fast) throws LoadLayerException, DataException {
960

  
961
		//try {
962
		ViewPort viewPort = getMapContext().getViewPort();
963

  
964
		getParameters().setExtent(this.getRectable2DFromEnvelope(viewPort.getAdjustedEnvelope()));
965
		if(getParameters().isSizeFixed()) {
966
			getParameters().setWidth((int)getParameters().getFixedSize().getWidth());
967
			getParameters().setHeight((int)getParameters().getFixedSize().getHeight());
968
		} else {
969
			getParameters().setWidth(viewPort.getImageWidth());
970
			getParameters().setHeight(viewPort.getImageHeight());
971
		}
972
		
973
		CancelTaskImpl cancellable = new CancelTaskImpl(cancel);
974
		getParameters().setCancellable(cancellable);
975
		
976
		String fInfo;
977
		try {
978
			//Point2D pt = new Point2D.Double();
979
			//try {
980
				//viewPort.getAffineTransform().transform(p, pt);
981
			/*} catch (NoninvertibleTransformException e) {
982
				return null;
983
			}*/
984
			
985
			Extent bbox = getExtentFromEnvelope(viewPort.getAdjustedEnvelope());
986
			fInfo = getDataStore().getInfoByPoint(p.getX(), 
987
					p.getY(), 
988
					bbox, 
989
					viewPort.getImageWidth(), 
990
					viewPort.getImageHeight(), 
991
					cancellable);
992
		} catch (InfoByPointException e) {
993
			throw new LoadLayerException("Error in getInfoByPoint", e);
994
		}
995
		return new DynObjectSetWMSInfo(fInfo, getParameters().getInfoFormat());
996
	}
997
	
998
	private Extent getExtentFromEnvelope(Envelope env) {
999
		double minx = env.getMinimum(0);
1000
		double miny = env.getMinimum(1);
1001
		double maxx = env.getMaximum(0);
1002
		double maxy = env.getMaximum(1);
1003
		Point2D ul = new Point2D.Double(minx, maxy);
1004
		Point2D ur = new Point2D.Double(maxx, maxy);
1005
		Point2D ll = new Point2D.Double(minx, miny);
1006
		Point2D lr = new Point2D.Double(maxx, miny);
1007
		return rManager.getDataStructFactory().createExtent(ul, lr, ur, ll);
1008
	}
1009
    
1010
    /**
1011
     * Sets the data store parameters
1012
     * @param params
1013
     * @throws InitializeException
1014
     */
1015
    public void setParameters(DataStoreParameters params) throws InitializeException {
1016
    	if(params instanceof TileDataParameters) {
1017
			((TileDataParameters)params).deleteCache(deleteCache);
1018
		}
1019
    	
1020
    	DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
1021
		try {
1022
			DataStore dStore = dataman.openStore(params.getDataStoreName(), params);
1023
			this.setDataStore(dStore);
1024
			
1025
			if(params instanceof WMSDataParameters) {
1026
				this.setName(((WMSDataParameters)params).getURI());
1027
			}
1028
			
1029
			if(params instanceof TileDataParameters) {
1030
				DataParameters p = ((TileDataParameters) params).getDataParameters();
1031
				if(p instanceof WMSDataParameters) {
1032
					this.setName(((WMSDataParameters) p).getURI());
1033
				}
1034
			}
1035
		} catch (ValidateDataParametersException e) {
1036
			throw new InitializeException(e);
1037
		} catch (ProviderNotRegisteredException e) {
1038
			throw new InitializeException(e);
1039
		} catch (LoadLayerException e) {
1040
			throw new InitializeException(e);
1041
		}
1042
    }
1043
    
1044
	public WMSDataParameters getParameters() {
1045
		return getWMSParameters(getDataStore().getParameters());
1046
    }
1047
    
1048
    /**
1049
     * Gets <code>WMSDataParameters</code>
1050
     * @param parameters
1051
     * @return
1052
     */
1053
    private WMSDataParameters getWMSParameters(DataStoreParameters parameters) {
1054
    	WMSDataParameters params = null;
1055
    	if(parameters instanceof WMSDataParameters) {
1056
			params = (WMSDataParameters) parameters;
1057
		}
1058
		
1059
		if(parameters instanceof TileDataParameters) {
1060
			DataParameters p = ((TileDataParameters) parameters).getDataParameters();
1061
			if(p instanceof WMSDataParameters) {
1062
				params = (WMSDataParameters) p;
1063
			}
1064
		}
1065
		return params;
1066
    }
1067
    
1068
    /**
1069
	 * Assigns the flag to delete this layer from the cache
1070
	 * @param selected
1071
	 */
1072
	public void deleteCache(boolean deleteCache) {
1073
		this.deleteCache = deleteCache;
1074
	}
1075
    
1076
    /**
1077
     * Sets the explorer
1078
     * @param explorer
1079
     */
1080
    public void setExplorer(WMSServerExplorer explorer) {
1081
    	if(getDataStore() != null)
1082
    		getDataStore().setExplorer(explorer);
1083
    }
1084
    
1085
    /**
1086
     * Gets the explorer
1087
     * @return
1088
     */
1089
    public WMSServerExplorer getExplorer() {
1090
    	try {
1091
			return (WMSServerExplorer)getDataStore().getExplorer();
1092
		} catch (ValidateDataParametersException e) {
1093
			logger.debug("Error getting the explorer", e);
1094
		} catch (DataException e) {
1095
			logger.debug("Error getting the explorer", e);
1096
		}
1097
    	return null;
1098
    }
1099
    
1100
	public FLayer cloneLayer() throws Exception {
1101
		RasterDataStore  ds = dataStore.cloneDataStore();
1102
		FLyrWMS newLayer = new FLyrWMS();
1103
		newLayer.setName(getName());
1104
		newLayer.setOpenRasterStore(ds);
1105
		//newLayer.firstLoad = firstLoad;
1106
		newLayer.setExplorer(getExplorer());
1107
		
1108
		List<RasterFilter> filters = getRender().getFilterList().getStatusCloned();
1109

  
1110
		//Hacemos una copia de las bandas a renderizar
1111
		ColorInterpretation ci = getRender().getRenderColorInterpretation();
1112
		if(ci != null) {
1113
			newLayer.getRender().setRenderColorInterpretation(ci.cloneColorInterpretation());
1114
		}
1115

  
1116
		//Asignamos el entorno
1117
		if(newLayer.getRender().getFilterList() == null)
1118
			newLayer.getRender().setFilterList(RasterLocator.getManager().createEmptyFilterList(getRender().getFilterList().getInitDataType()));
1119
		newLayer.getRender().getFilterList().setEnv(getRender().getFilterList().getEnv());
1120
		newLayer.getRender().getFilterList().setStatus(filters);
1121

  
1122
		// Asignamos los valores noData del original
1123
		newLayer.setNoDataValue(getNoDataValue());
1124
		if(dataStore.getNoDataValue().isDefined())
1125
			newLayer.setNoDataTransparent(true);
1126
		newLayer.enableOpen();
1127
		
1128
		return newLayer;
1129
	}
1130
	
1131
	@Override
1132
	public boolean isInside(Point2D p) {
1133
		// Don't call the data store isInside method, as the data store
1134
		// parameters change for every WMS tile that is drawn, so it does not
1135
		// return sensible results.
1136
		return rManager.getRasterUtils().isInside(p, getDataStore().getExtent());
1137
	}
1138
}
0 1139

  
org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.19/org.gvsig.raster.wms.app.wmsclient/src/main/java/org/gvsig/raster/wms/app/wmsclient/layer/ComposedLayerWMS.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.wms.app.wmsclient.layer;
23

  
24
import java.awt.Graphics2D;
25
import java.awt.image.BufferedImage;
26
import java.util.List;
27

  
28
import org.gvsig.compat.print.PrintAttributes;
29
import org.gvsig.fmap.dal.exception.ReadException;
30
import org.gvsig.fmap.mapcontext.ViewPort;
31
import org.gvsig.fmap.mapcontext.layers.FLayer;
32
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
33
import org.gvsig.raster.wms.io.RemoteWMSStyle;
34
import org.gvsig.tools.task.Cancellable;
35

  
36

  
37
/**
38
 * Group WMS layers to make a single request to the
39
 * server for all layers.
40
 *
41
 * It is posible only if almost all params are the same. For this
42
 * comparasion, ComposedLayerWMS uses the method
43
 * {@link org.gvsig.wms.fmap.layers.FLyrWMS#isComposedLayerCompatible(com.iver.cit.gvsig.fmap.layers.FLayer)}
44
 *
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff