Revision 21019

View differences:

org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.231/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.231</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.425</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.248</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.231</connection>
43
        <developerConnection>scm:svn:https://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.231</developerConnection>
44
        <url>https://devel.gvsig.org/redmine/projects/gvsig-raster/repository/show/org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.231</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.231</version>
74
			</dependency>
75
			<dependency>
76
				<groupId>org.gvsig</groupId>
77
				<artifactId>org.gvsig.raster.wms.remoteclient</artifactId>
78
				<version>2.2.231</version>
79
			</dependency>
80
			<dependency>
81
				<groupId>org.gvsig</groupId>
82
				<artifactId>org.gvsig.raster.wms.app.wmsclient</artifactId>
83
				<version>2.2.231</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.231/org.gvsig.raster.wms.app.wmsclient/buildNumber.properties
1
#Sun Jul 09 18:31:47 CEST 2023
2
buildNumber=287
0 3

  
org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.231/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.231/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
 *
45
 *
46
 * @see com.iver.cit.gvsig.fmap.layers.layerOperations.ComposedLayer
47
 * @see org.gvsig.wms.fmap.layers.FLyrWMS
48
 */
49
public class ComposedLayerWMS extends ComposedLayer {
50
	private FLyrWMS layer=null;
51

  
52
	/* (non-Javadoc)
53
	 * @see com.iver.cit.gvsig.fmap.layers.layerOperations.ComposedLayer#canAdd(com.iver.cit.gvsig.fmap.layers.FLayer)
54
	 */
55
	public boolean canAdd(FLayer layer) {
56
		if (this.layer != null) {
57
			return this.layer.isComposedLayerCompatible(layer);
58
		}
59
		return false;
60
	}
61

  
62
	public void doAdd(FLayer layer) throws Exception {
63
		FLyrWMS aLayer = (FLyrWMS)layer;
64
		if (this.layer == null) {
65
			this.layer = new FLyrWMS();
66
			//this.layer.setXMLEntity(aLayer.getXMLEntity());
67
                        this.layer.setDataStore(aLayer.getDataStore());
68
			return;
69
		}
70
		this.layer.getParameters().setLayerQuery( this.layer.getParameters().getLayerQuery() + ","+ aLayer.getParameters().getLayerQuery());
71
		List<RemoteWMSStyle> aStyles = aLayer.getParameters().getStyles();
72

  
73
		if (aStyles != null) {
74
			List<RemoteWMSStyle> myStyles = this.layer.getParameters().getStyles();
75
			if (myStyles == null) {
76
				this.layer.getParameters().setStyles(aStyles);
77
			} else {
78
				myStyles.addAll(aStyles);
79
				this.layer.getParameters().setStyles(myStyles);
80
			}
81
		}
82

  
83
		//revisar el fullextend para ajustarlo a todas las capas
84
		this.layer.getFullEnvelope().add(aLayer.getFullEnvelope());
85

  
86
	}
87

  
88

  
89
	@Override
90
	protected void doDraw(BufferedImage image, Graphics2D g, ViewPort viewPort,
91
			Cancellable cancel, double scale)
92
			throws ReadException {
93
		this.layer.draw(image, g, viewPort, cancel, scale);
94

  
95
	}
96

  
97
	@Override
98
	protected void doPrint(Graphics2D g, ViewPort viewPort,
99
			Cancellable cancel,
100
			double scale,
101
			PrintAttributes properties) throws ReadException {
102
		this.layer.print(g, viewPort, cancel, scale, properties);
103

  
104
	}
105

  
106
}
0 107

  
org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.231/org.gvsig.raster.wms.app.wmsclient/src/main/java/org/gvsig/raster/wms/app/wmsclient/layer/DynObjectIteratorWMSInfo.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.util.ArrayList;
25

  
26
import org.gvsig.fmap.dal.feature.Feature;
27
import org.gvsig.tools.dispose.DisposableIterator;
28
import org.gvsig.tools.dynobject.DynObject;
29
import org.gvsig.tools.dynobject.DynObjectSet;
30

  
31
/**
32
 * {@link DynObject} implementation to facade a iterator of a WMTSInfo
33
 * and allow to be used as a {@link DynObjectSet} iterator.
34
 * 
35
 * @author Nacho Brodin (nachobrodin@gmail.com)
36
 * @version $Id$
37
 * 
38
 */
