User Tools

Site Tools


source_code_serviceseditionsample_multigeorasterlayer_cs_090728.zip

Source Code ServicesEditionSample MultiGeoRasterLayer CS 090728.zip

MultiGeoRasterLayer.cs

 using System;  
 using System.Collections;  
 using System.Collections.ObjectModel;  
 using System.IO;  
 using GisSharpBlog.NetTopologySuite.Geometries;  
 using GisSharpBlog.NetTopologySuite.Index.Strtree;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace MultiGeoRasterLayer  
 {  
     // IMPORTANT: You have to reference NetTopologySuite.dll & GeoApi.dll in your project.  They come with Map Suite.  
 
     // This class speeds up the loading of a large number of Raster layers by loading and drawing on demand only the files  
     // in the current extent.  Normally if you had 100 Raster files you would need to load 100 layers; however, this has performance  
     // issues--so we created this high level layer.  It loads a reference file that contains the bounding box, path and file information for  
     // all of the Raster files.  We load this information into an in-memory spatial index. When the map requests to draw the layer, we find the  
     // Rasters that are in the current extent, create a layer on-the-fly, call their Draw method and then close them.  In this way, we load  
     // on demand only the files that are in the current extent.  
 
     // I have also included a small routine to build a reference file from a directory of Raster files.  
 
     // Reference File Format: [UpperLeftPointX],[LowerRightPoint.X],[UpperLeftPoint.Y],[LowerRightPoint.Y],[Path|& File Name to Raster]  
 
     // Sample:  
     // -180.02197265625,-157.52197265625,-67.47802734375,-89.97802734375,..\..\App_Data\RasterImage\1.jpg  
     // -112.52197265625,-90.02197265625,-67.47802734375,-89.97802734375,..\..\App_Data\RasterImage\10.jpg  
     // 67.47802734375,89.97802734375,67.52197265625,45.02197265625,..\..\App_Data\RasterImage\100.jpg  
     // 89.97802734375,112.47802734375,67.52197265625,45.02197265625,..\..\App_Data\RasterImage\101.jpg  
 
     public class MultiGeoRasterLayer : Layer  
     {  
         private string rasterRefrencePathFileName;  
         private STRtree spatialIndex;  
         private double upperScale;  
         private double lowerScale;  
         private RectangleShape boundingBox;  
 
         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 MultiGeoRasterLayer()  
             : this(string.Empty, double.MaxValue, double.MinValue)  
         { }  
 
         public MultiGeoRasterLayer(string rasterRefrencePathFileName)  
             : this(rasterRefrencePathFileName, double.MaxValue, double.MinValue)  
         { }  
 
         public MultiGeoRasterLayer(string rasterRefrencePathFileName, double upperScale, double lowerScale)  
         {  
             this.rasterRefrencePathFileName = rasterRefrencePathFileName;  
             this.upperScale = upperScale;  
             this.lowerScale = lowerScale;  
             boundingBox = new RectangleShape();  
         }  
 
         public string RasterRefrencePathFileName  
         {  
             get { return rasterRefrencePathFileName; }  
             set { rasterRefrencePathFileName = value; }  
         }  
 
         public double UpperScale  
         {  
             get { return upperScale; }  
             set { upperScale = value; }  
         }  
 
         public double LowerScale  
         {  
             get { return lowerScale; }  
             set { lowerScale = value; }  
         }  
 
         // Here on the OpenCore we load our reference file and build the spatial index, which will be used in the DrawCore later.  
         // You need to make sure the reference file is in the right format as described in the comments above.  
         protected override void OpenCore()  
         {  
             if (File.Exists(rasterRefrencePathFileName))  
             {  
                 string[] rasterFiles = File.ReadAllLines(rasterRefrencePathFileName);  
                 spatialIndex = new STRtree(rasterFiles.Length);  
 
                 Collection<BaseShape> boundingBoxes = new Collection<BaseShape>();  
 
                 foreach (string rasterLine in rasterFiles)  
                 {  
                     string[] parts = rasterLine.Split(new string[] { "," }, StringSplitOptions.None);  
                     RectangleShape rasterBoundingBox = new RectangleShape(new PointShape(double.Parse(parts[upperLeftXPosition]), double.Parse(parts[upperLeftYPosition])), new PointShape(double.Parse(parts[lowerRightXPosition]), double.Parse(parts[lowerRightYPosition])));  
                     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();  
                 boundingBox = ExtentHelper.GetBoundingBoxOfItems(boundingBoxes);  
             }  
             else  
             {  
                 throw new FileNotFoundException("The Raster reference file could not be found.", rasterRefrencePathFileName);  
             }  
         }  
 
         // Here we set the spatial index to null to clean up the memory and get ready for serialization  
         protected override void CloseCore()  
         {  
             spatialIndex = null;  
         }  
 
         // When we get to the Draw, things are easy.  First we check to make sure we are within our scales.  
         // Next we look up the Raster files in the spatial index,  
         // then open their layer, call their Draw and close them.  
         protected override void DrawCore(GeoCanvas canvas, Collection<SimpleCandidate> labelsInAllLayers)  
         {  
             double currentScale = ExtentHelper.GetScale(canvas.CurrentWorldExtent, canvas.Width, canvas.MapUnit);  
 
             if (currentScale >= lowerScale && currentScale <= upperScale)  
             {  
                 RectangleShape currentExtent = canvas.CurrentWorldExtent;  
                 Envelope currentExtentEnvelope = new Envelope(currentExtent.UpperLeftPoint.X, currentExtent.LowerRightPoint.X, currentExtent.UpperLeftPoint.Y, currentExtent.LowerRightPoint.Y);  
                 ArrayList rasters = (ArrayList)spatialIndex.Query(currentExtentEnvelope);  
 
                 foreach (string file in rasters)  
                 {  
                     GdiPlusRasterLayer rasterRasterLayer = new GdiPlusRasterLayer(file);  
                     rasterRasterLayer.Open();  
                     rasterRasterLayer.Draw(canvas, labelsInAllLayers);  
                     rasterRasterLayer.Close();  
                 }  
             }  
         }  
 
         // Here we let everyone know we support having a bounding box  
         public override bool HasBoundingBox  
         {  
             get  
             {  
                 return true;  
             }  
         }  
 
         //  We use the cached bounding box we set in the OpenCore  
         protected override RectangleShape GetBoundingBoxCore()  
         {  
             return boundingBox;  
         }  
 
         // This is just a handy function to build a reference file from a directory.  
         // You can tailor this code to fit your needs.  
         public static void BuildReferenceFile(string newReferencepathFileName, string pathOfRasterFiles)  
         {  
             if (Directory.Exists(pathOfRasterFiles))  
             {  
                 string[] files = Directory.GetFiles(pathOfRasterFiles, "*.jpg");  
                 StreamWriter streamWriter = null;  
 
                 try  
                 {  
                     streamWriter = File.CreateText(newReferencepathFileName);  
 
                     foreach (string file in files)  
                     {  
                         GdiPlusRasterLayer rasterRasterLayer = new GdiPlusRasterLayer(file);  
                         rasterRasterLayer.Open();  
                         RectangleShape boundingBox = rasterRasterLayer.GetBoundingBox();  
                         rasterRasterLayer.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 Raster files could not be found.");  
             }  
         }  
     }  
 }  
 
 

Program.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Windows.Forms;  
 
 namespace MultiGeoRasterLayer  
 {  
     static class Program  
     {  
         /// <summary>  
         /// The main entry point for the application.  
         /// </summary>  
         [STAThread]  
         static void Main()  
         {  
             Application.EnableVisualStyles();  
             Application.SetCompatibleTextRenderingDefault(false);  
             Application.Run(new TestForm());  
         }  
     }  
 }  
 

TestForm.cs

 using System;  
 using System.Drawing;  
 using System.Windows.Forms;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace MultiGeoRasterLayer  
 {  
     public partial class TestForm : Form  
     {  
         private MapEngine mapEngine = new MapEngine();  
         private Bitmap bitmap = null;  
 
         public TestForm()  
         {  
             InitializeComponent();  
         }  
 
         private void TestForm_Load(object sender, EventArgs e)  
         {  
             // Set the full extent and the background color  
             mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height);  
             mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);  
 
             //Add MultiGeoRasterLayer to the MapEngine  
             MultiGeoRasterLayer.BuildReferenceFile(@"..\..\Data\referenceFile.txt", @"..\..\Data");  
             MultiGeoRasterLayer multiGeoRasterLayer = new MultiGeoRasterLayer(@"..\..\Data\referenceFile.txt");  
             mapEngine.StaticLayers.Add("MultiGeoRasterLayer", multiGeoRasterLayer);  
 
             DrawImage();  
         }  
 
 
         private void DrawImage()  
         {  
             if (bitmap != null) { bitmap.Dispose(); }  
             bitmap = new Bitmap(Map.Width, Map.Height);  
             mapEngine.OpenAllLayers();  
             mapEngine.DrawStaticLayers(bitmap, GeographyUnit.DecimalDegree);  
             mapEngine.CloseAllLayers();  
 
             Map.Image = bitmap;  
         }  
 
         private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)  
         {  
             switch (e.Button.Tag.ToString())  
             {  
                 case "Zoom In":  
                     mapEngine.CurrentExtent.ScaleDown(50);  
                     break;  
                 case "Zoom Out":  
                     mapEngine.CurrentExtent.ScaleUp(50);  
                     break;  
                 case "Full Extent":  
                     mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height);  
                     break;  
                 case "Pan Left":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Left, 20);  
                     break;  
                 case "Pan Right":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Right, 20);  
                     break;  
                 case "Pan Up":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Up, 20);  
                     break;  
                 case "Pan Down":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Down, 20);  
                     break;  
                 default:  
                     break;  
             }  
             DrawImage();  
         }  
 
         private void btnClose_Click(object sender, EventArgs e)  
         {  
             this.Close();  
         }  
     }  
 }  
 
source_code_serviceseditionsample_multigeorasterlayer_cs_090728.zip.txt · Last modified: 2015/09/09 03:18 by admin