Custom tile provider: calculate tile center and which tiles are trimmed

6 posts, 0 answers
  1. Warren
    Warren avatar
    4 posts
    Member since:
    Mar 2014

    Posted 25 Mar 2015 Link to this post

    I am attempting to implement a custom tile provider using Decarta maps as the source. When I request the tiles, I need to know the lat/lon of the center of the tile.
    1.) How can I find the lat/lon of the center of the tile based upon the tilePositionx and tilePositiony that are passed to the GetTile method?
    2.) Which tiles are trimmed or cut off at the edges of the map? For example: let's say I have a map that has tiles 200 pixels wide and the map is 700 pixels wide. I would need a total of 4 tiles, which would be 800 pixels. Obviously, 800 pixels is wider than the 700 pixels of the map, so which tiles would be cut off or hidden beyond the bounds of the map?

    Thanks
  2. Martin
    Admin
    Martin avatar
    1101 posts

    Posted 30 Mar 2015 Link to this post

    Hi Warren

    We will need some time to check out on your case and we will contact you as soon as we have more information on the matter.

    Regards,
    Martin
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Martin
    Admin
    Martin avatar
    1101 posts

    Posted 01 Apr 2015 Link to this post

    Hi Warren,

    Let me get straight to your questions:
    •  How can I find the lat/lon of the center of the tile based upon the tilePositionx and tilePositiony that are passed to the GetTile method?
      Note that the tilePositionX and tilePositionY properties are not related to the logical or geographical coordinates of the map. Those are just indexes of the tile in the tile system. This means that getting the tile's bounds is not an easy task and it requires a custom algorithm that calculates the boundaries based on the zoom level of the tile and its x,y position in the tile system. I created a sample project that calculates the tile bounds using the EPSG:4326 projection and attached it in my reply. Please give it a try and let me know if it helps.
      Also, you can find the implementation here:

      public struct BoundsBox
      {
          public double East { get; set; }
          public double North { get; set; }
          public double West { get; set; }
          public double South { get; set; }
      }
       
      public class CustomTiledMapSource : TiledMapSource
      {
          private double TileWidth;
          private double TileHeight;
           
          public CustomTiledMapSource()
              : base(0, 15, 256, 256)
          {
              this.TileWidth = 256;
              this.TileHeight = 256;
          }
       
          protected override Uri GetTile(int tileLevel, int tilePositionX, int tilePositionY)
          {
              int zoomLevel = this.ConvertTileToZoomLevel(tileLevel);
              var bBox = XYZoomToBBox(tilePositionX, tilePositionY, zoomLevel);
               
              //return a URI
          }
       
          private BoundsBox XYZoomToBBox(int x, int y, int zoom)
          {
              // From the grid position and zoom, work out the min and max Latitude / Longitude values of this tile
              double pixelWidth = (double)this.TileWidth * Math.Pow(2, zoom);
              double west = ((double)(x * this.TileWidth) * 360.0 / pixelWidth) - 180.0d;
       
              double aspect = Math.Exp((0.5 - ((y * this.TileHeight) / this.TileWidth / Math.Pow(2, zoom))) * 4.0 * Math.PI);
              double north = (double)Math.Asin((aspect - 1) / (aspect + 1)) * 180.0 / Math.PI;
       
              double east = ((double)((x + 1) * this.TileWidth) * 360.0 / pixelWidth) - 180.0;
       
              aspect = Math.Exp((0.5 - (((y + 1) * this.TileHeight) / this.TileWidth / Math.Pow(2, zoom))) * 4.0 * Math.PI);
              double south = (double)Math.Asin((aspect - 1) / (aspect + 1)) * 180.0 / Math.PI;
       
              var bBox = new BoundsBox()
              {
                  East = east,
                  West = west,
                  North = north,
                  South = south
              };
       
              return bBox;
          }
      }
    • Which tiles are trimmed or cut off at the edges of the map? For example: let's say I have a map that has tiles 200 pixels wide and the map is 700 pixels wide. I would need a total of 4 tiles, which would be 800 pixels. Obviously, 800 pixels is wider than the 700 pixels of the map, so which tiles would be cut off or hidden beyond the bounds of the map?
      This depends entirely on the current zoom level and position of the control. The tiles won't be cut in equal parts, instead they will be positioned based on the previously mentioned factors - zoom and pan position - and the size of the tiles, which is 256x256 pixels by default.

    Regards,
    Martin
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  5. Warren
    Warren avatar
    4 posts
    Member since:
    Mar 2014

    Posted 01 Apr 2015 in reply to Martin Link to this post

    Thank you for the answers and the code sample. I'll give it a try and see how it goes.
  6. Warren
    Warren avatar
    4 posts
    Member since:
    Mar 2014

    Posted 01 Apr 2015 in reply to Warren Link to this post

    Well, It's kind of working. Unfortunately, it only displays a single tile. Panning and zooming don't load new tiles, but instead just pan and zoom on this single tile. The GetTile() method is called many times, but only a single one is ever displayed.
    Is this forum an appropriate venue for this kind of question, or should I email directly?

    Thanks,

    Warren
  7. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 06 Apr 2015 Link to this post

    Hello Warren,

    Could you please confirm that for every invocation of GetTile()  you build a different Uri refereing different Image ? If possible , check that the images you request are different and do not overlap each other. For example you can create a function which stores the Images in a folder where you can check them up.

    Forum is fine for such questions, however, we encourage you to take full advantage of our support service by sending a support ticket in which the 24 hours response time is guaranteed.

    Regards,
    Petar Mladenov
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
Back to Top
UI for WPF is Visual Studio 2017 Ready