39
public class DynObjectIteratorWMSInfo implements DisposableIterator {
40

  
41
    private ArrayList<Object> infoList = new ArrayList<Object>();
42
    private int               index    = -1;
43

  
44
    /**
45
     * Creates a new DynObjects iterator facade over a feature iterator.
46
     * Each WMTSInfo will be returned through a new or reused
47
     * {@link DynObjectWMTSInfo} which allows the {@link Feature} to be
48
     * used like a DynObject.
49
     * 
50
     * @param featureIterator
51
     *            to facade
52
     * @param featureFacade
53
     *            if not null this object will be reused as the facade for the
54
     *            Feature objects of the feature iterator
55
     */
56
    public DynObjectIteratorWMSInfo(Object info) {
57
        this.infoList.add(info);
58
        index = 0;
59
    }
60
    
61
    public void addObject(Object info) {
62
    	this.infoList.add(info);
63
    	if(index == -1)
64
    		index = 0;
65
    }
66

  
67
    public synchronized void dispose() {
68
    	this.infoList.clear();
69
    	index = -1;
70
    }
71

  
72
    public synchronized boolean hasNext() {
73
        return (infoList.size() == 0 || index >= infoList.size()) ? false : true;
74
    }
75

  
76
    public synchronized Object next() {
77
        Object o = infoList.get(index);
78
        index ++;
79
        return o;
80
    }
81

  
82
    public synchronized void remove() {
83
    	if(index < infoList.size() && index >= 0) {
84
    		index --;
85
    		infoList.remove(index);
86
    	}
87
    }
88
    
89
    public long getSize() {
90
        return infoList.size();
91
    }
92
}
0 93

  
org.gvsig.raster.wms/tags/org.gvsig.raster.wms-2.2.231/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.231/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.net.URI;
37
import java.net.URISyntaxException;
38
import java.util.ArrayList;
39
import java.util.HashMap;
40
import java.util.Iterator;
41
import java.util.List;
42
import java.util.Vector;
43
import java.util.prefs.Preferences;
44

  
45
import javax.print.attribute.PrintRequestAttributeSet;
46
import javax.swing.JOptionPane;
47

  
48
import org.cresques.cts.ICoordTrans;
49
import org.cresques.cts.IProjection;
50

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

  
111
import org.slf4j.Logger;
112
import org.slf4j.LoggerFactory;
113

  
114

  
115

  
116
/**
117
 * FMap's WMS Layer class.
118
 *
119
 * Las capas WMS son tileadas para descargarlas del servidor. Esto quiere decir que
120
 * est?n formadas por multiples ficheros raster. Por esto la fuente de datos raster (IRasterDatasource)
121
 * de la capa FLyrWMS es un objeto de tipo CompositeDataset. Este objeto est? compuesto por un array
122
 * bidimensional de MultiRasterDataset. Cada uno de los MultiRasterDataset corresponde con un tile
123
 * salvado en disco. Estos MultiRasterDataset se crean cada vez que se repinta ya que en WMS a cada
124
 * zoom varian los ficheros fuente. La secuencia de creaci?n de un CompositeDataset ser?a la siguiente:
125
 * <UL>
126
 * <LI>Se hace una petici?n de dibujado por parte del usuario llamando al m?todo draw de FLyrWMS</LI>
127
 * <LI>Se tilea la petici?n</LI>
128
 * <LI>Cada tile se dibuja abriendo una FLyerRaster para ese tile</LI>
129
 * <LI>Si es el primer dibujado se guarda una referencia en la capa WMS a las propiedades de renderizado, orden de bandas,
130
 * transparencia, filtros aplicados, ...</LI>
131
 * <LI>Si no es el primer dibujado se asignan las propiedades de renderizado cuya referencia se guarda en la capa WMS</LI>
132
 * <LI>Se guarda el MultiRasterDataset de cada tile</LI>
133
 * <LI>Al acabar todos los tiles creamos un CompositeDataset con los MultiRasterDataset de todos los tiles</LI>
134
 * <LI>Asignamos a la capa la referencia de las propiedades de renderizado que tenemos almacenadas. De esta forma si hay
135
 * alguna modificaci?n desde el cuadro de propiedades ser? efectiva sobre los tiles que se dibujan.</LI>
136
 * </UL>
137
 *
138
 *
139
 * @author Jaume Dominguez Faus
140
 *
141
 */
