Setting SRID value of FeatureTypeInfo - WFSClient

Topics: SharpMap v0.9 / v1.x, WinForms Controls
Nov 26, 2013 at 6:06 AM
Edited Nov 26, 2013 at 6:09 AM
Hi all,
I had an exception while using WFS client, it was trying to set srid value from xml which is read from geoserver's GetCapabilities response.
Response xml has a <DefaultSRS> element and it's data is EPSG:4326. The code block i've given below is setting _featureTypeInfo's SRID value from that xml.
_featureTypeInfo.SRID = _featureTypeInfoQueryManager.GetValueFromNode(
_featureTypeInfoQueryManager.Compile(_textResources.XPATH_SRS),
new[] {new DictionaryEntry("_param1", featureQueryName)});
This SRID value has a setter method like that:

public string SRID
{
    get { return _SRID; }
    set
    {
        if (string.IsNullOrEmpty(value))
            value = "4326";
        if (string.Compare(_SRID, value, StringComparison.InvariantCultureIgnoreCase) != 0)
        {
            Factory = GeometryServiceProvider.Instance.CreateGeometryFactory(int.Parse(value));
            _SRID = value;
        }
    }
}
As you see it compares existing _srid value with new "value" and if they are not equal it creates a new Geometry Factory then sets the _srid to the new value.

Everything is ok for now till parsed xml sends "EPSG:4326" to set new _srid, it tries to parse that value to int and our exception thrown!

It's interesting that after that assignment at WFSClient.cs there is a statement like that:
_featureTypeInfo.SRID = _featureTypeInfo.SRID.Substring(_featureTypeInfo.SRID.LastIndexOf(":") + 1);
That parses "EPSG:4326" to string/int parts and gets the int value. So that's not a surprise to get "EPSG:4326" as srid and trying to cast it to int without parsing throws an exception.

I'm not an experienced user of sharpmap or geoserver, i've fixed my source code and writing here to know if it's a bug or feature.
Coordinator
Nov 26, 2013 at 9:39 AM
It is at least inconsitent.
Could it be that WFSClient expectes GML 2.0 and you are receiving some GML 3.x?
Apr 28, 2014 at 5:47 AM
Edited Apr 28, 2014 at 5:54 AM
Edit: (I've been looking a v1.1 of sharpmap - although this still seems to be the same in trunk at the moment)

I'm exploring using Sharpmap to do some server side integration work with WFS layers (ie not rendering a map), I've come across this as well and have a little more information to add.

It looks like in commit 97623 the SRID property on the WfsFeatureTypeInfo class was changed from having a simple string backed property to also attempting to parse the value passed in and creating a geometry factory as above. The WFSClient hasn't changed at all to support this (the code below is the same since the initial commit that I can see on CodePlex). The WFSClient looks like it is using the SRID property to store the initially read value and then work on it from there (as below):
_featureTypeInfo.SRID = _featureTypeInfoQueryManager.GetValueFromNode(
                    _featureTypeInfoQueryManager.Compile(_textResources.XPATH_SRS),
                    new[] {new DictionaryEntry("_param1", featureQueryName)});
                /* If no SRID could be found, try '4326' by default */
                if (_featureTypeInfo.SRID == null) _featureTypeInfo.SRID = "4326";
                else
                    /* Extract number */
                    _featureTypeInfo.SRID = _featureTypeInfo.SRID.Substring(_featureTypeInfo.SRID.LastIndexOf(":") + 1);
I suggest that WFSClient.GetFeatureTypeInfo should be changed to incorporate this:
var srid = _featureTypeInfoQueryManager.GetValueFromNode(
                    _featureTypeInfoQueryManager.Compile(_textResources.XPATH_SRS),
                    new[] {new DictionaryEntry("_param1", featureQueryName)});
                /* If no SRID could be found, try '4326' by default */
                if (srid == null) _featureTypeInfo.SRID = "4326";
                else
                    /* Extract number */
                    _featureTypeInfo.SRID = _featureTypeInfo.SRID.Substring(_featureTypeInfo.SRID.LastIndexOf(":") + 1);
As for the values that I'm getting for the SRS out of GEOSERVER as the WFS (these aren't going to ever work):
  • WFS 1.0.0 -> EPSG:4326
  • WFS 1.1.0 -> urn:x-ogc:def:crs:EPSG:4326
I'm very new to sharpmap so maybe (and not an expert on the WFS standard either) I'm missing some configuration/setup somewhere?

My test app that has the problem is this (just a quick windows app):
public Form1()
        {
            InitializeComponent();

            GeoAPI.GeometryServiceProvider.Instance = new NetTopologySuite.NtsGeometryServices();
        }

        private void btnGo_Click(object sender, EventArgs e)
        {
            var wfs = new WFS(@"http://xxxxxxxx/geoserver/wfs", "topp", "states", WFS.WFSVersionEnum.WFS1_1_0);
        }