ThinkGeo.com    |     Documentation    |     Premium Support

Printing WmsAsyncLayer

Hi,

We have a project that allows maps to be printed. It builds up the layers by using MapPrinterLayer.Layers.Add(layer). However we would like to include one or more WmsAsyncLayers on the print but these are not of type Layer but rather LayerBase so we cannot add them.

Could you help understand how to include wms layers on a printout?

Thanks,
Jonathan

Hi Jonathan,

LayerBase is the base class of Layer and AsyncLayer, meaning you can add a WmsAsyncLayer into MapPrinterLayer.Layers (which is a collection of LayerBase) without any issues.

If you are not using the latest version, chances are the Layers are a collection of Layers instead of a collection of LayerBases and you will have an issue adding an AsyncLayer. Just upgrade it to the latest version would be fine.

Thanks,
Ben

Hi Ben,
Thanks for the suggestion. I updated .Printers and .Core to 4.3.0-beta064 from -beta012 and that did make a significant difference however it also appeared to introduce a different problem with WMTS layers that were working before the update. What looks to be happening is that in the previous version the WMTS sourced tiles all fitted together correctly on -beta064 they either misalign or have huge gaps depending on zoom level.

Should I raise a ticket and send some screen shots.

Kind Regards,
Jonathan

Hi Jonathan,

We recently made lots of improvements on WMTS. In the latest HowDoI sample (beta branch: samples/wpf/HowDoISample · master · ThinkGeo / Public / Desktop Maps · GitLab), you can find 2 WMTS Samples (“WMTS” is using WmtsOverlay while “Display Raster from WMTS Server” is using the WmtsAsyncLayer), in the sample we fetched the zooms from the WMTS server instead of using the 20 default zooms, we enabled client projection, support rendering lower zooms by stretching the tiles from upper zooms, and displayed debug info to help you understand where the tiles from. I’d suggest you check out that sample first, and if you still have issues, feel free to create a ticket and share some code to us and we can dive in.

Thanks,
Ben

Hi Ben,
I downloaded the sample project but cannot see the XYZ Based Layers node in the sample application tree and searching for WmtsOverlay in the code found no instances. So I am having trouble finding the relevant example.

Thanks,
Jonathan

Sorry, my bad. I told you beta branch but the link I sent is for master, here it is the right one: samples/wpf/HowDoISample · develop · ThinkGeo / Public / Desktop Maps · GitLab

Just FYI we just released v14.2.2 and we are in the middle of updating all the HowDoI samples, you will see the update samples in master branch in a couple days.

Hi Ben,
I am slowly getting there and have found that WmtsAsyncLayer works better than WmtsServer for resizing tiles and getting them in the right places. However still having problems with one source, MapBox, that needs to be reprojected, I had set this up as

myWmtsAsyncLayer.ProjectionConverter = new GdalProjectionConverter(3857, 27700);

But that is giving strange results with tiles looking to be in the wrong places, like a badly finished jigsaw, and maybe other inaccuracies.

I see that the example does have some reprojection information so will look into that next…

Jonathan

HI Jonathan,

The reprojection should have been taken care of. Take a look at the example and please send me your code snippet if you still see the issues.

Thanks,
Ben

Hi Ben,
Unfortunately we are still having a variety of issues including:

  • Tiles look muddled up. I think they are the correct tiles but definitely in the wrong order and I have not picked up a pattern for how they are disarranged.

  • As you zoom in the tiles have gaps between

  • Adding a projected tile cache causes an error that shows as the message ‘Arithmetic operation resulted in an overflow’ instead of actual tiles.

