Select to view content in your preferred language

WMS Problem with Flex 2.2 and WMSLayer Class

1976
12
03-16-2011 07:02 AM
BrianBehling
Deactivated User
Hello.

I am trying to add a FEMA WMS flood hazard layer to a Flex application using the WMSLayer class, but it appears something is wrong with this class.

I verified the WMS service is working ArcMap. Since FEMA does not have a crossdomain file on their servers, I have to use a proxy page. I verified the proxy page is working in Visual Studio. When I use Fiddler to check the response from FEMA's server, it tells me that the SRS parameter is not defined. The spatialReference property for this class is read only, so there is no way to specify what the SRS parameter is. I did notice in the URL string that the CRS is getting set.

Anyone know if this is a bug or if I will have to use the 1.3 method of getting a WMS service into my application since I can't set the SRS parameter? Simple test code I'm using below:

<esri:Map id="map1"  scaleBarVisible="false"  logoVisible="false" load="onLoad()" >
  
<esri:ArcGISDynamicMapServiceLayer url="http://localhost/ArcGIS/rest/services/testWMS  /MapServer"/>
<esri:WMSLayer id="floodplain2" imageFormat="png" url="http://hazards.fema.gov/wmsconnector/wmsconnector/Servlet/NFHL" skipGetCapabilities="false"  disableClientCaching="false" proxyURL="http://localhost/test/proxy.ashx"  >
<esri:visibleLayers>
   <mx:ArrayList>
      <fx:String>Flood_Hazard_Zones_General</fx:String>
  </mx:ArrayList>
    </esri:visibleLayers>
</esri:WMSLayer>
</esri:Map>
Tags (2)
0 Kudos
12 Replies
DasaPaddock
Esri Regular Contributor
You don't actually need a proxy if you set skipGetCapabilities to true, but you do need to set the version to one that the service supports. Since you have skipGetCapabilities set to false, it should be getting the capabilities and using the right version already, but you can try setting skipGetCapabilities to true and removing the proxy and setting the version to 1.1.1.
0 Kudos
DasaPaddock
Esri Regular Contributor
Here's a working example:

    <esri:Map width="1024" height="768">
        <esri:extent>
            <esri:Extent xmin="-120" ymin="34.1" xmax="-119.3" ymax="34.6">
                <esri:SpatialReference wkid="4326"/>
            </esri:Extent>
        </esri:extent>
        <esri:ArcGISTiledMapServiceLayer url="http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
        <esri:WMSLayer skipGetCapabilities="true"
                       url="http://hazards.fema.gov/wmsconnector/wmsconnector/Servlet/NFHL"
                       version="1.1.1">
            <esri:visibleLayers>
                <s:ArrayList>
                    <fx:String>Flood_Hazard_Zones_General</fx:String>
                </s:ArrayList>
            </esri:visibleLayers>
        </esri:WMSLayer>
    </esri:Map>
0 Kudos
BrianBehling
Deactivated User
Thanks for the reply. Nice. I didn't know I had to pass in the version. Too bad the error returned from FEMA's WMS service didn't specify that I had the incorrect version.
0 Kudos
SteveTest
Deactivated User
Brian -thanks for this thread and Dasa thanks for the working example which also helped solve a problem I was having with WMSLayer.

I have an additional question though. Is there a working example(s) of performing an identify on a WMSLayer ?

Thanks
Steve
0 Kudos
BrianBehling
Deactivated User
Steve -

I have no working examples of a WMS identify task. If you are speaking specifically about the FEMA WMS service, you might want to check and make sure their service supports identify queries - I dont think it does.

There are a couple of other items about working this FEMA service and the WMSLayer class I would like to mention.

First, the WMSLayer class by default does not expose any image height or width properties. The height and width is set automatically by the map.height and map.width properties. This is a problem with the FEMA service because they do not allow images larger than 1024 x 1024. So, if you map height and width is greater than 1024, you will not get an image returned from the server.

I talked to ESRI tech support, and the tech mentioned the WMSLayer class is meant to be used with WMS layers created from ArcGIS Server. The tech pointed me to this forum post:
http://forums.esri.com/Thread.asp?c=158&f=2421&t=296210

That post describes extending the DynamicMapServiceLayer class. By extending this class, you can set properties for the height and width of the image returned from the WMS server. I extended the ESRI Flex 2.2 DynamicMapServiceLayer class, using the correct parameters, and it works.

Note though that this extended class makes use of the URLVariables class. When using this class, the format of the URL parameters that are sent to the WMS service get all messed up and the request will fail, so I had to concatenate my own URL string and set the _urlRequest.data = to my URL string.

Finally, the parameter for TRANSPARENT in the FEMA service is TRANPARENT (notice the lack of an S). Took me about on hour to figure that one out.

Here is the code I used to extend the 2.2 DynamicMapServiceLayer :

