### Eclipse Workspace Patch 1.0
#P libJCRS
Index: src/org/gvsig/crs/ICrs.java
===================================================================
--- src/org/gvsig/crs/ICrs.java	(revision 38884)
+++ src/org/gvsig/crs/ICrs.java	(working copy)
@@ -58,11 +58,6 @@
 	 * @return
 	 */
 	int getCode();
-	/**
-	 * Cadena WKT del CRS utilizado
-	 * @return
-	 */
-	String getWKT();
 	
 	/**
 	 * Devuelve la cadena con el parámetro nadgrid para proj4
#P libRemoteServices
Index: src/org/gvsig/remoteClient/wms/WMSProtocolHandler.java
===================================================================
--- src/org/gvsig/remoteClient/wms/WMSProtocolHandler.java	(revision 38884)
+++ src/org/gvsig/remoteClient/wms/WMSProtocolHandler.java	(working copy)
@@ -669,22 +669,21 @@
     public String getPartialQuery(WMSStatus status)
     {
         StringBuffer req = new StringBuffer();
-        req.append("LAYERS=" + Utilities.Vector2CS(status.getLayerNames()))
-           .append("&" + getSRSParameter() + "=" + status.getSrs())
-           .append("&BBOX=" + status.getExtent().getMinX()+ "," )
-           .append(status.getExtent().getMinY()+ ",")
-           .append(status.getExtent().getMaxX()+ ",")
-           .append(status.getExtent().getMaxY())
-           .append("&WIDTH=" + status.getWidth())
-           .append("&HEIGHT=" + status.getHeight())
-           .append("&FORMAT=" + status.getFormat())
+        req.append("LAYERS=")
+           .append(Utilities.Vector2CS(status.getLayerNames()))
+           .append("&").append(getSRSParameter()).append("=").append(status.getSrs());
+        
+        appendBoundingBox(status, req);
+        req.append("&WIDTH=").append(status.getWidth())
+           .append("&HEIGHT=").append(status.getHeight())
+           .append("&FORMAT=").append(status.getFormat())
            .append("&STYLES=");
         Vector v = status.getStyles();
         if (v!=null && v.size()>0)
         	req.append(Utilities.Vector2CS(v));
         v = status.getDimensions();
         if (v!=null && v.size()>0)
-            req.append("&" + Utilities.Vector2URLParamString(v));
+            req.append("&").append(Utilities.Vector2URLParamString(v));
         if (status.getTransparency()) {
             req.append("&TRANSPARENT=TRUE");
         }
@@ -701,6 +700,15 @@
     public void close() {
         // your code here
     }
+    
+    protected StringBuffer appendBoundingBox(WMSStatus status, StringBuffer req) {
+    	req.append("&BBOX=")
+    	.append(status.getExtent().getMinX()).append(",")
+        .append(status.getExtent().getMinY()).append(",")
+        .append(status.getExtent().getMaxX()).append(",")
+        .append(status.getExtent().getMaxY());
+    	return req;
+    }
 
     /**
      * Inner class that represents the description of the WMS metadata.
Index: src/org/gvsig/remoteClient/wms/wms_1_3_0/WMSProtocolHandler1_3_0.java
===================================================================
--- src/org/gvsig/remoteClient/wms/wms_1_3_0/WMSProtocolHandler1_3_0.java	(revision 38884)
+++ src/org/gvsig/remoteClient/wms/wms_1_3_0/WMSProtocolHandler1_3_0.java	(working copy)
@@ -533,4 +533,25 @@
     protected String getSRSParameter(){
     	return "CRS";
     }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.gvsig.remoteClient.wms.WMSProtocolHandler#getBoundingBox()
+     */
+    protected StringBuffer appendBoundingBox(WMSStatus status, StringBuffer req) {
+    	if (status.getCrsAxisOrder()==WMSStatus.CRS_AXIS_NORTH_EAST) {
+    		// We should check whether we should also reverse the bounding box for other orientations
+    		// (such as WMSStatus.CRS_AXIS_SOUTH_WEST), but it is difficult to get test cases.
+    		// For the moment we are conservative and will only reverse when order is CRS_AXIS_NORTH_EAST.
+    		req.append("&BBOX=")
+    		.append(status.getExtent().getMinY()).append(",")
+    		.append(status.getExtent().getMinX()).append(",")
+    		.append(status.getExtent().getMaxY()).append(",")
+    		.append(status.getExtent().getMaxX());
+    		return req;
+    	}
+    	else {
+    		return super.appendBoundingBox(status, req);
+    	}
+    }
   }