The code looks like this:

        private static void InitialiseBackgrounds(MapView mapControl)
    {
        // If the setting exists in the setting file, then osMapsAPIKey will come out with its corresponding value and it returns true
        // Otherwise it returns false (meaning the osMapsAPIKey will contain an empty value) and we set it to the default key
        // To add a user key use a line like this in the setting file:
        // <OSMapsAPIKey>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</OSMapsAPIKey>

        Setting settings = new Setting(Setting.Usage.DEFAULT, Setting.Areas.GENERAL);

        if (!settings.GetSettingsValues().TryGetValue(Setting.GeneralKeys.OSMAPS_API_KEY, out _osMapsAPIKey))
            SetStandardOSKey();

        if (!settings.GetSettingsValues().TryGetValue(Setting.GeneralKeys.MAPBOX_API_KEY, out _mapboxAPIKey))
            SetStandardMapBoxKey();

        osMapLayer = new WmtsAsyncLayer(new Uri("https://api.os.uk/maps/raster/v1/wmts"))
        {
            Name = OS_BACKGROUND,
            AxisOrder = WmtsAxisOrder.XY,
            DrawingExceptionMode = DrawingExceptionMode.DrawException,
            WebProxy = null,
            ActiveLayerName = "Road_27700",
            ActiveStyleName = "Road",
            TileMatrixSetName = "EPSG:27700",
            IsVisible = true,
            OutputFormat = "image/png",
        };

        osMapLayer.TileCache = CreateCacheForLayer(osMapLayer.ActiveLayerName, MapBackgroundLayerStyle.OSAPI);
        osMapLayer.SendingHttpRequest += OsMapLayer_SendingHttpRequest;

        mapBoxLayer = new WmtsAsyncLayer(new Uri("https://api.mapbox.com/styles/v1/lukeor/ckfy0j3ye01d019pfob9re2zi/wmts"))
        {
            Name = MAPBOX_BACKGROUND,
            AxisOrder = WmtsAxisOrder.XY,
            DrawingExceptionMode = DrawingExceptionMode.DrawException,
            WebProxy = null,
            ActiveLayerName = "ckfy0j3ye01d019pfob9re2zi",
            ActiveStyleName = "default",
            TileMatrixSetName = "GoogleMapsCompatible",
            ProjectionConverter = new GdalProjectionConverter(3857, 27700),
            IsVisible = true,
        };

        mapBoxLayer.TileCache = CreateCacheForLayer(mapBoxLayer.ActiveLayerName, MapBackgroundLayerStyle.SATELLITE);
        mapBoxLayer.ProjectedTileCache = CreateCacheForLayer(mapBoxLayer.ActiveLayerName, MapBackgroundLayerStyle.SATELLITE_PROJECTED);

        // Include the key as a parameter
        mapBoxLayer.Parameters.Add("access_token", _mapboxAPIKey);

        wmtsBackgrounds.Name = WMTS_OVERLAY_NAME;
        wmtsBackgrounds.Layers.Add(MAPBOX_BACKGROUND, mapBoxLayer);
        wmtsBackgrounds.Layers.Add(OS_BACKGROUND, osMapLayer);            
        mapControl.Overlays.Add(WMTS_OVERLAY_NAME, wmtsBackgrounds);
        mapControl.Overlays.MoveToBottom(wmtsBackgrounds);
    }

Hi Jonathan,

Thanks for reporting. It does have some issues projecting from 27700 to 3857, and it’s been fixed in the latest beta074. Please have another try. Here below is how I tested:

1, I signed up an account at https://api.os.uk, get a key
2. I modified the WMTS HowDoI sample as following:

  wmtsAsyncLayer = new WmtsAsyncLayer(new Uri("https://api.os.uk/maps/raster/v1/wmts"))
  {
  Name = "OS_BACKGROUND",
  AxisOrder = WmtsAxisOrder.XY,
  DrawingExceptionMode = DrawingExceptionMode.DrawException,
  WebProxy = null,
  ActiveLayerName = "Road_27700",
  ActiveStyleName = "Road",
  TileMatrixSetName = "EPSG:27700",
  IsVisible = true,
  OutputFormat = "image/png",
  };
  
  //wmtsAsyncLayer.SendingHttpRequest += WmtsAsyncLayer_SendingHttpRequest;
  wmtsAsyncLayer.Parameters.Add("key", "GHA684whwoGwDnKtFHUB2dPqp6sr6Bdy");

  layerOverlay.TileType = TileType.SingleTile;
  layerOverlay.Layers.Add(wmtsAsyncLayer);
  1. Here is what it looks like:

reprojected to 3857 (there are 2 sets of tile ids, one is from the original cache tiles and the other is from the projected cache tiles)

Thanks,
Ben