DotSpatial and WMS

Nov 27, 2010 at 11:09 PM

Hi everybody.
I'm evaluating DotSpatial to build a .NET app. Till now, everything I've seen fulfills our requirements, except that I've not been able to check if it's possible to add a base WMS map for this app. I have read that there are some people that have added a WMS map with MapWindow 6 ocx and the Online Data Plugin, but I haven't found nothing about DotSpatial.

Can somebody confirm if it is possible to add a base WMS map to a DotSpatial C# (.NET) app? Could you give some insights about how to get it to work?

Thanks in advance,

Santiago

Developer
Nov 28, 2010 at 2:07 PM

Santiagol, Hi, and welcome.  I have not made a class that is as simple to use as pointing towards a WMS url and it works, or a simple drop down on the UI to show WMS layers.  Right now the folks that have gotten WMS working have learned how to use the current Map extents and query a WMS server to get back an image.  Once you have an image, you can create a DotSpatial.Data.InRamImageData object from the image that you retrieved.  You will need to set up the RasterBounds for the image, specifying the NumRows, NumCols, and at least the Extent, but even better an affine array.  For an image with no skew, the affine array is a 6 doubles like:

double[] affine = new double[] { topLeftCellCenter.X, cellWidth, 0, topLeftCellCenter.Y, 0, -cellHeight}

Then add that InRamImageData to the map.  If your image server is in a different projection from the map, as of the 11/27/2010 changeset, you can reproject the InRamImageData, but that means you will need to set the projection correctly first.  Apparently many servers use the WebMercator geographic trasnformation, but I won't know specifically in your case.  Reprojection just changes the affine, and so is fast.  It will not try to apply complicated distortions to your image.  This new feature will also be available as of today's release if you don't want to use the source code.

Finally, you can handle the Map.ViewExtentsChanged (this event on the map is available in this name only from the repository, but will be made available by the release version released today)  When the extents change you can download another image.  Create a new InRamImageData from the image, and set it to the DataSet property on your image layer.  Call Invalidate on the Map.MapFrame to force the buffer to redraw and then Map.Invalidate to force the map to refresh itself.  Whatever you do, do not alter the Map's extents in response to this, or you will create an infinite loop.  I do not know if this will be enough for you, but we do not currently have a point and shoot WMS implementation, but it is a high demand feature, so I would not be surprized to see it come along soon.  It could be written as an App as well.

Ted

Nov 29, 2010 at 10:40 PM

Hi, Shade, thank you very much for your detailed information. I'm new with DotSpatial and also with Visual Studio C#, but I will try to implement the solution you gave me. At this moment, I'm able to generate an image of the desired geographical extent from the WMS server in JPG or PNG format (it doesn't matter). What I need is to draw the image from the WMS server (EPSG:4326) in the map and next draw over it a shapefile (also EPSG:4326). So, as I told you I will work a bit with your guidelines trying to implement my solution.

When I finish (if I can) I will try to explain the solution in this Dot Spatial Developer Forum.

Anyway, before reading your answer, I was working on something different. I was trying to create a new class from the original DotSpatial.Controls.Map, with the ability to make it really transparent. The objective was to load the image from the WMS Server in a "panel" control (for example) and put over it a "transparent" DotSpatial.Controls.Map, in which I load the shapefile. I've been googleing about the possibility to make a control transparent and I found a possible solution based in the following code:

namespace WindowsFormsApplication1{

    public class mapTransp : DotSpatial.Controls.Map

    {

        public mapTransp()

        {

        }

        protected override CreateParams CreateParams

        {

            get

            {

                CreateParams cp = base.CreateParams;

                cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT

                return cp;

            }

        }

        protected override void OnPaintBackground(PaintEventArgs pevent)

        {

            //do not allow the background to be painted

         }

    }

}

But, till now, I'm not been able to make it work because it seems that, when I load the shapefile in the mapTransp control, the parts with no features keep white with no transparency.

Thank you very much again.

Santiago.

Developer
Nov 30, 2010 at 12:05 AM

I thought we had support for a background color.  If you set the background color to transparent, do you still see white?  My concern here is this.  When we "clear" content, we need to draw solid somewhere or else it never gets rid of the old stuff.  As in, if you take a transparent bitmap and draw it on top of the control with the GDI+ graphics object, it won't erase the previous content drawn on the control.  If we wanted to properly implement transparent control technology, we would have to do something like draw the background color solid in step 1, then use a color replacement scheme in step 2.  The problem is, the color replacement scheme and solid color scheme must both be drawn directly to the control or else any existing opaque content on the control won't go away.  This means that you would see a flickering of the solid color before it when transparent again.  I do think there is a method like "Clear" on the graphics object, where you can specify a color to "clear" with.  What I don't know is if specifying a transparent color will actually remove the content.

The transparent control technique you are using is an unmanaged API trick, and I have worked with it before.  It creates some strange effects when you are moving content around.  If the control will not move relative to the background, it may not be an issue, but when I moved the control over other stuff, it drew the background content with a slight delay so you got the impression of something being there, like looking through glass or something.  Also your trick may not be portable to other operating systems, but that may not matter in your case.  We may or may not support a background image.  We did at one time, but I think that may have been nixed in the revisions.

Ted

Developer
Nov 30, 2010 at 1:19 PM

Try setting the Map control background color to Transparent in VS Designer. We definitely initialize the bitmap with that color before drawing. I’m using a non-white back color all the time in my app. Haven’t tried transparent, but it should work.

Kyle

From: shade1974 [mailto:notifications@codeplex.com]
Sent: Monday, November 29, 2010 7:06 PM
To: kellison@geocue.com
Subject: Re: DotSpatial and WMS [DotSpatial:236245]

From: shade1974

I thought we had support for a background color. If you set the background color to transparent, do you still see white? My concern here is this. When we "clear" content, we need to draw solid somewhere or else it never gets rid of the old stuff. As in, if you take a transparent bitmap and draw it on top of the control with the GDI+ graphics object, it won't erase the previous content drawn on the control. If we wanted to properly implement transparent control technology, we would have to do something like draw the background color solid in step 1, then use a color replacement scheme in step 2. The problem is, the color replacement scheme and solid color scheme must both be drawn directly to the control or else any existing opaque content on the control won't go away. This means that you would see a flickering of the solid color before it when transparent again. I do think there is a method like "Clear" on the graphics object, where you can specify a color to "clear" with. What I don't know is if specifying a transparent color will actually remove the content.

The transparent control technique you are using is an unmanaged API trick, and I have worked with it before. It creates some strange effects when you are moving content around. If the control will not move relative to the background, it may not be an issue, but when I moved the control over other stuff, it drew the background content with a slight delay so you got the impression of something being there, like looking through glass or something. Also your trick may not be portable to other operating systems, but that may not matter in your case. We may or may not support a background image. We did at one time, but I think that may have been nixed in the revisions.

Ted

Read the full discussion online.

To add a post to this discussion, reply to this email (DotSpatial@discussions.codeplex.com@discussions.codeplex.com)

To start a new discussion for this project, email DotSpatial@discussions.codeplex.com@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com