Index: src/org/gvsig/remoteClient/wms/WMSStatus.java
===================================================================
--- src/org/gvsig/remoteClient/wms/WMSStatus.java	(revision 38884)
+++ src/org/gvsig/remoteClient/wms/WMSStatus.java	(working copy)
@@ -23,7 +23,15 @@
     private boolean transparency;
 	private String onlineResource;
 	private String infoFormat;
+	/* On WMS 1.3 we need to order the bounding box depending on the defined CRS axis order */
+	private int crsAxisOrder;
 	
+	public static final int CRS_AXIS_NORTH_EAST = 0;
+	public static final int CRS_AXIS_EAST_NORTH = 1;
+	public static final int CRS_AXIS_SOUTH_WEST = 2;
+	public static final int CRS_AXIS_WEST_SOUTH = 3;
+	public static final int CRS_AXIS_OTHER_OR_UNKNOWN = 4;
+	
     public String getInfoFormat() {
 		return infoFormat;
 	}
@@ -265,4 +273,28 @@
 	public void setOnlineResource(String url) {
 		onlineResource = url;
 	}
+	
+	/**
+	 * Returns the axis order as specified by the CRS, as this defines the
+	 * order of the bounding box parameters on WMS 1.3.
+	 * 
+	 *  Valid values include: {@link #CRS_AXIS_EAST_NORTH},
+	 *  {@link #CRS_AXIS_NORTH_EAST}, {@link #CRS_AXIS_SOUTH_WEST},
+	 *  {@link #CRS_AXIS_WEST_SOUTH}, {@link #CRS_AXIS_OTHER_OR_UNKNOWN}.
+	 */
+	public int getCrsAxisOrder() {
+		return crsAxisOrder;
+	}
+	
+	/**
+	 * Sets the axis order as specified by the CRS, as this defines the
+	 * order of the bounding box parameters on WMS 1.3.
+	 * 
+	 *  Valid values include: {@link #CRS_AXIS_EAST_NORTH},
+	 *  {@link #CRS_AXIS_NORTH_EAST}, {@link #CRS_AXIS_SOUTH_WEST},
+	 *  {@link #CRS_AXIS_WEST_SOUTH}, {@link #CRS_AXIS_OTHER_OR_UNKNOWN}.
+	 */
+	public void setCrsAxisOrder(int axisOrder) {
+		this.crsAxisOrder = axisOrder;
+	}
 }
#P extWMS
Index: src/com/iver/cit/gvsig/fmap/layers/FLyrWMS.java
===================================================================
--- src/com/iver/cit/gvsig/fmap/layers/FLyrWMS.java	(revision 38883)
+++ src/com/iver/cit/gvsig/fmap/layers/FLyrWMS.java	(working copy)
@@ -67,11 +67,14 @@
 import java.util.Vector;
 import java.util.logging.Logger;
 import java.util.prefs.Preferences;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.print.attribute.PrintRequestAttributeSet;
 import javax.swing.ImageIcon;
 import javax.swing.JOptionPane;
 
+import org.cresques.cts.IProjection;
 import org.cresques.geo.ViewPortData;
 import org.cresques.px.Extent;
 import org.exolab.castor.xml.ValidationException;
