User Tools

Site Tools


source_code_serviceseditionsample_cachegenerator_cs_120619.zip

Source Code ServicesEditionSample CacheGenerator CS 120619.zip

CacheGeneratorProgressChangedEventArgs.cs

 using System.ComponentModel;  
 
 namespace CacheGenerator  
 {  
     class CacheGeneratorProgressChangedEventArgs : ProgressChangedEventArgs  
     {  
         private int currentTileIndex;  
         private long totalTileCount;  
 
         public int CurrentTileIndex  
         {  
             get { return currentTileIndex; }  
             set { currentTileIndex = value; }  
         }  
 
         public long TotalTilesCount  
         {  
             get { return totalTileCount; }  
             set { totalTileCount = value; }  
         }  
 
         private CacheGeneratorProgressChangedEventArgs()  
             : this(0, null, 0, 0)  
         { }  
 
         public CacheGeneratorProgressChangedEventArgs(int progressPercentage, object userState, int currentTileIndex, long totalTilesCount)  
             : base(progressPercentage, userState)  
         {  
             this.currentTileIndex = currentTileIndex;  
             this.totalTileCount = totalTilesCount;  
         }  
     }  
 }  
 

CreatingCellsArgument.cs

 using ThinkGeo.MapSuite.Core;  
 
 namespace CacheGenerator  
 {  
     class CreatingCellsArgument  
     {  
         private FileBitmapTileCache tileCache;  
         private long currentRowIndex = 0;  
         private long currentColumnIndex = 0;  
         private long rowCount;  
         private long columnCount;  
         private double cellWidth;  
         private double cellHeight;  
         private double startRowIndex;  
         private double startColumnIndex;  
 
         public CreatingCellsArgument()  
         { }  
 
         public FileBitmapTileCache TileCache  
         {  
             get { return tileCache; }  
             set { tileCache = value; }  
         }  
         public long CurrentRowIndex  
         {  
             get { return currentRowIndex; }  
             set { currentRowIndex = value; }  
         }  
         public long CurrentColumnIndex  
         {  
             get { return currentColumnIndex; }  
             set { currentColumnIndex = value; }  
         }  
         public long RowCount  
         {  
             get { return rowCount; }  
             set { rowCount = value; }  
         }  
         public long ColumnCount  
         {  
             get { return columnCount; }  
             set { columnCount = value; }  
         }  
         public double CellWidth  
         {  
             get { return cellWidth; }  
             set { cellWidth = value; }  
         }  
         public double CellHeight  
         {  
             get { return cellHeight; }  
             set { cellHeight = value; }  
         }  
         public double StartRowIndex  
         {  
             get { return startRowIndex; }  
             set { startRowIndex = value; }  
         }  
         public double StartColumnIndex  
         {  
             get { return startColumnIndex; }  
             set { startColumnIndex = value; }  
         }  
 
         public RectangleShape GetCurrentCellExtent()  
         {  
             RectangleShape boundingBox = TileCache.TileMatrix.BoundingBox;  
             PointShape upperLeftPoint = new PointShape(boundingBox.UpperLeftPoint.X + CurrentColumnIndex * CellWidth + StartColumnIndex * CellWidth, boundingBox.UpperLeftPoint.Y - CurrentRowIndex * CellHeight - StartRowIndex * CellHeight);  
             PointShape lowerRightPoint = new PointShape(boundingBox.UpperLeftPoint.X + (CurrentColumnIndex + 1) * CellWidth + StartColumnIndex * CellWidth, boundingBox.UpperLeftPoint.Y - (CurrentRowIndex + 1) * CellHeight - StartRowIndex * CellHeight);  
             RectangleShape totalExtent = new RectangleShape(upperLeftPoint, lowerRightPoint);  
             return totalExtent;  
         }  
     }  
 }  
 

CreatingTilesArgument.cs

 using System;  
 using System.Collections.Generic;  
 using System.Text;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace CacheGenerator  
 {  
     class CreatingTilesArgument  
     {  
         private FileBitmapTileCache tileCache;  
         private RectangleShape extent;  
         private int bitmapWidth;  
         private int bitmapHeight;  
 
         public CreatingTilesArgument(FileBitmapTileCache tileCache, RectangleShape extent, int bitmapWidth, int bitmapHeight)  
         {  
             this.tileCache = tileCache;  
             this.extent = extent;  
             this.bitmapWidth = bitmapWidth;  
             this.bitmapHeight = bitmapHeight;  
         }  
 
         public FileBitmapTileCache TileCache  
         {  
             get { return tileCache; }  
             set { tileCache = value; }  
         }  
 
         public RectangleShape Extent  
         {  
             get { return extent; }  
             set { extent = value; }  
         }  
 
         public int BitmapWidth  
         {  
             get { return bitmapWidth; }  
             set { bitmapWidth = value; }  
         }  
 
         public int BitmapHeight  
         {  
             get { return bitmapHeight; }  
             set { bitmapHeight = value; }  
         }  
     }  
 }  
 

LayerProvider.cs

 using System.Collections.ObjectModel;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace CacheGenerator  
 {  
     class LayerProvider  
     {  
         // You can insert your layer to "layersToCache" in this function, they will be used for cache.  
         public static Collection<Layer> GetLayersToCache()  
         {  
             Collection<Layer> layersToCache = new Collection<Layer>();  
 
             ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(@"..\..\App_Data\cntry02.shp", ShapeFileReadWriteMode.ReadOnly);  
             layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;  
             layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             layersToCache.Add(layer);  
 
             return layersToCache;  
         }  
 
         // You can insert your scales to "scalesToCache" in this function, they will be used for cache.  
         public static Collection<double> GetScalesToCache()  
         {  
             ZoomLevelSet zoomLevelSet = new ZoomLevelSet();  
 
             Collection<double> scalesToCache = new Collection<double>();  
             scalesToCache.Add(zoomLevelSet.ZoomLevel01.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel02.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel03.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel04.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel05.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel06.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel07.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel08.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel09.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel10.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel11.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel12.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel13.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel14.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel15.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel16.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel17.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel18.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel19.Scale);  
             scalesToCache.Add(zoomLevelSet.ZoomLevel20.Scale);  
 
             return scalesToCache;  
         }  
     }  
 }  
 

MainForm.cs

 using System;  
 using System.Collections.ObjectModel;  
 using System.Drawing;  
 using System.Text;  
 using System.Windows.Forms;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace CacheGenerator  
 {  
     public partial class MainForm : Form  
     {  
         delegate void InvokeMethod();  
         DateTime startTime;  
         TileCacheGenerator tileCacheGenerator;  
         GeographyUnit mapUnit = GeographyUnit.DecimalDegree;  
 
         public MainForm()  
         {  
             InitializeComponent();  
         }  
 
         private void CachedImagesGenerateroForm_Load(object sender, EventArgs e)  
         {  
             cmbStartZoomLevel.Text = "ZoomLevel01";  
             cmbEndZoomLevel.Text = "ZoomLevel07";  
             cmbTileImageType.Text = "PNG";  
         }  
 
         private Collection<double> GetScalesToCache()  
         {  
             Collection<double> scales = LayerProvider.GetScalesToCache();  
 
             if (cmbStartZoomLevel.SelectedIndex > cmbEndZoomLevel.SelectedIndex)  
             {  
                 cmbStartZoomLevel.SelectedIndex = cmbEndZoomLevel.SelectedIndex;  
             }  
             Collection<double> scalesToCache = new Collection<double>();  
             for (int i = cmbStartZoomLevel.SelectedIndex; i <= cmbEndZoomLevel.SelectedIndex; i++)  
             {  
                 scalesToCache.Add(scales[i]);  
             }  
 
             return scalesToCache;  
         }  
 
         private void btnGenerate_Click(object sender, EventArgs e)  
         {  
             btnGenerate.Enabled = false;  
 
             tileCacheGenerator = new TileCacheGenerator();  
             tileCacheGenerator.ProgressChanged += new EventHandler<CacheGeneratorProgressChangedEventArgs>(tileCacheGenerator_ProgressChanged);  
             tileCacheGenerator.GenerationCompleted += new EventHandler<EventArgs>(tileCacheGenerator_GenerationCompleted);  
 
             if (cmbTileImageType.Text.ToUpperInvariant() == "PNG")  
             {  
                 tileCacheGenerator.TileImageFormat = TileImageFormat.Png;  
             }  
             else if (cmbTileImageType.Text.ToUpperInvariant() == "JPEG")  
             {  
                 tileCacheGenerator.TileImageFormat = TileImageFormat.Jpeg;  
                 tileCacheGenerator.JpegQuality = Int16.Parse(txtJpegQuality.Text);  
             }  
 
             tileCacheGenerator.ScalesToCache = GetScalesToCache();  
             tileCacheGenerator.LayersToCache = LayerProvider.GetLayersToCache();  
 
             string[] upperLeftPointInString = txtUpperLeftX.Text.Split(',');  
             string[] lowerRightPointInString = txtLowerRightX.Text.Split(',');  
             tileCacheGenerator.CachingExtent = new RectangleShape(double.Parse(upperLeftPointInString[0]), double.Parse(upperLeftPointInString[1]), double.Parse(lowerRightPointInString[0]), double.Parse(lowerRightPointInString[1]));  
 
             if (checkBoxWatermark.Checked)  
             {  
                 tileCacheGenerator.WatermarkBitmap = new Bitmap(txtWatermarkPath.Text);  
             }  
 
             if (checkBoxRestrict.Checked)  
             {  
                 tileCacheGenerator.RestrictShapeFilePathName = txtRestrictionLayerPath.Text;  
 
                 int gridSize = Convert.ToInt32(txtGridSize.Text);  
                 if (gridSize != 0)  
                 {  
                     GridRestrictionLayer(txtRestrictionLayerPath.Text, tileCacheGenerator.CachingExtent, gridSize, txtRestrictionLayerPath.Text.Replace(".shp", "_Grid.shp"));  
                     tileCacheGenerator.RestrictShapeFilePathName = txtRestrictionLayerPath.Text.Replace(".shp", "_Grid.shp");  
                 }  
             }  
 
             tileCacheGenerator.MapUnit = mapUnit;  
             tileCacheGenerator.CacheFolder = txtCacheFolder.Text;  
             tileCacheGenerator.ThreadsCount = Convert.ToInt32(txtThreadsCount.Text);  
 
             startTime = System.DateTime.Now;  
             tileCacheGenerator.GenerateTiles();  
         }  
 
         private void GridRestrictionLayer(string restrictShapePathFileName, RectangleShape extentToGrid, int gridSize, string gridedRestrictShapePathFileName)  
         {  
             ShapeFileFeatureSource.BuildIndexFile(restrictShapePathFileName, BuildIndexMode.DoNotRebuild);  
 
             ShapeFileFeatureLayer restrictionLayer = new ShapeFileFeatureLayer(restrictShapePathFileName);  
             restrictionLayer.Open();  
 
             if (restrictionLayer.GetShapeFileType() == ShapeFileType.Polygon)  
             {  
                 ShapeFileFeatureSource.CreateShapeFile(ShapeFileType.Polygon, gridedRestrictShapePathFileName, new Collection<DbfColumn>() { new DbfColumn("RECID", DbfColumnType.Integer, 10, 0) }, Encoding.Default, OverwriteMode.Overwrite);  
 
                 ShapeFileFeatureSource gridedRestrictionLayer = new ShapeFileFeatureSource(gridedRestrictShapePathFileName, ShapeFileReadWriteMode.ReadWrite);  
                 gridedRestrictionLayer.Open();  
                 gridedRestrictionLayer.BeginTransaction();  
 
                 double startX = extentToGrid.UpperLeftPoint.X;  
                 double startY = extentToGrid.UpperLeftPoint.Y;  
 
                 double cellWidth = extentToGrid.Width / gridSize;  
                 double cellHeight = extentToGrid.Height / gridSize;  
 
                 for (int x = 0; x < gridSize; x++)  
                 {  
                     for (int y = 0; y < gridSize; y++)  
                     {  
                         RectangleShape boundingBox = new RectangleShape(startX + x * cellWidth, startY - y * cellHeight, startX + x * cellWidth + cellWidth, startY - y * cellHeight - cellHeight);  
                         Collection<Feature> fearures = restrictionLayer.QueryTools.GetFeaturesInsideBoundingBox(boundingBox, new Collection<string>() { "RECID" });  
 
                         foreach (Feature feature in fearures)  
                         {  
                             MultipolygonShape polygon = (MultipolygonShape)feature.GetShape();  
                             BaseShape areaIntersection = polygon.GetIntersection(boundingBox);  
 
                             if (areaIntersection != null)  
                             {  
                                 Feature newFeature = new Feature(areaIntersection);  
                                 newFeature.ColumnValues.Add("RECID", feature.ColumnValues["RECID"].ToString());  
                                 gridedRestrictionLayer.AddFeature(newFeature);  
                             }  
 
                             lblTotalTime.Text = string.Format("Griding the restrict file: Row {0} of {1}, Column {2} of {3}", x, gridSize, y, gridSize);  
                             lblCurrentImageCount.Text = string.Empty;  
                             Application.DoEvents();  
                         }  
                     }  
                 }  
                 gridedRestrictionLayer.CommitTransaction();  
                 gridedRestrictionLayer.Close();  
             }  
         }  
 
         void tileCacheGenerator_ProgressChanged(object sender, CacheGeneratorProgressChangedEventArgs e)  
         {  
             // Make the label update every 100 tiles.  
             if (e.CurrentTileIndex % 100 != 0 && e.CurrentTileIndex < e.TotalTilesCount)  
             {  
                 return;  
             }  
             TimeSpan timeSpan = DateTime.Now - startTime;  
 
             lblCurrentImageCount.Invoke((InvokeMethod)delegate()  
             {  
                 lblCurrentImageCount.Text = string.Format("Current Progress: {0} %", e.ProgressPercentage);  
             });  
 
             lblTileStatus.Invoke((InvokeMethod)delegate  
             {  
                 lblTileStatus.Text = String.Format("{0:N0} Tiles Generated. ", e.CurrentTileIndex);  
             });  
 
             double totalMilliseconds = timeSpan.TotalMilliseconds;  
             double averageMilliseconds = totalMilliseconds / e.CurrentTileIndex;  
             double remainingTime = (e.TotalTilesCount - e.CurrentTileIndex) * averageMilliseconds;  
             if (remainingTime < 0)  
             {  
                 remainingTime = 0;  
             }  
 
             lblTotalTime.Invoke((InvokeMethod)delegate()  
             {  
                 lblTotalTime.Text = String.Format("TotalTime: {0}; RemainingTime: {1}; AverageTime: {2} ms/Tile", FormattedTimeString(timeSpan), FormattedTimeString(TimeSpan.FromMilliseconds(remainingTime)), averageMilliseconds.ToString("N1"));  
             });  
         }  
 
         void tileCacheGenerator_GenerationCompleted(object sender, EventArgs e)  
         {  
             btnGenerate.Invoke((InvokeMethod)delegate()  
             {  
                 btnGenerate.Enabled = true;  
             });  
 
             lblCurrentImageCount.Invoke((InvokeMethod)delegate()  
             {  
                 lblCurrentImageCount.Text = "Current Progress: 100%";  
             });  
 
             MessageBox.Show("Generation Completed!");  
         }  
 
         public static string FormattedTimeString(TimeSpan ts)  
         {  
             if (ts.Days > 0)  
             {  
                 return String.Format("{0} Days {1} Hours", ts.Days.ToString(), ts.Hours.ToString());  
             }  
             else if (ts.Hours > 0)  
             {  
                 return String.Format("{0} Hours {1} Minutes", ts.Hours.ToString(), ts.Minutes.ToString());  
             }  
             else if (ts.Minutes > 0)  
             {  
                 return String.Format("{0} Minutes {1} Seconds", ts.Minutes.ToString(), ts.Seconds.ToString());  
             }  
             else  
             {  
                 return String.Format("{0} Seconds", ts.Seconds.ToString());  
             }  
         }  
 
         private void btnPreview_Click(object sender, EventArgs e)  
         {  
             TileCacheGenerator tileCacheGenerator = new TileCacheGenerator();  
             tileCacheGenerator.MapUnit = mapUnit;  
             tileCacheGenerator.ScalesToCache = GetScalesToCache();  
 
             string[] upperLeftPointInString = txtUpperLeftX.Text.Split(',');  
             string[] lowerRightPointInString = txtLowerRightX.Text.Split(',');  
             tileCacheGenerator.CachingExtent = new RectangleShape(double.Parse(upperLeftPointInString[0]), double.Parse(upperLeftPointInString[1]), double.Parse(lowerRightPointInString[0]), double.Parse(lowerRightPointInString[1]));  
 
             if (checkBoxRestrict.Checked)  
             {  
                 tileCacheGenerator.RestrictShapeFilePathName = txtRestrictionLayerPath.Text;  
             }  
 
             Collection<long> tilesCount = tileCacheGenerator.GetTilesCountsForScales();  
             long totalTilesCount = 0;  
 
             int startIndex = cmbStartZoomLevel.SelectedIndex;  
             StringBuilder sb = new StringBuilder();  
             sb.AppendLine();  
             sb.AppendLine();  
 
             for (int i = 0; i < tilesCount.Count; i++)  
             {  
                 totalTilesCount += tilesCount[i];  
                 sb.AppendFormat("Tiles Count In {0}: {1:N0}", cmbStartZoomLevel.Items[startIndex++], tilesCount[i]);  
                 sb.AppendLine();  
             }  
 
             sb.Insert(0, string.Format("Total Tiles Count: {0:N0}", totalTilesCount));  
             tileCacheGenerator.Close();  
 
             MessageBox.Show(sb.ToString());  
         }  
 
         private void btnSelectCacheFolder_Click(object sender, EventArgs e)  
         {  
             FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();  
             if (folderBrowserDialog.ShowDialog() == DialogResult.OK)  
             {  
                 txtCacheFolder.Text = folderBrowserDialog.SelectedPath;  
             }  
         }  
 
         private void btnSelectWatermark_Click(object sender, EventArgs e)  
         {  
             OpenFileDialog openFileDialog = new OpenFileDialog();  
             openFileDialog.InitialDirectory = Application.StartupPath;  
             openFileDialog.Filter = "Image File(*.jpg,*.gif,*.bmp,*.png)|*.jpg;*.gif;*.bmp;*.png|All File(*.*)|*.*";  
             if (openFileDialog.ShowDialog() == DialogResult.OK)  
             {  
                 txtWatermarkPath.Text = openFileDialog.FileName;  
             }  
         }  
 
         private void btnSelectRestrictionLayer_Click(object sender, EventArgs e)  
         {  
             OpenFileDialog openFileDialog = new OpenFileDialog();  
             openFileDialog.InitialDirectory = Application.StartupPath;  
             openFileDialog.Filter = "Shape File(*.shp)|*.shp|All File(*.*)|*.*";  
             if (openFileDialog.ShowDialog() == DialogResult.OK)  
             {  
                 txtRestrictionLayerPath.Text = openFileDialog.FileName;  
             }  
         }  
 
         private void cmbTileImageType_SelectedIndexChanged(object sender, EventArgs e)  
         {  
             txtJpegQuality.Enabled = (cmbTileImageType.Text == "JPEG");  
             lblJpegQuality.Enabled = txtJpegQuality.Enabled;  
         }  
 
         private void btnCancel_Click(object sender, EventArgs e)  
         {  
             this.Close();  
         }  
 
         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)  
         {  
             if (tileCacheGenerator != null)  
             {  
                 tileCacheGenerator.Close();  
             }  
         }  
 
         private void checkBoxRestrict_CheckedChanged(object sender, EventArgs e)  
         {  
             txtRestrictionLayerPath.ReadOnly = !checkBoxRestrict.Checked;  
             txtGridSize.ReadOnly = !checkBoxRestrict.Checked;  
         }  
 
         private void checkBoxWatermark_CheckedChanged(object sender, EventArgs e)  
         {  
             txtWatermarkPath.ReadOnly = !checkBoxWatermark.Checked;  
         }  
     }  
 }  
 

Program.cs

 using System;  
 using System.Windows.Forms;  
 using System.IO;  
 
 namespace CacheGenerator  
 {  
     static class Program  
     {  
         /// <summary>  
         /// The main entry point for the application.  
         /// </summary>  
         [STAThread]  
         static void Main(string[] args)  
         {  
             Application.EnableVisualStyles();  
             Application.SetCompatibleTextRenderingDefault(false);  
             Application.Run(new MainForm());  
         }  
     }  
 }  
 

TileCacheGenerator.cs

 using System;  
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Drawing;  
 using System.IO;  
 using System.Threading;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace CacheGenerator  
 {  
     class TileCacheGenerator  
     {  
         private int tileWidth = 256;  
         private int tileHeight = 256;  
         // We have this maxTileCountInOneBitmap for optimization. we would rather draw a 4096*4096 bitmap once and split it to 256 tiles,  
         // than draw a 256*256 tile for 256 times.  
         private int maxTileCountInOneBitmap = 16;  
 
         private int threadsCount;  
         private short jpegQuality;  
         private TileImageFormat tileImageFormat;  
         Collection<Layer> layersToCache;  
         GeographyUnit mapUnit;  
         Collection<double> scales;  
         RectangleShape cachingExtent;  
         string cacheFolder;  
         string restrictShapeFilePathName;  
         Bitmap watermarkBitmap;  
         ShapeFileFeatureLayer restrictionLayer;  
 
         int currentTileIndex = 0;  
         long totalTilesCount = 0;  
         Collection<Thread> workingThreads;  
         int workingThreadCount;  
 
         public event EventHandler<CacheGeneratorProgressChangedEventArgs> ProgressChanged;  
         public event EventHandler<EventArgs> GenerationCompleted;  
 
         Collection<CreatingCellsArgument> cellsArguments = new Collection<CreatingCellsArgument>();  
 
         public TileCacheGenerator()  
         {  
             ThreadsCount = 4;  
         }  
 
         public int ThreadsCount  
         {  
             get { return threadsCount; }  
             set { threadsCount = value; }  
         }  
 
         public int TileWidth  
         {  
             get { return tileWidth; }  
             set { tileWidth = value; }  
         }  
 
         public int TileHeight  
         {  
             get { return tileHeight; }  
             set { tileHeight = value; }  
         }  
 
         public TileImageFormat TileImageFormat  
         {  
             get { return tileImageFormat; }  
             set { tileImageFormat = value; }  
         }  
 
         public short JpegQuality  
         {  
             get { return jpegQuality; }  
             set { jpegQuality = value; }  
         }  
 
         public Collection<Layer> LayersToCache  
         {  
             get { return layersToCache; }  
             set { layersToCache = value; }  
         }  
 
         public GeographyUnit MapUnit  
         {  
             get { return mapUnit; }  
             set { mapUnit = value; }  
         }  
 
         public Collection<double> ScalesToCache  
         {  
             get { return scales; }  
             set { scales = value; }  
         }  
 
         public RectangleShape CachingExtent  
         {  
             get { return cachingExtent; }  
             set { cachingExtent = value; }  
         }  
 
         public string CacheFolder  
         {  
             get { return cacheFolder; }  
             set { cacheFolder = value; }  
         }  
 
         public string RestrictShapeFilePathName  
         {  
             get { return restrictShapeFilePathName; }  
             set { restrictShapeFilePathName = value; }  
         }  
 
         public Bitmap WatermarkBitmap  
         {  
             get { return watermarkBitmap; }  
             set { watermarkBitmap = value; }  
         }  
 
         public void GenerateTiles()  
         {  
             if (!string.IsNullOrEmpty(restrictShapeFilePathName))  
             {  
                 restrictionLayer = new ShapeFileFeatureLayer(restrictShapeFilePathName, ShapeFileReadWriteMode.ReadOnly);  
                 restrictionLayer.Open();  
             }  
 
             currentTileIndex = 0;  
             totalTilesCount = GetTilesCount();  
 
             workingThreads = new Collection<Thread>();  
             Thread thread = new Thread(new ParameterizedThreadStart(GenerateTiles));  
             thread.Start(scales);  
             workingThreads.Add(thread);  
         }  
 
         private void GenerateTiles(object scales)  
         {  
             workingThreadCount = this.ThreadsCount;  
 
             Collection<double> doubleScales = (Collection<double>)scales;  
             foreach (double scale in doubleScales)  
             {  
                 GenerateTilesForOneScale(scale);  
             }  
 
             ManualResetEvent manualResetEvent = new ManualResetEvent(false);  
             for (int i = 0; i < this.ThreadsCount; i++)  
             {  
                 Thread thread = new Thread(new ParameterizedThreadStart(CreateTiles));  
                 thread.Start(manualResetEvent);  
                 workingThreads.Add(thread);  
             }  
 
             manualResetEvent.WaitOne();  
 
             foreach (Layer layer in layersToCache)  
             {  
                 if (layer.IsOpen)  
                 {  
                     layer.Close();  
                 }  
             }  
 
             if (restrictionLayer != null && restrictionLayer.IsOpen)  
             {  
                 restrictionLayer.Close();  
             }  
 
             OnGenerationCompleted(new EventArgs());  
         }  
 
         private void GenerateTilesForOneScale(object scale)  
         {  
             MapSuiteTileMatrix tileMatrix = new MapSuiteTileMatrix((double)scale, tileWidth, tileHeight, mapUnit);  
             tileMatrix.BoundingBoxUnit = mapUnit;  
             FileBitmapTileCache tileCache = new FileBitmapTileCache(cacheFolder, string.Empty, TileImageFormat, tileMatrix);  
             tileCache.JpegQuality = JpegQuality;  
 
             RectangleShape matrixBoundingBox = tileCache.TileMatrix.BoundingBox;  
 
             RowColumnRange rowColumnRange = tileCache.TileMatrix.GetIntersectingRowColumnRange(matrixBoundingBox);  
             int deltaColumnIndex = (int)(rowColumnRange.MaxColumnIndex - rowColumnRange.MinColumnIndex);  
             int deltaRowIndex = (int)(rowColumnRange.MaxRowIndex - rowColumnRange.MinRowIndex);  
             int deltaIndex = Math.Max(deltaColumnIndex, deltaRowIndex);  
 
             double cellWidth = tileCache.TileMatrix.CellWidth;  
             double cellHeight = tileCache.TileMatrix.CellHeight;  
 
             if (deltaIndex < maxTileCountInOneBitmap)  
             {  
                 int bitMapWidth = tileWidth * (deltaColumnIndex + 1);  
                 int bitMapHeight = tileHeight * (deltaRowIndex + 1);  
 
                 if (deltaIndex == 0)  
                 {  
                     CreateTiles(tileCache, matrixBoundingBox, bitMapWidth, bitMapHeight, watermarkBitmap, restrictionLayer);  
                 }  
                 else  
                 {  
                     CreateTiles(tileCache, cachingExtent, bitMapWidth, bitMapHeight, watermarkBitmap, restrictionLayer);  
                 }  
             }  
             else  
             {  
                 long bigCellRowCount = (deltaRowIndex + 1) / (maxTileCountInOneBitmap);  
                 long bigCellColumnCount = (deltaColumnIndex + 1) / (maxTileCountInOneBitmap);  
 
                 CreatingCellsArgument cellArgument = new CreatingCellsArgument();  
 
                 cellArgument.CellWidth = cellWidth * maxTileCountInOneBitmap;  
                 cellArgument.CellHeight = cellHeight * maxTileCountInOneBitmap;  
 
                 cellArgument.StartRowIndex = rowColumnRange.MinRowIndex;  
                 cellArgument.StartColumnIndex = rowColumnRange.MinColumnIndex;  
 
                 cellArgument.ColumnCount = bigCellColumnCount;  
                 cellArgument.RowCount = bigCellRowCount;  
 
                 cellArgument.TileCache = tileCache;  
                 cellsArguments.Add(cellArgument);  
             }  
         }  
 
         private void CreateTiles(object manualResetEvent)  
         {  
             ManualResetEvent resetEvent = (ManualResetEvent)manualResetEvent;  
 
             Bitmap clonedWatermarkBitmap = GetWatermarkBitmap();  
             ShapeFileFeatureLayer clonedRestrictedLayer = GetRestrictionLayer();  
 
             while (true)  
             {  
                 CreatingTilesArgument currentArgument = GetTilesCreatingArgument();  
                 if (currentArgument != null)  
                 {  
                     CreateTiles(currentArgument.TileCache, currentArgument.Extent, currentArgument.BitmapWidth, currentArgument.BitmapHeight, clonedWatermarkBitmap, clonedRestrictedLayer);  
                 }  
                 else  
                 {  
                     break;  
                 }  
             }  
             if (clonedRestrictedLayer != null)  
             {  
                 clonedRestrictedLayer.Close();  
             }  
 
             if (Interlocked.Decrement(ref workingThreadCount) == 0)  
             {  
                 resetEvent.Set();  
             }  
         }  
 
         private CreatingTilesArgument GetTilesCreatingArgument()  
         {  
             CreatingTilesArgument tilesCreatingArgument = null;  
             lock (cellsArguments)  
             {  
                 if (cellsArguments.Count == 0)  
                 {  
                     return null;  
                 }  
 
                 CreatingCellsArgument tileArgument = cellsArguments[0];  
 
                 if (tileArgument.CurrentRowIndex == tileArgument.RowCount)  
                 {  
                     cellsArguments.RemoveAt(0);  
                     tilesCreatingArgument = GetTilesCreatingArgument();  
                 }  
                 else if (tileArgument.CurrentColumnIndex == tileArgument.ColumnCount)  
                 {  
                     tileArgument.CurrentColumnIndex = 0;  
                     tileArgument.CurrentRowIndex++;  
                     tilesCreatingArgument = GetTilesCreatingArgument();  
                 }  
                 else  
                 {  
                     RectangleShape totalExtent = tileArgument.GetCurrentCellExtent();  
 
                     // This is a workaround of an issue or RectangleShape.  
                     MultipolygonShape intersection = ((AreaBaseShape)cachingExtent).GetIntersection(totalExtent);  
                     if (intersection != null)  
                     {  
                         tilesCreatingArgument = new CreatingTilesArgument(tileArgument.TileCache, totalExtent, maxTileCountInOneBitmap * tileWidth, maxTileCountInOneBitmap * tileHeight);  
                     }  
                     tileArgument.CurrentColumnIndex++;  
                 }  
             }  
             return tilesCreatingArgument;  
         }  
 
         private void CreateTiles(FileBitmapTileCache tileCache, RectangleShape extent, int bitmapWidth, int bitmapHeight, Bitmap watermarkBitmap, ShapeFileFeatureLayer restrictionLayer)  
         {  
             if (restrictionLayer == null || restrictionLayer.QueryTools.GetFeaturesIntersecting(extent, ReturningColumnsType.NoColumns).Count > 0)  
             {  
                 Bitmap bitmap = new Bitmap(bitmapWidth, bitmapHeight);  
                 DrawOnBitmap(LayersToCache, mapUnit, extent, bitmap);  
                 SaveBitmapToTiles(tileCache, bitmap, extent, cachingExtent, watermarkBitmap, restrictionLayer, tileWidth, tileHeight);  
                 bitmap.Dispose();  
             }  
         }  
 
         public void DrawOnBitmap(IEnumerable<Layer> layersTmp, GeographyUnit mapUnit, RectangleShape extent, Bitmap bitmap)  
         {  
             GeoCanvas canvas = new GdiPlusGeoCanvas();  
             canvas.BeginDrawing(bitmap, extent, mapUnit);  
             Collection<Layer> layers = LayerProvider.GetLayersToCache();  
             foreach (Layer layer in layers)  
             {  
                 if (!layer.IsOpen)  
                 {  
                     layer.Open();  
                 }  
                 layer.Draw(canvas, new Collection<SimpleCandidate>());  
             }  
             canvas.EndDrawing();  
         }  
 
         private void SaveBitmapToTiles(FileBitmapTileCache tileCache, Bitmap bitmap, RectangleShape bitmapExtent, RectangleShape cachingExtent, Bitmap watermarkBitmap, ShapeFileFeatureLayer restrictionLayer, int tileWidth, int tileHeight)  
         {  
             MultipolygonShape resultShapes = ((AreaBaseShape)cachingExtent).GetIntersection(bitmapExtent);  
 
             if (resultShapes != null)  
             {  
                 RectangleShape cachingExtentInBitmapExtent = resultShapes.Polygons[0].GetBoundingBox();  
                 Collection<TileMatrixCell> cells = tileCache.TileMatrix.GetIntersectingCells(cachingExtentInBitmapExtent);  
 
                 foreach (TileMatrixCell cell in cells)  
                 {  
                     if (restrictionLayer == null || restrictionLayer.QueryTools.GetFeaturesIntersecting(cell.BoundingBox, ReturningColumnsType.NoColumns).Count > 0)  
                     {  
                         // If the tile exists, do nothing.  
                         String tileImageFileName = tileCache.GetTileImageFileName(cell.Row, cell.Column);  
                         bool isTileExisting = File.Exists(tileImageFileName);  
                         if (!isTileExisting)  
                         {  
                             Bitmap cellBitmap = GetCellFromBitmap(bitmap, bitmapExtent, cell.BoundingBox, tileWidth, tileHeight);  
 
                             BitmapTile savingBitmapTile = new BitmapTile(cellBitmap, cell.BoundingBox, tileCache.TileMatrix.Scale);  
 
                             if (watermarkBitmap != null && savingBitmapTile != null)  
                             {  
                                 using (Graphics graphics = Graphics.FromImage(savingBitmapTile.Bitmap))  
                                 {  
                                     graphics.DrawImageUnscaled(watermarkBitmap, 0, 0);  
                                 }  
                             }  
 
                             tileCache.SaveTile(savingBitmapTile);  
                             cellBitmap.Dispose();  
                             savingBitmapTile.Dispose();  
                         }  
                         lock (this)  
                         {  
                             currentTileIndex++;  
                             int percentage = (int)(currentTileIndex * 100 / totalTilesCount);  
                             if (percentage > 100)  
                             {  
                                 percentage = 100;  
                             }  
                             OnProgressChanged(new CacheGeneratorProgressChangedEventArgs(percentage, null, currentTileIndex, totalTilesCount));  
                         }  
                     }  
                 }  
             }  
         }  
 
         public Bitmap GetCellFromBitmap(Bitmap sourceBitmap, RectangleShape sourceExtent, RectangleShape cellExtent, int tileWidth, int tileHeight)  
         {  
             Bitmap cellBitmap = null;  
 
             if (sourceBitmap != null)  
             {  
                 Graphics graphics = null;  
 
                 try  
                 {  
                     ScreenPointF upperLeftPoint = ExtentHelper.ToScreenCoordinate(sourceExtent, cellExtent.UpperLeftPoint, Convert.ToSingle(sourceBitmap.Width), Convert.ToSingle(sourceBitmap.Height));  
                     cellBitmap = new Bitmap(tileWidth, tileHeight);  
 
                     graphics = Graphics.FromImage(cellBitmap);  
                     graphics.DrawImageUnscaled(sourceBitmap, -(int)Math.Round(upperLeftPoint.X), -(int)Math.Round(upperLeftPoint.Y));  
                 }  
                 finally  
                 {  
                     if (graphics != null) { graphics.Dispose(); }  
                 }  
             }  
 
             return cellBitmap;  
         }  
 
         public long GetTilesCount()  
         {  
             long tilesCount = 0;  
             Collection<long> cells = GetTilesCountsForScales();  
             foreach (long cellCount in cells)  
             {  
                 tilesCount += cellCount;  
             }  
             return tilesCount;  
         }  
 
         public Collection<long> GetTilesCountsForScales()  
         {  
             if (!string.IsNullOrEmpty(restrictShapeFilePathName))  
             {  
                 restrictionLayer = new ShapeFileFeatureLayer(restrictShapeFilePathName, ShapeFileReadWriteMode.ReadOnly);  
                 restrictionLayer.Open();  
             }  
 
             Collection<long> cells = new Collection<long>();  
             foreach (double scale in scales)  
             {  
                 MapSuiteTileMatrix tileMatrix = new MapSuiteTileMatrix(scale, tileWidth, tileHeight, mapUnit);  
                 RowColumnRange rowColumnRange = tileMatrix.GetIntersectingRowColumnRange(cachingExtent);  
                 long deltaColumn = rowColumnRange.MaxColumnIndex - rowColumnRange.MinColumnIndex + 1;  
                 long deltaRow = rowColumnRange.MaxRowIndex - rowColumnRange.MinRowIndex + 1;  
 
                 long cellsCountUnderScale = deltaColumn * deltaRow;  
                 if (restrictionLayer != null)  
                 {  
                     Collection<Feature> features = restrictionLayer.QueryTools.GetFeaturesInsideBoundingBox(cachingExtent, ReturningColumnsType.NoColumns);  
                     double totalArea = cachingExtent.Width * cachingExtent.Height;  
                     double area = 0;  
                     foreach (Feature feature in features)  
                     {  
                         // Use the same unit here (Meter and SquarMeter) to just make the calculation easy.  
                         area += ((AreaBaseShape)feature.GetShape()).GetIntersection(cachingExtent).GetArea(GeographyUnit.Meter, AreaUnit.SquareMeters);  
                     }  
                     cellsCountUnderScale = (long)Math.Ceiling(cellsCountUnderScale * area / totalArea);  
                 }  
                 cells.Add(cellsCountUnderScale);  
             }  
             return cells;  
         }  
 
         public void Close()  
         {  
             if (workingThreads != null)  
             {  
                 foreach (Thread workingThread in workingThreads)  
                 {  
                     if (workingThread != null && workingThread.IsAlive)  
                     {  
                         workingThread.Abort();  
                     }  
 
                 }  
             }  
             if (layersToCache != null)  
             {  
                 foreach (Layer layer in layersToCache)  
                 {  
                     if (layer.IsOpen)  
                     {  
                         layer.Close();  
                     }  
                 }  
             }  
 
             if (restrictionLayer != null && restrictionLayer.IsOpen)  
             {  
                 restrictionLayer.Close();  
             }  
         }  
 
         protected virtual void OnProgressChanged(CacheGeneratorProgressChangedEventArgs e)  
         {  
             EventHandler<CacheGeneratorProgressChangedEventArgs> handler = ProgressChanged;  
             if (handler != null)  
             {  
                 handler(this, e);  
             }  
         }  
 
         protected virtual void OnGenerationCompleted(EventArgs e)  
         {  
             EventHandler<EventArgs> handler = GenerationCompleted;  
             if (handler != null)  
             {  
                 handler(this, e);  
             }  
         }  
 
         private Bitmap GetWatermarkBitmap()  
         {  
             if (watermarkBitmap == null)  
             {  
                 return null;  
             }  
 
             Bitmap clonedWatermarkBitmap = null;  
             lock (watermarkBitmap)  
             {  
                 clonedWatermarkBitmap = (Bitmap)watermarkBitmap.Clone();  
             }  
             return clonedWatermarkBitmap;  
         }  
 
         private ShapeFileFeatureLayer GetRestrictionLayer()  
         {  
             if (restrictionLayer == null)  
             {  
                 return null;  
             }  
 
             ShapeFileFeatureLayer clonedRestrictionLayer = new ShapeFileFeatureLayer(restrictionLayer.ShapePathFileName, ShapeFileReadWriteMode.ReadOnly);  
             clonedRestrictionLayer.Open();  
 
             return clonedRestrictionLayer;  
         }  
     }  
 }
source_code_serviceseditionsample_cachegenerator_cs_120619.zip.txt · Last modified: 2015/09/08 05:18 by admin