예제 #1
0
        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());
        }
예제 #2
0
        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();
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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") + ")";
        }
예제 #7
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);
            }
        }
예제 #8
0
        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);
        }