ThinkGeo.com    |     Documentation    |     Premium Support

Custom Point and Text Styles

I am using custom point and text styles and have run into a problem.  I need to set the scale of the item being drawn in the custom style.  I have several scale settings that I can get to, but I need to know the current scale of the WinformMap control to which the custom style is drawing.  I see a CurrentScale property of the window, but if I have multiple WinformMap controls in my project, I don't know which is active when drawing inside the custom style.  Is there a way around this problem?


My second question is what does the CurrentScale display?  The value of CurrentScale when I first open the project is 576749.


 


Charles



As I wade into drawing my custom point style I am running into other issues.  I thought I would use PNG images for my point symbols, but I find the image quality is not acceptable when I display them on a map.  I think that the problem is related to scaling but I don't think there is a solution involving image files.  The other choices in the PointType enum would be Character and Symbol.  As I understand these two, the first is a windows font character similar to WingDings and the second is built into MapSuite and not modifiable by the programmer.  Is this correct?  I have looked into creating Windows Fonts and the process appears complex and/or costly.  I think I need to draw vector graphics and the closest PointType would be Symbol (although I must admit I'm not sure exactly what your symbols are).  Is the symbol a vector graphic and, if so, is there any way I can create my own symbol collection for use inside of MapSuite?


Charles



Posted By Charles on 06-22-2009 07:43 AM 

I am using custom point and text styles and have run into a problem.  I need to set the scale of the item being drawn in the custom style.  I have several scale settings that I can get to, but I need to know the current scale of the WinformMap control to which the custom style is drawing.  I see a CurrentScale property of the window, but if I have multiple WinformMap controls in my project, I don’t know which is active when drawing inside the custom style.  Is there a way around this problem?


My second question is what does the CurrentScale display?  The value of CurrentScale when I first open the project is 576749.


 


Charles



Charles,
 
Hopefully, my following answers can give you some help.
 
For your first questions
I want to make myself understood the same page with you. Your idea is that we have one created CustomStyle which will be shared in 2 or more than 2 winformMaps used in the App.
 
During the drawing of the CustomStyle, you are trying to do is:
 
If(winformMap1)
{
            If(WinformMap1. CurrentScale < SomeSpeficiedScale1)
{
     Draw1
}
Else if( WinformMap1.CurrentScale < SomeSpecifiedScale2)
{
     Draw2
}
}
Else if( winformMap2)
{
           If(WinformMap2. CurrentScale < SomeSpeficiedScale3)
{
     Draw3
}
Else if( WinformMap2.CurrentScale < SomeSpecifiedScale4)
{
     Draw4
}
}
 
If I am understanding correctly, my suggestion is Create 2 separate CustomStyle, and ONLY one custom style is used for ONLY one winformMapControl. In the DrawCore override method, GetScale from the Canvas, and then do what you want to do, in this way, it will make things much easier and understood.

protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
{
   double scale = ExtentHelper.GetScale(canvas.CurrentWorldExtent, canvas.Width, canvas.MapUnit);

   if (scale > 10000)
   {
      PointStyle pointStyle = new PointStyle(PointSymbolType.Diamond, new GeoSolidBrush(GeoColor.SimpleColors.Red), new GeoPen(GeoColor.SimpleColors.Blue, 5), 10);
      pointStyle.Draw(features, canvas, labelsInThisLayer, labelsInAllLayers);
   }
   else
   {
      PointStyle pointStyle = new PointStyle(PointSymbolType.Star, new GeoSolidBrush(GeoColor.SimpleColors.Red), new GeoPen(GeoColor.SimpleColors.Blue, 5), 10);
      pointStyle.Draw(features, canvas, labelsInThisLayer, labelsInAllLayers);
   }
}

For your second questions


TheCurrentScale stands for the Scale of the WinformsMap control, of course, it will introduce some precision when calculation. I think your default value is 5765749 is reasonable somehow, it depends on your MapControl width.
 
In fact, you can see that this value depends on following 3 parameters:

ExtentHelper.GetScale(CurrentWorldExtent, winformsMap1.Width, winformsMap1.MapUnit);

Any more questions just let me know.


 
Thanks
 
Yale

Posted By Charles on 06-22-2009 08:58 AM 

