ThinkGeo.com    |     Documentation    |     Premium Support

Exception in WinformsMap

In my exploration of your desktop map control, I have stumbled onto an exception in your code when a PointStyle uses a character index with a Font that does not have a glyph defined at that index.  What it should do is either provide a "non printable character" place holder (like what happens with certain Asian characters on many systems), or "nothing", which is what your old pre-3.0 control apparently did.  The current control produces the following exception call stack in this scenario.



System.ArgumentException: The parameter you supplied may not be empty.

Parameter name: text

   at ohM=.ZWA=.4WA=(String 4mA=, String 42A=)

   at ThinkGeo.MapSuite.Core.GeoCanvas.DrawText(String text, GeoFont font, GeoBrush fillBrush, GeoPen haloPen, IEnumerable`1 textPathInScreen, DrawingLevel drawingLevel, Single xOffset, Single yOffset, Single rotateAngle)

   at ThinkGeo.MapSuite.Core.PointStyle.31w=(Int32 4Fw=, PointShape 4Vw=, GeoCanvas 4lw=, GeoBrush 41w=, GeoPen 5Fw=)

   at ThinkGeo.MapSuite.Core.PointStyle.2Vw=(Int32 2lw=, Feature 21w=, GeoCanvas 3Fw=, GeoBrush 3Vw=, GeoPen 3lw=)

   at ThinkGeo.MapSuite.Core.PointStyle.DrawCore(IEnumerable`1 features, GeoCanvas canvas, Collection`1 labelsInThisLayer, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.Style.Draw(IEnumerable`1 features, GeoCanvas canvas, Collection`1 labelsInThisLayer, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.ZoomLevel.DrawCore(GeoCanvas canvas, IEnumerable`1 features, Collection`1 currentLayerLabels, Collection`1 allLayerLabels)

   at ThinkGeo.MapSuite.Core.ZoomLevel.Draw(GeoCanvas canvas, IEnumerable`1 features, Collection`1 currentLayerLabels, Collection`1 allLayerLabels)

   at ThinkGeo.MapSuite.Core.ShapeFileFeatureLayer.sy4=(GeoCanvas yy4=, RectangleShape zC4=, Collection`1 zS4=, ZoomLevel zi4=, Collection`1 zy4=, Collection`1 0C4=, ShapeFileFeatureSource 0S4=, Collection`1 0i4=, Collection`1 0y4=)

   at ThinkGeo.MapSuite.Core.ShapeFileFeatureLayer.qS4=(GeoCanvas wy4=, RectangleShape xC4=, Collection`1 xS4=, ZoomLevel xi4=, Collection`1 xy4=, ShapeFileFeatureSource yC4=, Collection`1 yS4=, Collection`1 yi4=)

   at ThinkGeo.MapSuite.Core.ShapeFileFeatureLayer.DrawCore(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.Layer.Draw(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.DesktopEdition.LayerOverlay.DrawCore(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.axQ=(GeoCanvas bBQ=)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.Draw(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.shM=(IEnumerable`1 XRc=, RectangleShape Xhc=)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.sBM=(RectangleShape Wxc=, RectangleShape XBc=)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.9xM=(RectangleShape lRc=)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.7BM=(InteractionArguments jBc=)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.0hM=(Object dhc=, 0xU= dxc=)

   at ThinkGeo.MapSuite.DesktopEdition.MouseEventAnalyzer.OnMouseEvent(0xU= e)

   at ThinkGeo.MapSuite.DesktopEdition.MouseEventAnalyzer.whQ=(Double wxQ=, Double xBQ=, Double xRQ=, Double xhQ=, Int32 xxQ=)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.iRc=(Object ihc=, MouseEventArgs ixc=)

   at System.Windows.Forms.Control.OnMouseWheel(MouseEventArgs e)

   at System.Windows.Forms.Control.WmMouseWheel(Message& m)

   at System.Windows.Forms.Control.WndProc(Message& m)

   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Hi Russ, 
  
 Thanks for your detail information. 
  
 It looks this exception thrown because the text haven’t pass our validation, system think it’s a empty string.  
  
 I am sorry our strategy for handle exception is different between 3.0 and 8.0, but I think if the character cannot be known by system, it still be have a messy code there but not empty. So if possible, could you please upload a small sample contains test data, so we can look into it and found whether we have a solution for it? 
  
 Regards, 
  
 Don

I’ll try to get some time to create a repro for you, but it really is a just a missing glyph in the selected font.  In my case, I simply changed the character index to an index that has a valid glyph, and the exception no longer reproduced.  With that information and the call stack I think the dev team should be able to sort it out.  If not, I’ll see if I can put together something, but right now I’m looking at looming deadlines with no time to spare.

Hi Russ, 
  
 I don’t know how you detail implement that, but I think you should add many zoomLevel to the customZoomLevels of map. Then you should set the style for the customZoomLevels of your layer. 
  
 I did a test and found when we modify the customeZoomLevel and modify the style of layer, it still works. 
  
 Please see my test code as below and let me know if I misunderstand your question. 
  
  
private void SelectFeatures_Load(object sender, EventArgs e)
        {
            winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
            winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

            winformsMap1.ZoomLevelSet.CustomZoomLevels.Add(winformsMap1.ZoomLevelSet.ZoomLevel01);
            winformsMap1.ZoomLevelSet.CustomZoomLevels.Add(winformsMap1.ZoomLevelSet.ZoomLevel02);

            ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"…\SampleData\Data\Countries02.shp");
            worldLayer.ZoomLevelSet = winformsMap1.ZoomLevelSet;
            worldLayer.ZoomLevelSet.CustomZoomLevels[0].DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Transparent, GeoColor.FromArgb(100, GeoColor.SimpleColors.Green));
            worldLayer.ZoomLevelSet.CustomZoomLevels[1].DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Transparent, GeoColor.FromArgb(100, GeoColor.SimpleColors.Blue));

            LayerOverlay staticOverlay = new LayerOverlay();
            staticOverlay.Layers.Add(“WorldLayer”, worldLayer);
            winformsMap1.Overlays.Add(staticOverlay);

            winformsMap1.MapClick += new EventHandler<MapClickWinformsMapEventArgs>(winformsMap1_MapClick);

            winformsMap1.CurrentExtent = new RectangleShape(-139.2, 92.4, 120.9, -93.2);
            winformsMap1.Refresh();
        }

        void winformsMap1_MapClick(object sender, MapClickWinformsMapEventArgs e)
        {
            winformsMap1.ZoomLevelSet.CustomZoomLevels.Add(winformsMap1.ZoomLevelSet.ZoomLevel03);
            winformsMap1.ZoomLevelSet.CustomZoomLevels.Add(winformsMap1.ZoomLevelSet.ZoomLevel04);

            ((winformsMap1.Overlays[0] as LayerOverlay).Layers[0] as ShapeFileFeatureLayer).ZoomLevelSet.CustomZoomLevels[2].DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Transparent, GeoColor.FromArgb(100, GeoColor.SimpleColors.Yellow));
            ((winformsMap1.Overlays[0] as LayerOverlay).Layers[0] as ShapeFileFeatureLayer).ZoomLevelSet.CustomZoomLevels[3].DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Transparent, GeoColor.FromArgb(100, GeoColor.SimpleColors.Red));
        }
 
  
 Regards, 
  
 Don

Hi Russ, 
  
 Sorry I maybe misunderstand your problem in last reply. 
  
 Today I did a test like this: 
  
 

          PointStyle style = new PointStyle(new GeoFont(“Arial”, 12), 55555, new GeoSolidBrush(GeoColor.StandardColors.Black));
            style.PointType = PointType.Character;
 
 
  
 It only don’t shows any icon on map, but still won’t throw exception, so I still don’t know where is the problem, if you found anyway I can reproduce that it should be very helpful. 
  
 Regards, 
  
 Don

While doing some further exploration, I stumbled across one of your samples that could be easily adapted to reproduce the exception.  You should find that modified sample attached.  Inside the zip you will also find a TTF that I had specific experiences with a known index that had no glyph in the font.  So first you will need to install the TTF to your fonts, then run the project, you should get the exception indicated.  To avoid the exception, all you have to do is use an index with a valid glyph in the indicated font.  I’ve provided that as well, and you can see it run without crashing by simply commenting out the CRASH define at the top of the file.

CrashRepro.zip (90.2 KB)

Hi Russ,



I guess there should be something wrong with the setting of the FontStyle, please try the code as following:


internal static PointStyle GetFontPointStyle()
{
    PointStyle pointStyle = new PointStyle();
    pointStyle.PointType = PointType.Character;
    pointStyle.CharacterSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.Black);
    pointStyle.CharacterIndex = 170;
    pointStyle.Name = @"Font Point Style";
    pointStyle.CharacterFont = new GeoFont("TMap Symbols", 20);
 
    return pointStyle;
}



Thanks,

Johnny

Why try that code?  It’s not going to repro because for some reason you changed the character index.  The whole point of the repro I submitted was that it exposes a bug in your component when there is not a valid glyph in the font at character index specified.  When you change to a character index that has a glyph, you avoid the repro.  But just for the sake of giving it a shot, I pasted in your code, changed the index to 160 so as to test what was reported, and it crashes just the same as my original (basically equivalent) code did.

Russ, 



The only change you need to do is changing the “CharacterIndex” in the code I attached from “170” to “160”, Sorry for my mistake that I pasted 170 before. Then all works fine on my end, but it shows nothing on the vertexes, I did a double-check with some font visualization tool, I think it’s correct, because the font of “CharacterIndex” 160 is transparent blank. Could you let me know what’s the version you are using? Including the version of MapSuiteCore.dll and DesktopEdition.dll?  



From the exception you attached, I guess the error is caused by the missing of the “ColumnName” of TextStyle is missed,rather then the method “GetFontPointStyle” we are talking about. However, the weird thing is that all works fine for me when I was doing test with your sample. 



Waiting for your further information. 



Thanks, 

Johnny

Exactly.  And when I substituted your code directly, using 170, it works for me.  When I change your code to 160, I again get the same exception using your code with nothing changed but the index.  The only difference between exception and no exception is the index 160.  The only thing I can see is that if 170 (and others) work, then 160 (and I think 32 as well IIRC, there are others) should not result in a thrown exception stating "The parameter you supplied may not be empty" just because the glyph is missing, blank, zero sized, or whatever.  The exception indicates an empty string, and that is not what this is.   



MapSuiteCore.dll shows 8.0.0.160.

Ok, Russ, I have recreated the problem with the specific version, would you please update the DLL you are using to the latest version to have a try? It should be fixed sometime ago.I guess any Development or Product branch is ok. 
  
 Thanks, 
 Johnny

Will do.  In an effort to avoid "shifting sands", we always establish a base line and avoid updates unless specifically warranted.  Looks like we will be updating to the latest early next week.  Thank you for your assistance.

Welcome Russ, I guess you can try a stable release update after around 2 days, it’s version is 8.0.0.188. Please have a try and any questions please let me know. 
  
 Regards, 
 Johnny

Thanks for the insight.  I would rather make one update rather than risk potential multiple updates. 


Hi Russ, 
  
 If you get any question after upgrade, please feel free to let us know. 
  
 Thanks, 
  
 Kevin 


I’m just now back from extended holiday vacation and I am preparing to update 1 final time to the version that will (baring blockers) be used (frozen with no updates) for our initial implementation.  The current “Full Production” version is 8.0.0.209.  Is this a good version to lock in on?  Or is there anything on the horizon I should wait for?  Or possibly prefer a recent previous more stable version? 
  
 Also, our 3rd party library protocol requires us to be able to duplicate exact development environment, and of course configure the integration build to match.  So, the problem I have is that the only obvious way to get the current “full prod” version build installed is through the Product Center, which wants to download and run the install immediately.  I think I found links to download specific version install packages, but it’s not apparent to me now. I’ll keep looking while awaiting your advice on which version we should freeze on for the next integration and product cycle.  But if I haven’t posted an answer, it means I haven’t found it yet, so would appreciate a link I can use to download an install package that can be captured in our source/build repository.

Looks like I had to go through the “customer portal” to get the current as a downloadable zip for archiving.  I assume that unzipping and putting things in the “Current Version” and version specific folder is the same as running the Product Center updater? 
  
 helpdesk.thinkgeo.com/FullDownload 
  
 Though I didn’t see a way to get older version builds there.

Knowing that I would be unlikely to get a result until the early hours of the morning (here), I just tested with 8.0.0.209 (current full production), and it still has the same exception.  I’ve confirmed that the latest assembly (8.0.0.209) is the one referenced and loaded with my test. 
  
 So clearly we can’t move to and stabilize on this build.  Please retest and advise ASAP.

Hi Russ, 
  
 Please get 8.0.209.0 but not 8.0.0.209. I tested both of them, 8.0.209.0 works well and 8.0.0.209 throw exception. 
  
 If that’s proved fixed OK in 8.0.x.0 we will move the change to 8.0.0.x. 
  
 Regards, 
  
 Don

When will a production build be available?  We need an official production build to produce a stable base for our integration and push to release.  We cannot do that with an intermediate development build that will require at least one more update after we would normally expect a stable base, barring release blocking defect identification.