142
@SuppressWarnings("deprecation")
143
public class FLyrWMS extends DefaultFLyrRaster {
144
	public static final String           PERSISTENT_NAME           = "FLyrWMS_Persistent";
145
	public static final String           PERSISTENT_DESCRIPTION    = "FLyrWMS Persistent Definition";
146

  
147
	private static final GeometryManager geomManager               = GeometryLocator.getGeometryManager();
148
	private static final Logger          logger                    = LoggerFactory.getLogger(FLyrWMS.class);
149
	private boolean 					 mustSplitRequest          = false;
150
	private final int 					 maxTileDrawWidth          = 1023;
151
	private final int 					 maxTileDrawHeight         = 1023;
152
	private final int 					 maxTilePrintWidth         = 1023;
153
	private final int 					 maxTilePrintHeight        = 1023;
154
	private List<WeakReference<Thread>>	 disableUpdateDrawVersion;
155
	//private Envelope					 fullEnvelope              = null;
156
	private boolean						 firstLoad                 = false;
157
	private RasterManager                rManager                  = RasterLocator.getManager();
158
	//private WMSServerExplorer            explorer                  = null;
159
	private boolean                      deleteCache               = false;
160

  
161
	public FLyrWMS() {
162
		super();
163
		this.updateDrawVersion();
164
		try {
165
			enableAwake();
166
		} catch (NotAvailableStateException e) {
167
			logger.error("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), this, e);
168
		}
169
	}
170

  
171
   public FLyrWMS(DataStoreParameters dataStoreParameters) throws Exception {
172
        this();
173
        //Create the explorer and connect
174
        DataManager dataManager = DALLocator.getDataManager();
175
        WMSServerExplorerParameters explorerParams = (WMSServerExplorerParameters)
176
               dataManager.createServerExplorerParameters(WMSServerExplorer.NAME);
177
        explorerParams.setHost(((URI)dataStoreParameters.getDynValue("uri")).toString());
178
        WMSServerExplorer wmsServerExplorer =
179
            (WMSServerExplorer) dataManager.openServerExplorer(WMSServerExplorer.NAME, explorerParams);
180
        wmsServerExplorer.connect(null, ((RemoteStoreParameters)dataStoreParameters).isDeletingCache());
181

  
182
        //Set the parameters
183
        setParameters((WMSDataParameters)dataStoreParameters);
184
        setExplorer(wmsServerExplorer);
185
    }
186

  
187
	public static DataStore createDataStore(String host, IProjection srs) throws InitializeException {
188
		DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
189
		RasterDataParameters params = null;
190
		try {
191
			params = (RasterDataParameters)dataman.createServerExplorerParameters(WMSServerExplorer.NAME);
192
		} catch (InitializeException e) {
193
			return null;
194
		} catch (ProviderNotRegisteredException e) {
195
			return null;
196
		}
197
		try {
198
            params.setURI(new URI(host));
199
        } catch (URISyntaxException e1) {
200
            throw new InitializeException("Can't create URI from "+host, e1);
201
        }
202
		params.setSRS(srs);
203

  
204
		try {
205
			return dataman.openStore(params.getDataStoreName(), params);
206
		} catch (ValidateDataParametersException e) {
207
			throw new InitializeException(e);
208
		} catch (ProviderNotRegisteredException e) {
209
			throw new InitializeException(e);
210
		}
211
	}
212

  
213
	public void setDataStore(DataStore dataStore) throws LoadLayerException {
214
		this.dataStore = (RasterDataStore) dataStore;
215
		try {
216
			this.dataStore.isOpen();
217
			if(!isOpen())
218
				enableOpen();
219
		} catch (NotAvailableStateException e) {
220
			logger.error("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), this, e);
221
		}
222
		setProjection(this.dataStore.getProjection());
223
	}
224

  
225
	/**
226
	 * It choose the best format to load different maps if the server
227
	 * supports it. This format could be png, because it supports
228
	 * transparency.
229
	 * @param formats
230
	 * Arraywith all the formats supported by the server
231
	 * @return
232
	 */
233
	@SuppressWarnings("unused")
234
	private String getGreatFormat(Vector<String> formats){
235
		for (int i = 0 ; i < formats.size() ; i++){
236
			String format = (String) formats.get(i);
237
			if (format.equals("image/jpg")){
238
				return format;
239
			}
240
			if (format.equals("image/jpeg")){
241
				return format;
242
			}
243
		}
244
		return (String)formats.get(0);
245
	}
246

  
247
	public static void registerPersistent() {
248
		PersistenceManager manager = ToolsLocator.getPersistenceManager();
249
		DynStruct definition = manager.getDefinition("FLyrWMS_Persistent");
250
		if( definition == null ) {
251
			if (manager.getDefinition(DefaultFLyrRaster.class) == null) {
252
				DefaultFLyrRaster.registerPersistence();
253
			}
254

  
255
			definition = manager.addDefinition(
256
					FLyrWMS.class,
257
					"FLyrWMS_Persistent",
258
					"FLyrWMS Persistent Definition",
259
					null,
260
					null
261
			);
262

  
263
			definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE, DefaultFLyrRaster.PERSISTENT_NAME);
264
		}
265

  
266
		DefaultFLyrRaster.registerPersistence(definition);
267
	}
268

  
269
	public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
270
			Cancellable cancel, double scale) throws ReadException {
271
		TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
272
		SimpleTaskStatus taskStatus = new RasterTaskStatus("Drawing " + getName() + "...", cancel);
273
		manager.add(taskStatus);
274
		taskStatus.setAutoremove(true);
275
		splitRequestCalculation(viewPort.getImageWidth(), viewPort.getImageHeight());
276

  
277
		if(!firstLoad) {
278
			try {
279
				initFilters();
280
				try {
281
					if(!isOpen())
282
						enableOpen();
283
				} catch (NotAvailableStateException e) {
284
					throw new ReadException("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), e);
285
				}
286
			} catch (FilePaletteException e) {
287
				logger.error(e.getMessage(), this, e);
288
			}
289
			firstLoad = true;
290
		}
291

  
292
		enableStopped();
293

  
294
		if(recalcLevel) {
295
			double pixelSize = viewPort.getEnvelope().getLength(0) / (double)viewPort.getImageWidth();
296
			zoomLevel = dataStore.getNearestLevel(pixelSize);
297
		}
298
		recalcLevel = true;
299

  
300
		if (isWithinScale(scale)) {
301

  
302
			if(mustSplitRequest) {
303
				Point2D p = viewPort.getOffset();
304
				Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), viewPort.getImageWidth(), viewPort.getImageHeight());
305
				Tiling tiles = new Tiling(maxTileDrawWidth, maxTileDrawHeight, r);
306
				tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
307

  
308
				for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
309
					// drawing part
310
					try {
311
						ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
312
						drawTile(g, vp, taskStatus, scale);
313
					} catch (LoadLayerException e) {
314
						throw new ReadException(e.getMessage(), e);
315
					} catch (NoninvertibleTransformException e) {
316
						throw new ReadException(e.getMessage(), e);
317
					}
318
				}
319
			} else {
320
				try {
321
					drawTile(g, viewPort, taskStatus, scale);
322
				} catch (LoadLayerException e) {
323
					setAvailable(false);
324
					logger.error("Server error:" + e.getMessage(), e);
325
				}
326
			}
327
		}
