5

I have a use case where an external WMS server can serve maps in the Web Mercator projection using EPSG code 900913, but won't recognize ESRI's 102100 code.

My question is: can I force all WMS requests to use EPSG code 900913?

To illustrate, I have a simple map page:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Test</title>

        <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">

        <script src="http://js.arcgis.com/3.8/"></script>
        <script src="./test.js"></script>
    </head>
    <body>
        <div id="mapDiv"></div>
    </body>
</html>

Where test.js creates a simple map and adds a WMSLayer to it:

var wmsAddress = "http://some.server.com/wms";
var map, srs, extent;

require(["esri/map",
         "esri/layers/WMSLayer",
         "esri/layers/WMSLayerInfo",
         "esri/geometry/Extent",
         "esri/geometry/Point",
         "esri/SpatialReference",
         "dojo/domReady!"],
        function (Map, WMSLayer, WMSLayerInfo, Extent, Point, SpatialReference) {

    srs = new SpatialReference({wkid:900913});
    extent = new Extent(
            1362550.0288221193, 7616458.979152972,
            2281987.5791366613, 9525359.127428867,
            srs);
    map = new Map("mapDiv", {
        center: new Point(1800000, 7900000, srs),
        extent: extent
    });

    var wmsService = new WMSLayer(wmsAddress, {
        resourceInfo: {
            extent: extent,
            layerInfos: [new WMSLayerInfo({name:"layerName",title:"TestMap"})]
        },
        visibleLayers: ["layerName"]
    });
    map.addLayers([wmsService]);
});

When loading the application, the request that is sent to the WMS server looks like this (viewed in a browser console):

http//some.server.com/wms?SERVICE=WMS&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=TRUE&STYLES=&VERSION=1.3.0&LAYERS=layerName&WIDTH=1904&HEIGHT=400&CRS=EPSG:102100&BBOX=-2743182.35289663,6945549.925862053,6343182.35289663,8854450.074137948

Which results in this response from the server:

<ServiceExceptionReport xmlns="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.3.0" xsi:schemaLocation="http://www.opengis.net/ogc http://some.server.com:80/geoserver/schemas/wms/1.3.0/exceptions_1_3_0.xsd">
    <ServiceException code="InvalidCRS">
        Error occurred decoding the espg code urn:x-ogc:def:crs:EPSG:102100 No code "EPSG:102100" from authority "European Petroleum Survey Group" found for object of type "IdentifiedObject".
    </ServiceException>
</ServiceExceptionReport>
6

I'm not sure if this is the right way to do it, but there is a spatialreferences attribute of the WMSLayer object that contains a list of numbers that represent what to request from the backing server.

If you insert 900913 as the first element:

var wmsService = new WMSLayer(wmsAddress, {
    resourceInfo: {
        extent: extent,
        layerInfos: [new WMSLayerInfo({name:"layerName",title:"TestMap"})]
    },
    visibleLayers: ["layerName"]
});
wmsService.spatialReferences[0] = 900913;
map.addLayers([wmsService]);

Then the javascript API will use 900913 when requesting the map. For an example, see this jsfiddle.

The spatialReferences object does not appear in the documentation, but it also is not prefixed with an underscore so I presume it's OK to manipulate like this.

  • WMSLayers are returned as images in the specified spatial ref. therefore if it's returned with a spatial ref different to the one the map is using, I think the map will refuse to draw it. – Kate Feb 12 '14 at 20:49
  • 1
    True, but WKID 900913, 102100, and 3857 are all equivalent. Some WMS services will refuse to draw if you give them a WKID that isn't among the expected ones. – mwalker Feb 12 '14 at 21:32
  • Ah, I knew 102100 and 3857 were considered the same by ArcGIS but didn't know 900913 was also. This could well work then, I'd be interested to hear back. – Kate Feb 12 '14 at 22:31
  • Thank you, this solved my problem in a very convenient way. I'm curious about this functionality, and wonder whether it will continue to work in future versions (considering it's not in the documentation). But at least for now this was the perfect solution! – MattiasSp Feb 13 '14 at 11:11
2

I believe so. I did this in Silverlight. It was a matter of creating a new class that inherited from WMSLayer. I then overrode the GetUrl() method to substitute the CRS property with the value I wanted to send. I believe this principal should be adaptable to JavaScript but haven't got a code example.

Edit: I just found this example on the JavaScript API. It shows how to inherit from a dynamic layer to achieve the purpose of overriding the getImageUrl() method. You can see where to set the spatial ref.

https://developers.arcgis.com/javascript/jssamples/layers_custom_wms.html

  • This is a nice anecdote, but it isn't a useful answer. – Derek Swingley Feb 12 '14 at 17:51
  • Upvoted because I think this answer would also work as a solution to my problem, although it would require a lot more work. Thanks for the suggestion anyways! – MattiasSp Feb 13 '14 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.