package com.esri.ags.samples
{

import com.esri.ags.SpatialReference;
import com.esri.ags.Units;
import com.esri.ags.geometry.Extent;
import com.esri.ags.layers.DynamicMapServiceLayer;

import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLVariables;

/**
 * WMSLayer
 */
public class WMSLayer extends DynamicMapServiceLayer
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Creates a new WMSLayer object.
     */
    public function WMSLayer()
    {
        super();
        
        setLoaded(true); // Map will only use loaded layers
        
        // init constant parameter values
        _params = new URLVariables();
        _params.REQUEST = "GetMap";
        _params.TRANPARENT = "true";
        _params.FORMAT = "image/png";
        _params.VERSION = "1.1.1";
        _params.LAYERS = "Flood_Hazard_Zones_General";
        _params.STYLES = "";
        _params.SERVICE = "WMS";
        _params.SERVICENAME = "WMS";
        
  var url:String = "http://hazards.fema.gov/wmsconnector/wmsconnector/Servlet/NFHL";
       // var url:String = "http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?";
        _urlRequest = new URLRequest(url);
        //_urlRequest.data = _params; // set params on URLRequest object
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    private var _params:URLVariables;
    private var _urlRequest:URLRequest;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //      initialExtent()
    //      spatialReference()
    //      units()
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  initialExtent
    //  - needed if Map doesn't have an extent
    //----------------------------------

    override public function get initialExtent():Extent
    {
        return new Extent(-105.261295716 ,39.467332551,-104.545150425 ,40.065272394, new SpatialReference(4326));
    }

    //----------------------------------
    //  spatialReference
    //  - needed if Map doesn't have a spatialReference
    //----------------------------------

    override public function get spatialReference():SpatialReference
    {
        return new SpatialReference(4326);
    }

    //----------------------------------
    //  units
    //  - needed if Map doesn't have it set
    //----------------------------------

    override public function get units():String
    {
        return Units.DECIMAL_DEGREES;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //      loadMapImage(loader:Loader):void
    //
    //--------------------------------------------------------------------------
    
    override protected function loadMapImage(loader:Loader):void
    {
  
        // update changing values
        _params.BBOX =  map.extent.xmin.toString() + "," + map.extent.ymin.toString() + "," + map.extent.xmax.toString() + "," + map.extent.ymax.toString() ;
        _params.SRS = "EPSG:4326";
       // _params.WIDTH = map.width;
  // _params.HEIGHT = map.height;
  
  //for the FEMA WMS layer, the max size they allow is 1024x1024
  _params.WIDTH = 1024;
  _params.HEIGHT = 1024;

  
  /* We have to format our URL parameters as a string because the the bounding box parameters will get messed up if we don't */
  var urlParams:String;
  
  urlParams = "FORMAT=" + _params.FORMAT + "&" + "HEIGHT=" + _params.HEIGHT + "&" + "BBOX=" + _params.BBOX + "&" + "WIDTH=" + _params.WIDTH + "&" + "LAYERS=" + _params.LAYERS + "&" + "SRS=" + _params.SRS + 
      "&" + "VERSION=" + _params.VERSION + "&" + "STYLES=" + _params.STYLES + "&" + "REQUEST=" + _params.REQUEST + "&" + "SERVICE=" + _params.SERVICE + "&" + "TRANPARENT=" + _params.TRANPARENT +
     "&" + "SERVICENAME=" + _params.SERVICENAME;
        
  _urlRequest.data = urlParams;
  
  loader.load(_urlRequest);
    }
}

}
0 Kudos
SteveTest
Deactivated User
Brian

I don't have a current requirement for the FEMA services but thanks for those extra details - as they could crop up elsewhere.

I now have two approaches to incorporating WMS services both of which work fine so far for my data.

1. <esri:WMSLayer>
2. extend DynamicMapServiceLayer

Getting these working was great progress for me!

All I need now is to solve the identify-WMS-feature problem.  :confused:
0 Kudos
eddiequinlan
Deactivated User
Hopefully someone can enlighten me.

I'm fundamentally struggling with the WMSLayer class.  My goal is to use my
var WMSurl = "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0q-t.cgi?" from Iowa State as an overlay on my map.

Bringing this service into an ArcMap document is fairly simple.  I can see the map, properties, available layers, etc....

When I try to implement the WMSLayer method mentioned above I keep getting a repeating error when I'm debugging the app.
Trace returns this...."[SWF] /cgi-bin/wms/nexrad/n0q-t.cgi - 0 bytes after decompression"

If I try the same method to connect to the FEMA WMS I get a similar error.
Trace returns this...."[SWF] /wmsconnector/wmsconnector/Servlet/NFHL - 0 bytes after decompression".

So here are my questions:

1.  Though I could publish a map service on my server using the WMS, is this the best practice?  Seems like alot of connections/maintainance/and trouble rather than connecting from my Flex app directly to the WMS service.

2.  Is there a reason/advantage to connecting via "WMSLayer extends DynamicMapServiceLayer" method?

3.  When connecting to the layer are we connecting to a Layer or an actual Service?

I have also been testing this method:

var nexrad:WMSLayer = new WMSLayer(WMSurl);

nexrad.version = "1.3.0";
nexrad.imageFormat = "png";
nexrad.skipGetCapabilities = false;
myMap.addLayer(nexrad);
nexrad.refresh();

This gives no error indications, but also does not display a Layer.

Can someone get me over the hump?
Thanx,
Eddie
0 Kudos
DasaPaddock
Esri Regular Contributor
You need to specify at least one visible layer. See this example:
http://forums.arcgis.com/threads/18988-How-to-get-WMSLayer-to-work?p=60641&viewfull=1#post60641
0 Kudos
eddiequinlan
Deactivated User
Hi Dasa,

Thank you for the quick response.  Previously I did try adding the layer and got the same results.  However, I did notice in your previous post your url is

......wms/nexrad/n0r.cgi    and the layer is              nexrad-n0r

mine was ........wms/nexrad/n0q-t.cgi    and the layer was       nexrad-n0r

I've made the changes and can now see a displayed layer.  I need to do some testing for various functionality, but you got me over the hill.........  thanx.

Can you enlighten me on the other questions?   Should I approach adding this WMS layer via a .mxd published map service?
0 Kudos