@@ -194,6 +197,8 @@
 	private int                         lastNColumns = 0;
 	private int                         lastNRows = 0;
 	private boolean 					hasImageLegend = false;
+	
+	private int cachedAxisOrientation = WMSStatus.CRS_AXIS_OTHER_OR_UNKNOWN;
 
 	/***
 	 * WMS 1.3 standard defines a fixed pixel size of 0.28 mm for the server.
@@ -677,10 +682,10 @@
 				wmsStatus.setFormat( m_Format );
 				wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
 				wmsStatus.setSrs(m_SRS);
+				wmsStatus.setCrsAxisOrder(cachedAxisOrientation);
 				wmsStatus.setStyles(styles);
 				wmsStatus.setDimensions(dimensions);
 				wmsStatus.setTransparency(wmsTransparency);
-				wmsStatus.setSrs(m_SRS);
 				MyCancellable c = new MyCancellable(cancellable);
 				try {
 					item[0] = new StringXMLItem(new String(getDriver()
@@ -935,6 +940,7 @@
 			wmsStatus.setWidth( fixedSize.width );
 			wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
 			wmsStatus.setSrs(m_SRS);
+			wmsStatus.setCrsAxisOrder(cachedAxisOrientation);
 			wmsStatus.setStyles(styles);
 			wmsStatus.setDimensions(dimensions);
 			wmsStatus.setTransparency(wmsTransparency);
@@ -1196,6 +1202,7 @@
 			wmsStatus.setWidth( wImg );
 			wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
 			wmsStatus.setSrs(m_SRS);
+			wmsStatus.setCrsAxisOrder(cachedAxisOrientation);
 			wmsStatus.setStyles(styles);
 			wmsStatus.setDimensions(dimensions);
 			wmsStatus.setTransparency(wmsTransparency);
@@ -2294,4 +2301,48 @@
 		return null;
 	}
 
+	/**
+	 * Try to guess the axis orientation from the CRS WKT definition,
+	 * as there is no good way to do this using libProjection API.
+	 * 
+	 * @return One of @link {@link WMSStatus#CRS_AXIS_EAST_NORTH},
+	 * {@link WMSStatus#CRS_AXIS_NORTH_EAST}, {@link WMSStatus#CRS_AXIS_SOUTH_WEST},
+	 * {@link WMSStatus#CRS_AXIS_WEST_SOUTH}, {@link WMSStatus#CRS_AXIS_OTHER_OR_UNKNOWN}.
+	 */
+	private int guessAxisOrientation() {
+		if (this.getProjection()!=null) {
+			String wkt = this.getProjection().getWKT();
+			if (wkt!=null) {
+				String wktup = wkt.toUpperCase();
+				Pattern p = Pattern.compile(".*AXIS\\[(.*)\\]\\s*,\\s*AXIS\\[(.*)\\].*", Pattern.DOTALL);
+				Matcher m = p.matcher(wkt);
+				if (m.matches()) {
+					String firstAxis = m.group(1);
+					String secondAxis = m.group(2);
+					if (firstAxis.contains("EAST")
+							&& secondAxis.contains("NORTH")) {
+						return WMSStatus.CRS_AXIS_EAST_NORTH;
+					}
+					else if (firstAxis.contains("NORTH")
+							&& secondAxis.contains("EAST")) {
+						return WMSStatus.CRS_AXIS_NORTH_EAST;
+					}
+					else if (firstAxis.contains("WEST")
+							&& secondAxis.contains("SOUTH")) {
+						return WMSStatus.CRS_AXIS_WEST_SOUTH;
+					}
+					else if (firstAxis.contains("SOUTH")
+							&& secondAxis.contains("WEST")) {
+						return WMSStatus.CRS_AXIS_SOUTH_WEST;
+					}
+				}
+			}
+		}
+		return WMSStatus.CRS_AXIS_OTHER_OR_UNKNOWN;
+	}
+	
+	public void setProjection(IProjection proj) {
+		super.setProjection(proj);
+		cachedAxisOrientation = guessAxisOrientation();
+	}
 }