328
		disableStopped();
329
	}
330

  
331

  
332
	/**
333
	 * This is the method used to draw a tile in a WMS mosaic layer.
334
	 * @throws LoadLayerException
335
	 * @throws ReadDriverException
336
	 * @return true when a tile has been painted
337
	 */
338
	private void drawTile(Graphics2D g, ViewPort vp, SimpleTaskStatus taskStatus, double scale) throws LoadLayerException, ReadException {
339
		// Compute the query geometry
340
		// 1. Check if it is within borders
341
		Envelope layerEnv = getFullEnvelope();
342
		Envelope vpEnv = vp.getAdjustedEnvelope();
343
		if (!vpEnv.intersects(layerEnv)) {
344
			return;
345
		}
346
		try {
347
			Rectangle2D vpRect = getRectable2DFromEnvelope(vpEnv);
348
			Rectangle2D layerRect = getRectable2DFromEnvelope(layerEnv);
349
			// 2. Intersect layer and viewport extents to get the area of interest
350
			Rectangle2D requestedRect = new Rectangle2D.Double();
351
			Rectangle2D.intersect(layerRect, vpRect, requestedRect);
352

  
353
			// 3. Compute image size in pixels from the requested Extent
354
			double scalex = vp.getAffineTransform().getScaleX();
355
			double scaley = vp.getAffineTransform().getScaleY();
356
			int wImg = (int) Math.ceil(Math.abs(requestedRect.getWidth() * scalex));
357
			int hImg = (int) Math.ceil(Math.abs(requestedRect.getHeight() * scaley));
358
			if ((wImg <= 0) || (hImg <= 0)) {
359
				return;
360
			}
361

  
362
			// 4. compute exactly the requested extent (from the rounded image size)
363
			// ensuring we are still within the layer extent
364
			double worldWidth = Math.abs((double)wImg/scalex);
365
			double worldHeigh = Math.abs((double)hImg/scaley);
366
			double worldX;
367
			if (requestedRect.getX()+worldWidth>layerEnv.getMaximum(0)) {
368
				// we've got outside of layer extent due to rounding
369
				worldX = layerEnv.getMaximum(0)-worldWidth;
370
			}
371
			else {
372
				worldX = requestedRect.getX();
373
			}
374
			double worldY;
375
			if (requestedRect.getY()+worldHeigh>layerEnv.getMaximum(1)) {  // FIXME: test with different CRSs
376
				worldY = layerEnv.getMaximum(1)-worldHeigh;
377
			}
378
			else {
379
				worldY = requestedRect.getMinY();
380
			}
381

  
382
			requestedRect.setRect(worldX, worldY, worldWidth, worldHeigh);
383
			Envelope requestedEnvelope = geomManager.createEnvelope(requestedRect.getMinX(),
384
					requestedRect.getMinY(),
385
					requestedRect.getMaxX(),
386
					requestedRect.getMaxY(),
387
					SUBTYPES.GEOM2D);
388
			Extent requestedExtent = rManager.getDataStructFactory().createExtent(
389
					requestedEnvelope.getMinimum(0),
390
					requestedEnvelope.getMaximum(1),
391
					requestedEnvelope.getMaximum(0),
392
					requestedEnvelope.getMinimum(1));
393

  
394
			// 5. compute the new AffineTransform (ViewPort class can do it for us
395
			// if we provide the image size, extent and offset)
396
			ViewPort auxVp = (ViewPort) vp.clone();
397
			Dimension sz = new Dimension(wImg, hImg);
398
			auxVp.setImageSize(sz);
399
			auxVp.setEnvelope(requestedEnvelope);
400

  
401

  
402
			// 6. compute tile offeset. It is the sum of the original viewport offset
403
			// plus the offset introduced by intersecting layer and viewport extents
404
			double offsetX = vp.getOffset().getX();
405
			if (requestedEnvelope.getMinimum(0)-vpEnv.getMinimum(0)>0) {
406
				offsetX = offsetX + (requestedEnvelope.getMinimum(0)-vpEnv.getMinimum(0))*auxVp.getAffineTransform().getScaleX();
407
			}
408
			double offsetY = vp.getOffset().getY(); // FIXME: test with different CRSs
409
			if (requestedEnvelope.getMaximum(1)-vpEnv.getMaximum(1)<0) {
410
				offsetY = offsetY + (requestedEnvelope.getMaximum(1)-vpEnv.getMaximum(1))*auxVp.getAffineTransform().getScaleY();
411
			}
412

  
413
			// 7. Compute again the AffineTransform considering also the offset
414
			auxVp.setOffset(new Point2D.Double(offsetX, offsetY));
415
			auxVp.refreshExtent(); // necessary after updating the offset
416

  
417
			ViewPortData vpData = rManager.getDataStructFactory().createViewPortData(auxVp.getProjection(), requestedExtent, sz);
418
			vpData.setMat(auxVp.getAffineTransform());
419
			vpData.setDPI((int)auxVp.getDPI());
420
			getParameters().setExtent(requestedRect);
421
			if(getParameters().isSizeFixed()) {
422
				getParameters().setWidth((int)getParameters().getFixedSize().getWidth());
423
				getParameters().setHeight((int)getParameters().getFixedSize().getHeight());
424
			} else {
425
				getParameters().setWidth(wImg);
426
				getParameters().setHeight(hImg);
427
			}
428
			if(getDataStore().getParameters() instanceof WMSDataParameters) {
429
				getRender().draw(g, vpData, taskStatus);
430
			} else {
431
				Extent vpExtent = rManager.getDataStructFactory().createExtent(
432
						vpEnv.getMinimum(0),
433
						vpEnv.getMaximum(1),
434
						vpEnv.getMaximum(0),
435
						vpEnv.getMinimum(1));
436
				ViewPortData vp2 = rManager.getDataStructFactory().createViewPortData(vp.getProjection(), vpExtent, vp.getImageSize() );
437
				vp2.setMat(vp.getAffineTransform());
438
				vp2.setDPI((int)vp.getDPI());
439
				getParameters().setExtent(vpExtent.toRectangle2D());
440
				getRender().drawTiledService(g, vp2, vp.getImageSize(), taskStatus);
441
			}
442
		} catch (ProcessInterruptedException e) {
443
		} catch (CloneNotSupportedException e) {
444
			drawingError(e);
445
		}
446
		catch (QueryException e) {
447
			drawingError(e);
448
		} catch (CreateEnvelopeException e) {
449
			drawingError(e);
450
		} finally {
451
			taskStatus.terminate();
452
		}
453
	}
