Brightness

Apr 27, 2009 at 6:34 PM
Hi Radioman,

I want to show barcharts etc in the OnRender. Based on your sample, that was not a real problem. However my map is now too "present", even with the Terrain type. But I couldn´t find something like brightness, alpha blending etc.

I made a small adjustment to your DrawMapGDIplus(Graphics g) method. I changed line
     g.DrawImageUnscaled(img.Img, Core.tileRect.X, Core.tileRect.Y);
into
     g.DrawImageUnscaled(AdjustBrightnessMatrix(img.Img, 60), Core.tileRect.X, Core.tileRect.Y);

the 60 is a brightness value from 0 to 255.

This is the procedure
public static Image AdjustBrightnessMatrix(Image img, int value)
        {
            // http://en.csharp-online.net/GDIplus_Graphics_Transformation%E2%80%94Translating_Colors
            // http://www.codeproject.com/KB/graphics/bitmapmanip.aspx
            if (value == 0) // No change, so just return
                return img;
            float sb = (float)value / 255F;

            float[][] colorMatrixElements = {
                 new float[]{1, 0,  0, 0f, 0f},
                new float[]{0, 1,  0, 0f, 0f},
                new float[]{0,  0,  1, 0f, 0f},
                new float[]{0f, 0f, 0f, 1f, 0f},
                new float[]{sb, sb, sb, 0f, 1f}};

            System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix(colorMatrixElements);
            System.Drawing.Imaging.ImageAttributes imgattr = new System.Drawing.Imaging.ImageAttributes();
            System.Drawing.Rectangle rc = new System.Drawing.Rectangle(0, 0, img.Width, img.Height);
            Bitmap newBmp = new Bitmap(img.Width, img.Height);
            //Create a graphics object attached to the bitmap
            Graphics g = Graphics.FromImage(newBmp);
            try
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                imgattr.SetColorMatrix(cm);
                g.DrawImage(img, rc, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgattr);
                //Clean everything up
                imgattr.Dispose();
                g.Dispose();
            }
            catch
            {

            }
            return newBmp;
        }
                                   
I hope you can incorporate something like the above.

Thanks,
Frank
Coordinator
Apr 27, 2009 at 7:07 PM
i'll try, i think i can make public property of System.Drawing.Imaging.ImageAttributes, so if its not null, it is used, also user can setup it if he wants, ok?
Apr 27, 2009 at 10:05 PM
That could work I guess and is faster and more generic than what I wrote.

However, keep in mind I had to copy the image like described above. First I tried using the Clone() option and later Graphics.FromImage(Stream), but some bitmaps resulted in failures.

Thanks radioman!

Frank

PS Why the nick? You're a electrical engineer, disc jockey, presenter, listener, radio beams are comming out of your ears...
Coordinator
Apr 28, 2009 at 12:58 PM
;] p.s. before enter programming i was interested in electronics, but now it's more like "radio beams are comming out of your ears..." ;D

...i was thinking what about painting transparent quad with brightness control on top of the map, i'll try to test these options...
Coordinator
Apr 28, 2009 at 1:19 PM
Edited Apr 28, 2009 at 1:20 PM
what about that:

using System.Drawing;
using System.Windows.Forms;

namespace Demo.WindowsForms
{
   public class Map : GMap
   {
      /// <summary>
      /// any custom drawing here
      /// </summary>
      /// <param name="drawingContext"></param>
      protected override void OnPaint(PaintEventArgs e)
      {
         base.OnPaint(e);

         // brightness control
         using(SolidBrush brush = new SolidBrush(Color.FromArgb(111, Color.Black)))
         {
           e.Graphics.FillRectangle(brush, 0, 0, Width, Height);
         }
      }
   }
}
Apr 28, 2009 at 2:26 PM
Hmm, don't get where you want to go. The component creates the map (via base.OnPaint) and afterwards I can do something with that?

That's not what I like. You've made the markers very friendly. I just put them on a list (with my own properties) and don't have to take care of that. I even can create a kind of drill-down option, when the user clicks on a marker another detail form can be created. I really like using that.

One solution (new feature) might be using layers, with each layer its own ImageAttributes, Visibility, etcetera. So you have the base layer (the map), but you can create as many layers as you like. A marker should then be linked to a layer.

