|
4 | 4 |
|
5 | 5 | MapLibre Native currently supports two ways to provide vector tile data: |
6 | 6 |
|
7 | | -1. **URL-based sources** (`vector` source type) — tiles are fetched from a remote server via HTTP. |
| 7 | +1. **URL-based sources** (`vector` source type) — tiles are fetched according to the protocol of the URL (`http://`, |
| 8 | + `file://`, etc.). |
8 | 9 | 2. **CustomGeometrySource** — accepts GeoJSON features programmatically, but internally re-encodes them into vector |
9 | 10 | tiles, adding overhead and limiting control over the tile encoding. |
10 | 11 |
|
11 | | -This proposal comes from the need for an efficient way to connect a proprietary data source. |
12 | | -That data source provides a gRPC service that has a simple API to request tiles by X/Y/Z (similarly to vector tiles) and the |
13 | | -format itself is pretty close to vector tiles. |
14 | | -CustomGeometrySource was considered but it has some obvious drawbacks: |
| 12 | +This proposal comes from the need for an efficient and kotlin native way to asynchronously connect a tile data source |
| 13 | +similar to vector tile. |
| 14 | +CustomGeometrySource was considered, but it has some obvious drawbacks: |
15 | 15 |
|
16 | 16 | 1. Tile requests are in the format of a bounding box — since it's not a tile X/Y/Z it is pretty unclear what logic it |
17 | 17 | conforms to. |
18 | 18 | 1. Is it just a tile X/Y/Z but converted to geo bounds? |
19 | 19 | 2. Can it ever request data in a bounding box that is bigger than just one X/Y/Z tile |
20 | 20 | 3. Additional boilerplate of mapping geo bounds into tile X/Y/Z |
21 | | -2. Internally CustomGeometrySource spawns a 4 thread threadpool and runs tasks one by one inside. It's a good old technique |
| 21 | +2. Internally CustomGeometrySource spawns a 4 thread threadpool and runs tasks one by one inside. It's a good old |
| 22 | + technique |
22 | 23 | but Kotlin has things like coroutines which are a more ergonomic way to handle suspendable operations (like network |
23 | 24 | requests). |
24 | 25 | 3. CustomGeometrySource operates over GeoJSON. So in case of a vector tiles like format it needs to be converted to |
@@ -67,10 +68,10 @@ requests tiles by `CanonicalTileID`, and the application responds asynchronously |
67 | 68 |
|
68 | 69 | ### Key Design Decisions |
69 | 70 |
|
70 | | -1. **Binary data, not GeoJSON.** For the Kotlin layer to send data to C++, it needs to be marshalled into some |
71 | | - data format that can be passed across languages. One could come up with a new binary format, implement an encoder in Kotlin |
72 | | - and a decoder in C++. But it turns out MVT is already such a format — just a binary blob that can be passed simply |
73 | | - as a sized buffer. Existing infrastructure of `MVT` tile data is just reused as is. |
| 71 | +1. **Binary data, not GeoJSON.** For the Kotlin layer to send data to C++, it needs to be marshaled into some |
| 72 | + data format that can be passed across languages. One could come up with a new binary format, implement an encoder in |
| 73 | + Kotlin and a decoder in C++. But it turns out MVT is already such a format — just a binary blob that can be passed |
| 74 | + simply as a sized buffer. Existing infrastructure of `MVT` tile data is just reused as is. |
74 | 75 |
|
75 | 76 | 2. **Actor-based concurrency.** `CustomVectorTileLoader` runs on a background thread via MapLibre's Actor system. The |
76 | 77 | platform callback (fetch/cancel) is invoked on this thread; the platform layer is responsible for dispatching to its |
|
0 commit comments