Ejemplo n.º 1
0
        /// <summary>
        /// Fetch the Image Tile from given Tile Server  <see cref="TileServer" />
        /// </summary>
        /// <param name = "SourceTile">Source Tile <see cref="Tile"/></param>
        /// <param name = "SourceTileServer">The source Tile Server where Tile Images would be grabbed from <see cref="TileServer"/></param>
        /// <param name = "Subdomain">Subdomain of Source Tile Server to get the image from <see cref="TileServer" /></param>
        /// <param name = "Zoom">Zoom Level <see href="http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels" /> </param>
        /// <param name = "XOffset">(Optional) Image Offest in the X-Axis (e.g. Use 1 if you want to retrieve the tile image above the Source Tile <see cref="Tile"/></param>
        /// <param name = "YOffset">(Optional) Image Offest in the Y-Axis (e.g. Use 1 if you want to retrieve the tile image to the right of the Source Tile <see cref="Tile"/> </param>
        /// <param name = "Timeout">(Optional) Optional timeout in milliseconds /> </param>
        /// <returns>Tile Image as a Byte Array</returns>
        public static byte[] FetchTile(Tile SourceTile, TileServer SourceTileServer, char Subdomain,
                                       int Zoom = 0, short XOffset = 0, short YOffset = 0, int Timeout = 10000)
        {
            var tileUri     = GetTileUri(SourceTileServer, Subdomain, Zoom, (int)(SourceTile.X) + XOffset, (int)(SourceTile.Y) + YOffset);
            var tileRequest = (HttpWebRequest)WebRequest.Create(tileUri);

            tileRequest.UseDefaultCredentials = true;
            System.Diagnostics.Debug.WriteLine(tileRequest.RequestUri.ToString());
            try
            {
                using (var serverResponse = GetSyncResponse(tileRequest, Timeout))
                {
                    if (serverResponse == null)
                    {
                        throw (new WebException("Error fetching tile from: " + tileUri.OriginalString, null));
                    }
                    else
                    {
                        if (serverResponse.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
                        {
                            using (Stream responseStream = serverResponse.GetResponseStream())
                            {
                                return(ReadFully(responseStream));
                            }
                        }
                        else
                        {
                            throw (new WebException("Error fetching tile from: " + tileUri.OriginalString + Environment.NewLine
                                                    + "Instead of an image tile, the following content type " + Environment.NewLine
                                                    + "was returned instead: " + serverResponse.ContentType + Environment.NewLine
                                                    + (serverResponse.ContentType.StartsWith("text", StringComparison.OrdinalIgnoreCase) ?
                                                       ReadAllText(serverResponse.GetResponseStream()) : "")
                                                    , null));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw (new WebException("Error fetching tile from: " + tileUri.OriginalString + Environment.NewLine +
                                        ex.Message, null));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a Tile Cache in MBTiles v1.1 Format <see href="https://github.com/mapbox/mbtiles-spec" />
        /// from a given Bounding Box (SouthEast Lat/Lon, NorthWest Lat/Lon, Minimum Zoom and Maximum Zoom)
        /// </summary>
        /// <param name = "SourceTileServer">The source Tile Server where Tile Images would be grabbed from <see cref="TileServer"/></param>
        /// <param name = "SqlConnection">A valid SQLiteConnection based on the SQLite PCL-Net</param>
        /// <param name = "SELat">Latitude of SouthEast corner of map extent</param>
        /// <param name = "SELon">Longitude of SouthEast corner of map extent</param>
        /// <param name = "NWLat">Latitude of NorthWest corner of map extent</param>
        /// <param name = "NWLon">Longitude of NorthWest corner of map extent</param>
        /// <param name = "MinZoom">Minimum map Zoom Level</param>
        /// <param name = "MaxZoom">(Optional) Maximum map Zoom Level</param>
        /// <returns>Generates an MBTiles File in the specified SQLiteConnection</returns>
        public static void CreateTileCache(TileServer SourceTileServer, SQLiteConnection SqlConnection,
                                           float SELat, float SELon, float NWLat, float NWLon,
                                           ushort MinZoom, ushort MaxZoom = 100)
        {
            // Calculate Maximum Zoom Level
            if (MaxZoom > SourceTileServer.MaxZoom)
            {
                MaxZoom = SourceTileServer.MaxZoom;
            }

            // Check for valid Zoom Level
            if (MinZoom > MaxZoom)
            {
                throw new Exception("Minimum Zoom should be less than Maximum Zoom");
            }

            // Get number of subdomains for given Tile Server
            int s    = 0; // Define starting subdomain
            int sMax = SourceTileServer.Subdomains.Count() - 1;

            // Setup SQLite Connection
            SQLiteCommand sqlCommand;
            string        sql;

            // Create Metadata Table
            sql        = "CREATE TABLE metadata (name text, value text)";
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            // Create Tiles Table
            sql        = "CREATE TABLE tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob)";
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            // Insert Required Metadata
            sql        = "INSERT INTO metadata VALUES ('name','Test')";
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            sql        = "INSERT INTO metadata VALUES ('type','baselayer')";
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            sql        = "INSERT INTO metadata VALUES ('version','1')";
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            sql        = "INSERT INTO metadata VALUES ('description','Test Tileset')";
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            sql        = string.Format("INSERT INTO metadata VALUES ('format','{0}')", SourceTileServer.imgFormat);
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            sql = string.Format("INSERT INTO metadata VALUES ('bounds','{0},{1},{2},{3}')", float.Parse(SELon.ToString(), CultureInfo.InvariantCulture),
                                float.Parse(SELat.ToString(), CultureInfo.InvariantCulture),
                                float.Parse(NWLon.ToString(), CultureInfo.InvariantCulture),
                                float.Parse(NWLat.ToString(), CultureInfo.InvariantCulture));
            sqlCommand = SqlConnection.CreateCommand(sql);
            sqlCommand.ExecuteNonQuery();

            // Iteration Sequence: Bottom-Left (SE) to Top-Right (NW), from lowest Zoom Level to Highest Zoom Level
            // Iterate through all Zoom Levels (from lowest/zoomed-out to highest/zoomed-in)
            int zoomLevels = MaxZoom - MinZoom;
            int zoomLevel  = MinZoom;

            for (int z = 0; z <= zoomLevels; z++)
            {
                // Set Zoom
                zoomLevel = MinZoom + z;

                System.Diagnostics.Debug.WriteLine("Zoom: " + zoomLevel.ToString());

                // Get minimum Tile X, Y values
                OSMCoordinate MinTMS = GetOSMCoordinates(SELat, SELon, zoomLevel);

                // Get maximum Tile X, Y values
                OSMCoordinate MaxTMS = GetOSMCoordinates(NWLat, NWLon, zoomLevel);


                // Iterate through all Rows (Y-Axis)
                int numOfRows = MinTMS.Y - MaxTMS.Y;
                for (int y = 0; y <= numOfRows; y++)
                {
                    System.Diagnostics.Debug.WriteLine("Row: " + (MinTMS.Y - y).ToString());

                    // Retrieve tiles from Left to Right (X-Axis)
                    int numOfTiles = MaxTMS.X - MinTMS.X;
                    for (int x = 0; x <= numOfTiles; x++)
                    {
                        // Fetch Tile
                        System.Diagnostics.Debug.WriteLine("X: {0}  Y: {1}  Zoom: {2}",
                                                           (MinTMS.X + x).ToString(), (MinTMS.Y - y).ToString(), zoomLevel.ToString());

                        // Check subdomain to retrieve from
                        if (s > sMax)
                        {
                            s = 0;
                        }

                        Tile   tile      = new Tile(MinTMS.X + x, MinTMS.Y - y);
                        byte[] tileBytes = FetchTile(tile, SourceTileServer, SourceTileServer.Subdomains[s], zoomLevel);
                        s++;

                        // Insert into database
                        sqlCommand.CommandText = "INSERT INTO tiles (zoom_level, tile_column, tile_row, tile_data) VALUES (@zoom,@x,@y,@image)";
                        sqlCommand.Bind("@zoom", zoomLevel);
                        sqlCommand.Bind("@x", MinTMS.X + x);
                        sqlCommand.Bind("@y", ((1 << zoomLevel) - (MinTMS.Y - y) - 1));
                        sqlCommand.Bind("@image", tileBytes);

                        sqlCommand.ExecuteNonQuery();
                    }
                }
            }


            // Close SQL Connection
            SqlConnection.Close();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates the URI for a requested Tile
        /// </summary>
        /// <param name="Tile">The Slippy Map Tile<see cref="Tile"/></param>
        /// <returns>The URI that will be used for the web request.</returns>
        public static Uri GetTileUri(TileServer tileServer, char subdomain, int zoom, int x, int y)
        {
            string url = string.Format(tileServer.UriFormat, subdomain, zoom.ToString(), x.ToString(), y.ToString(), tileServer.imgFormat);

            return(new Uri(url.ToString()));
        }