\ No newline at end of file
#P libProjection
Index: src/org/cresques/cts/IProjection.java
===================================================================
--- src/org/cresques/cts/IProjection.java	(revision 38884)
+++ src/org/cresques/cts/IProjection.java	(working copy)
@@ -75,4 +75,10 @@
 
     public double getScale(double minX, double maxX, double width, double dpi);
     public Rectangle2D getExtent(Rectangle2D extent,double scale,double wImage,double hImage,double mapUnits,double distanceUnits,double dpi);
+    
+    /**
+     * Returns the definition of this CRS as well-known-text format (WKT), if
+     * available. Otherwise return null. 
+     */
+	public String getWKT();
 }
Index: src/org/cresques/geo/Gauss.java
===================================================================
--- src/org/cresques/geo/Gauss.java	(revision 38884)
+++ src/org/cresques/geo/Gauss.java	(working copy)
@@ -141,4 +141,13 @@
 	public String getFullCode() {
 		return getAbrev();
 	}
+	
+    /*
+     * (non-Javadoc)
+     * @see org.cresques.cts.IProjection#getWKT()
+     */
+	public String getWKT() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
Index: src/org/cresques/geo/Mercator.java
===================================================================
--- src/org/cresques/geo/Mercator.java	(revision 38884)
+++ src/org/cresques/geo/Mercator.java	(working copy)
@@ -389,4 +389,13 @@
 	public String getFullCode() {
 		return getAbrev();
 	}
+	
+    /*
+     * (non-Javadoc)
+     * @see org.cresques.cts.IProjection#getWKT()
+     */
+	public String getWKT() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
Index: src/org/cresques/geo/CCLambert.java
===================================================================
--- src/org/cresques/geo/CCLambert.java	(revision 38884)
+++ src/org/cresques/geo/CCLambert.java	(working copy)
@@ -141,4 +141,13 @@
 	public String getFullCode() {
 		return getAbrev();
 	}
+	
+    /*
+     * (non-Javadoc)
+     * @see org.cresques.cts.IProjection#getWKT()
+     */
+	public String getWKT() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
Index: src/org/cresques/geo/Geodetic.java
===================================================================
--- src/org/cresques/geo/Geodetic.java	(revision 38884)
+++ src/org/cresques/geo/Geodetic.java	(working copy)
@@ -314,4 +314,13 @@
 	public String getFullCode() {
 		return getAbrev();
 	}
+
+    /*
+     * (non-Javadoc)
+     * @see org.cresques.cts.IProjection#getWKT()
+     */
+	public String getWKT() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
Index: src/org/cresques/cts/gt2/CoordSys.java
===================================================================
--- src/org/cresques/cts/gt2/CoordSys.java	(revision 38884)
+++ src/org/cresques/cts/gt2/CoordSys.java	(working copy)
@@ -218,4 +218,17 @@
 	public String getFullCode() {
 		return getAbrev();
 	}
+
+    /*
+     * (non-Javadoc)
+     * @see org.cresques.cts.IProjection#getWKT()
+     */
+	public String getWKT() {
+		if (isProjected()) {
+			return projCS.toWKT();
+		}
+		else {
+			return geogCS.toWKT();	
+		}
+	}
 }
Index: src/org/cresques/geo/UtmZone.java
===================================================================
--- src/org/cresques/geo/UtmZone.java	(revision 38884)
+++ src/org/cresques/geo/UtmZone.java	(working copy)
@@ -400,4 +400,13 @@
 	public String getFullCode() {
 		return getAbrev();
 	}
+	
+    /*
+     * (non-Javadoc)
+     * @see org.cresques.cts.IProjection#getWKT()
+     */
+	public String getWKT() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
