コード例 #1
0
 public void TestBleedInPixelsPreservesTileSize()
 {
     TileProvider t = new TileProvider(TileConsumer.TileMapService);
     t.BleedInPixels = 100;
     using (Bitmap b = t.DrawTile(new Map(), 0,0,0))
     {
         Assert.AreEqual(256, b.Width);
     }
 }
コード例 #2
0
        public void TestMinZoomLevel()
        {
            TileProvider t = new TileProvider(TileConsumer.GoogleMaps);

            t.CalculateNumberOfTilesAcross(-1);
        }
コード例 #3
0
 public void TestConvertTileToQuadKey()
 {
     TileProvider t = new TileProvider(TileConsumer.VirtualEarth);
     Assert.AreEqual("213", t.ConvertTileToQuadKey(3, 5, 3));
 }
コード例 #4
0
ファイル: Main.cs プロジェクト: agrath/cumberland
        public static void Main(string[] args)
        {
            #region check arguments

            Rectangle worldExtents = null;
            Rectangle extents = new Rectangle();
            string path = ".";
            bool showHelp = false;
            int maxZoomLevel = 19;
            int minZoomLevel = 0;
            bool onlyCount = false;
            TileConsumer consumer = TileConsumer.GoogleMaps;
            bool mxzlChanged = false;
            bool mnzlChanged = false;
            int bleedInPixels = 0;
            bool showVersion = false;

            OptionSet options = new OptionSet();
            options.Add("e|extents=",
                        "comma-delimited extents for clipping tile generation (e.g. -180,-90,180,90).  Overrides the map file.  (Must be in map's coordinate system)",
                        delegate (string v) { extents = ParseExtents(v); });
            options.Add("h|help",  "show this message and exit",
                        delegate (string v) { showHelp = v!= null; });
            options.Add("o|output=",
                        "the path of the where to create.  Defaults to current directory",
                        delegate (string v) { path = v; });
            options.Add("x|maxzoom=",
                        "the maximum zoom level",
                        delegate (string v) { maxZoomLevel = int.Parse(v, CultureInfo.InvariantCulture); mxzlChanged = true; });
            options.Add("n|minzoom=",
                        "the minimum zoom level",
                        delegate (string v) { minZoomLevel = int.Parse(v, CultureInfo.InvariantCulture); mnzlChanged = true; });
            options.Add("t|test",
                        "Test - only calculate the total and return",
                        delegate (string v) { onlyCount = v != null; });
            options.Add("c|consumer=",
                        "The consumer.  Valid values are 'googlemaps', 'tms', and 've'.",
                        delegate (string v)
                        {
                if (v == "googlemaps")
                {
                    consumer = TileConsumer.GoogleMaps;
                }
                else if (v == "tms")
                {
                    consumer = TileConsumer.TileMapService;
                }
                else if (v == "ve")
                {
                    consumer = TileConsumer.VirtualEarth;
                }
                else
                {
                    System.Console.WriteLine("Error: Unknown consumer.");
                    ShowHelp(options);
                    return;
                }
            });
            options.Add("w|worldextents=",
                        "comma-delimited extents for defining world (e.g. -180,-90,180,90). Valid only for TMS",
                        delegate (string v) { worldExtents = ParseExtents(v); } );
            options.Add("b|bleed=",
                        "the bleed in pixels for tiles (useful for catching overrunning symbols/labels from other tiles",
                        delegate (string v) { bleedInPixels = int.Parse(v, CultureInfo.InvariantCulture); });
            options.Add("v|version",
                        "shows the version and exits",
                        delegate (string v) { showVersion = v != null; });

            List<string> rest = options.Parse(args);

            if (showVersion)
            {
                System.Console.WriteLine("Version " +
                                         System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
                return;
            }

            if (showHelp)
            {
                ShowHelp(options);
                return;
            }

            if (rest.Count == 0)
            {
                System.Console.WriteLine("No map provided");
                ShowHelp(options);
                return;
            }

            if (!File.Exists(rest[0]))
            {
                System.Console.WriteLine("Map xml file not found");
                ShowHelp(options);
                return;
            }

            if ((consumer == TileConsumer.GoogleMaps || consumer == TileConsumer.VirtualEarth) &&
                worldExtents != null)
            {
                System.Console.WriteLine("Error: cannot set world extents for this consumer");
                ShowHelp(options);
                return;
            }

            #endregion

            #region get map

            // search in the local directory for espg files
            // so Windows ppl don't have to have it installed
            ProjFourWrapper.CustomSearchPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            MapSerializer ms = new MapSerializer();
            ms.AddDatabaseFeatureSourceType<Cumberland.Data.PostGIS.PostGISFeatureSource>();
            ms.AddDatabaseFeatureSourceType<Cumberland.Data.SqlServer.SqlServerFeatureSource>();

            Map map = ms.Deserialize(rest[0]);

            // use map extents as clipping range if not provided
            if (extents.IsEmpty && !map.Extents.IsEmpty)
            {
                extents = map.Extents;
            }

            // if map has a projection, reproject clipping area
            if ((consumer == TileConsumer.GoogleMaps || consumer == TileConsumer.VirtualEarth) &&
                !extents.IsEmpty)
            {
                if (!string.IsNullOrEmpty(map.Projection))
                {
                    using (ProjFourWrapper src = new ProjFourWrapper(map.Projection))
                    {
                        using (ProjFourWrapper dst = new ProjFourWrapper(ProjFourWrapper.SphericalMercatorProjection))
                        {
                            extents = new Rectangle(src.Transform(dst, extents.Min),
                                                    src.Transform(dst, extents.Max));
                        }
                    }
                }
                else
                {
                    System.Console.WriteLine(@"Warning: Your map doesn't have a projection.
                                            Unless your data is in spherical mercator,
                                            you will not get correct tiles");
                }
            }

            if (consumer == TileConsumer.VirtualEarth)
            {
                if (!mnzlChanged) minZoomLevel = 1;
                if (!mxzlChanged) maxZoomLevel = 23;
            }

            #endregion

            #region calculate total # of tiles

            TileProvider tp;
            if (worldExtents == null)
            {
                tp = new TileProvider(consumer);
            }
            else
            {
                tp = new TileProvider(consumer, worldExtents);
            }
            tp.DrawExceptionsOnTile = false;
            tp.BleedInPixels = bleedInPixels;

            // calculate total number of tiles
            long totalCount = 0;
            for (int ii = minZoomLevel; ii <= maxZoomLevel; ii++)
            {
                //System.Console.WriteLine(tp.ClipRectangleAtZoomLevel(extents, ii).ToString());
                if (extents.IsEmpty)
                {
                    int across = tp.CalculateNumberOfTilesAcross(ii);
                    totalCount += (Convert.ToInt64(across)*Convert.ToInt64(across));
                }
                else
                {
                    System.Drawing.Rectangle r = tp.ClipRectangleAtZoomLevel(extents, ii);
                    totalCount += Convert.ToInt64(r.Width+1) * Convert.ToInt64(r.Height+1);
                }
            }

            string info = string.Format("0{0} of {1}", new string(' ', totalCount.ToString().Length-1),totalCount);
            System.Console.Write(info);

            if (onlyCount)
            {
                return;
            }

            #endregion

            #region render tiles

            Directory.CreateDirectory(path);

            #region Handle TMS xml file

            XmlWriter writer = null;

            if (consumer == TileConsumer.TileMapService)
            {
                writer = new XmlTextWriter(Path.Combine(path, "tilemapresource.xml"),
                                                 Encoding.UTF8);
                writer.WriteStartDocument();

                writer.WriteStartElement("TileMap");
                writer.WriteAttributeString("version", "1.0.0");
                writer.WriteAttributeString("tilemapservice", "http://tms.osgeo.org/1.0.0");

                writer.WriteElementString("Title", string.Empty);
                writer.WriteElementString("Abstract", string.Empty);

                int epsg;
                if (ProjFourWrapper.TryParseEpsg(map.Projection, out epsg))
                {
                    writer.WriteElementString("SRS", "EPSG:" + epsg.ToString());
                }
                else
                {
                    writer.WriteElementString("SRS", string.Empty);

                    System.Console.WriteLine("Warning: could not parse epsg code from map projection.  SRS element not set");
                }

                writer.WriteStartElement("BoundingBox");
                writer.WriteAttributeString("minx", extents.Min.X.ToString());
                writer.WriteAttributeString("miny", extents.Min.Y.ToString());
                writer.WriteAttributeString("maxx", extents.Max.X.ToString());
                writer.WriteAttributeString("maxy", extents.Max.Y.ToString());
                writer.WriteEndElement(); // BoundingBox

                writer.WriteStartElement("Origin");
                writer.WriteAttributeString("x", extents.Center.X.ToString());
                writer.WriteAttributeString("y", extents.Center.Y.ToString());
                writer.WriteEndElement(); // Origin

                writer.WriteStartElement("TileFormat");
                writer.WriteAttributeString("width", "256");
                writer.WriteAttributeString("height", "256");
                writer.WriteAttributeString("mime-type", "image/png");
                writer.WriteAttributeString("extension", "png");
                writer.WriteEndElement(); // TileFormat

                writer.WriteStartElement("TileSets");
                writer.WriteAttributeString("profile", "local");
            }

            #endregion

            long current = 0;
            for (int ii = minZoomLevel; ii <= maxZoomLevel; ii++)
            {
                string tilepath = Path.Combine(path, ii.ToString());

                if (consumer == TileConsumer.VirtualEarth)
                {
                    tilepath = path;
                }

                Directory.CreateDirectory(tilepath);

                System.Drawing.Rectangle r;
                if (extents.IsEmpty)
                {
                    int across = tp.CalculateNumberOfTilesAcross(ii);
                    r = new System.Drawing.Rectangle(0, 0, across, across);
                }
                else
                {
                    r = tp.ClipRectangleAtZoomLevel(extents, ii);
                }

                if (consumer == TileConsumer.TileMapService)
                {
                    writer.WriteStartElement("TileSet");
                    writer.WriteAttributeString("href", tilepath);
                    writer.WriteAttributeString("units-per-pixel", tp.CalculateMapUnitsPerPixel(ii).ToString());
                    writer.WriteAttributeString("order", ii.ToString());
                    writer.WriteEndElement(); // TileSet
                }

                for (int x = r.Left; x <= (r.Left+r.Width); x++)
                {
                    string xtilepath = Path.Combine(tilepath, x.ToString());

                    if (consumer == TileConsumer.VirtualEarth)
                    {
                        xtilepath = path;
                    }

                    Directory.CreateDirectory(xtilepath);

                    for (int y = r.Top; y <= (r.Top+r.Height); y++)
                    {
                        current++;

                        // render tile and save to file
                        Bitmap b = tp.DrawTile(map, x, y, ii);
                        string tileFile = string.Format("{0}{1}{2}.png",
                                      xtilepath,
                                      Path.DirectorySeparatorChar,
                                      (consumer == TileConsumer.VirtualEarth ? tp.ConvertTileToQuadKey(x,y,ii) : y.ToString()));
                        b.Save(tileFile ,ImageFormat.Png);

                        // update count in console
                        Console.SetCursorPosition(0, Console.CursorTop);
                        Console.Write(current.ToString());
                        Console.SetCursorPosition(info.Length+1, Console.CursorTop);
                    }
                }
            }

            if (consumer == TileConsumer.TileMapService)
            {
                writer.WriteEndElement(); // TileSets
                writer.WriteEndElement(); // TileMap
                writer.Close();
            }

            #endregion

            System.Console.WriteLine("Finished!");
        }