454

  
455
	private void drawingError(Exception e) {
456
		setAvailable(false);
457
		JOptionPane.showMessageDialog(null, "Problems drawing this layer:" + e.getMessage(), Messages.getText("Error"), JOptionPane.ERROR_MESSAGE);
458
		logger.info("Problems drawing this layer:" + e.getMessage(), e);
459
	}
460

  
461
	/**
462
	 * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
463
	 * 		com.iver.cit.gvsig.fmap.ViewPort,
464
	 * 		com.iver.cit.gvsig.fmap.operations.Cancellable)
465
	 */
466
	public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet properties)
467
	throws ReadException {
468
		TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
469
		SimpleTaskStatus taskStatus = new RasterTaskStatus("Printing " + getName() + "...", cancel);
470
		manager.add(taskStatus);
471
		taskStatus.setAutoremove(true);
472
		splitRequestCalculation(viewPort.getImageWidth(), viewPort.getImageHeight());
473

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

  
496
	public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
497
			double scale) throws ReadException {
498
		draw(null, g, viewPort, cancel,scale);
499
	}
500

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

  
527
	/**
528
	 * Creates the part of a OGC's MapContext document that would describe this
529
	 * layer(s).
530
	 * @param version, The desired version of the resulting document. (1.1.0)
531
	 * @return String containing the xml.
532
	 * @throws UnsupportedVersionLayerException
533
	 */
534
	@SuppressWarnings({ "unchecked", "rawtypes" })
