ThinkGeo.com    |     Documentation    |     Premium Support

Exception thrown when initializing connection to WMTS server

Hello,

I’m evaluating your product to see if it goes well with our specifications, but haven’t been able to connect to one of the maps we need.

I think the setup is good, but can’t find what goes wrong and why. Here is my code:

        var wmtsTiledOverlay = new WmtsTiledOverlay(new Collection<Uri> { new Uri("http://www.ign.es/wmts/ign-base") });
        wmtsTiledOverlay.WmtsServerEncodingType = ThinkGeo.MapSuite.Wpf.WmtsSeverEncodingType.Kvp;
        wmtsTiledOverlay.Parameters.Add(key: "LAYER", value: "IGNBaseTodo");
        wmtsTiledOverlay.Parameters.Add(key: "FORMAT", value: "image/jpeg");
        wmtsTiledOverlay.Parameters.Add(key: "TILEMATRIXSET", value: "GoogleMapsCompatible");
        wmtsTiledOverlay.InitializeConnection();

When the InitializeConnection line executes, it throws a “FormatException: Input string was not in a correct format”, with the stacktrace being:

   in System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   in System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   in ThinkGeo.MapSuite.Wpf.WmtsTiledOverlay.skI=(XmlNode node, XmlNamespaceManager namespaceManager)
   in ThinkGeo.MapSuite.Wpf.WmtsTiledOverlay.gRo=(XmlElement element, XmlNamespaceManager namespaceManager)
   in ThinkGeo.MapSuite.Wpf.WmtsTiledOverlay.InitializeConnection()
  ...

I have seen, with Fiddler, that the “GetCapabilities” call is being done, and responded OK, so I think the problem may be parsing the response XML.
I also have tried to contact the server referenced in Errors connection to some WMTS , just to try, and that worked well.

Is there anything wrong with the code?

Thanks,
Euyen

Hi Euyen,

Yes you’re right, the exception is thrown because when we parse the capability it met an error here: ows:SupportedCRShttp://www.opengis.net/def/crs/OGC/1.3/CRS84</ows:SupportedCRS>

The format is looks like this format in your capability XML file:

And this format should be supported.

Regards,

Ethan

So, it’s not possible to connect to that provider? Using a SendingWebRequest delegate to handle web requests it seems that even if I don’t use the InitializeConnection line, it tries to get capabilities and, again, it crashes. It doesn’t depend on which TileMatrixSet I use, it seems.

Are there any workarounds about that?

Hi Euyen,

The existing events are not helpful for this problem.

If you can control the server, directly modify that is the best solution.

If that’s not your server, you can try this steps to handle it:

  1. Write custom code to download the capability xml: http://www.ign.es/wmts/ign-base?Service=WMTS&Request=GetCapabilities

  2. Modify the local capability file and save it to the cache folder

  3. Call the InitializeConnection function and it will render the cached capability XML now

The saved path should be calculated like this:
Path.GetTempPath() + “MapSuite\WmtsOverlay\” + “http://www.ign.es/wmts/ign-base?Service=WMTS”.GetHashCode() + “.xml”

Wish that’s helpful.

Regards,

Ethan

Hello,

I tried what you say in the post and, although it seemed to work well when I move around the map, when I zoom in, the tiles seem to be incorrectly placed.

So I tried a different approach. This provider uses XYZ tiles like OpenStreetMap, so I used the OSMOverlay with custom Uri, and it seemed to work well. But we have another problem here: IGN(fyi “Instituto Geográfico Nacional” - National Geographic Institute) have a 20th level of zooming , but I can’t get there, since OSM have until level 19.
Code for adding this layer:

            var IGNOverlay = new OpenStreetMapOverlay
        {
            Name = CARTOCIUDAD_MAP_KEY,
            DrawingExceptionMode = DrawingExceptionMode.ThrowException,
            IsVisible = false,
        };

        IGNOverlay.CustomServerUris.Add(new Uri("http://www.ign.es/wmts/ign-base?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=IGNBaseTodo&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX={0}&TILEROW={2}&TILECOL={1}&FORMAT=image/jpeg"));

        
        IGNOverlay.SendingWebRequest += IGNOverlay_SendingWebRequest;
        IGNOverlay.TimeoutInSeconds = 120;
        IGNOverlay.DrawingExceptionMode = DrawingExceptionMode.DrawException;
        Proj4Projection proj4 = new Proj4Projection()
        {
            InternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString(),
            ExternalProjectionParametersString = Proj4Projection.GetDecimalDegreesParametersString()
        };

        IGNOverlay.ProjectionFromSphericalMercator = proj4;

        _mapControl.Overlays.Add(CARTOCIUDAD_MAP_KEY, IGNOverlay);

Here is an example of an uri inside this 20th level:
http://www.ign.es/wmts/ign-base?layer=IGNBaseTodo&tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fjpeg&TileMatrix=20&TileCol=523144&TileRow=398986

I tried to add a new ZoomLevel, and with it, the map zooms, but it doesn’t request new tiles, so we only have zoomed(and pixeled) tiles. Can I make the map send a new request for the 20th zoom level?
Code for adding this zoom level:

            ZoomLevelSet customZoomLevelSet = new SphericalMercatorZoomLevelSet();
        foreach (var item in new SphericalMercatorZoomLevelSet().GetZoomLevels())
        {
            customZoomLevelSet.CustomZoomLevels.Add(new ZoomLevel(item.Scale));
        }
        customZoomLevelSet.CustomZoomLevels.Add(new ZoomLevel(customZoomLevelSet.CustomZoomLevels.Last().Scale / 2));

        _mapControl.ZoomLevelSet = customZoomLevelSet;

Thanks,
Euyen

Hi Euyen,

The solution is use Layer instead of Overlay, because you need to assign the custom zoomlevel to layer also.

When it’s overlay you cannot assign that, please see the code as below:

            OpenStreetMapLayer layer = new OpenStreetMapLayer();
        layer.CustomServerUris.Add(new Uri("http://www.ign.es/wmts/ign-base?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=IGNBaseTodo&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX={0}&TILEROW={2}&TILECOL={1}&FORMAT=image/jpeg"));
        layer.TimeoutInSeconds = 120;
        LayerOverlay IGNOverlay = new LayerOverlay();
        IGNOverlay.Layers.Add(layer);
        layer.ZoomlevelSet = customZoomLevelSet;

You should want to download the special package for OpenStreetMapLayer from NuGet.

Regards,

Ethan