|
| 1 | +# J4JMapLibrary: Projection |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +- [Interface](#interface) |
| 6 | +- [Meta Information](#meta-information) |
| 7 | +- [Map Scale](#map-scale) |
| 8 | +- [Authentication](#authentication) |
| 9 | +- [Retrieving Imagery](#retrieving-imagery) |
| 10 | + |
| 11 | +`Projection` and its subclasses define how the library interfaces with various mapping services. They handle the processes of authentication and image retrieval, and provide information about a particular service's capabilities. |
| 12 | + |
| 13 | +There is a subclass for each mapping service. They derive from two general-purpose subclasses, one for *static* map services which only ever return single images (e.g., Google Maps), and one for *tiled* map services, which return imagery organized around multiple tiles (e.g., Bing Maps). `StaticProjection` does not support caching. Projection classes derived from `TiledProjection` do. |
| 14 | + |
| 15 | +Here is the class hierarchy with their corresponding named interfaces: |
| 16 | + |
| 17 | +- `Projection` (`IProjection`) |
| 18 | + - `StaticProjection` (`IStaticProjection`) |
| 19 | + - `GoogleMapsProjection` |
| 20 | + - `TiledProjection` (`ITiledProjection`) |
| 21 | + - `BingMapsProjection` |
| 22 | + - `OpenStreetMapsProjection` |
| 23 | + - `OpenTopoMapsProjection` |
| 24 | + |
| 25 | +## Interface |
| 26 | + |
| 27 | +Here is the `IProjection` interface: |
| 28 | + |
| 29 | +```csharp |
| 30 | + event EventHandler<bool>? LoadComplete; |
| 31 | + |
| 32 | + string Name { get; } |
| 33 | + string Copyright { get; } |
| 34 | + Uri? CopyrightUri { get; } |
| 35 | + bool Initialized { get; } |
| 36 | + |
| 37 | + float MaxLatitude { get; } |
| 38 | + float MinLatitude { get; } |
| 39 | + MinMax<float> LatitudeRange { get; } |
| 40 | + |
| 41 | + float MaxLongitude { get; } |
| 42 | + float MinLongitude { get; } |
| 43 | + MinMax<float> LongitudeRange { get; } |
| 44 | + |
| 45 | + int MaxRequestLatency { get; set; } |
| 46 | + int TileHeightWidth { get; } |
| 47 | + string ImageFileExtension { get; } |
| 48 | + |
| 49 | + int MinScale { get; } |
| 50 | + int MaxScale { get; } |
| 51 | + MinMax<int> ScaleRange { get; } |
| 52 | + int GetHeightWidth( int scale ); |
| 53 | + MinMax<float> GetXYRange( int scale ); |
| 54 | + MinMax<int> GetTileRange( int scale ); |
| 55 | + int GetNumTiles( int scale ); |
| 56 | + |
| 57 | + bool SetCredentials( object credentials ); |
| 58 | + |
| 59 | + Task<bool> SetCredentialsAsync( |
| 60 | + object credentials, |
| 61 | + CancellationToken ctx = default ); |
| 62 | + |
| 63 | + byte[]? GetImage( MapTile mapTile ); |
| 64 | + Task<byte[]?> GetImageAsync( MapTile mapTile, CancellationToken ctx = default ); |
| 65 | + |
| 66 | + Task<MapTile> GetMapTileWraparoundAsync( |
| 67 | + int xTile, |
| 68 | + int yTile, |
| 69 | + int scale, |
| 70 | + CancellationToken ctx = default ); |
| 71 | + |
| 72 | + Task<MapTile> GetMapTileAbsoluteAsync( |
| 73 | + int xTile, |
| 74 | + int yTile, |
| 75 | + int scale, |
| 76 | + CancellationToken ctx = default ); |
| 77 | + |
| 78 | + Task<bool> LoadImageAsync( MapTile mapTile, CancellationToken ctx = default ); |
| 79 | + |
| 80 | + Task<bool> LoadRegionAsync( |
| 81 | + MapRegion.MapRegion region, |
| 82 | + CancellationToken ctx = default |
| 83 | + ); |
| 84 | +``` |
| 85 | + |
| 86 | +[return to top](#overview) |
| 87 | + |
| 88 | +[return to usage table of contents](usage.md) |
| 89 | + |
| 90 | +## Meta Information |
| 91 | + |
| 92 | +`Projection` defines a number of properties which simply describe a mapping service: |
| 93 | + |
| 94 | +|Property|Type|Description| |
| 95 | +|--------|----|-----------| |
| 96 | +|`Name`|`string`|the unique name of the projection/mapping service| |
| 97 | +|`Copyright`|`string`|holds the copyright notice most services require you to display a copyright notice when you display their imagery. Set when the projection is authenticated.| |
| 98 | +|`CopyrightUri`|`Uri?`|holds the copyright Uri some services require you to display when you display their imagery. Set when the projection is authenticated.| |
| 99 | +|`Initialized`|`bool`|`true` after the projection is initialized and authenticated, `false` otherwise| |
| 100 | +|`MaxLatitude`|float|the maximum latitude supported by the projection| |
| 101 | +|`MinLatitude`|float|the minimum latitude supported by the projection| |
| 102 | +|`LatitudeRange`|`MinMax<float>`|used to conform latitude values to the allowable range of latitude values| |
| 103 | +|`MaxLongitude`|float|the maximum longitude supported by the projection| |
| 104 | +|`MinLongitude`|float|the minimum longitude supported by the projection| |
| 105 | +|`LongitudeRange`|`MinMax<float>`|used to conform longitude values to the allowable range of longitude values| |
| 106 | +|`MaxRequestLatency`|`int`|the maximum number of milliseconds a web request will wait to complete. Negative values mean 'wait forever'.| |
| 107 | +|`TileHeightWidth`|`int`|the height and width of the map service's tiles. Generally 256. Even *static* projections, like Google Maps, which do not return tiles use tiles internally.| |
| 108 | +|`ImageFileExtension`|`string`|defines the nature of the image data returned by a mapping service. Used when creating cached files by `FileSystemCache`.| |
| 109 | + |
| 110 | +`Name` is used by other parts of the library to identify a particular projection class. The value of `Name` should be unique within an application (and, ideally, throughout the world so that any custom projection classes you write won't collide with someone else's). |
| 111 | + |
| 112 | +[return to top](#overview) |
| 113 | + |
| 114 | +[return to usage table of contents](usage.md) |
| 115 | + |
| 116 | +## Map Scale |
| 117 | + |
| 118 | +While a `Projection` defines the interaction with a mapping service, it does not define the details of the map service's underlying map. That's because the underlying map changes depending upon the *scale* at which it is viewed or used. `Projection` defines a number of properties and methods to work with map scaling. |
| 119 | + |
| 120 | +|Property|Type|Description| |
| 121 | +|--------|----|-----------| |
| 122 | +|`MinScale`|`int`|the minimum scale factor supported by the map service. Usually, but not always, 0 (Bing Maps' minimum is 1)| |
| 123 | +|`MaxScale`|`int`|the maximum scale factor supported by the map service| |
| 124 | +|`ScaleRange`|`MinMax<int>`|used to conform map scale values to the allowable range of map scale values| |
| 125 | + |
| 126 | +|Method|Return Value|Arguments|Description| |
| 127 | +|------|------------|---------|-----------| |
| 128 | +|`GetHeightWidth`|`int`|`int` scale|gets the height and width of the map service's underlying map at a given map scale (the underlying maps are square)| |
| 129 | +|`GetXYRange`|`MinMax<float>`|`int` scale|gets the allowable range of X and Y Cartesian coordinates of the map service's underlying map at a given map scale| |
| 130 | +|`GetTileRange`|`MinMax<int>`|`int` scale|gets the allowable range of horizontal/vertical *tile coordinates* of the map service's underlying map at a given map scale| |
| 131 | +|`GetNumTiles`|`int`|`int` scale|gets the total number of tiles in the map service's underlying map at a given map scale| |
| 132 | + |
| 133 | +[return to top](#overview) |
| 134 | + |
| 135 | +[return to usage table of contents](usage.md) |
| 136 | + |
| 137 | +## Authentication |
| 138 | + |
| 139 | +Authenticating a `Projection` relies on processing a *credentials* object. There are two methods for doing so: |
| 140 | + |
| 141 | +```csharp |
| 142 | +bool SetCredentials( object credentials ); |
| 143 | + |
| 144 | +Task<bool> SetCredentialsAsync( |
| 145 | + object credentials, |
| 146 | + CancellationToken ctx = default ); |
| 147 | +``` |
| 148 | + |
| 149 | +The *credentials* object is projection-specific. If you supply the wrong kind of object authentication will fail. Here are the credentials objects for each of the supported projections: |
| 150 | + |
| 151 | +|Projection Type|Credentials Type| |
| 152 | +|---------------|----------------| |
| 153 | +|`BingMapsProjection`|`BingCredentials`| |
| 154 | +|`GoogleMapsProjection`|`GoogleCredentials`| |
| 155 | +|`OpenStreetMapsProjection`|`OpenStreetCredentials`| |
| 156 | +|`OpenTopoMapsProjection`|`OpenTopoCredentials`| |
| 157 | + |
| 158 | +The structure of a credential type reflects the information needed to authenticate with its mapping service: |
| 159 | + |
| 160 | +|Credentials Type|Property|Property Type|Comments| |
| 161 | +|----------------|--------|-------------|-----------| |
| 162 | +|`BingCredentials`|`ApiKey`|`string`|| |
| 163 | +|`GoogleCredentials`|`ApiKey`|`string`|| |
| 164 | +||`SignatureSecret`|`string`|used to encrypt each web request| |
| 165 | +|`OpenStreetCredentials`|`UserAgent`|chosen by you, but must uniquely identify your application. Consult the online documentation for details| |
| 166 | +|`OpenTopoCredentials`|`UserAgent`|chosen by you, but must uniquely identify your application. Consult the online documentation for details| |
| 167 | + |
| 168 | +[return to top](#overview) |
| 169 | + |
| 170 | +[return to usage table of contents](usage.md) |
| 171 | + |
| 172 | +## Retrieving Imagery |
| 173 | + |
| 174 | +There are five methods defined for retrieving map imagery from a `Projection`. All of them are asynchronous, because they deal with web-based services: |
| 175 | + |
| 176 | +```csharp |
| 177 | +Task<byte[]?> GetImageAsync( MapTile mapTile, CancellationToken ctx = default ); |
| 178 | + |
| 179 | +Task<MapTile> GetMapTileWraparoundAsync( |
| 180 | + int xTile, |
| 181 | + int yTile, |
| 182 | + int scale, |
| 183 | + CancellationToken ctx = default ); |
| 184 | + |
| 185 | +Task<MapTile> GetMapTileAbsoluteAsync( |
| 186 | + int xTile, |
| 187 | + int yTile, |
| 188 | + int scale, |
| 189 | + CancellationToken ctx = default ); |
| 190 | + |
| 191 | +Task<bool> LoadImageAsync( MapTile mapTile, CancellationToken ctx = default ); |
| 192 | + |
| 193 | +Task<bool> LoadRegionAsync( |
| 194 | + MapRegion.MapRegion region, |
| 195 | + CancellationToken ctx = default |
| 196 | +); |
| 197 | +``` |
| 198 | + |
| 199 | +They differ in whether they simply return `byte[]` data or load an object (i.e., `MapTile`, `MapRegion`) with `byte[]` data: |
| 200 | + |
| 201 | +|Method|Arguments|Comments| |
| 202 | +|------|---------|--------| |
| 203 | +|`GetImageAsync`|`MapTile` mapTile|gets the image data associated with a map service tile described by `mapTile`| |
| 204 | +||`CancellationToken` ctx|| |
| 205 | +|`GetMapTileWraparoundAsync`|`int` xTile|creates and loads a `MapTile` based on the supplied `scale`, `xTile` and `yTile` values. Wraparound is supported.| |
| 206 | +||`int` yTile|| |
| 207 | +||`int` scale|the map scale factor to use in defining the `MapTile`| |
| 208 | +||`CancellationToken` ctx|| |
| 209 | +|`GetMapTileAbsoluteAsync`|`int` xTile|creates and loads a `MapTile` based on the supplied `scale`, `xTile` and `yTile` values. Wraparound is *not* supported.| |
| 210 | +||`int` yTile|| |
| 211 | +||`int` scale|the map scale factor to use in defining the `MapTile`| |
| 212 | +||`CancellationToken` ctx|| |
| 213 | +|`LoadImageAsync`|`MapTile` mapTile|loads image data into `mapTile`, getting it either from the cache (if one is defined) or the mapping service.| |
| 214 | +||`CancellationToken` ctx|| |
| 215 | +|`LoadRegionAsync`|`MapRegion` region|loads image data into all the MapTiles defined for `region`, getting it either from the cache (if one is defined) or the mapping service.| |
| 216 | +||`CancellationToken` ctx|| |
| 217 | + |
| 218 | +[return to top](#overview) |
| 219 | + |
| 220 | +[return to usage table of contents](usage.md) |
0 commit comments