|
| 1 | +# J4JMapLibrary: Using the Projection Factory |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +- [Ensuring Your Credentials Can Be Found](#ensuring-your-credentials-can-be-found) |
| 6 | +- [Creating the Factory](#creating-the-factory) |
| 7 | +- [Creating a Projection](#creating-a-projection) |
| 8 | +- Custom Projections and Credentials |
| 9 | + - [Scanning for Custom Projections and Credentials](#scanning-for-custom-projections-and-credentials) |
| 10 | + - [Ensuring Custom Projections Can Be Found](#ensuring-custom-projections-can-be-found) |
| 11 | + |
| 12 | +While it's fairly straightforward to create a projection, in order to make it possible to do so by choosing one of the caches at run time inspired me to write `ProjectionFactory`. |
| 13 | + |
| 14 | +In order for the factory to work, however, two things are necessary: |
| 15 | + |
| 16 | +- all authentication information must be available through the `IConfiguration` system; and, |
| 17 | +- you must have the factory scan whatever assemblies contain `Projection` classes. By default, the factory will scan the library itself, so the four default projections -- Bing Maps, Google Maps, Open Street Maps and Open Topo Maps -- will be included. |
| 18 | + |
| 19 | +This is covered in more detail below. |
| 20 | + |
| 21 | +## Ensuring Your Credentials Can Be Found |
| 22 | + |
| 23 | +To make a projection's credential information available through the `IConfiguration` system, it must be organized in a configuration section called **Credentails**, further identified by the credentials's name. That's so the following code can work: |
| 24 | + |
| 25 | +```csharp |
| 26 | +var retVal = Activator.CreateInstance( credType.CredentialsType )!; |
| 27 | + |
| 28 | +var section = _config.GetSection( $"Credentials:{credType.Name}" ); |
| 29 | +section.Bind( retVal ); |
| 30 | +``` |
| 31 | + |
| 32 | +The built-in credentials have the following names: |
| 33 | + |
| 34 | +|Credential Class|Name| |
| 35 | +|----------|----| |
| 36 | +|`BingCredentials`|BingMaps| |
| 37 | +|`GoogleCredentials`|GoogleMaps| |
| 38 | +|`OpenStreetCredentials`|OpenStreetMaps| |
| 39 | +|`OpenTopoCredentials`|OpenTopoMaps| |
| 40 | + |
| 41 | +For more details on custom credentials and projections, consult the [documentation on how to create custom projections and credentials](custom-projections.md). |
| 42 | + |
| 43 | +[return to table of contents](#overview) |
| 44 | + |
| 45 | +[return to usage table of contents](usage.md#overview) |
| 46 | + |
| 47 | +## Creating the Factory |
| 48 | + |
| 49 | +The factory constructor takes the following parameters: |
| 50 | + |
| 51 | +|Parameter|Parameter Description| |
| 52 | +|---------|---------------------| |
| 53 | +|`IConfiguration` config|provides access to the Microsoft configuration system| |
| 54 | +|`ILoggerFactory?` loggerFactory = null|optional; provides access to the Microsoft logging factory| |
| 55 | +|`bool` includeDefaults = true|default (true) is to scan the library itself| |
| 56 | + |
| 57 | +*You must call `InitializeFactory()` before attempting to use it*. It returns `true` if at least one `Projection` class was found, `false` otherwise. Initialization is somewhat fragile because a lot of reflection is used in order to locate the projection classes and their corresponding credential classes. |
| 58 | + |
| 59 | +[return to table of contents](#overview) |
| 60 | + |
| 61 | +[return to usage table of contents](usage.md#overview) |
| 62 | + |
| 63 | +## Creating a Projection |
| 64 | + |
| 65 | +Once you've initialized the factory you can call one of its creation methods to obtain a projection, all of which return an instance of `ProjectionFactoryResult`. Each comes in both synchronous and asynchronous forms. |
| 66 | + |
| 67 | +### CreateProjection(), CreateProjectionAsync() |
| 68 | + |
| 69 | +|Parameter|Parameter Description| |
| 70 | +|---------|---------------------| |
| 71 | +|`string` projName|the name of the projection (see below)| |
| 72 | +|`ITileCache?` cache = null|the cache to use (optional); ignored for projections which don't support caching| |
| 73 | +|`string?` credentialsName = null|the name of the credentials class (optional)| |
| 74 | +|`bool` authenticate = true|controls whether or not to authenticate the projection after it's created (default: true)| |
| 75 | + |
| 76 | +### Generic CreateProjection<TProj>(), CreateProjectionAsync<TProj>() |
| 77 | + |
| 78 | +|Parameter|Parameter Description| |
| 79 | +|---------|---------------------| |
| 80 | +|`TProj`|the projection type (e.g., `BingMapsProjection`)| |
| 81 | +|`ITileCache?` cache = null|the cache to use (optional); ignored for projections which don't support caching| |
| 82 | +|`string?` credentialsName = null|the name of the credentials class (optional)| |
| 83 | +|`bool` authenticate = true|controls whether or not to authenticate the projection after it's created (default: true)| |
| 84 | + |
| 85 | +### Type-based CreateProjection(), CreateProjectionAsync() |
| 86 | + |
| 87 | +|Parameter|Parameter Description| |
| 88 | +|---------|---------------------| |
| 89 | +|`Type` projType|the projection type (e.g., `typeof(BingMapsProjection)`)| |
| 90 | +|`ITileCache?` cache = null|the cache to use (optional); ignored for projections which don't support caching| |
| 91 | +|`string?` credentialsName = null|the name of the credentials class (optional)| |
| 92 | +|`bool` authenticate = true|controls whether or not to authenticate the projection after it's created (default: true)| |
| 93 | + |
| 94 | +The names of the built-in projections are as follows: |
| 95 | + |
| 96 | +|Projection Class|Name| |
| 97 | +|----------|----| |
| 98 | +|`BingMapsProjection`|BingMaps| |
| 99 | +|`GoogleMapsProjection`|GoogleMaps| |
| 100 | +|`OpenStreetMapsProjection`|OpenStreetMaps| |
| 101 | +|`OpenTopoMapsProjection`|OpenTopoMaps| |
| 102 | + |
| 103 | +[return to table of contents](#overview) |
| 104 | +[return to usage table of contents](usage.md#overview) |
| 105 | + |
| 106 | +## Scanning for Custom Projections and Credentials |
| 107 | + |
| 108 | +To have the factory include custom projection and credential classes you may have written you need to call one of the `ScanAssembly()` methods before calling `InitializeFactory()`. The `ScanAssemblies()` methods return the `ProjectionFactory` itself, so they can be daisy-chained. |
| 109 | + |
| 110 | +[return to table of contents](#overview) |
| 111 | + |
| 112 | +[return to usage table of contents](usage.md#overview) |
| 113 | + |
| 114 | +## Ensuring Custom Projections Can Be Found |
| 115 | + |
| 116 | +If you create a custom projection class you must deocrate it with a `ProjectionAttribute` in order for the factory to find it when it scans the assembly where it's defined. Here's an example of how the built-in `BingMapsProjection` class is named: |
| 117 | + |
| 118 | +```csharp |
| 119 | +[ Projection( "BingMaps" ) ] |
| 120 | +public sealed class BingMapsProjection : TiledProjection<BingCredentials> |
| 121 | +``` |
| 122 | + |
| 123 | +Projection names must be unique within the application's environment, so be sure not to duplicate any of the built-in names: |
| 124 | + |
| 125 | +|Projection Class|Name| |
| 126 | +|----------|----| |
| 127 | +|`BingMapsProjection`|BingMaps| |
| 128 | +|`GoogleMapsProjection`|GoogleMaps| |
| 129 | +|`OpenStreetMapsProjection`|OpenStreetMaps| |
| 130 | +|`OpenTopoMapsProjection`|OpenTopoMaps| |
| 131 | + |
| 132 | +For more details on custom credentials and projections, consult the [documentation on how to create custom projections and credentials](custom-projections.md). |
| 133 | + |
| 134 | +[return to table of contents](#overview) |
| 135 | + |
| 136 | +[return to usage table of contents](usage.md#overview) |
0 commit comments