|
| 1 | +# J4JMapLibrary: The MapTile Object |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +`MapTile` is the class used to return image data in the library. This is true even for **static** projections, like Google Maps, which only ever return one 'tile' (whose size depends on the request being made). |
| 6 | + |
| 7 | +`MapTile` is a fairly complex object, offering a lot of information about the map area it represents, in addition to the actual image data. It's also one of the ways -- and arguably the best way -- to retrieve image data, from either the cache (if one is being used) or the underlying online map service. |
| 8 | + |
| 9 | +`MapTile`s always exist in relation to some `MapRegion`. There are no independent `MapTile`s. That's because a `MapRegion` defines certain essential features of multiple `MapTile`s. This includes the projection the `MapTile` is drawn from and the map scale it embodies. |
| 10 | + |
| 11 | +Here's what the `MapTile` interface looks like: |
| 12 | + |
| 13 | +```csharp |
| 14 | +MapRegion Region { get; } |
| 15 | +bool InProjection { get; } |
| 16 | + |
| 17 | +float Height { get; set; } |
| 18 | +float Width { get; set; } |
| 19 | + |
| 20 | +int X { get; } |
| 21 | +int Y { get; } |
| 22 | +MapTile SetXRelative( int relativeX ); |
| 23 | +MapTile SetXAbsolute( int absoluteX ); |
| 24 | +MapTile SetRowColumn( int row, int column ); |
| 25 | +int Row { get; } |
| 26 | +int Column { get; } |
| 27 | + |
| 28 | +(int X, int Y) GetUpperLeftCartesian(); |
| 29 | + |
| 30 | +string FragmentId { get; } |
| 31 | +string QuadKey { get; } |
| 32 | + |
| 33 | +byte[]? ImageData { get; set; } |
| 34 | +long ImageBytes { get; } |
| 35 | +byte[]? GetImage(); |
| 36 | +Task<byte[]?> GetImageAsync( CancellationToken ctx = default ); |
| 37 | +Task<bool> LoadImageAsync( CancellationToken ctx = default ); |
| 38 | +Task<bool> LoadFromCacheAsync( ITileCache? cache, CancellationToken ctx = default ); |
| 39 | +``` |
| 40 | + |
| 41 | +## The Constructor and Contextual Properties |
| 42 | + |
| 43 | +`Region` and `InProjection` are properties that relate to the context in which a `MapTile` exists. |
| 44 | + |
| 45 | +`Region` is the `MapRegion` object within which the `MapTile` was created. It must be specified in the `MapTile` constructor: |
| 46 | + |
| 47 | +```csharp |
| 48 | +public partial class MapTile : Tile |
| 49 | +{ |
| 50 | + public MapTile( |
| 51 | + MapRegion region, |
| 52 | + int absoluteY |
| 53 | + ) |
| 54 | + : base( region, -1, absoluteY ) |
| 55 | + { |
| 56 | + //... |
| 57 | + } |
| 58 | + |
| 59 | + //... |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +`MapTile`s are subclasses of the `Tile` class, which itself is "unaware" of things like image data. `Tile`s are essentially just locations on a tiled grid. |
| 64 | + |
| 65 | +The other required constructor parameter is the `MapTile`'s *vertical tile coordinate* (`absoluteY`). This is *from the perspective of the projection to which the `MapRegion` is bound*. In other words, it's the row in the projection to which the `MapTile` is related. |
| 66 | + |
| 67 | +In this context, the row number can be any integer; it doesn't have to correspond to an actual row in the current projection and the current scale. A negative number simply means it's a row "above" any row in the actual projection. A number greater than the maximum number of tiles at the current map scale simply means the row is "below" any row in the actual projection. |
| 68 | + |
| 69 | +The `Tile` constructor requires both a row number and a column (horizontal, *X*) number. The column number can be any value, but values below 0 or above the maximum number of tiles at the current map scale imply wraparound. When a `MapTile` is created its `X` property is set to -1. |
| 70 | + |
| 71 | +## Positioning and Sizing MapTiles |
| 72 | + |
| 73 | +MapTiles have both a position and a size. In fact -- and this complicates using them -- MapTiles have multiple *kinds* of positions associated with them: |
| 74 | + |
| 75 | +|Property|Description| |
| 76 | +|--------|-----------| |
| 77 | +|`X`|the horizontal/column position of the `MapTile` within the projection, at the current map scale| |
| 78 | +|`Y`|the vertical/row position of the `MapTile` within the projection, at the current map scale| |
| 79 | +|`Row`|the row number, within the MapRegion's collection of MapTiles, where the `MapTile` is stored| |
| 80 | +|`Column`|the column number, within the MapRegion's collection of MapTiles, where the `MapTile` is stored| |
| 81 | + |
| 82 | +Moreover, the `Y` tile coordinate (row) cannot be changed after the `MapTile` is created. That's because the projections don't wraparound vertically (i.e., the top and bottom edges of the projection are not connected like the right and left edges are). |
| 83 | + |
| 84 | +The `X` tile coordinate (column) can be changed after a `MapTile` is created. In fact, it can be changed in two different ways so as to be able support wraparound: |
| 85 | + |
| 86 | +|X Coordinate Setter|Argument|Description| |
| 87 | +|-------------------|--------|-----------| |
| 88 | +|`SetXRelative`|`int` relativeX|move the `X` coordinate right (for positive values of `relativeX`) or left (for negative values of `relativeX`), taking into account the possibility of wrapping around the projection| |
| 89 | +|`SetXAbsolute`|`int` absoluteX|set the `X` coordinate to `absoluteX`| |
| 90 | + |
| 91 | +Both methods also update a MapTile's `QuadKey` and `FragmentId` (both described below). |
| 92 | + |
| 93 | +The `Row` and `Column` properties are changed by calling the `SetRowColumn()` method. It checks the proposed row and column values to ensure they are within the bounds of the array holding them within the `MapRegion` object. Exceptions are thrown if they are not. |
| 94 | + |
| 95 | +The `Height` and `Width` properties allow the `MapTile` to be sized. They can accept any values, but they are intended to be set to positive values. |
| 96 | + |
| 97 | +`MapTile` also contains a pair of properties that describe its position in a way required to support caching and, for Bing Maps, image retrieval: |
| 98 | + |
| 99 | +|Property|Type|Description| |
| 100 | +|--------|----|-----------| |
| 101 | +|`QuadKey`|`string`|a string which uniquely define's a MapTile's position. This value is needed to retrieve iamges from the Bing Maps service. You can learn more about it in the [Bing Maps documentation](https://learn.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system).| |
| 102 | +|`FragmentId`|`string`|a string which uniquely define's a MapTile in a way which can be incorporated into a file name for caching purposes| |
| 103 | + |
| 104 | +Both of these properties are updated automatically whenever the `X` coordinate changes. |
0 commit comments