535
	public String toMapContext(String mapContextVersion) {
536
		XmlBuilder xml = new XmlBuilder();
537

  
538
		String query = getParameters().getLayerQuery();
539
		String[] layerNames = query.split(",");
540
		List<RemoteWMSStyle> styleList = getParameters().getStyles();
541
		for (int i = 0; i < layerNames.length; i++) {
542
			WMSLayerNode layer = getExplorer().getLayer(layerNames[i]);
543
			HashMap xmlAttrs = new HashMap();
544

  
545
			// <Layer>
546
			xmlAttrs.put(WebMapContextTags.HIDDEN, !isVisible() + "");
547
			xmlAttrs.put(WebMapContextTags.QUERYABLE, getExplorer().isQueryable() + "");
548
			xml.openTag(WebMapContextTags.LAYER, xmlAttrs);
549
			xmlAttrs.clear();
550
			if (mapContextVersion.equals("1.1.0") || mapContextVersion.equals("1.0.0")) {
551
				// <Server>
552
				xmlAttrs.put(WebMapContextTags.SERVICE, WebMapContextTags.WMS);
553
				xmlAttrs.put(WebMapContextTags.VERSION, getExplorer().getVersion());
554
				xmlAttrs.put(WebMapContextTags.SERVER_TITLE, getExplorer().getServiceTitle());
555
				xml.openTag(WebMapContextTags.SERVER, xmlAttrs);
556
				xmlAttrs.clear();
557

  
558
				// <OnlineResource>
559
				xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
560
				xmlAttrs.put(WebMapContextTags.XLINK_HREF, getParameters().getURI().toString());
561
				xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
562
				xmlAttrs.clear();
563
				// </OnlineResource>
564

  
565
				xml.closeTag();
566
				// </Server>
567

  
568
				// <Name>
569
				xml.writeTag(WebMapContextTags.NAME, layer.getName().trim());
570
				// </Name>
571

  
572
				// <Title>
573
				xml.writeTag(WebMapContextTags.TITLE, layer.getTitle().trim());
574
				//?xml.writeTag(WebMapContextTags.TITLE, getName().trim());
575
				// </Title>
576

  
577
				// <Abstract>
578
				if (layer.getAbstract() != null) {
579
					xml.writeTag(WebMapContextTags.ABSTRACT, layer.getAbstract());
580
					// </Abstract>
581
				}
582

  
583
				// <SRS> (a list of available SRS for the enclosing layer)
584
				String[] strings = (String[]) layer.getAllSrs().toArray(new String[0]);
585
				String mySRS = strings[0];
586
				for (int j = 1; j < strings.length; j++) {
587
					mySRS += ","+strings[j];
588
				}
589
				xml.writeTag(WebMapContextTags.SRS, mySRS);
590
				// </SRS>
591

  
592
				// <FormatList>
593
				xml.openTag(WebMapContextTags.FORMAT_LIST);
594
				strings = getExplorer().getFormats();
595
				for (int j = 0; j < strings.length; j++) {
596
					// <Format>
597
					String str = strings[j].trim();
598
					if (str.equals(getParameters().getFormat())) {
599
						xml.writeTag(WebMapContextTags.FORMAT, str, WebMapContextTags.CURRENT, "1");
600
					} else {
601
						xml.writeTag(WebMapContextTags.FORMAT, str);
602
						// </Format>
603
					}
604
				}
605
				xml.closeTag();
606
				// </FormatList>
607

  
608
				// <StyleList>
609
				xml.openTag(WebMapContextTags.STYLE_LIST);
610

  
611
				if (layer.getStyles().size() > 0) {
612
					for (int j = 0; j < layer.getStyles().size(); j++) {
613
						// <Style>
614
						RemoteWMSStyle st = layer.getStyles().get(j);
615
						if (st.getName().equals(styleList.get(i).getName())) {
616
							xmlAttrs.put(WebMapContextTags.CURRENT, "1");
617
						}
618
						xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
619
						xmlAttrs.clear();
620

  
621
						// <Name>
622
						xml.writeTag(WebMapContextTags.NAME, st.getName());
623
						// </Name>
624

  
625
						// <Title>
626
						xml.writeTag(WebMapContextTags.TITLE, st.getTitle());
627
						// </Title>
628

  
629
						// <LegendURL width="180" format="image/gif" height="50">
630
						// <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
631
						// </OnlineResource>
632
						// </LegendURL>
633
						xml.closeTag();
634
						// </Style>
635

  
636
					}
637

  
638
				} else {
639
					// Create fake style (for compatibility issues)
640
					xmlAttrs.put(WebMapContextTags.CURRENT, "1");
641
					// <Style>
642
					xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
643
					xmlAttrs.clear();
644
					// <Name>
645
					xml.writeTag(WebMapContextTags.NAME, "default");
646
					// </Name>
647

  
648
					// <Title>
649
					xml.writeTag(WebMapContextTags.TITLE, "default");
650
					xml.closeTag();
651
				}
652
				// </StyleList>
653
				xml.closeTag();
654
				if (mapContextVersion.compareTo("1.0.0") > 0) {
655
					// <DimensionList>
656
					xml.openTag(WebMapContextTags.DIMENSION_LIST);
657
					// <Dimension>
658
					// </Dimension>
659
					xml.closeTag();
660
					// </DimensionList>
661
				}
662
			} else {
663
				xml.writeTag("ERROR", PluginServices.getText(this, "unsupported_map_context_version"));
664
			}
665
			// </Layer>
666
			xml.closeTag();
667
		}
668
		return xml.getXML();
669
	}
