Hi,
some more question about raster layer:
If I use a lot of raster files (20+) from one directory / in an overlay I like to display only the files which are in the current extent of my map.
This should reduce memory and speed up performance.
How to set a maximum of Raster to be displayed?
Do you have a code snippet, please?!
Hardy
ECW / Raster
Hi Hartwig,
I hope following statements will be helpful:
RectangleShape maxExtent = new RectangleShape(-40, 40, 40, -40);
EcwRasterLayer ecw1 = new EcwRasterLayer(@"…\SampleData\World.ecw");
ecw1.Open();
RectangleShape ecw1Box = ecw1.GetBoundingBox();
if (ecw1Box.Intersects(rect))
{
//ToDo: implement appending this layer.
}
Thanks,
Lee
Lee,
I think there must be an event to hook up (after zooming, extent chaged, before overlay drawing) when to check if bounding box intersects the map’s bounding box and to set the ECW invisible.
What time is best to prevent ECW from drawing?
Regards
Hardy
Hi,
I think that overriding EcwRasterLayer and EcwRasterSource is better way as following statements snippet:
class CustomizeEcwRasterLayer : EcwRasterLayer
{
public CustomizeEcwRasterLayer(string pathName)
{
ImageSource = new CustomizeEcwRasterSource(pathName);
}
}
class CustomizeEcwRasterSource : EcwRasterSource
{
public CustomizeEcwRasterSource(string Path)
: base(Path)
{
}
public RectangleShape LimitedBoundingBox
{
get;
set;
}
protected override GeoImage GetImageCore(RectangleShape worldExtent, int canvasWidth, int canvasHeight)
{
GeoImage image = null;
if (LimitedBoundingBox != null)
{
if (LimitedBoundingBox.Intersects(GetBoundingBox()))
{
image = base.GetImageCore(worldExtent, canvasWidth, canvasHeight);
}
}
return image;
}
}
Thanks,
Hi,
I have found a working solution:
When the Map will draw the Overlays I’m checking if bounding boxes intersects. If not the ecw will be set to invisible.
That’s working well.
Regards
Hardy
Hi Hartwig,
Actually we did the same thing in the Layer.Draw(…) method, we just get the images in current boundingbox for drawing, could you give more description on this topic on what extent you would like to clip the image? A specific boundingbox or the extent of the map?
Thanks,
Johnny
Hi Johnny,
for me it’s important to check the current map/view extent.
If we have a customer with 100+ ECW’s in one Overlay the performance will be poor when all ECW’s are loaded.
So I define a maximum (4 tiles or 9 tiles for example).
When the user zooms to a feature I will check the bounding boxes.
If a tile is in the view I will set visibility = true and increment my counter +=1. If my counter will become maximum every other tile will be invisible.
So the map is dealing only with 4 or 9 tiles than 100+ and that’s ok for the user because a tile in general is 2 x 2 Km.
Hope my explanation is ok for you.
Regards
Hardy
Hi Hardy,
Thanks for your description, please try the code as following:
public
class
MultiEcwRasterLayer : RasterLayer
{
private
List<
string
> filePathNames;
private
Dictionary<EcwRasterLayer, RectangleShape> rasterLayers;
public
MultiEcwRasterLayer(IEnumerable<
string
> ecwFilePathNames)
{
this
.rasterLayers =
new
Dictionary<EcwRasterLayer, RectangleShape>();
this
.filePathNames =
new
List<
string
>(ecwFilePathNames);
}
protected
override
RectangleShape GetBoundingBoxCore()
{
RectangleShape bbox =
new
RectangleShape();
foreach
(var item
in
rasterLayers)
{
bbox.ExpandToInclude(item.Value);
}
return
bbox;
}
protected
override
void
OpenCore()
{
base
.OpenCore();
foreach
(
string
filePath
in
filePathNames)
{
EcwRasterLayer ecwRasterLayer =
new
EcwRasterLayer(filePath);
ecwRasterLayer.Open();
RectangleShape boundingBox = ecwRasterLayer.GetBoundingBox();
this
.rasterLayers.Add(ecwRasterLayer, boundingBox);
}
}
protected
override
void
DrawCore(GeoCanvas canvas, Collection<SimpleCandidate> labelsInAllLayers)
{
foreach
(var ecwLayer
in
this
.rasterLayers)
{
var layerBbox = ecwLayer.Value;
// todo: I guess you can do more check here to improve the performance
if
(ecwLayer.Value.Intersects(canvas.CurrentWorldExtent))
{
ecwLayer.Key.Draw(canvas, labelsInAllLayers);
}
}
}
}
Thanks,
Johnny
Hi Johnny,
I think you idea is a good alternative.
I have still done a solution which is working well:
1. Loading ECWs and set them invisible by default
Also set the Attribute “Attribution” from Overlay where ECW-Layers are in to the maximum tile counter (4 for example)
2. Handling the OverlayDrawing event
Private Sub TheMap_OverlayDrawing(sender As Object, e As OverlayDrawingWinformsMapEventArgs) Handles TheMap.OverlayDrawing
Dim theOverlay As LayerOverlay = e.Overlay
’looking for the maximum tile counter
If theOverlay.Attribution <> “” And theOverlay.IsVisible Then
Dim maxLayer As Integer = theOverlay.Attribution
For Each LayerCandidate In theOverlay.Layers
’is Layer intersecting?
If TheMap.CurrentExtent.Intersects(LayerCandidate.GetBoundingBox) Then
If maxLayer > 0 Then
LayerCandidate.IsVisible = True
OverlayTreeIsDirty = True
maxLayer -= 1
Else
LayerCandidate.IsVisible = False
End If
Else
LayerCandidate.IsVisible = False
End If
Next
End If
End Sub
So, thank you for your support.
It’s working fine.
Regards
Hardy
Cool, Hardy, I guess your solution is good as well. Anything else please feel free to let us know.
Regards,
Johnny
Hi Hartwig,
I’m glad to hear that. About the 2nd point, I think “Intersects” is better than the other way, the result of “Intersection” include internal geometry objects and intersecting geometry objects.
Thanks,