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 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); }
private void WmtsCapabilities100(IServiceRequestContext context, TileServiceMetadata metadata) { gView.Framework.OGC.WMTS.Version_1_0_0.Capabilities capabilities = new Framework.OGC.WMTS.Version_1_0_0.Capabilities() { version = "1.0.0" }; capabilities.NameSpaces = new System.Xml.Serialization.XmlSerializerNamespaces(); capabilities.NameSpaces.Add("ows", "http://www.opengis.net/ows/1.1"); capabilities.NameSpaces.Add("xlink", "http://www.w3.org/1999/xlink"); capabilities.NameSpaces.Add("gml", "http://www.opengis.net/gml"); #region ServiceIndentification capabilities.ServiceIdentification = new gView.Framework.OGC.WMTS.Version_1_0_0.ServiceIdentification(); capabilities.ServiceIdentification.Title = new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType() { Value = context.ServiceMap.Name } }; capabilities.ServiceIdentification.ServiceType = new gView.Framework.OGC.WMTS.Version_1_0_0.CodeType() { Value = "OGC WMTS" }; capabilities.ServiceIdentification.ServiceTypeVersion = new string[] { "1.0.0" }; #endregion string restFulUrl = context.ServiceRequest.OnlineResource.ToLower().Replace("/maprequest/wmts/", "/tilewmts/"); #region OperationsMetadata capabilities.OperationsMetadata = new gView.Framework.OGC.WMTS.Version_1_0_0.OperationsMetadata(); var getCapOperation = new gView.Framework.OGC.WMTS.Version_1_0_0.Operation() { name = "GetCapabilities" }; getCapOperation.DCP = new gView.Framework.OGC.WMTS.Version_1_0_0.DCP[] { new gView.Framework.OGC.WMTS.Version_1_0_0.DCP() }; getCapOperation.DCP[0].Item = new gView.Framework.OGC.WMTS.Version_1_0_0.HTTP(); getCapOperation.DCP[0].Item.Items = new gView.Framework.OGC.WMTS.Version_1_0_0.RequestMethodType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.RequestMethodType() }; getCapOperation.DCP[0].Item.Items[0].href = context.ServiceRequest.OnlineResource + "?SERVICE=WMTS&VERSION=1.0.0" + "&"; getCapOperation.DCP[0].Item.Items[0].Constraint = new gView.Framework.OGC.WMTS.Version_1_0_0.DomainType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.DomainType() }; getCapOperation.DCP[0].Item.Items[0].Constraint[0].name = "GetEncoding"; getCapOperation.DCP[0].Item.Items[0].Constraint[0].AllowedValues = new object[] { new gView.Framework.OGC.WMTS.Version_1_0_0.ValueType() { Value = "KVP" /*"RESTful"*/ } }; getCapOperation.DCP[0].Item.ItemsElementName = new gView.Framework.OGC.WMTS.Version_1_0_0.ItemsChoiceType[] { gView.Framework.OGC.WMTS.Version_1_0_0.ItemsChoiceType.Get }; var getTileOperation = new gView.Framework.OGC.WMTS.Version_1_0_0.Operation() { name = "GetTile" }; getTileOperation.DCP = new gView.Framework.OGC.WMTS.Version_1_0_0.DCP[] { new gView.Framework.OGC.WMTS.Version_1_0_0.DCP() }; getTileOperation.DCP[0].Item = new gView.Framework.OGC.WMTS.Version_1_0_0.HTTP(); getTileOperation.DCP[0].Item.Items = new gView.Framework.OGC.WMTS.Version_1_0_0.RequestMethodType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.RequestMethodType() }; getTileOperation.DCP[0].Item.Items[0].href = restFulUrl; getTileOperation.DCP[0].Item.Items[0].Constraint = new gView.Framework.OGC.WMTS.Version_1_0_0.DomainType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.DomainType() }; getTileOperation.DCP[0].Item.Items[0].Constraint[0].name = "GetEncoding"; getTileOperation.DCP[0].Item.Items[0].Constraint[0].AllowedValues = new object[] { new gView.Framework.OGC.WMTS.Version_1_0_0.ValueType() { Value = "RESTful" } }; getTileOperation.DCP[0].Item.ItemsElementName = new gView.Framework.OGC.WMTS.Version_1_0_0.ItemsChoiceType[] { gView.Framework.OGC.WMTS.Version_1_0_0.ItemsChoiceType.Get }; capabilities.OperationsMetadata.Operation = new gView.Framework.OGC.WMTS.Version_1_0_0.Operation[] { getCapOperation, getTileOperation }; #endregion #region Contents capabilities.Contents = new gView.Framework.OGC.WMTS.Version_1_0_0.ContentsType(); List <gView.Framework.OGC.WMTS.Version_1_0_0.LayerType> layers = new List <gView.Framework.OGC.WMTS.Version_1_0_0.LayerType>(); List <gView.Framework.OGC.WMTS.Version_1_0_0.TileMatrixSet> matrixSets = new List <gView.Framework.OGC.WMTS.Version_1_0_0.TileMatrixSet>(); ISpatialReference sRef4326 = SpatialReference.FromID("epsg:4326"); foreach (var epsg in metadata.EPSGCodes) { IEnvelope extent = metadata.GetEPSGEnvelope(epsg); if (extent == null) { continue; } IPoint origin = metadata.GetOriginUpperLeft(epsg); if (origin == null) { continue; } ISpatialReference sRef = SpatialReference.FromID("epsg:" + epsg); IEnvelope extent4326 = GeometricTransformer.Transform2D(extent, sRef, sRef4326).Envelope; if (double.IsInfinity(extent4326.minx)) { extent4326.minx = -180D; } if (double.IsInfinity(extent4326.miny)) { extent4326.miny = -90D; } if (double.IsInfinity(extent4326.maxx)) { extent4326.maxx = 180D; } if (double.IsInfinity(extent4326.maxy)) { extent4326.maxy = 90D; } foreach (string cacheType in new string[] { "classic", "compact" }) { string epsgPath = _mapServer.TileCachePath + @"\" + context.ServiceMap.Name + @"\_alllayers\" + (cacheType == "compact" ? @"compact\" : "") + TileServiceMetadata.EpsgPath(GridOrientation.UpperLeft, epsg); if (!new DirectoryInfo(epsgPath).Exists) { continue; } #region Layer string layerName = context.ServiceMap.Name + " EPSG:" + epsg + " " + cacheType; string layerId = context.ServiceMap.Name.ToLower().Replace(" ", "_") + "_" + epsg + "_" + cacheType; var layer = new gView.Framework.OGC.WMTS.Version_1_0_0.LayerType(); layer.Title = new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType() { Value = layerName } }; layer.Identifier = new gView.Framework.OGC.WMTS.Version_1_0_0.CodeType() { Value = layerId }; List <gView.Framework.OGC.WMTS.Version_1_0_0.Style> styles = new List <Framework.OGC.WMTS.Version_1_0_0.Style>(); //styles.Add(new gView.Framework.OGC.WMTS.Version_1_0_0.Style() //{ // Title = new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType() { Value = "Default Style" } }, // Identifier = new gView.Framework.OGC.WMTS.Version_1_0_0.CodeType() { Value = "default" } //}); foreach (var styleVal in Enum.GetValues(typeof(ImageProcessingFilters))) { string name = Enum.GetName(typeof(ImageProcessingFilters), styleVal); styles.Add(new Framework.OGC.WMTS.Version_1_0_0.Style() { Title = new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType() { Value = name } }, Identifier = new gView.Framework.OGC.WMTS.Version_1_0_0.CodeType() { Value = name.ToLower() } }); } layer.Style = styles.ToArray(); #region BoundingBox layer.BoundingBox = new gView.Framework.OGC.WMTS.Version_1_0_0.BoundingBoxType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.BoundingBoxType() { crs = "urn:ogc:def:crs:EPSG::" + epsg, LowerCorner = PointToString(extent.LowerLeft, sRef), UpperCorner = PointToString(extent.UpperRight, sRef) } }; layer.WGS84BoundingBox = new gView.Framework.OGC.WMTS.Version_1_0_0.WGS84BoundingBoxType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.WGS84BoundingBoxType() { crs = "urn:ogc:def:crs:OGC:2:84", // urn:ogc:def:crs:OGC:2:84 LowerCorner = PointToString(extent4326.LowerLeft, sRef4326), UpperCorner = PointToString(extent4326.UpperRight, sRef4326) } }; #endregion layer.TileMatrixSetLink = new gView.Framework.OGC.WMTS.Version_1_0_0.TileMatrixSetLink[] { new gView.Framework.OGC.WMTS.Version_1_0_0.TileMatrixSetLink() { TileMatrixSet = layerId + "_default_matrixset" } }; List <string> formats = new List <string>(); if (metadata.FormatJpg) { formats.Add("image/jpg"); } if (metadata.FormatPng) { formats.Add("image/png"); } layer.Format = formats.ToArray(); List <Framework.OGC.WMTS.Version_1_0_0.URLTemplateType> resourceURLs = new List <Framework.OGC.WMTS.Version_1_0_0.URLTemplateType>(); if (metadata.FormatJpg) { resourceURLs.Add(new Framework.OGC.WMTS.Version_1_0_0.URLTemplateType() { resourceType = Framework.OGC.WMTS.Version_1_0_0.URLTemplateTypeResourceType.tile, format = "image/jpg", template = restFulUrl + "/" + cacheType + "/ul/" + epsg + "/{Style}/{TileMatrix}/{TileRow}/{TileCol}.jpg" }); } if (metadata.FormatPng) { resourceURLs.Add(new Framework.OGC.WMTS.Version_1_0_0.URLTemplateType() { resourceType = Framework.OGC.WMTS.Version_1_0_0.URLTemplateTypeResourceType.tile, format = "image/png", template = restFulUrl + "/" + cacheType + "/ul/" + epsg + "/{Style}/{TileMatrix}/{TileRow}/{TileCol}.png" }); } layer.ResourceURL = resourceURLs.ToArray(); layers.Add(layer); #endregion #region Matrix Set double matrixSetWidth = extent.Width; double matrixSetHeight = extent.Height; var matrixSet = new gView.Framework.OGC.WMTS.Version_1_0_0.TileMatrixSet(); matrixSet.Title = new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType[] { new gView.Framework.OGC.WMTS.Version_1_0_0.LanguageStringType() { Value = layerName + " Default Matrix Set" } }; matrixSet.Identifier = new gView.Framework.OGC.WMTS.Version_1_0_0.CodeType() { Value = layerId + "_default_matrixset" }; matrixSet.SupportedCRS = "urn:ogc:def:crs:EPSG::" + epsg; matrixSet.TileMatrix = new gView.Framework.OGC.WMTS.Version_1_0_0.TileMatrix[metadata.Scales.Count]; #region DPI double inchMeter = 0.0254; /* 0.0254000508001016;*/ double dpi = inchMeter * 1000D / 0.28D; // wmts 0.28mm -> 1 Pixel; double dpm = dpi / inchMeter; #endregion for (int s = 0, to = metadata.Scales.Count; s < to; s++) { string scalePath = _mapServer.TileCachePath + @"\" + context.ServiceMap.Name + @"\_alllayers\" + (cacheType == "compact" ? @"compact\" : "") + TileServiceMetadata.ScalePath(GridOrientation.UpperLeft, epsg, metadata.Scales[s]); if (!new DirectoryInfo(scalePath).Exists) { break; } double resolution = metadata.Scales[s] / (metadata.Dpi / inchMeter); matrixSet.TileMatrix[s] = new gView.Framework.OGC.WMTS.Version_1_0_0.TileMatrix(); matrixSet.TileMatrix[s].Identifier = new gView.Framework.OGC.WMTS.Version_1_0_0.CodeType() { Value = s.ToString() }; matrixSet.TileMatrix[s].TopLeftCorner = PointToString(origin, sRef); matrixSet.TileMatrix[s].TileWidth = metadata.TileWidth.ToString(); matrixSet.TileMatrix[s].TileHeight = metadata.TileHeight.ToString(); double tileWidth = metadata.TileWidth * resolution; double tileHeight = metadata.TileHeight * resolution; int matrixWidth = (int)Math.Round(matrixSetWidth / tileWidth + 0.5); int matrixHeight = (int)Math.Round(matrixSetHeight / tileHeight + 0.5); matrixSet.TileMatrix[s].MatrixWidth = matrixWidth.ToString(); matrixSet.TileMatrix[s].MatrixHeight = matrixHeight.ToString(); matrixSet.TileMatrix[s].ScaleDenominator = resolution * dpm; } matrixSets.Add(matrixSet); #endregion } } capabilities.Contents.DatasetDescriptionSummary = layers.ToArray(); capabilities.Contents.TileMatrixSet = matrixSets.ToArray(); #endregion XsdSchemaSerializer <gView.Framework.OGC.WMTS.Version_1_0_0.Capabilities> ser = new XsdSchemaSerializer <gView.Framework.OGC.WMTS.Version_1_0_0.Capabilities>(); string xml = ser.Serialize(capabilities, null); xml = xml.Replace(@"<ows:DatasetDescriptionSummary xsi:type=""LayerType"">", "<Layer>"); xml = xml.Replace(@"</ows:DatasetDescriptionSummary>", "</Layer>"); context.ServiceRequest.Response = xml; }
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); }