ThinkGeo.com    |     Documentation    |     Premium Support

Cache Generator Crash

Since adding in my styling code into the generator, it keeps crashing with:

"An unhandled exception of type ‘System.IndexOutOfRangeException’ occurred in MapSuiteCore.dll
Additional information: Index was outside the bounds of the array."



It seems it is fine if I use one of the Line or Area styles, but when I’m using my custom styles it will crash the cache generator when calling layer.Draw(canvas, new Collection<SimpleCandidate()) in the DrawOnBitmap() function in the TileCacheGenerator.cs file. 



The styles work perfectly when I’m using it in my program. Only the cache generator tool seem to have issues with it. Any ideas on what may cause this?

Hi Jonci, 
  
 You said when you using your custom style that exception thrown, so that should related with how you write your custom style. 
  
 For help you quickly, could you please upload a simple sample, we can view your code and debug to trace the reason. 
  
 Regards, 
  
 Don

Sample code below. I can’t provide the data files used, however.






        public static Collection<Layer> GetLayersToCache()
        {
            Collection<Layer> layersToCache = new Collection<Layer>();
  
            ShapeFileFeatureLayer layer;
  
            layer = new ShapeFileFeatureLayer(@“C:\ThinkGeoFiles\62 Circles Green.shp”, ShapeFileReadWriteMode.ReadOnly);
            ApplyStyle(layer);
            layersToCache.Add(layer);
  
            
  
            return layersToCache;
}
         /// <summary>
        /// Returns the ZoomLevel reference based on int value passed in
        /// </summary>
        private static ZoomLevel GetZoomLevelByNumber(ShapeFileFeatureLayer layer, int zoomLevel)
        {
            Collection<ZoomLevel> levels = layer.ZoomLevelSet.GetZoomLevels();
            if (zoomLevel >= 1 && zoomLevel <= 20)
                return levels[zoomLevel - 1];
            return null;
        }
 
        private static void ApplyStyle(ShapeFileFeatureLayer layer)
        {
            ApplyStyle(layer, 1, ApplyUntilZoomLevel.Level03, -1, ApplyUntilZoomLevel.Level04, -1, ApplyUntilZoomLevel.Level08);
        }
        /// <summary>
        /// Sets up for 3 scale styles (high, medium, low), due to lines not scaling for zoom.
        /// </summary>
        private static void ApplyStyle(ShapeFileFeatureLayer layer, int highApplyFrom, ApplyUntilZoomLevel highApplyTo, int medApplyFrom, ApplyUntilZoomLevel medApplyTo, int lowApplyFrom, ApplyUntilZoomLevel lowApplyTo)
        {
            CopyZoomLevelsFromMap(layer);
            ShapeFileFeatureLayer.BuildIndexFile(layer.ShapePathFileName, BuildIndexMode.DoNotRebuild);
  
            layer.Open();
            ShapeFileType type = layer.GetShapeFileType();
            layer.Close();
            if (type == ShapeFileType.Polygon)
                ApplyHTMLAreaStyle(layer, GetZoomLevelByNumber(layer, highApplyFrom), lowApplyTo); // Just apply from high to low, because polygons scale properly.
            else if (type == ShapeFileType.Polyline)
                ApplyHTMLLineStyle(layer, GetZoomLevelByNumber(layer, highApplyFrom), highApplyTo, GetZoomLevelByNumber(layer, medApplyFrom), medApplyTo, GetZoomLevelByNumber(layer, lowApplyFrom), lowApplyTo);
            else if (type == ShapeFileType.Point)
            {
                layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.City1;
                layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            }
        }
  
        ///////////////////
        // Custom style classes
        class HTMLAreaStyle : AreaStyle
        {
            protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
            {
                double customWidth = 0;
                int customOpacity = 0;
                GeoColor customColor;
                string html;
                foreach (Feature feature in features)
                {
                    html = feature.ColumnValues[“HTML”];
                    if (html.StartsWith("##"))
                        html = html.Remove(0, 1);
                    if (html[0] != ‘#’)
                        html = “#” + html;
                    customWidth = Convert.ToDouble(feature.ColumnValues["#StrokeWei"]);
                    customOpacity = (int)(Convert.ToInt32(feature.ColumnValues["#Opacity"]) * 2.55);
                    customColor = GeoColor.FromHtml(html);
                    canvas.DrawArea(feature, this.OutlinePen, new GeoSolidBrush(GeoColor.FromArgb(customOpacity, customColor)), DrawingLevel.LevelOne, this.XOffsetInPixel, this.YOffsetInPixel, this.PenBrushDrawingOrder);
                }
            }
        }
  
        class HTMLLineStyle : LineStyle
        {
            protected int m_ScaleValue = 1;
            protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
            {
                double customWidth = 0;
                int customOpacity = 0;
                GeoColor customColor;
                string html;
                foreach (Feature feature in features)
                {
                    html = feature.ColumnValues[“HTML”];
                    if (html.StartsWith("##"))
                        html = html.Remove(0, 1);
                    if (html[0] != ‘#’)
                        html = “#” + html;
                    customWidth = Convert.ToDouble(feature.ColumnValues["#StrokeWei"]) * m_ScaleValue;
                    customOpacity = (int)(Convert.ToInt32(feature.ColumnValues["#Opacity"]) * 2.55);
                    customColor = GeoColor.FromHtml(html);
  
                    canvas.DrawLine(feature, new GeoPen(GeoColor.FromArgb(customOpacity, customColor), (float)customWidth), DrawingLevel.LevelOne);
                }
            }
        }
        class HTMLLineStyleMed : HTMLLineStyle
        {
            public HTMLLineStyleMed() : base() { m_ScaleValue = 5; }
        }
        class HTMLLineStyleLow : HTMLLineStyle
        {
            public HTMLLineStyleLow() : base() { m_ScaleValue = 10; }
        }






Hi Jonci, 
  
 Thanks for your codes, but seems there still are three methods missing: CopyZoomLevelsFromMap, ApplyHTMLAreaStyle and ApplyHTMLLineStyle. 
  
 I have reviewed your codes and not sure but just guess the issue might be related the zoom level applying which might be not matched. In order to debug it, We need to the missing methods or a sample can recreate the exception. 
  
 I just guess if our shape file "Countries02.shp" or any attached shape files in the installation folder can still recreate your issue? 
  
 Thanks, 
 Troy 



public static Collection<double> GetScalesToCache()
{
    ZoomLevelSet zls = new ZoomLevelSet();
 
    Collection<double> scalesToCache = new Collection<double>();
 
    zls.ZoomLevel01.Scale = 576749.794921875;
    zls.ZoomLevel02.Scale = 288374.8974609375;
    zls.ZoomLevel03.Scale = 72093.7243652344;
    zls.ZoomLevel04.Scale = 18023.43;
    zls.ZoomLevel05.Scale = 4505.85;
    zls.ZoomLevel06.Scale = 1126.46;
    zls.ZoomLevel07.Scale = 281.61;
    zls.ZoomLevel08.Scale = 100;
    zls.ZoomLevel09.Scale = 10;
    zls.ZoomLevel10.Scale = 0;
    zls.ZoomLevel11.Scale = 0;
    zls.ZoomLevel12.Scale = 0;
    zls.ZoomLevel13.Scale = 0;
    zls.ZoomLevel14.Scale = 0;
    zls.ZoomLevel15.Scale = 0;
    zls.ZoomLevel16.Scale = 0;
    zls.ZoomLevel17.Scale = 0;
    zls.ZoomLevel18.Scale = 0;
    zls.ZoomLevel19.Scale = 0;
    zls.ZoomLevel20.Scale = 0;
 
    scalesToCache.Add(zls.ZoomLevel01.Scale);
    scalesToCache.Add(zls.ZoomLevel02.Scale);
    scalesToCache.Add(zls.ZoomLevel03.Scale);
    scalesToCache.Add(zls.ZoomLevel04.Scale);
    scalesToCache.Add(zls.ZoomLevel05.Scale);
    scalesToCache.Add(zls.ZoomLevel06.Scale);
    scalesToCache.Add(zls.ZoomLevel07.Scale);
    scalesToCache.Add(zls.ZoomLevel08.Scale);
    scalesToCache.Add(zls.ZoomLevel09.Scale);
    scalesToCache.Add(zls.ZoomLevel10.Scale);
    scalesToCache.Add(zls.ZoomLevel11.Scale);
    scalesToCache.Add(zls.ZoomLevel12.Scale);
    scalesToCache.Add(zls.ZoomLevel13.Scale);
    scalesToCache.Add(zls.ZoomLevel14.Scale);
    scalesToCache.Add(zls.ZoomLevel15.Scale);
    scalesToCache.Add(zls.ZoomLevel16.Scale);
    scalesToCache.Add(zls.ZoomLevel17.Scale);
    scalesToCache.Add(zls.ZoomLevel18.Scale);
    scalesToCache.Add(zls.ZoomLevel19.Scale);
    scalesToCache.Add(zls.ZoomLevel20.Scale);
 
    return scalesToCache;
}
 
/// <summary>
/// Default style setting call
/// </summary>
private static void ApplyStyle(ShapeFileFeatureLayer layer)
{
    ApplyStyle(layer, 1, ApplyUntilZoomLevel.Level03, -1, ApplyUntilZoomLevel.Level04, -1, ApplyUntilZoomLevel.Level08);
}
/// <summary>
/// Sets up for 3 scale styles (high, medium, low), due to lines not scaling for zoom.
/// </summary>
private static void ApplyStyle(ShapeFileFeatureLayer layer, int highApplyFrom, ApplyUntilZoomLevel highApplyTo, int medApplyFrom, ApplyUntilZoomLevel medApplyTo, int lowApplyFrom, ApplyUntilZoomLevel lowApplyTo)
{
    CopyZoomLevelsFromMap(layer);
    ShapeFileFeatureLayer.BuildIndexFile(layer.ShapePathFileName, BuildIndexMode.DoNotRebuild);
 
    layer.Open();
    ShapeFileType type = layer.GetShapeFileType();
    layer.Close();
    if (type == ShapeFileType.Polygon)
        ApplyHTMLAreaStyle(layer, GetZoomLevelByNumber(layer, highApplyFrom), lowApplyTo); // Just apply from high to low, because polygons scale properly.
    else if (type == ShapeFileType.Polyline)
        ApplyHTMLLineStyle(layer, GetZoomLevelByNumber(layer, highApplyFrom), highApplyTo, GetZoomLevelByNumber(layer, medApplyFrom), medApplyTo, GetZoomLevelByNumber(layer, lowApplyFrom), lowApplyTo);
    else if (type == ShapeFileType.Point)
    {
        layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.City1;
        layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
    }
}
 
/// <summary>
/// Grabs the Map's set zoomlevels and applies them to layer passed in
/// </summary>
private static void CopyZoomLevelsFromMap(ShapeFileFeatureLayer layer)
{
    ZoomLevelSet zls = new ZoomLevelSet();
    Collection<double> scales = GetScalesToCache();
    zls.ZoomLevel01.Scale = scales[0];
    zls.ZoomLevel02.Scale = scales[1];
    zls.ZoomLevel03.Scale = scales[2];
    zls.ZoomLevel04.Scale = scales[3];
    zls.ZoomLevel05.Scale = scales[4];
    zls.ZoomLevel06.Scale = scales[5];
    zls.ZoomLevel07.Scale = scales[6];
    zls.ZoomLevel08.Scale = scales[7];
    zls.ZoomLevel09.Scale = scales[8];
    zls.ZoomLevel10.Scale = scales[9];
    zls.ZoomLevel11.Scale = scales[10];
    zls.ZoomLevel12.Scale = scales[11];
    zls.ZoomLevel13.Scale = scales[12];
    zls.ZoomLevel14.Scale = scales[13];
    zls.ZoomLevel15.Scale = scales[14];
    zls.ZoomLevel16.Scale = scales[15];
    zls.ZoomLevel17.Scale = scales[16];
    zls.ZoomLevel18.Scale = scales[17];
    zls.ZoomLevel19.Scale = scales[18];
    zls.ZoomLevel20.Scale = scales[19];
    layer.ZoomLevelSet = zls;
}
 
/// <summary>
/// Returns the ZoomLevel reference based on int value passed in
/// </summary>
private static ZoomLevel GetZoomLevelByNumber(ShapeFileFeatureLayer layer, int zoomLevel)
{
    Collection<ZoomLevel> levels = layer.ZoomLevelSet.GetZoomLevels();
    if (zoomLevel >= 1 && zoomLevel <= 20)
        return levels[zoomLevel - 1];
    return null;
}
 
private static void ApplyHTMLAreaStyle(ShapeFileFeatureLayer layer, ZoomLevel applyFrom, ApplyUntilZoomLevel applyTo)
{
    if (applyFrom != null)
    {
        HTMLAreaStyle areaStyle = new HTMLAreaStyle();
        areaStyle.RequiredColumnNames.Add("HTML");
        areaStyle.RequiredColumnNames.Add("#StrokeWei");
        areaStyle.RequiredColumnNames.Add("#Opacity");
        applyFrom.CustomStyles.Add(areaStyle);
        applyFrom.ApplyUntilZoomLevel = applyTo;
    }
}
 
private static void ApplyHTMLLineStyle(ShapeFileFeatureLayer layer, ZoomLevel highApplyFrom, ApplyUntilZoomLevel highApplyTo, ZoomLevel medApplyFrom, ApplyUntilZoomLevel medApplyTo, ZoomLevel lowApplyFrom, ApplyUntilZoomLevel lowApplyTo)
{
    // High level
    if (highApplyFrom != null)
    {
        HTMLLineStyle lineStyle = new HTMLLineStyle();
        lineStyle.RequiredColumnNames.Add("HTML");
        lineStyle.RequiredColumnNames.Add("#StrokeWei");
        lineStyle.RequiredColumnNames.Add("#Opacity");
 
        highApplyFrom.CustomStyles.Add(lineStyle);
        highApplyFrom.ApplyUntilZoomLevel = highApplyTo;
    }
    // Med level
    if (medApplyFrom != null)
    {
        HTMLLineStyleMed lineStyleMed = new HTMLLineStyleMed();
        lineStyleMed.RequiredColumnNames.Add("HTML");
        lineStyleMed.RequiredColumnNames.Add("#StrokeWei");
        lineStyleMed.RequiredColumnNames.Add("#Opacity");
 
        medApplyFrom.CustomStyles.Add(lineStyleMed);
        medApplyFrom.ApplyUntilZoomLevel = medApplyTo;
    }
    // Low level
    if (lowApplyFrom != null)
    {
        HTMLLineStyleLow lineStyleLow = new HTMLLineStyleLow();
        lineStyleLow.RequiredColumnNames.Add("HTML");
        lineStyleLow.RequiredColumnNames.Add("#StrokeWei");
        lineStyleLow.RequiredColumnNames.Add("#Opacity");
 
        lowApplyFrom.CustomStyles.Add(lineStyleLow);
        lowApplyFrom.ApplyUntilZoomLevel = lowApplyTo;
    }
}
 
class HTMLAreaStyle : AreaStyle
{
    protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
    {
        double customWidth = 0;
        int customOpacity = 0;
        GeoColor customColor;
        string html;
        foreach (Feature feature in features)
        {
            html = feature.ColumnValues["HTML"];
            if (html.StartsWith("##"))
                html = html.Remove(0, 1);
            if (html[0] != '#')
                html = "#" + html;
            customWidth = Convert.ToDouble(feature.ColumnValues["#StrokeWei"]);
            customOpacity = (int)(Convert.ToInt32(feature.ColumnValues["#Opacity"]) * 2.55);
            customColor = GeoColor.FromHtml(html);
            canvas.DrawArea(feature, this.OutlinePen, new GeoSolidBrush(GeoColor.FromArgb(customOpacity, customColor)), DrawingLevel.LevelOne, this.XOffsetInPixel, this.YOffsetInPixel, this.PenBrushDrawingOrder);
        }
    }
}
 
class HTMLLineStyle : LineStyle
{
    protected int m_ScaleValue = 1;
    protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
    {
        double customWidth = 0;
        int customOpacity = 0;
        GeoColor customColor;
        string html;
        foreach (Feature feature in features)
        {
            html = feature.ColumnValues["HTML"];
            if (html.StartsWith("##"))
                html = html.Remove(0, 1);
            if (html[0] != '#')
                html = "#" + html;
            customWidth = Convert.ToDouble(feature.ColumnValues["#StrokeWei"]) * m_ScaleValue;
            customOpacity = (int)(Convert.ToInt32(feature.ColumnValues["#Opacity"]) * 2.55);
            customColor = GeoColor.FromHtml(html);
 
            canvas.DrawLine(feature, new GeoPen(GeoColor.FromArgb(customOpacity, customColor), (float)customWidth), DrawingLevel.LevelOne);
        }
    }
}
class HTMLLineStyleMed : HTMLLineStyle
{
    public HTMLLineStyleMed() : base() { m_ScaleValue = 5; }
}
class HTMLLineStyleLow : HTMLLineStyle
{
    public HTMLLineStyleLow() : base() { m_ScaleValue = 10; }
}


Hi Jonci, 
  
 Sorry I still can’t recreate your issue with our existing shape files. I guess here are some ways you might try: 
 1. Send us the shape file to debug if possible. if the file size is too large, please send to forumsupport@thinkgeo.com 
 2. Comment out the DrawCore method of HTMLLineStyle and HTMLAreaStyle one by one to see if this part result to the issue. 
 3. Can you comparing with your program which works fine with the styles to see what’s the differences between it and the generator code? such as the scales and each zoomlevel styles you apply to. 
  
 Waiting for your further information. 
 Regards, 
 Troy