670

  
671
	public String getTocImageIcon() {
672
		return "icon-layer-wms";
673
	}
674

  
675
	public int[] getTileSize() {
676
		int[] size = {maxTileDrawWidth, maxTileDrawHeight};
677
		return size;
678
	}
679

  
680
	public boolean isTiled() {
681
		return mustSplitRequest;
682
	}
683

  
684
	private void splitRequestCalculation(int width, int height) {
685
            RasterDataStore store = this.getDataStore();
686
            if( store == null ) {
687
                String msg = "Can't get RasterDataStore associated to this layer ("+this.toString()+").";
688
                logger.warn(msg);
689
                throw new RuntimeException(msg);
690
            }
691
            mustSplitRequest = (!store.isTiled() && (width > maxTileDrawWidth || height > maxTileDrawHeight));
692
	}
693

  
694
	public ComposedLayer newComposedLayer() {
695
		Preferences prefs = Preferences.userRoot().node("gvsig.wms");
696

  
697
		/*
698
		 * from java.util.prefs import Preferences
699
		 * prefs = Preferences.userRoot().node("gvsig.wms")
700
		 * prefs.put("useComposedLayer","true")
701
		 */
702

  
703
		String str = prefs.get("useComposedLayer","false");
704
		Boolean useComposedLayer = Boolean.TRUE; // por defecto ya se usan
705
		try {
706
			useComposedLayer = Boolean.valueOf(str);
707
		} catch (Exception e) {
708

  
709
		}
710
		if (useComposedLayer.booleanValue()) {
711
			return new ComposedLayerWMS();
712
		} else {
713
			return null;
714
		}
715
	}
716

  
717
	/*
718
	 * Checks if can make a single petition for the two layers to the server
719
	 * @see com.iver.cit.gvsig.fmap.layers.ComposedLayerWMS#canAdd(com.iver.cit.gvsig.fmap.layers.FLayer)
720
	 */
721
	boolean isComposedLayerCompatible(FLayer layer) {
722
		FLyrWMS aLayer;
723

  
724
		if (!(layer instanceof FLyrWMS)) {
725
			return false;
726
		}
727
		aLayer = (FLyrWMS)layer;
728
		if (!getParameters().getURI().equals(aLayer.getParameters().getURI())) {
729
			return false;
730
		}
731

  
732
		WMSDataParameters p = getWMSParameters(getDataStore().getParameters());
733

  
734
		if (!p.getFormat().equals(aLayer.getParameters().getFormat())) {
735
			return false;
736
		}
737
		if (!p.getSRS().equals(aLayer.getParameters().getSRS())) {
738
			return false;
739
		}
740
		if (p.getInfoLayerQuery() != null) {
741
			if (!p.getInfoLayerQuery().equals(aLayer.getParameters().getInfoLayerQuery())) {
742
				return false;
743
			}
744
		}else if (p.getInfoLayerQuery() != null) {
745
			return false;
746
		}
747

  
748

  
749
		// isFixedSize es privado
750
		if ((getParameters().getFixedSize() != null) &&
751
				(aLayer.getParameters().getFixedSize() != null)) {
752
			if (getParameters().getFixedSize().equals(aLayer.getParameters().getFixedSize())) {
753
				return false;
754
			}
755
		} else if ((getParameters().getFixedSize() != null) != (aLayer.getParameters().getFixedSize() != null)) {
756
			return false;
757
		}
758

  
759
		// time elevation (dimensions)
760
		if ((p.getDimensions() != null) &&
761
				(aLayer.getParameters().getDimensions() != null)) {
762
			if (p.getDimensions().size() != aLayer.getParameters().getDimensions().size()) {
763
				return false;
764
			} else {
765
				Iterator<String> iter = p.getDimensions().iterator();
766
				while (iter.hasNext()) {
767
					if (!aLayer.getParameters().getDimensions().contains(iter.next())) {
768
						return false;
769
					}
770
				}
771
			}
772

  
773
		} else if ((p.getDimensions() != null) != (aLayer.getParameters().getDimensions() != null)) {
774
			return false;
775
		}
776

  
777
		return true;
778
	}
779

  
780
	public boolean isActionEnabled(int action) {
781
		switch (action) {
782
		case IRasterLayerActions.ZOOM_PIXEL_RESOLUTION:
783
		case IRasterLayerActions.FLYRASTER_BAR_TOOLS:
784
		case IRasterLayerActions.BANDS_FILE_LIST:
785
		case IRasterLayerActions.COLOR_TABLE:
786
		case IRasterLayerActions.GEOLOCATION:
787
		case IRasterLayerActions.PANSHARPENING:
788
		case IRasterLayerActions.SAVE_COLORINTERP:
789
		case IRasterLayerActions.SAVEAS:
790
		case IRasterLayerActions.BANDS_RGB:
791
		case IRasterLayerActions.ENHANCED:
792
		case IRasterLayerActions.STATS:
793
		case IRasterLayerActions.NODATA:
794
			return false;
795
		case IRasterLayerActions.REMOTE_ACTIONS:
796
			return true;
797
		}
798

  
799
		return super.isActionEnabled(action);
800
	}
