private string TmsCapabilities(IServiceRequestContext context, TileServiceMetadata metadata, int srs) { IEnvelope box = metadata.GetEPSGEnvelope(srs); if (box == null) { return(String.Empty); } ISpatialReference sRef = SpatialReference.FromID("epsg:" + srs); StringBuilder sb = new StringBuilder(); sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); sb.Append("<TileMap version=\"1.0.0\" tilemapservice=\"" + context.ServiceRequest.OnlineResource + "\" >"); sb.Append("<Title>" + context.ServiceMap.Name + "</Title>"); sb.Append("<Abstract>gView Tile Cache</Abstract>"); sb.Append("<SRS>EPSG:" + srs + "</SRS>"); sb.Append("<BoundingBox minx=\"" + box.minx.ToString(_nhi) + "\" miny=\"" + box.miny.ToString(_nhi) + "\" maxx=\"" + box.maxx.ToString(_nhi) + "\" maxy=\"" + box.maxy.ToString(_nhi) + "\" />"); sb.Append("<Origin x=\"" + box.minx.ToString(_nhi) + "\" y=\"" + box.miny.ToString(_nhi) + "\" />"); sb.Append("<TileFormat width=\"" + metadata.TileWidth + "\" height=\"" + metadata.TileHeight + "\" mime-type=\"image/png\" extension=\"png\" />"); sb.Append("<TileSets>"); int level = 0; foreach (double scale in metadata.Scales) { double res = (double)scale / (metadata.Dpi / 0.0254); if (sRef.SpatialParameters.IsGeographic) { GeoUnitConverter converter = new GeoUnitConverter(); res = converter.Convert(res, GeoUnits.Meters, GeoUnits.DecimalDegrees); } sb.Append("<TileSet href=\"" + context.ServiceRequest.OnlineResource + "/" + level + "\" "); sb.Append("units-per-pixel=\"" + res.ToString(_nhi) + "\" order=\"" + level + "\" />"); level++; } sb.Append("</TileSets>"); sb.Append("</TileMap>"); return(sb.ToString()); }
private void GetCompactTile(IServiceRequestContext context, TileServiceMetadata metadata, int epsg, double scale, int row, int col, string format, GridOrientation orientation, BoundingTiles boundingTiles, bool renderOnTheFly) { if (!metadata.EPSGCodes.Contains(epsg)) { throw new ArgumentException("Wrong epsg argument"); } if (orientation != GridOrientation.UpperLeft) { throw new ArgumentException("Compact Tiles Orientation must bei Upper Left!"); } scale = metadata.Scales.GetScale(scale); if (scale <= 0.0) { throw new ArgumentException("Wrong scale argument"); } //IEnvelope bounds = metadata.GetEGPSEnvelope(epsg); //if (bounds == null || bounds.Width == 0.0 || bounds.Height == 0.0) // throw new Exception("No bounds defined for EPSG:" + epsg); IPoint origin = metadata.GetOriginUpperLeft(epsg); if (origin == null) { throw new Exception("No origin defined for EPSG:" + epsg); } format = format.ToLower(); if (format != ".png" && format != ".jpg") { throw new Exception("Unsupported image format"); } if (format == ".png" && metadata.FormatPng == false) { throw new Exception("Format image/png not supported"); } if (format == ".jpg" && metadata.FormatJpg == false) { throw new Exception("Format image/jpeg no supported"); } string path = _mapServer.TileCachePath + @"\" + context.ServiceMap.Name + @"\_alllayers\compact\" + TileServiceMetadata.ScalePath(orientation, epsg, scale); string compactTileName = CompactTileName(row, col); string bundleFilename = path + @"\" + compactTileName + ".tilebundle"; string bundleDoneFilename = path + @"\" + compactTileName + ".tilebundle.done"; string bundleCalcFilename = path + @"\" + compactTileName + ".tilebundle.calc"; if (new FileInfo(bundleFilename).Exists) { GetCompactTileBytes(context, path, row, col); return; } else if (!renderOnTheFly || new FileInfo(bundleDoneFilename).Exists || new FileInfo(bundleCalcFilename).Exists /* && !metadata.RenderTilesOnTheFly*/) { return; // Empty } DirectoryInfo di = new DirectoryInfo(path); if (!di.Exists) { di.Create(); } try { File.Delete(bundleFilename); } catch { } //temp //string pathTemp = path + @"\temp"; //DirectoryInfo diTemp = new DirectoryInfo(pathTemp); //if (!diTemp.Exists) // diTemp.Create(); File.WriteAllText(bundleCalcFilename, "calc..."); CompactTilesIndexBuilder indexBuilder = new CompactTilesIndexBuilder(); int startRow = CompactTileStart(row), startCol = CompactTileStart(col); ISpatialReference sRef = SpatialReference.FromID("epsg:" + epsg); using (IServiceMap map = context.ServiceMap) { map.Display.SpatialReference = sRef; map.Display.dpi = metadata.Dpi; double res = (double)scale / (metadata.Dpi / 0.0254); if (map.Display.MapUnits != GeoUnits.Meters) { GeoUnitConverter converter = new GeoUnitConverter(); res = converter.Convert(res, GeoUnits.Meters, map.Display.MapUnits); } string bundleTempFilename = path + @"\" + compactTileName + "." + Guid.NewGuid().ToString("N").ToLower() + ".tilebundle"; string bundleIndexFilename = path + @"\" + compactTileName + ".tilebundlx"; File.WriteAllBytes(bundleTempFilename, new byte[0]); int bundlePos = 0; int tileMatrixWidth = 8, tileMatrixHeight = 8; map.Display.iWidth = metadata.TileWidth * tileMatrixWidth; map.Display.iHeight = metadata.TileHeight * tileMatrixHeight; for (int r = 0; r < 128; r += 8) { File.WriteAllText(bundleCalcFilename, "calc...row" + r); for (int c = 0; c < 128; c += 8) { int currentRow = r + startRow, currentCol = c + startCol; if (boundingTiles != null) { if (!boundingTiles.Check(currentRow, currentCol, 8, 8)) { continue; } } double H = metadata.TileHeight * res; double y = origin.Y - H * (currentRow + tileMatrixHeight); double W = metadata.TileWidth * res; double x = origin.X + W * currentCol; map.Display.ZoomTo(new Envelope(x, y, x + W * tileMatrixWidth, y + H * tileMatrixHeight)); if (format != ".jpg") // Make PNG Transparent { map.Display.BackgroundColor = System.Drawing.Color.Transparent; } map.ReleaseImage(); // Delete old Image !!! Because there is no map.SaveImage()!!!! map.Render(); if (IsEmptyBitmap(map.MapImage, map.Display.BackgroundColor)) { continue; } // Temp //map.MapImage.Save(pathTemp + @"\matrix_" + (startRow + r) + "_" + (startCol + c) + ".png", ImageFormat.Png); for (int j = 0; j < tileMatrixHeight; j++) { for (int i = 0; i < tileMatrixWidth; i++) { int tileRow = currentRow + j, tileCol = currentCol + i; if (boundingTiles != null) { if (!boundingTiles.Check(tileRow, tileCol, 8, 8)) { continue; } } using (Bitmap bm = new Bitmap(metadata.TileWidth, metadata.TileHeight, map.MapImage.PixelFormat)) using (Graphics gr = Graphics.FromImage(bm)) { gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; gr.DrawImage(map.MapImage, new RectangleF(0f, 0f, (float)bm.Width, (float)bm.Height), new RectangleF(-0.5f + (float)(i * metadata.TileWidth), -0.5f + (float)(j * metadata.TileHeight), (float)metadata.TileWidth, (float)metadata.TileHeight), GraphicsUnit.Pixel); //for (int py = 0, to_py = bm.Height; py < to_py; py++) //{ // for (int px = 0, to_px = bm.Width; px < to_px; px++) // { // var pCol = map.MapImage.GetPixel(px + i * metadata.TileHeight, py + j * metadata.TileHeight); // bm.SetPixel(px, py, pCol); // } //} if (IsEmptyBitmap(bm, map.Display.BackgroundColor)) { continue; } // Temp //bm.Save(pathTemp + @"\tile_" + tileRow + "_" + tileCol + ".png", ImageFormat.Png); //try //{ // if (format != ".jpg" && map.Display.BackgroundColor.A > 0) // Make PNG Transparent // bm.MakeTransparent(map.Display.BackgroundColor); //} //catch { } MemoryStream ms = new MemoryStream(); bm.Save(ms, format == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png); byte[] imageBytes = ms.ToArray(); using (var stream = new FileStream(bundleTempFilename, FileMode.Append)) { stream.Write(imageBytes, 0, imageBytes.Length); } indexBuilder.SetValue(r + j, c + i, bundlePos, imageBytes.Length); bundlePos += imageBytes.Length; } } } } map.ReleaseImage(); GC.Collect(); } try { File.Delete(bundleFilename); } catch { } if (bundlePos == 0) { File.Delete(bundleTempFilename); File.WriteAllText(bundleDoneFilename, ""); } else { File.Move(bundleTempFilename, bundleFilename); indexBuilder.Save(bundleIndexFilename); } try { File.Delete(bundleCalcFilename); } catch { } } GC.Collect(); }
private void GetTile(IServiceRequestContext context, TileServiceMetadata metadata, int epsg, double scale, int row, int col, string format, GridOrientation orientation, bool renderOnTheFly) { if (!metadata.EPSGCodes.Contains(epsg)) { throw new ArgumentException("Wrong epsg argument"); } //if (!metadata.Scales.Contains(scale)) // throw new ArgumentException("Wrong scale argument"); scale = metadata.Scales.GetScale(scale); if (scale <= 0.0) { throw new ArgumentException("Wrong scale argument"); } //IEnvelope bounds = metadata.GetEPSGEnvelope(epsg); //if (bounds == null || bounds.Width == 0.0 || bounds.Height == 0.0) // throw new Exception("No bounds defined for EPSG:" + epsg); format = format.ToLower(); if (format != ".png" && format != ".jpg") { throw new Exception("Unsupported image format"); } if (format == ".png" && metadata.FormatPng == false) { throw new Exception("Format image/png not supported"); } if (format == ".jpg" && metadata.FormatJpg == false) { throw new Exception("Format image/jpeg no supported"); } string path = _mapServer.TileCachePath + @"\" + context.ServiceMap.Name + @"\_alllayers\" + TileServiceMetadata.TilePath(orientation, epsg, scale, row, col) + format; if ((orientation == GridOrientation.UpperLeft && metadata.UpperLeftCacheTiles) || (orientation == GridOrientation.LowerLeft && metadata.LowerLeftCacheTiles)) { FileInfo fi = new FileInfo(path); if (fi.Exists) { context.ServiceRequest.Response = fi.FullName; return; } else if (!renderOnTheFly && !metadata.RenderTilesOnTheFly) { return; // Empty } if (!fi.Directory.Exists) { fi.Directory.Create(); } } else { path = _mapServer.OutputPath + @"\tile_" + Guid.NewGuid().ToString("N").ToLower() + format; } ISpatialReference sRef = SpatialReference.FromID("epsg:" + epsg); using (IServiceMap map = context.ServiceMap) { map.Display.SpatialReference = sRef; map.Display.dpi = metadata.Dpi; map.Display.iWidth = metadata.TileWidth; map.Display.iHeight = metadata.TileHeight; double res = (double)scale / (metadata.Dpi / 0.0254); if (map.Display.MapUnits != GeoUnits.Meters) { GeoUnitConverter converter = new GeoUnitConverter(); res = converter.Convert(res, GeoUnits.Meters, map.Display.MapUnits); } var origin = orientation == GridOrientation.UpperLeft ? metadata.GetOriginUpperLeft(epsg) : metadata.GetOriginLowerLeft(epsg); double H = metadata.TileHeight * res; double y = (orientation == GridOrientation.UpperLeft ? origin.Y - H * (row + 1) : origin.Y + H * row); double W = metadata.TileWidth * res; //if (map.Display.MapUnits == GeoUnits.DecimalDegrees) //{ // double phi = (2 * y + H) / 2.0; // W /= Math.Cos(phi / 180.0 * Math.PI); //} double x = origin.X + W * col; map.Display.ZoomTo(new Envelope(x, y, x + W, y + H)); map.Render(); bool maketrans = map.Display.MakeTransparent; map.Display.MakeTransparent = true; map.SaveImage(path, format == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png); map.Display.MakeTransparent = maketrans; context.ServiceRequest.Response = path; _mapServer.Log("CreateTile:", loggingMethod.request_detail, path); } }
private byte[] GetCompactTile(IServiceRequestContext context, TileServiceMetadata metadata, int epsg, double scale, int row, int col, string format, GridOrientation orientation) { if (!metadata.EPSGCodes.Contains(epsg)) { throw new ArgumentException("Wrong epsg argument"); } if (orientation != GridOrientation.UpperLeft) { throw new ArgumentException("Compact Tiles Orientation must bei Upper Left!"); } scale = metadata.Scales.GetScale(scale); if (scale <= 0.0) { throw new ArgumentException("Wrong scale argument"); } //IEnvelope bounds = metadata.GetEGPSEnvelope(epsg); //if (bounds == null || bounds.Width == 0.0 || bounds.Height == 0.0) // throw new Exception("No bounds defined for EPSG:" + epsg); IPoint origin = metadata.GetOriginUpperLeft(epsg); if (origin == null) { throw new Exception("No origin defined for EPSG:" + epsg); } format = format.ToLower(); if (format != ".png" && format != ".jpg") { throw new Exception("Unsupported image format"); } if (format == ".png" && metadata.FormatPng == false) { throw new Exception("Format image/png not supported"); } if (format == ".jpg" && metadata.FormatJpg == false) { throw new Exception("Format image/jpeg no supported"); } string path = _mapServer.TileCachePath + @"\" + context.ServiceMap.Name + @"\_alllayers\compact\" + TileServiceMetadata.ScalePath(orientation, epsg, scale); string compactTileName = CompactTileName(row, col); string bundleFilename = path + @"\" + compactTileName + ".tilebundle"; string bundleDoneFilename = path + @"\" + compactTileName + ".tilebundle.done"; string bundleCalcFilename = path + @"\" + compactTileName + ".tilebundle.calc"; if (new FileInfo(bundleFilename).Exists) { return(GetCompactTileBytes(context, path, row, col, format)); } if (IsDirectoryEmpty(path)) { #region On The Fly using (IServiceMap map = context.ServiceMap) { ISpatialReference sRef = SpatialReference.FromID("epsg:" + epsg); map.Display.SpatialReference = sRef; map.Display.dpi = metadata.Dpi; map.Display.iWidth = metadata.TileWidth; map.Display.iHeight = metadata.TileHeight; double res = (double)scale / (metadata.Dpi / 0.0254); if (map.Display.MapUnits != GeoUnits.Meters) { GeoUnitConverter converter = new GeoUnitConverter(); res = converter.Convert(res, GeoUnits.Meters, map.Display.MapUnits); } origin = orientation == GridOrientation.UpperLeft ? metadata.GetOriginUpperLeft(epsg) : metadata.GetOriginLowerLeft(epsg); double H = metadata.TileHeight * res; double y = (orientation == GridOrientation.UpperLeft ? origin.Y - H * (row + 1) : origin.Y + H * row); double W = metadata.TileWidth * res; double x = origin.X + W * col; map.Display.ZoomTo(new Envelope(x, y, x + W, y + H)); map.Render(); bool maketrans = map.Display.MakeTransparent; map.Display.MakeTransparent = true; MemoryStream ms = new MemoryStream(); map.SaveImage(ms, format == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png); map.Display.MakeTransparent = maketrans; return(ms.ToArray()); } #endregion #region Tile from Existing UpLevel Tiles (Vorteil Resampling wird nicht von Browser erledigt, ist meistens Fast -> hier Nearstneigbor) int level2 = metadata.Scales.IndexOf(scale); if (level2 <= 0) { return(null); } using (IServiceMap map = context.ServiceMap) { double res = (double)scale / (metadata.Dpi / 0.0254); if (map.Display.MapUnits != GeoUnits.Meters) { GeoUnitConverter converter = new GeoUnitConverter(); res = converter.Convert(res, GeoUnits.Meters, map.Display.MapUnits); } double H = metadata.TileHeight * res; double y = origin.Y - H * (row + 1); double W = metadata.TileWidth * res; double x = origin.X + W * col; while (true) { if (level2 <= 0) { break; } double scale2 = metadata.Scales[level2 - 1]; string path2 = _mapServer.TileCachePath + @"\" + context.ServiceMap.Name + @"\_alllayers\compact\" + TileServiceMetadata.ScalePath(orientation, epsg, scale2); if (IsDirectoryEmpty(path2)) { level2--; continue; } double res2 = scale2 / (metadata.Dpi / 0.0254); double W2 = metadata.TileWidth * res2; double H2 = metadata.TileHeight * res2; int col2_0 = (int)Math.Floor((x - origin.X) / W2); int row2_0 = (int)Math.Floor((origin.Y - (y + H)) / H2); int col2_1 = (int)Math.Floor((x + W - origin.X) / W2); int row2_1 = (int)Math.Floor((origin.Y - y) / H2); double x2_0 = origin.X + W2 * col2_0, y2_0 = origin.Y - H2 * (row2_1 + 1); double W20 = Math.Abs(col2_1 - col2_0 + 1) * W2, H20 = Math.Abs(row2_1 - row2_0 + 1) * H2; using (Bitmap bm = new Bitmap(Math.Abs(col2_1 - col2_0 + 1) * metadata.TileWidth, Math.Abs(row2_1 - row2_0 + 1) * metadata.TileHeight)) using (Graphics gr = Graphics.FromImage(bm)) { for (int r2 = row2_0; r2 <= row2_1; r2++) { for (int c2 = col2_0; c2 <= col2_1; c2++) { byte[] buffer = GetCompactTileBytes(context, path2, r2, c2, format); if (buffer != null && buffer.Length > 0) { MemoryStream ms = new MemoryStream(buffer); var tileImage = Image.FromStream(ms); gr.DrawImage(tileImage, new PointF((c2 - col2_0) * metadata.TileWidth, (r2 - row2_0) * metadata.TileHeight)); } } } float imageX = (float)((x - x2_0) / W20 * (double)bm.Width); float imageY = bm.Height - (float)((y - y2_0) / H20 * (double)bm.Height); float imageW = (float)((double)metadata.TileWidth * res / res2); float imageH = (float)((double)metadata.TileHeight * res / res2); using (Bitmap outputBm = new Bitmap(metadata.TileWidth, metadata.TileHeight)) using (Graphics outputGr = Graphics.FromImage(outputBm)) { outputGr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; outputGr.DrawImage(bm, new RectangleF(-.5f, -.5f, (float)outputBm.Width + 1f, (float)outputBm.Height + 1f), new RectangleF(imageX, imageY - imageH, imageW, imageH), GraphicsUnit.Pixel); MemoryStream output = new MemoryStream(); outputBm.Save(output, format == ".png" ? ImageFormat.Png : ImageFormat.Jpeg); return(output.ToArray()); } } } } #endregion } return(null); }
public void Renderer(string server, string service, string user = "", string pwd = "") { ISpatialReference sRef = SpatialReference.FromID($"epsg:{ _epsg }"); if (sRef == null) { throw new Exception($"Can't load SpatialReference EPSG:{ _epsg }"); } IEnvelope metadataBBox = _metadata.GetEPSGEnvelope(_epsg); if (metadataBBox == null) { throw new Exception($"Can't get extent for EPSG:{ _epsg } from metadata"); } if (_bbox == null) { _bbox = metadataBBox; } else if (metadataBBox.Contains(_bbox)) { throw new Exception($"BBox must be completly contained in tile cache BBox: { metadataBBox.ToBBoxString() }"); } double width = _bbox.Width; double height = _bbox.Height; double dpu = 1.0; if (sRef.SpatialParameters.IsGeographic) { GeoUnitConverter converter = new GeoUnitConverter(); dpu = converter.Convert(1.0, GeoUnits.Meters, GeoUnits.DecimalDegrees); } Grid grid = new Grid( (_orientation == GridOrientation.UpperLeft ? _metadata.GetOriginUpperLeft(_epsg) : _metadata.GetOriginLowerLeft(_epsg)), _metadata.TileWidth, _metadata.TileHeight, 96.0, _orientation); int level = 0; foreach (double scale in _metadata.Scales) { double res = scale / (96.0 / 0.0254) * dpu; grid.AddLevel(level++, res); } ServerConnection connector = new ServerConnection(server); int step = _cacheFormat == "compact" ? 128 : 1; #region Count Tiles int featureMax = 0; foreach (double scale in _preRenderScales ?? _metadata.Scales) { double res = scale / (96.0 / 0.0254) * dpu; int col0 = grid.TileColumn(_bbox.minx, res), col1 = grid.TileColumn(_bbox.maxx, res); int row0 = grid.TileRow(_bbox.maxy, res), row1 = grid.TileRow(_bbox.miny, res); featureMax += Math.Max(1, (Math.Abs(col1 - col0) + 1) * (Math.Abs(row1 - row0) + 1) / step / step); } #endregion Console.WriteLine($"TilesCount: { featureMax }"); RenderTileThreadPool threadPool = new RenderTileThreadPool(connector, service, user, pwd, _maxParallelRequests); var thread = threadPool.FreeThread; if (_orientation == GridOrientation.UpperLeft) { thread.Start($"init/{ _cacheFormat }/ul/{ _epsg }/{ _imageFormat.Replace(".", "") }"); } else { thread.Start($"init/{ _cacheFormat }/ll/{ _epsg }/{ _imageFormat.Replace(".", "") }"); } foreach (double scale in _preRenderScales ?? _metadata.Scales) { double res = scale / (96.0 / 0.0254) * dpu; int col0 = grid.TileColumn(_bbox.minx, res), col1 = grid.TileColumn(_bbox.maxx, res); int row0 = grid.TileRow(_bbox.maxy, res), row1 = grid.TileRow(_bbox.miny, res); int cols = Math.Abs(col1 - col0) + 1; int rows = Math.Abs(row1 - row0) + 1; col0 = Math.Min(col0, col1); row0 = Math.Min(row0, row1); int tilePos = 0; Console.WriteLine(); Console.WriteLine("Scale: " + scale.ToString() + " - " + Math.Max(1, (rows * cols) / step / step).ToString() + " tiles..."); string boundingTiles = _cacheFormat == "compact" ? "/" + row0 + "|" + (row0 + rows) + "|" + col0 + "|" + (col0 + cols) : String.Empty; for (int row = row0; row < (row0 + rows) + (step - 1); row += step) { for (int col = col0; col < (col0 + cols) + (step - 1); col += step) { while ((thread = threadPool.FreeThread) == null) { Thread.Sleep(50); //if (!_cancelTracker.Continue) // return; } if (_orientation == GridOrientation.UpperLeft) thread.Start("tile:render/" + _cacheFormat + "/ul/" + _epsg + "/" + scale.ToDoubleString() + "/" + row + "/" + col + _imageFormat + boundingTiles); else thread.Start("tile:render/" + _cacheFormat + "/ll/" + _epsg + "/" + scale.ToDoubleString() + "/" + row + "/" + col + _imageFormat + boundingTiles); tilePos++; if (tilePos % 5 == 0 || _cacheFormat == "compact") Console.Write($"...{ tilePos }"); //if (!_cancelTracker.Continue) // return; } } } while (threadPool.IsFinished == false) { Thread.Sleep(50); } if (!String.IsNullOrEmpty(threadPool.Exceptions)) { //MessageBox.Show(threadPool.Exceptions, "Exceptions", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
private void cmbEpsg_SelectedIndexChanged(object sender, EventArgs e) { lstScales.Items.Clear(); if (_metadata == null) { return; } ISpatialReference sRef = SpatialReference.FromID("epsg:" + cmbEpsg.SelectedItem.ToString()); if (sRef == null) { return; } IEnvelope extent = _metadata.GetEPSGEnvelope((int)cmbEpsg.SelectedItem); if (extent == null) { return; } double width = extent.Width; double height = extent.Height; double dpu = 1.0; if (sRef.SpatialParameters.IsGeographic) { GeoUnitConverter converter = new GeoUnitConverter(); dpu = converter.Convert(1.0, GeoUnits.Meters, GeoUnits.DecimalDegrees); } foreach (double scale in _metadata.Scales) { double tileWidth = (double)_metadata.TileWidth * (double)scale / (96.0 / 0.0254); double tileHeight = (double)_metadata.TileHeight * (double)scale / (96.0 / 0.0254); tileWidth *= dpu; tileHeight *= dpu; int tx = (int)Math.Floor(width / tileWidth) + 1; int ty = (int)Math.Floor(height / tileHeight) + 1; lstScales.Items.Add(new ListViewItem(new string[] { scale.ToString(_nhi), ty.ToString(), tx.ToString(), (tx * ty).ToString() })); lstScales.Items[lstScales.Items.Count - 1].Checked = true; } if (!Envelope.IsNull(this.CurrentExtent) && cmbEpsg.SelectedItem != null) { ISpatialReference oldSRef = SpatialReference.FromID(lblEpsg.Text.Replace("(", "").Replace(")", "")); ISpatialReference newSRef = SpatialReference.FromID("epsg:" + cmbEpsg.SelectedItem.ToString()); IGeometry geom = GeometricTransformer.Transform2D(this.CurrentExtent, oldSRef, newSRef); if (geom != null) { this.CurrentExtent = geom.Envelope; } } lblEpsg.Text = "(EPSG:" + (cmbEpsg.SelectedItem != null ? cmbEpsg.SelectedItem.ToString() : "0") + ")"; }
private void Run() { if (_metadata == null || _mapServerClass == null || _mapServerClass.Dataset == null || _preRenderScales.Count == 0) { return; } string server = ConfigTextStream.ExtractValue(_mapServerClass.Dataset.ConnectionString, "server"); string service = ConfigTextStream.ExtractValue(_mapServerClass.Dataset.ConnectionString, "service"); string user = ConfigTextStream.ExtractValue(_mapServerClass.Dataset.ConnectionString, "user"); string pwd = ConfigTextStream.ExtractValue(_mapServerClass.Dataset.ConnectionString, "pwd"); ISpatialReference sRef = SpatialReference.FromID("epsg:" + _selectedEpsg); if (sRef == null) { return; } IEnvelope extent = _metadata.GetEPSGEnvelope(_selectedEpsg); if (extent == null) { return; } if (_bounds == null) { _bounds = extent; } double width = extent.Width; double height = extent.Height; double dpu = 1.0; if (sRef.SpatialParameters.IsGeographic) { GeoUnitConverter converter = new GeoUnitConverter(); dpu = converter.Convert(1.0, GeoUnits.Meters, GeoUnits.DecimalDegrees); } Grid grid = new Grid( (_orientation == GridOrientation.UpperLeft ? _metadata.GetOriginUpperLeft(_selectedEpsg) : _metadata.GetOriginLowerLeft(_selectedEpsg)), /*new Point(extent.minx, extent.maxy) : * new Point(extent.minx, extent.miny))*/ _metadata.TileWidth, _metadata.TileHeight, 96.0, _orientation); int level = 0; foreach (double scale in _metadata.Scales) { double res = scale / (96.0 / 0.0254) * dpu; grid.AddLevel(level++, res); } MapServerConnection connector = new MapServerConnection(server); ProgressReport report = new ProgressReport(); _cancelTracker.Reset(); int step = _cacheFormat == "compact" ? 128 : 1; #region Count Tiles report.featureMax = 0; foreach (double scale in _preRenderScales) { double res = scale / (96.0 / 0.0254) * dpu; int col0 = grid.TileColumn(_bounds.minx, res), col1 = grid.TileColumn(_bounds.maxx, res); int row0 = grid.TileRow(_bounds.maxy, res), row1 = grid.TileRow(_bounds.miny, res); report.featureMax += Math.Max(1, (Math.Abs(col1 - col0) + 1) * (Math.Abs(row1 - row0) + 1) / step / step); } #endregion RenderTileThreadPool threadPool = new RenderTileThreadPool(connector, service, user, pwd, _maxParallelRequests); var thread = threadPool.FreeThread; if (_orientation == GridOrientation.UpperLeft) { thread.Start("init/" + _cacheFormat + "/ul/" + cmbEpsg.SelectedItem.ToString() + "/" + _imgExt.Replace(".", "")); } else { thread.Start("init/" + _cacheFormat + "/ll/" + cmbEpsg.SelectedItem.ToString() + "/" + _imgExt.Replace(".", "")); } foreach (double scale in _preRenderScales) { double res = scale / (96.0 / 0.0254) * dpu; int col0 = grid.TileColumn(_bounds.minx, res), col1 = grid.TileColumn(_bounds.maxx, res); int row0 = grid.TileRow(_bounds.maxy, res), row1 = grid.TileRow(_bounds.miny, res); int cols = Math.Abs(col1 - col0) + 1; int rows = Math.Abs(row1 - row0) + 1; col0 = Math.Min(col0, col1); row0 = Math.Min(row0, row1); if (ReportProgress != null) { report.Message = "Scale: " + scale.ToString() + " - " + Math.Max(1, (rows * cols) / step / step).ToString() + " tiles..."; ReportProgress(report); } string boundingTiles = _cacheFormat == "compact" ? "/" + row0 + "|" + (row0 + rows) + "|" + col0 + "|" + (col0 + cols) : String.Empty; for (int row = row0; row < (row0 + rows) + (step - 1); row += step) { for (int col = col0; col < (col0 + cols) + (step - 1); col += step) { while ((thread = threadPool.FreeThread) == null) { Thread.Sleep(50); if (!_cancelTracker.Continue) { return; } } if (_orientation == GridOrientation.UpperLeft) { thread.Start("tile:render/" + _cacheFormat + "/ul/" + cmbEpsg.SelectedItem.ToString() + "/" + scale.ToString(_nhi) + "/" + row + "/" + col + _imgExt + boundingTiles); } else { thread.Start("tile:render/" + _cacheFormat + "/ll/" + cmbEpsg.SelectedItem.ToString() + "/" + scale.ToString(_nhi) + "/" + row + "/" + col + _imgExt + boundingTiles); } if (ReportProgress != null) { report.featurePos++; if (report.featurePos % 5 == 0 || _cacheFormat == "compact") { ReportProgress(report); } } if (!_cancelTracker.Continue) { return; } } } } while (threadPool.IsFinished == false) { Thread.Sleep(50); } if (!String.IsNullOrEmpty(threadPool.Exceptions)) { MessageBox.Show(threadPool.Exceptions, "Exceptions", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
private byte[] GetCompactTile(IServiceRequestContext context, TileServiceMetadata metadata, int epsg, double scale, int row, int col, string format, GridOrientation orientation) { if (!metadata.EPSGCodes.Contains(epsg)) { throw new ArgumentException("Wrong epsg argument"); } if (orientation != GridOrientation.UpperLeft) { throw new ArgumentException("Compact Tiles Orientation must bei Upper Left!"); } scale = metadata.Scales.GetScale(scale); if (scale <= 0.0) { throw new ArgumentException("Wrong scale argument"); } //IEnvelope bounds = metadata.GetEGPSEnvelope(epsg); //if (bounds == null || bounds.Width == 0.0 || bounds.Height == 0.0) // throw new Exception("No bounds defined for EPSG:" + epsg); IPoint origin = metadata.GetOriginUpperLeft(epsg); if (origin == null) { throw new Exception("No origin defined for EPSG:" + epsg); } format = format.ToLower(); if (format != ".png" && format != ".jpg") { throw new Exception("Unsupported image format"); } if (format == ".png" && metadata.FormatPng == false) { throw new Exception("Format image/png not supported"); } if (format == ".jpg" && metadata.FormatJpg == false) { throw new Exception("Format image/jpeg no supported"); } string path = _mapServer.TileCachePath + @"\" + MapName(context) + @"\_alllayers\compact\" + TileServiceMetadata.ScalePath(orientation, epsg, scale); string compactTileName = CompactTileName(row, col); string bundleFilename = path + @"\" + compactTileName + ".tilebundle"; string bundleDoneFilename = path + @"\" + compactTileName + ".tilebundle.done"; string bundleCalcFilename = path + @"\" + compactTileName + ".tilebundle.calc"; if (new FileInfo(bundleFilename).Exists) { return(GetCompactTileBytes(context, path, row, col, format)); } if (IsDirectoryEmpty(path)) { #region On The Fly using (IServiceMap map = context.CreateServiceMapInstance()) { ISpatialReference sRef = SpatialReference.FromID("epsg:" + epsg); map.Display.SpatialReference = sRef; map.Display.dpi = metadata.Dpi; map.Display.iWidth = metadata.TileWidth; map.Display.iHeight = metadata.TileHeight; double res = (double)scale / (metadata.Dpi / 0.0254); if (map.Display.MapUnits != GeoUnits.Meters) { GeoUnitConverter converter = new GeoUnitConverter(); res = converter.Convert(res, GeoUnits.Meters, map.Display.MapUnits); } origin = orientation == GridOrientation.UpperLeft ? metadata.GetOriginUpperLeft(epsg) : metadata.GetOriginLowerLeft(epsg); double H = metadata.TileHeight * res; double y = (orientation == GridOrientation.UpperLeft ? origin.Y - H * (row + 1) : origin.Y + H * row); double W = metadata.TileWidth * res; double x = origin.X + W * col; map.Display.ZoomTo(new Envelope(x, y, x + W, y + H)); map.Render(); bool maketrans = map.Display.MakeTransparent; map.Display.MakeTransparent = true; MemoryStream ms = new MemoryStream(); map.SaveImage(ms, format == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png); map.Display.MakeTransparent = maketrans; return(ms.ToArray()); } #endregion } return(null); }