As I wade into drawing my custom point style I am running into other issues.  I thought I would use PNG images for my point symbols, but I find the image quality is not acceptable when I display them on a map.  I think that the problem is related to scaling but I don’t think there is a solution involving image files.  The other choices in the PointType enum would be Character and Symbol.  As I understand these two, the first is a windows font character similar to WingDings and the second is built into MapSuite and not modifiable by the programmer.  Is this correct?  I have looked into creating Windows Fonts and the process appears complex and/or costly.  I think I need to draw vector graphics and the closest PointType would be Symbol (although I must admit I’m not sure exactly what your symbols are).  Is the symbol a vector graphic and, if so, is there any way I can create my own symbol collection for use inside of MapSuite?


Charles





 


Charles,
 
You can use the Character as following code showed:

GeoFont geoFont = new GeoFont(“wingdings”,12);
CustomPointStyle customPointStyle = new CustomPointStyle(geoFont, 200, new GeoSolidBrush(GeoColor.SimpleColors.Red));

About the Symbol PointType, I don’t think you can extend the items in PointSymbolType, butyou can use your own logic to create the vector image instead of using the logic built in MapSuite. 


Following is some code you can take reference.
 

protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
{
  if (PointType != PointType.Symbol)
  {
     base.DrawCore(features, canvas, labelsInThisLayer, labelsInAllLayers);
  }
  else
  {
     PointSymbolType pointSymbolType = SymbolType;

     if (pointSymbolType == PointSymbolType.Circle)
     {
       foreach (Feature feature in features)
       {
         // MapSuite default logic
         canvas.DrawEllipse(feature, SymbolSize, SymbolSize,SymbolPen, SymbolSolidBrush, DrawingLevel.LevelOne,XOffsetInPixel, YOffsetInPixel, PenBrushDrawingOrder.BrushFirst);

         //Create your own logic
       }
     }
   }
}

Any more questions just let me know.


Thanks
 
Yale

Yale, 



Thanks, the example was very useful.   What I am doing is continuously scaling the image based on the map window scale.   Rather than using a different Draw event, I set the image scale before I draw it.  I think the continuous scaling is the problem with images, which is why I asked about Symbols.  I can override the symbol all together and stroke out a vector version of our symbols.  The only problem with this approach is that our symbols are sometimes filled with the background color (simulating an opaque area), sometimes filled with the layer color (solid fill), sometimes transparent, and occasionally filled in more than one way in a single symbol.  The combination means I have to use multiple features to represent a symbol, which doesn't lend itself to editing. 



Can you think of any other options? 



Charles



I have modified my code to draw vector based symbols from our SQL Server Spatial Database. As it turns out I didn't need the map window scale to do this.  The resulting symbols looks good and drawing is quite fast.  By the way, the AreaBaseShape and LineBaseShape objects are great.  Now I need to look at drawing scalable text in my custom style.  I saw some code in the Desktop 2.0 forum that changes the font point size based on the scale.  This will work as long as the Font has a large enough selection of point sizes available.  I know that some fonts are rather limited in this area.  The GeoFont object requires a name and a size.  I see that the size is a float.  Is this different from a point size which would normally be an integer?  Can I use any font installed on the computer with the GeoFont object?  I have seen code that allows me to resize a windows font.  Is there any possibility of using a window font object in the constructor of the GeoFont in a future version of MapSuite? 



Charles



Charles, 


Hopefully my following answers can give you some hints!
 
 
Use multiple features to represent a symbol!
First, I think that depends on you, you can have your own logic to deal with this in the DrawCore of your own created “CustomPointStyle”.
 
 
Second,
The GeoFont is supposed to be equivalent to Font object provided in the System.Drawing namespace. It also gets a float font size.
 
Third,
I think probably you can only use the Font provided by the .net, any all, if you can use in System.Drawing.Font, then it should be supported in GeoFont.
 
Forth,
Because the GeoFont is supposed to be used in Canvas, no matter it is GdiPlusCanvas or WpfCanvas or other kinds of customized canvas. So I think if is very hard to be specified to accept a Font provided only in Gdi+ drawing system.
 
Any more problems just let me know.
 
Thanks.
 
Yale