Beispiel #1
0
        async private Task GetCompactTile(IServiceRequestContext context, IServiceMap serviceMap, 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 + @"\" + 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, serviceMap, 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);

            serviceMap.Display.SpatialReference = sRef;
            serviceMap.Display.dpi = metadata.Dpi;

            double res = (double)scale / (metadata.Dpi / 0.0254);

            if (serviceMap.Display.MapUnits != GeoUnits.Meters)
            {
                GeoUnitConverter converter = new GeoUnitConverter();
                res = converter.Convert(res, GeoUnits.Meters, serviceMap.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;

            serviceMap.Display.iWidth  = metadata.TileWidth * tileMatrixWidth;
            serviceMap.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;

                    serviceMap.Display.ZoomTo(new Envelope(x, y, x + W * tileMatrixWidth, y + H * tileMatrixHeight));
                    if (format != ".jpg" && metadata.MakeTransparentPng == true)
                    {
                        serviceMap.Display.BackgroundColor = ArgbColor.Transparent;
                    }

                    serviceMap.ReleaseImage();  // Delete old Image !!! Because there is no map.SaveImage()!!!!
                    await serviceMap.TryRender(3);

                    if (IsEmptyBitmap(serviceMap.MapImage, serviceMap.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 (var bitmap = Current.Engine.CreateBitmap(metadata.TileWidth, metadata.TileHeight, serviceMap.MapImage.PixelFormat))
                                using (var canvas = bitmap.CreateCanvas())
                                {
                                    canvas.InterpolationMode = InterpolationMode.NearestNeighbor;
                                    canvas.DrawBitmap(serviceMap.MapImage,
                                                      new CanvasRectangleF(0f, 0f, (float)bitmap.Width, (float)bitmap.Height),
                                                      new CanvasRectangleF(-0.5f + (float)(i * metadata.TileWidth), -0.5f + (float)(j * metadata.TileHeight), (float)metadata.TileWidth, (float)metadata.TileHeight));

                                    //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(bitmap, serviceMap.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 { }

                                    canvas.Flush();
                                    MemoryStream ms = new MemoryStream();
                                    bitmap.Save(ms, format == ".jpg" ? ImageFormat.Jpeg : 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;
                                }
                        }
                    }
                }

                serviceMap.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();
        }
Beispiel #2
0
        async private Task GetTile(IServiceRequestContext context, IServiceMap serviceMap, 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 + @"\" + 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);

            serviceMap.Display.SpatialReference = sRef;
            serviceMap.Display.dpi = metadata.Dpi;

            serviceMap.Display.iWidth  = metadata.TileWidth;
            serviceMap.Display.iHeight = metadata.TileHeight;

            double res = (double)scale / (metadata.Dpi / 0.0254);

            if (serviceMap.Display.MapUnits != GeoUnits.Meters)
            {
                GeoUnitConverter converter = new GeoUnitConverter();
                res = converter.Convert(res, GeoUnits.Meters, serviceMap.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;

            serviceMap.Display.ZoomTo(new Envelope(x, y, x + W, y + H));

            if (format != ".jpg" && metadata.MakeTransparentPng == true)
            {
                serviceMap.Display.BackgroundColor = ArgbColor.Transparent;
            }

            await serviceMap.TryRender(3);

            await serviceMap.SaveImage(path, format == ".jpg"?ImageFormat.Jpeg : ImageFormat.Png);

            context.ServiceRequest.Response = path;
        }