WMS Layer

Jul 9, 2014 at 12:35 PM
Hi.
I have already implemented within my program a button to add the openstreetmap layers with the BruTileLayer, now I have to implement a button that allows me to enter the parameters of a wms server to add wms layers in the control map but I couldn't find what classes I have to use.
Can anyone help me?
Developer
Jul 9, 2014 at 12:38 PM
Why don't you use the WebMap-Plugin? I think it does what you described.
Jul 9, 2014 at 12:42 PM
I tried to look WebMap-Plugin but I could not find anything.
Do you know where I can find some documentation or some example?
Thanks!
Developer
Jul 9, 2014 at 1:52 PM
See https://dotspatial.codeplex.com/discussions/521280 There is an explanation how to use WMS layers in WebMap plugin.
Jul 9, 2014 at 2:28 PM
Mogikanin thanks for the reply.
My program is in MFC not in framework. The entire management of the map control is inside a library framework linked by the program.
The control map is loaded into one of the views of the program.
When I click a button in a toolbar (MFC), I want to call a library method that opens the dialog "WMS Server Parameters" from which to choose the layer i want to load into my map control.
It's possible to do it by calling some class of the WebMap-Plugin?
Thanks!
Jul 10, 2014 at 10:57 AM
Analyzing the sources of the Webmap plugin I found the classes WmsServiceProvider and ServiceProviderFactory.
I used them trying to create the serviceprovider

Serviceprovider prov = ServiceProviderFactory.Create ("WMS");

or trying to create a list of providers to get WMS serviceprovider from the list

List <ServiceProvider> prov = new List <ServiceProvider> (ServiceProviderFactory.GetDefaultServiceProviders ());

but when it enters the Create method of the class ServiceProviderFactory gives me the error

"An unhandled exception of type 'System.ArgumentOutOfRangeException' occured in DotSpatial.Plugins.WebMap.dll Additional information: Startindex can not be less than zero."

It is correct to use these classes? I have to instantiate some other class before? Or I have to create them in a different way?
Thanks!
Developer
Jul 10, 2014 at 11:12 AM
Edited Jul 10, 2014 at 11:12 AM
Hi Angela,
Webmap plugin was developed to use it only as plugin (via AppManager). And at the moment you can't use it in another way. This plugin needed some deeper refactoring to allow such things which you want.

Maxim.
Jul 24, 2014 at 7:30 AM
Hi Maxim,
looking through discussions i have found this discussion

https://dotspatial.codeplex.com/discussions/346844

and i was able to access the functionality of the plugin Webmap without a framework gui.
Unfortunately I noticed that if I load a wms layer it doesn't have the transparent background and I didn't find methods in the plugin
to make the background transparent. So to enable this feature I had to modify two files: Webmapplugin.cs and AppManager.cs.

Inside dell'AppManager.cs I added two public fields:
public bool bTransparentBack = false;
public Color ColorBck = Color.White;
It can be changed at any time, then I changed the method "UpdateStichedBasemap" in WebMapPlugin.cs adding the following rows:
if (App.bTransparentBack == true) 
{
       stitchedBasemap.MakeTransparent (App.ColorBck); 
} 
immediately before the creation of InRanImageData.

The code of method became:
private void UpdateStichedBasemap(DoWorkEventArgs e)
        {
            var map = App.Map as Map;
            if (map == null) return;
            
            var bwProgress = (Func<int, bool>) (delegate(int p)
            {
                _bw.ReportProgress(p);
                if (_bw.CancellationPending)
                {
                    e.Cancel = true;
                    return false;
                }
                return true;
            });

            var rectangle = map.Bounds;
            var webMercExtent = map.ViewExtents;

            //Clip the reported Web Merc Envelope to be within possible Web Merc extents
            //  This fixes an issue with Reproject returning bad results for very large (impossible) web merc extents reported from the Map
            var webMercTopLeftX = TileCalculator.Clip(webMercExtent.MinX, TileCalculator.MinWebMercX, TileCalculator.MaxWebMercX);
            var webMercTopLeftY = TileCalculator.Clip(webMercExtent.MaxY, TileCalculator.MinWebMercY, TileCalculator.MaxWebMercY);
            var webMercBtmRightX = TileCalculator.Clip(webMercExtent.MaxX, TileCalculator.MinWebMercX, TileCalculator.MaxWebMercX);
            var webMercBtmRightY = TileCalculator.Clip(webMercExtent.MinY, TileCalculator.MinWebMercY, TileCalculator.MaxWebMercY);
            
            if (!bwProgress(25)) return;

            //Get the web mercator vertices of the current map view
            var mapVertices = new[] { webMercTopLeftX, webMercTopLeftY, webMercBtmRightX, webMercBtmRightY };
            double[] z = { 0, 0 };

            //Reproject from web mercator to WGS1984 geographic
            Reproject.ReprojectPoints(mapVertices, z, WebMercProj, Wgs84Proj, 0, mapVertices.Length / 2);
            var geogEnv = new Envelope(mapVertices[0], mapVertices[2], mapVertices[1], mapVertices[3]);
            
            if (!bwProgress(40)) return;

            //Grab the tiles
            var tiles = _tileManager.GetTiles(geogEnv, rectangle, _bw);
            if (!bwProgress(50)) return;

            //Stitch them into a single image
            var stitchedBasemap = TileCalculator.StitchTiles(tiles.Bitmaps, _opacity);
            if (App.bTransparentBack == true)
            {
                stitchedBasemap.MakeTransparent(App.ColorBck);
            }
            var tileImage = new InRamImageData(stitchedBasemap);

            //report progress and check for cancel
            if (!bwProgress(70)) return;

            // Tiles will have often slightly different bounds from what we are displaying on screen
            // so we need to get the top left and bottom right tiles' bounds to get the proper extent
            // of the tiled image
            var tileVertices = new[]
            {
                tiles.TopLeftTile.TopLeft().X, tiles.TopLeftTile.TopLeft().Y,
                tiles.BottomRightTile.BottomRight().X, tiles.BottomRightTile.BottomRight().Y
            };

            //Reproject from WGS1984 geographic coordinates to web mercator so we can show on the map
            Reproject.ReprojectPoints(tileVertices, z, Wgs84Proj, WebMercProj, 0, tileVertices.Length / 2);

            tileImage.Bounds = new RasterBounds(stitchedBasemap.Height, stitchedBasemap.Width,
                new Extent(tileVertices[0], tileVertices[3], tileVertices[2], tileVertices[1]));
            
            //report progress and check for cancel
            if (!bwProgress(90)) return;

            _baseMapLayer.Image = tileImage;
            
// ReSharper disable RedundantJumpStatement
            //report progress and check for cancel
            if (!bwProgress(99)) return;
// ReSharper restore RedundantJumpStatement
        }
This way I can add and show in map multiple WMS layers.

I hope this will be of help to others who need to do similar work.