Klaus,
Here is the code I whipped up. It uses a reference file and I included a static method to build it. Feel free to enhance this anyway you need to. The code is pretty simple and straight forward. Let me know if you have any questions. Also make sure to read the comments in the code, it explains everything.
David
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.IO;
using System.Collections.Generic;
using GisSharpBlog.NetTopologySuite.Index.Strtree;
using GisSharpBlog.NetTopologySuite.Geometries;
using GisSharpBlog.NetTopologySuite;
using System.Collections;
using ThinkGeo.MapSuite.Core;
//IMPORTANT: You have to reference NetTopologySuite.dll & GeoApi.dll in your project. They come with Map Suite.
// This class speeds up the loading of large number of GeoTiff layers by loading and drawing on deman just the files
// in the current extent. Normally if you had 100 GeoTiff files you would need to load 100 layers however this has performance
// issues so we created this high level layer. It loads a refrence file that contains the bounding box and path and file infromation for all of the
// GeoTiff files. We load this infromation into an in memeory spatial index. When the map requests to draw the layer we find the
// GeoTiff's that are in the current extent and create a layer on the fly and call their Draw method and close them. In this way we load
// on demand just the files that are in the current extent.
// I have also included a small routine to build a refrence file from a directory of GeoTiff files.
// Reference File Format: [UpperLeftPointX],[LowerRightPoint.X],[UpperLeftPoint.Y],[LowerRightPoint.Y],[Path & File Name to GeoTiff]
public class MultiGeoTiffLayer : Layer
{
string geoTiffRefrencePathFileName;
STRtree spatialIndex;
private const int upperLeftXPosition = 0;
private const int upperLeftYPosition = 2;
private const int lowerRightXPosition = 1;
private const int lowerRightYPosition = 3;
private const int pathFileNamePosition = 4;
public MultiGeoTiffLayer()
: this(string.Empty)
{}
public MultiGeoTiffLayer(string geoTiffRefrencePathFileName)
{
this.geoTiffRefrencePathFileName = geoTiffRefrencePathFileName;
}
public string GeoTiffRefrencePathFileName
{
get { return geoTiffRefrencePathFileName; }
set { geoTiffRefrencePathFileName = value; }
}
// Here on the OpenCore we load our reference file and build the spatial index for use int he DrawCore later.
// You need to make sure the reference file is in the right format as described above.
protected override void OpenCore()
{
if (File.Exists(geoTiffRefrencePathFileName))
{
string[] geoTiffFiles = File.ReadAllLines(geoTiffRefrencePathFileName);
spatialIndex = new STRtree(geoTiffFiles.Length);
foreach (string geoTiffLine in geoTiffFiles)
{
string[] parts = geoTiffLine.Split(new string[] { "," }, StringSplitOptions.None);
Envelope envelope = new Envelope(double.Parse(parts[upperLeftXPosition]), double.Parse(parts[lowerRightXPosition]), double.Parse(parts[upperLeftYPosition]), double.Parse(parts[lowerRightYPosition]));
spatialIndex.Insert(envelope, parts[pathFileNamePosition]);
}
spatialIndex.Build();
}
else
{
throw new FileNotFoundException("The GeoTiff reference file could not be found.", geoTiffRefrencePathFileName);
}
}
// When we get to the Draw things are easy. We lookup the GeoTiff files in the spatial index
// and then open their layer and call their Draw and close them.
protected override void DrawCore(GeoCanvas canvas, Collection<SimpleCandidate> labelsInAllLayers)
{
RectangleShape currentExtent = canvas.CurrentWorldExtent;
Envelope currentExtentEnvelope = new Envelope(currentExtent.UpperLeftPoint.X, currentExtent.LowerRightPoint.X, currentExtent.UpperLeftPoint.Y, currentExtent.LowerRightPoint.Y);
ArrayList geoTiffs = (ArrayList)spatialIndex.Query(currentExtentEnvelope);
foreach (string file in geoTiffs)
{
GeoTiffRasterLayer geoTiffRasterLayer = new GeoTiffRasterLayer(file);
geoTiffRasterLayer.Open();
geoTiffRasterLayer.Draw(canvas, labelsInAllLayers);
geoTiffRasterLayer.Close();
}
}
public static void BuildReferenceFile(string newReferencepathFileName, string pathOfGeoTiffFiles)
{
if (Directory.Exists(pathOfGeoTiffFiles))
{
string[] files = Directory.GetFiles(pathOfGeoTiffFiles, "*.ti*");
StreamWriter streamWriter = null;
try
{
streamWriter = File.CreateText(newReferencepathFileName);
foreach (string file in files)
{
GeoTiffRasterLayer geoTiffRasterLayer = new GeoTiffRasterLayer(file);
geoTiffRasterLayer.Open();
RectangleShape boundingBox = geoTiffRasterLayer.GetBoundingBox();
geoTiffRasterLayer.Close();
streamWriter.WriteLine(string.Format("{0},{1},{2},{3},{4}", boundingBox.UpperLeftPoint.X, boundingBox.LowerRightPoint.X, boundingBox.UpperLeftPoint.Y, boundingBox.LowerRightPoint.Y, file));
}
streamWriter.Close();
}
finally
{
if (streamWriter != null) { streamWriter.Dispose();}
}
}
else
{
throw new DirectoryNotFoundException("The path containing the GeoTiff files could not be found.");
}
}
}