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?
Cache Generator Crash
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