Eg you have three types of markers (I don't mean parent-child relation ships): Large-Medium-Small. Now you have to color them or using different images or something like that. It could be very croudy.
I imagine a menu option with three tickboxes. When Large is ticked category "large markers" is visible, unticked ones are invisible. I'm using MapInfo and that is what they do there as well, but also for the different maps itself (but that is impossible for GMap I assume). Of course this can all be programmed by me (just updating the marker list).

What I miss here (at least I didn't find it): areas. Eg a country, territory, postal codes areas. I have those maps and I don't know how to get these into GMaps. I create bar charts per area (I have the geocentre of these areas, and I draw a bar chart at that point via a marker). Much nicer would be adding an area as a layer with ImageAttributes. So you'll see the bounding of a postal code area.

Sorry radioman, I just let my mind go. It is really no problem if you say something like: "in the next major release", or "forget it".
Frank.
Coordinator
Apr 28, 2009 at 3:16 PM
yeah, overlays would be cool!
Apr 29, 2009 at 8:55 AM
Hi  frankvandenbergh ,

I too use mappoint and am very interested how i could get post code areas and territory into this map control, i am in the UK, do you have those territory details, and if so how do i get them ??? also how are you drawing BarCharts at marker points, is it possible for you to provide me with an example,

Thanks,
Paul.

Apr 29, 2009 at 10:23 AM
Hi Paul,

I'm not using areas yet. As I first want to know if it is possible to create areas. Radioman didn't answer that yet. Probably I can create Routes or something like that, but I want to fill the inner. I converted the MapInfo files using fGis (http://www.forestpal.com/fgis.html) into SHP files.I think the main problem would be having way too many points (I mean too much detail). If you are on a low zoom level (eg Europe visible) you want to see the first two digits postal codes where boundaries are just a straigth line from corner to corner. If you zoom in to the max you may want to see PC 4/5 with boundaries that follow the correct path. So I would think creating subsets of PC 4/5, eg one super detailed for zoomlevel 15, one less detailed for zoomlevel 14, etcetera. The maps itself can only be bought I think, I don't think these can be acquired for free somewhere. Our Dutch national bureau for statstics (CBS) provides municipality maps for free. But I don't think TNT/Royal Mail will provide postal code areas. Once you have a postal code area you can easily create your own territories by merging postal code areas.

One option might be to draw the areas by yourself. After the map is finished painting, paint over de territories. Just a thought. But hey, I downloaded this component last weekend, so I'm not an expert.

This is what I did to test my bar chart. Improvements are always welcome to hear.
I put some general values in here, just for explination. In the GMapMarker class I added a property Value, which gives the absolute value of that marker.
I also colored an image, based on the value. The two commented out lines refer to that.

        public override void OnRender(Graphics g)
        {
            if (Value >= 0)
            {
                Image imag = Demo.WindowsForms.MainForm.busstop.Clone() as Image;
                int maxValue = 300;
                int minValue = 40;
                double factor = (Value - minValue) / maxValue;
                int black = 255 - (int)(factor * 255);
                if (black < 1)
                    black = 1;
                else if (black > 255)
                    black = 255;

                // leave this
                //AdjustBrightnessMatrix(imag, black);
                //g.DrawImageUnscaled(imag, LocalPosition.X - 10, LocalPosition.Y - 10);

                int Height = 20;
                Height = (int)(((double)Value / (double)maxValue) * 30);
                if (Height > 50)
                    Height = 50;
                int Width = 10;
                int leftBar = LocalPosition.X - (Width / 2);
                int topBar = LocalPosition.Y - Height;

                if (Demo.WindowsForms.MainForm.zoomLevel > 8)
                {
                    // create a shadow
                    Pen whitePen = new Pen(Color.DarkGray, 1);
                    System.Drawing.Rectangle r1 = new System.Drawing.Rectangle(leftBar - 5, topBar - 5, Width + 10, Height + 10);
                    System.Drawing.Drawing2D.LinearGradientBrush hb1 = new System.Drawing.Drawing2D.LinearGradientBrush(r1, Color.WhiteSmoke, Color.White, System.Drawing.Drawing2D.LinearGradientMode.ForwardDiagonal);
                    g.FillRectangle(hb1, r1);
                    g.DrawRectangle(whitePen, r1);
                }
                System.Drawing.Rectangle r = new System.Drawing.Rectangle(leftBar, topBar, Width, Height);
                System.Drawing.Drawing2D.HatchBrush hb = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal, Color.Green, Color.Black);
                int bottomBar = topBar + Height;
                g.FillRectangle(hb, r);
                // draw a base line
                Pen blackPen = new Pen(Color.Black, 1);
                g.DrawLine(blackPen, leftBar - 3, bottomBar, leftBar + Width + 3, bottomBar);
            }
            else g.DrawImageUnscaled(Demo.WindowsForms.MainForm.busstop, LocalPosition.X - 10, LocalPosition.Y - 10);
        }

It is not 3D. I tested this with about 700 markers. This is not perfect, its base line is on the centre of the marker. But the tooltip is around the marker, so if you move just below the mini-bar, you'll also get the tooltip. Which is not really a problem. The tooltip-move-over area is a circle, but you probably want to have it just around the bar (eg more like a ellipse/rectangle with another centre or with dimensions). I don't know if that is possible.

Good luck and let me know how it works out,
Frank.

Apr 29, 2009 at 10:31 AM
Thanks very much frank for you detailed example and explination.  I will look at fGis to see what i get do with MapPoint data.  I hope we can get Overlays working on this control also.
Thanks again.
Paul.
Apr 29, 2009 at 10:45 AM
Hi Paul,

I just saw Microsoft Mappoint 2009 is available for Europe. I might be using it to create territories. Is that easy? And I'm also interested in your search to create shape files (or usable files).
Google resulted in http://www.mpsupershape.com/
You might have a look there as well.

I don't think fGis is capable.

Frank.