801

  
802
	public ILegend getLegend() {
803
		if(getDataStore() != null) {
804
			Image img = getDataStore().getImageLegend();
805
			if(img != null)
806
				return new ImageLegend(img);
807
		}
808
		return null;
809
	}
810

  
811
	public boolean isRemote() {
812
		return true;
813
	}
814

  
815
	public boolean overviewsSupport() {
816
		return false;
817
	}
818

  
819
	protected void updateDrawVersion() {
820
		if (this.disableUpdateDrawVersion != null){
821

  
822
			Thread curThread = Thread.currentThread();
823

  
824
			Thread aThread;
825

  
826
			Iterator<WeakReference<Thread>> iter = this.disableUpdateDrawVersion.iterator();
827
			while (iter.hasNext()){
828
				aThread = (Thread) ((WeakReference<?>)iter.next()).get();
829
				if (aThread == null){
830
					iter.remove();
831
				} else if(aThread.equals(curThread)){
832
					return;
833
				}
834
			}
835
		}
836
		//		Exception ex = new Exception();
837
		//		ex.printStackTrace();
838
		super.updateDrawVersion();
839
	}
840

  
841
	protected void disableUpdateDrawVersion() {
842
		if (this.disableUpdateDrawVersion == null) {
843
			this.disableUpdateDrawVersion = new ArrayList<WeakReference<Thread>>();
844
		}
845
		this.disableUpdateDrawVersion.add(new WeakReference<Thread>(Thread.currentThread()));
846
	}
847

  
848
	protected void enableUpdateDrawVersion() {
849
		if (this.disableUpdateDrawVersion == null){
850
			return;
851
		}
852
		Thread curThread = Thread.currentThread();
853
		Thread aThread;
854

  
855
		Iterator<WeakReference<Thread>> iter = this.disableUpdateDrawVersion.iterator();
856
		while (iter.hasNext()) {
857
			aThread = (Thread) ((WeakReference<?>)iter.next()).get();
858
			if (aThread == null) {
859
				iter.remove();
860
			} else if(aThread.equals(curThread)) {
861
				iter.remove();
862
				break;
863
			}
864
		}
865

  
866
	}
867

  
868
	private Rectangle2D.Double getRectable2DFromEnvelope(Envelope env) {
869
		return new Rectangle2D.Double(env.getMinimum(0), env.getMinimum(1), env
870
				.getLength(0), env.getLength(1));
871
	}
872

  
873
	/*private Envelope getEnvelopeFromRectable2D(Rectangle2D rect) {
874
		try {
875
			return geomManager.createEnvelope(rect.getMinX(), rect.getMinY(),
876
					rect.getMaxX(), rect.getMaxY(),
877
					SUBTYPES.GEOM2D);
878
		} catch (CreateEnvelopeException e) {
879
			logger.error("Error creating the envelope", e);
880
		}
881
		return null;
882
	}*/
883

  
884
	@Override
885
	public String getFileFormat() {
886
		return "WMS";
887
	}
888

  
889
	@Override
890
	public FLayer getFileLayer() throws RasterDriverException {
891
		/*if(getDataStore() instanceof DefaultRemoteRasterStore) {
892
			RemoteRasterProvider prov = (RemoteRasterProvider)((DefaultRemoteRasterStore)getDataStore()).getProvider(0);
893
			File file = null;
894

  
895
			if(getParameters().isSizeFixed()) {
896
				file = prov.getFileLayer();
897
			} else {
898
				file = prov.getLastRequest();
899
			}
900

  
901
			if(file == null)
902
				return null;
903

  
904
			try {
905
				return DefaultFLyrRaster.createLayer("tmp", file);
906
			} catch (LoadLayerException e) {
907
				throw new RasterDriverException(e.getMessage(), e);
908
			}
909
		}*/
910
		return null;
911
	}
912

  
913
	/**
914
	 * Devuelve el envelope en la proyeccion de la vista
915
	 */
916
	public Envelope getFullEnvelope() {
917
		Extent e1 = getDataStore().getExtent();
918
		Envelope rAux = null;
919
		try {
920
			rAux = geomManager.createEnvelope(e1.getMin().getX(), e1.getMin().getY(), e1.getMax().getX(), e1.getMax().getY(), SUBTYPES.GEOM2D);
921
		} catch (CreateEnvelopeException exc) {
922
			logger.error("Error creating the envelope", exc);
923
		}
924

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

  
954
	}
955

  
956
	public Extent getFullRasterExtent() {
957
		return getExtentFromEnvelope(getFullEnvelope());
958
	}
959

  
960
	public DynObjectSet getInfo(org.gvsig.fmap.geom.primitive.Point p, double tolerance) throws LoadLayerException, DataException {
961
		Point p1 = new Point((int)p.getX(), (int)p.getY());
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff