/// <summary> /// Initializes a new instance of the TileChopper class /// </summary> /// <param name="fileName"> /// Full path of the image. /// </param> /// <param name="serializer"> /// Tile serializer. /// </param> /// <param name="projectionType"> /// Projection type. /// </param> /// <param name="inputBoundary"> /// Input boundary. /// </param> public TileChopper(string fileName, IImageTileSerializer serializer, ProjectionTypes projectionType, Boundary inputBoundary) { if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException("fileName"); } try { this.TileSerializer = serializer; this.projectionType = projectionType; this.inputBoundary = inputBoundary; // Create a bitmap object and read the color pixels into the grid. using (Bitmap inputImage = new Bitmap(fileName)) { this.Initialize(inputImage); } } catch (OutOfMemoryException) { throw; } catch { string message = "An error occurred while reading input image file. Check the path and try again."; throw new InvalidOperationException(message); } }
/// <summary> /// This function is used to generate the base level plate files. /// </summary> /// <param name="serializer"> /// Image tile serializer to retrieve the tile. /// </param> private void CreateBaseLevelPlateFiles(IImageTileSerializer serializer) { int maxPlate = (int)Math.Pow(2, this.plateFileDetails.MinOverlappedLevel); Parallel.For( 0, maxPlate, yPlate => { for (int xPlate = 0; xPlate < maxPlate; xPlate++) { // Get plate file name base don the X and Y coordinates of the plate file. string plateFilePath = System.IO.Path.Combine(this.platesFolderPath, this.plateFileDetails.MinOverlappedLevel.ToString(CultureInfo.InvariantCulture), string.Format(CultureInfo.InvariantCulture, Constants.BaseLevelPlateFormat, this.plateFileDetails.MinOverlappedLevel, xPlate, yPlate)); // Create the plate file instance. PlateFile currentPlate = new PlateFile(plateFilePath, this.plateFileDetails.LevelsPerPlate); currentPlate.Create(); for (int level = this.plateFileDetails.LevelsPerPlate - 1; level >= 0; level--) { // Get the number of tiles for the given level index. int numberOftiles = (int)Math.Pow(2, level); // Calculate the start and end index of X axis. int xStart = xPlate * numberOftiles; // Calculate the start and end index of Y axis. int yStart = yPlate * numberOftiles; // Add each tile to the plate file. for (int yIndex = 0; yIndex < numberOftiles; yIndex++) { for (int xIndex = 0; xIndex < numberOftiles; xIndex++) { TilesProcessed++; if (serializer != null) { Bitmap tile = serializer.Deserialize((this.maxLevels - (this.plateFileDetails.LevelsPerPlate - 1) + level), xStart + xIndex, yStart + yIndex); if (tile != null) { using (MemoryStream ms = new MemoryStream()) { ms.Seek(0, SeekOrigin.Begin); tile.Save(ms, format); currentPlate.AddStream(ms, level, xIndex, yIndex); } tile.Dispose(); } } } } } // Update the header and close the file stream. currentPlate.UpdateHeaderAndClose(); } }); }
/// <summary> /// This function is used to create the plate file from already generated pyramids. /// </summary> /// <param name="serializer"> /// Image tile serializer to retrieve the tile. /// </param> public void CreateFromImageTile(IImageTileSerializer serializer) { System.IO.Directory.CreateDirectory(System.IO.Path.Combine(platesFolderPath, this.plateFileDetails.MinOverlappedLevel.ToString(CultureInfo.InvariantCulture))); TilesProcessed = 0; CreateBaseLevelPlateFiles(serializer); CreateTopLevelPlateFile(serializer); }
/// <summary> /// Aggregates lower level image tiles to construct upper level tiles. /// </summary> /// <param name="level"> /// Zoom level. /// </param> /// <param name="tileX"> /// X coordinate. /// </param> /// <param name="tileY"> /// Y coordinate. /// </param> /// <param name="tileSerializer"> /// Serializer to invoke in order to persist the bitmap image. /// </param> public static void CreateParent(int level, int tileX, int tileY, IImageTileSerializer tileSerializer) { if (tileSerializer == null) { throw new ArgumentNullException("tileSerializer"); } int level1 = checked (level + 1); int x1 = checked (2 * tileX); int y1 = checked (2 * tileY); using (Bitmap bmp = new Bitmap(2 * Constants.TileSize, 2 * Constants.TileSize)) using (Graphics g = Graphics.FromImage(bmp)) using (Bitmap b00 = tileSerializer.Deserialize(level1, x1, y1)) using (Bitmap b10 = tileSerializer.Deserialize(level1, x1 + 1, y1)) using (Bitmap b01 = tileSerializer.Deserialize(level1, x1, y1 + 1)) using (Bitmap b11 = tileSerializer.Deserialize(level1, x1 + 1, y1 + 1)) { // Default is to display color indicating no data. g.Clear(Color.Transparent); // Draw each quadrant keeping track of number of quadrants actually drawn. short drawn = 0; if (b00 != null) { g.DrawImage(b00, 0, 0); drawn++; } if (b01 != null) { g.DrawImage(b01, 0, Constants.TileSize); drawn++; } if (b10 != null) { g.DrawImage(b10, Constants.TileSize, 0); drawn++; } if (b11 != null) { g.DrawImage(b11, Constants.TileSize, Constants.TileSize); drawn++; } // If we actually have data, shrink the tile and save it. if (drawn > 0) { using (Bitmap b = ResizeBitmap(bmp, Constants.TileSize, Constants.TileSize)) { tileSerializer.Serialize(b, level, tileX, tileY); } } } }
/// <summary> /// Initializes a new instance of the ToastTileCreator class. /// </summary> /// <param name="map"> /// Color map. /// </param> /// <param name="serializer"> /// Tile serializer. /// </param> public ToastTileCreator(IColorMap map, IImageTileSerializer serializer) { if (map == null) { throw new ArgumentNullException("map"); } if (serializer == null) { throw new ArgumentNullException("serializer"); } this.ColorMap = map; this.TileSerializer = serializer; }
/// <summary> /// Initializes a new instance of the MercatorTileCreator class. /// </summary> /// <param name="map"> /// Color map. /// </param> /// <param name="serializer"> /// Tile serializer. /// </param> public MercatorTileCreator(IColorMap map, IImageTileSerializer serializer) { if (map == null) { throw new ArgumentNullException("map"); } if (serializer == null) { throw new ArgumentNullException("serializer"); } this.ColorMap = map; this.TileSerializer = serializer; }
/// <summary> /// Initializes a new instance of the MaskedTileCreator class. /// </summary> /// <param name="map"> /// Color map. /// </param> /// <param name="serializer"> /// Tile serializer. /// </param> /// <param name="lookAtOutsideSurface"> /// True if the projection is from outside the sphere, False if it's from inside. /// </param> public MaskedTileCreator(IColorMap map, IImageTileSerializer serializer, bool lookAtOutsideSurface) { if (map == null) { throw new ArgumentNullException("map"); } if (serializer == null) { throw new ArgumentNullException("serializer"); } this.ColorMap = map; this.TileSerializer = serializer; this.LookAtOutsideSurface = lookAtOutsideSurface; }
/// <summary> /// Initializes a new instance of the ShapeTileCreator class. /// </summary> /// <param name="serializer">Tile serializer to be used.</param> /// <param name="colorMap">Color map.</param> /// <param name="type">Desired projection type.</param> /// <param name="maximumLevel">Maximum level of the image pyramid.</param> public ShapeTileCreator(IImageTileSerializer serializer, IColorMap colorMap, ProjectionTypes type, int maximumLevel) { if (serializer == null) { throw new ArgumentNullException("serializer"); } if (colorMap == null) { throw new ArgumentNullException("colorMap"); } this.tileSerializer = serializer; this.colorMap = colorMap; this.ProjectionType = type; this.maximumLevel = maximumLevel; }
/// <summary> /// This function is used to generate the top level plate file. /// </summary> /// <param name="serializer"> /// Image tile serializer to retrieve the tile. /// </param> private void CreateTopLevelPlateFile(IImageTileSerializer serializer) { string plateFilePath = System.IO.Path.Combine(this.platesFolderPath, Constants.TopLevelPlate); PlateFile currentPlate = new PlateFile(plateFilePath, this.maxLevels); currentPlate.Create(); for (int level = 0; level <= this.plateFileDetails.MaxOverlappedLevel; level++) { // Number of tiles in each direction at this level int n = (int)Math.Pow(2, level); // Add each tile to the plate file. for (int indexY = 0; indexY < n; indexY++) { for (int indexX = 0; indexX < n; indexX++) { TilesProcessed++; if (serializer != null) { Bitmap tile = serializer.Deserialize(level, indexX, indexY); if (tile != null) { using (MemoryStream ms = new MemoryStream()) { ms.Seek(0, SeekOrigin.Begin); tile.Save(ms, format); currentPlate.AddStream(ms, level, indexX, indexY); } tile.Dispose(); } } } } } // Update the header and close the file stream. currentPlate.UpdateHeaderAndClose(); }
/// <summary> /// This function is used to create the plate file from already generated pyramids. /// </summary> /// <param name="serializer"> /// Image tile serializer to retrieve the tile. /// </param> public void CreateFromImageTile(IImageTileSerializer serializer) { TilesProcessed = 0; PlateFile currentPlate = new PlateFile(this.PlateFilePath, this.Levels); currentPlate.Create(); for (int level = 0; level <= Levels; level++) { // Number of tiles in each direction at this level int n = (int)Math.Pow(2, level); // Add each tile to the plate file. for (int indexY = 0; indexY < n; indexY++) { for (int indexX = 0; indexX < n; indexX++) { TilesProcessed++; if (serializer != null) { Bitmap tile = serializer.Deserialize(level, indexX, indexY); if (tile != null) { using (MemoryStream ms = new MemoryStream()) { ms.Seek(0, SeekOrigin.Begin); tile.Save(ms, ImageFormat.Png); currentPlate.AddStream(ms, level, indexX, indexY); } tile.Dispose(); } } } } } // Update the header and close the file stream. currentPlate.UpdateHeaderAndClose(); }
public static void ToBitmap(int level, int tileX, int tileY, int[] values, IImageTileSerializer serializer) { TileHelper.ToBitmap(level, tileX, tileY, values, serializer, null); }
/// <summary> /// Creates an image tile creator instance for the specified projection type. /// </summary> /// <param name="map"> /// Color map used. /// </param> /// <param name="projectionType"> /// Projection type desired. /// </param> /// <param name="serializer"> /// Tile serializer instance. /// </param> /// <returns> /// ITileCreator instance. /// </returns> public static ITileCreator CreateImageTileCreator(IColorMap map, ProjectionTypes projectionType, IImageTileSerializer serializer) { if (map == null) { throw new ArgumentNullException("map"); } if (serializer == null) { throw new ArgumentNullException("serializer"); } switch (projectionType) { case ProjectionTypes.Mercator: return new MercatorTileCreator(map, serializer); default: return new ToastTileCreator(map, serializer); } }
public static void ToBitmap(int level, int tileX, int tileY, int[] values, IImageTileSerializer serializer, IImageTileSerializer referenceImageSerializer) { byte[] referenceImage = null; using (Bitmap image = new Bitmap(Constants.TileSize, Constants.TileSize, PixelFormat.Format32bppArgb)) { // Set the data row by row Rectangle dimension = new Rectangle(0, 0, Constants.TileSize, Constants.TileSize); BitmapData imageData = image.LockBits(dimension, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte[] rgb = new byte[imageData.Stride]; int position = -1; if (referenceImageSerializer != null) { referenceImage = TileHelper.BitmapToBytes(referenceImageSerializer.Deserialize(level, tileX, tileY)); } for (int pixelY = 0; pixelY < Constants.TileSize; pixelY++) { Array.Clear(rgb, 0, rgb.Length); int pos = 0; Color referenceColor = Color.White; for (int pixelX = 0; pixelX < Constants.TileSize; pixelX++) { Color color = Color.Transparent; position++; if (referenceImage != null) { if (referenceImage != null && referenceImage[(position * 4)] == referenceColor.B && referenceImage[(position * 4) + 1] == referenceColor.G && referenceImage[(position * 4) + 2] == referenceColor.R) { if (values != null) { color = Color.FromArgb(values[position]); } } } else { if (values != null) { color = Color.FromArgb(values[position]); } } rgb[pos++] = color.B; rgb[pos++] = color.G; rgb[pos++] = color.R; rgb[pos++] = color.A; } IntPtr p = new IntPtr(imageData.Scan0.ToInt64() + (pixelY * imageData.Stride)); System.Runtime.InteropServices.Marshal.Copy(rgb, 0, p, rgb.Length); } image.UnlockBits(imageData); if (serializer != null) { serializer.Serialize(image, level, tileX, tileY); } imageData = null; rgb = null; } }
/// <summary> /// Initializes a new instance of the TileChopper class /// </summary> /// <param name="fileName"> /// Full path of the image. /// </param> /// <param name="serializer"> /// Tile serializer. /// </param> /// <param name="projectionType"> /// Projection type. /// </param> public TileChopper(string fileName, IImageTileSerializer serializer, ProjectionTypes projectionType) : this(fileName, serializer, projectionType, new Boundary(-180, -90, 180, 90)) { }
/// <summary> /// Creates an image tile creator instance for the specified projection type. /// </summary> /// <param name="map"> /// Color map used. /// </param> /// <param name="projectionType"> /// Projection type desired. /// </param> /// <param name="serializer"> /// Tile serializer instance. /// </param> /// <returns> /// ITileCreator instance. /// </returns> public static ITileCreator CreateImageTileCreator(IColorMap map, ProjectionTypes projectionType, IImageTileSerializer serializer) { if (map == null) { throw new ArgumentNullException("map"); } if (serializer == null) { throw new ArgumentNullException("serializer"); } switch (projectionType) { case ProjectionTypes.Mercator: return(new MercatorTileCreator(map, serializer)); default: return(new ToastTileCreator(map, serializer)); } }
/// <summary> /// Aggregates lower level image tiles to construct upper level tiles. /// </summary> /// <param name="level"> /// Zoom level. /// </param> /// <param name="tileX"> /// X coordinate. /// </param> /// <param name="tileY"> /// Y coordinate. /// </param> /// <param name="tileSerializer"> /// Serializer to invoke in order to persist the bitmap image. /// </param> public static void CreateParent(int level, int tileX, int tileY, IImageTileSerializer tileSerializer) { if (tileSerializer == null) { throw new ArgumentNullException("tileSerializer"); } int level1 = checked(level + 1); int x1 = checked(2 * tileX); int y1 = checked(2 * tileY); using (Bitmap bmp = new Bitmap(2 * Constants.TileSize, 2 * Constants.TileSize)) using (Graphics g = Graphics.FromImage(bmp)) using (Bitmap b00 = tileSerializer.Deserialize(level1, x1, y1)) using (Bitmap b10 = tileSerializer.Deserialize(level1, x1 + 1, y1)) using (Bitmap b01 = tileSerializer.Deserialize(level1, x1, y1 + 1)) using (Bitmap b11 = tileSerializer.Deserialize(level1, x1 + 1, y1 + 1)) { // Default is to display color indicating no data. g.Clear(Color.Transparent); // Draw each quadrant keeping track of number of quadrants actually drawn. short drawn = 0; if (b00 != null) { g.DrawImage(b00, 0, 0); drawn++; } if (b01 != null) { g.DrawImage(b01, 0, Constants.TileSize); drawn++; } if (b10 != null) { g.DrawImage(b10, Constants.TileSize, 0); drawn++; } if (b11 != null) { g.DrawImage(b11, Constants.TileSize, Constants.TileSize); drawn++; } // If we actually have data, shrink the tile and save it. if (drawn > 0) { using (Bitmap b = ResizeBitmap(bmp, Constants.TileSize, Constants.TileSize)) { tileSerializer.Serialize(b, level, tileX, tileY); } } } }