Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable basemaps from init json #5140

Merged
merged 27 commits into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
be07a69
make base maps configurable from init files
zoran995 Jan 14, 2021
b0dc6b4
default previewBaseMapId to basemap-positron
zoran995 Jan 14, 2021
10163f0
set the defaultBaseMaps after load of all init files if there are no …
zoran995 Jan 14, 2021
f2babec
remove bad import and unnecessary check
zoran995 Jan 14, 2021
d399d68
Merge remote-tracking branch 'terriajs/next' into configurable-basemaps
zoran995 Jan 14, 2021
5d25dc1
don't add multiple basemaps with same id
zoran995 Jan 14, 2021
14ac1f0
remove unused import
zoran995 Jan 15, 2021
5302c6f
Merge remote-tracking branch 'terriajs/next' into configurable-basemaps
zoran995 Jan 16, 2021
b32da7d
add tests and fix loading of default basemaps
zoran995 Jan 17, 2021
b6bd5a1
add default for previewBaseMapId
zoran995 Jan 17, 2021
7375a1d
update documentation for init files
zoran995 Jan 17, 2021
35c8d14
fix init files doc, missing blank line
zoran995 Jan 17, 2021
188b60a
Update CHANGES.md
zoran995 Jan 17, 2021
c8c27fc
Update CHANGES.md
zoran995 Jan 17, 2021
90e9ade
update references to corr
zoran995 Jan 17, 2021
bd30dbf
document the rest of init properties
zoran995 Jan 17, 2021
7d7f804
document the rest of init properties 2
zoran995 Jan 17, 2021
f0e7c79
add missing initData prop
zoran995 Jan 19, 2021
9f0fca1
Restore wrong path in doc
zoran995 Jan 19, 2021
fb0f9ba
Merge remote-tracking branch 'terriajs/next' into configurable-basemaps
zoran995 Feb 25, 2021
bf7a849
Merge remote-tracking branch 'origin/next' into configurable-basemaps
nf-s Mar 22, 2021
23f6b4c
changes
nf-s Mar 22, 2021
7f189de
fix mappable
nf-s Mar 22, 2021
55a1cf3
remove references to v7 docs
nf-s Mar 22, 2021
4405c0e
change comment
nf-s Mar 22, 2021
b3d834a
add breaking changes warning to CHANGES.md
nf-s Mar 22, 2021
c1445a8
change default basemap assetId to ionAssetId
nf-s Mar 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Change Log
### MobX Development

#### next release (8.0.0-alpha.69)

- **Breaking changes**:
- Basemaps are now configured through catalog JSON instead of TerriaMap - see https://github.com/TerriaJS/terriajs/blob/next/doc/customizing/initialization-files.md#base-maps

* Make base maps configurable from init files and update documentation for init files [#5140](https://github.com/TerriaJS/terriajs/pull/5140).
* [The next improvement]

#### 8.0.0-alpha.68
Expand Down
1 change: 1 addition & 0 deletions doc/connecting-to-data/catalog-functions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## TODO: V8 `CatalogFunction` Docs
1 change: 1 addition & 0 deletions doc/connecting-to-data/catalog-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## TODO: V8 `CatalogGroup` Docs
1 change: 1 addition & 0 deletions doc/connecting-to-data/catalog-items.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## TODO: V8 `CatalogItem` Docs
152 changes: 104 additions & 48 deletions doc/customizing/initialization-files.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
A catalog in TerriaJS is defined in one or more "initialization files" (or init files). In a default TerriaMap installation, the main init file is found in `wwwroot/init/terria.json`.
A catalog in TerriaJS is defined in one or more "initialization files" (or init files). In a default TerriaMap installation, the main init file is found in `wwwroot/init/simple.json`.

An init file is a [JSON file](https://en.wikipedia.org/wiki/JSON) with this basic structure:

```
```json
{
"catalog": [
{
Expand All @@ -21,7 +21,20 @@ An init file is a [JSON file](https://en.wikipedia.org/wiki/JSON) with this basi
"west": 109
},
"initialCamera": { ... },
"corsDomains": [ "myserver.gov.au" ]
"corsDomains": [ "myserver.gov.au" ],
"baseMapId": "basemap-dark-matter",
"previewBaseMapId": "basemap-dark-matter",
"baseMaps": [
{
"item": {
"id": "basemap-darkmatter",
"name": "Dark Matter",
...
},
"image": "/images/dark-matter.png"
},
...
]
}
```

Expand Down Expand Up @@ -55,29 +68,37 @@ Catalog files can be edited two ways:
2. Using a JSON-specific editor, such as [http://www.jsoneditoronline.org/](http://www.jsoneditoronline.org/). This has the advantage that your file will be valid JSON.

## Catalog file properties

### `corsDomains`

By default, TerriaJS proxies all requests within the proxy whitelist specified in the [Server-side Config](server-side-config.md), making the assumption that the servers do not support CORS. You can add hosts that are known to support CORS to this property to avoid proxying them.

`"corsDomains": [ "myserver.gov.au" ]`

See [Cross-Origin Resource Sharing](../connecting-to-data/cross-origin-resource-sharing.md) for more information.

### `homeCamera` and `initialCamera`

Maps have two camera positions, `homeCamera` and `initialCamera`. They are specified identically. All the examples here use `homeCamera`, but apply equally to both.

* `initialCamera`: the location when the map first displays
* `homeCamera`: where the camera goes when you click the "home" button between the zoom-in and zoom-out buttons.
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|corsDomains|no|**string[]**||By default, TerriaJS proxies all requests within the proxy whitelist specified in the [Server-side Config](server-side-config.md), making the assumption that the servers do not support CORS. You can add hosts that are known to support CORS to this property to avoid proxying them.|
|catalog|no|[**CatalogItem[]**](../connecting-to-data/catalog-items.md), [**CatalogGroup[]**](../connecting-to-data/catalog-groups.md), [**CatalogFunction[]**](../connecting-to-data/catalog-functions.md)||An array of catalog items, groups and functions. Check example above.|
|initialCamera|no|[**CameraPosition**](#CameraPosition)||The location when the map first displays.|
|stories|no|[**Story[]**](#story)||An array of stories to be loaded.|
|viewerMode|no|**"3d"** or **"3dSmooth"** or **"2D"** |"3d"|The id of the viewer mode to be shown initialy.|
|homeCamera|yes|[**CameraPosition**](#CameraPosition)||Where the camera goes when you click the "home" button between the zoom-in and zoom-out buttons.|
|<a id="base-maps"></a>baseMaps|no|[**`baseMaps`**](#baseMaps)|[default list of basemaps](../../lib/Models/BaseMaps/defaultBaseMaps.ts)|The array of the base maps to be shown to the user.|
|<a id="base-map-id"></a>baseMapId|no|**string**||The id of the baseMap user will see on the first mapLoad. The value must be an id of the catalog item from the [`baseMaps`](#base-maps) array|
|previewBaseMapId|no|**string**|[`baseMapId`](#base-map-id)|The id of the baseMap to be used as the base map in data preview. The value must be an id of the catalog item from the [`baseMaps`](#base-maps) array.|
|showSplitter|no|**boolean**|false|Show splitter initally.|
|splitPosition|no|**number**|0.5|The position of splitter.|
|workbench|no|**string[]**||List of items ids to initially add to workbench.|
|previewedItemId|no|string||ID of the catalog member that is currently being previewed.|

### CameraPosition

#### Option 1: `north`, `south`, `east`, `west`

The bounding box method uses `north`, `east `,`south`, and `west`, in lat/lng decimal degrees. The camera will be positioned in the center point of those bounds, looking toward the Earth's center, zoomed back enough to see to the edges of the bounds.

This is the only mode supported in 2D mode (Leaflet). Therefore, you should always include a bounding box, even if you also use another mode.

```
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|north|yes|**number**|||
|east|yes|**number**|||
|south|yes|**number**|||
|west|yes|**number**|||

**Example**
```json
"homeCamera": {
"north": -8,
"east": 158,
Expand All @@ -100,15 +121,18 @@ the north pole, positive X points toward
equator intersects with 0 degrees longitude, and positive Y points at
(0, 90E) -- which is in the Indian Ocean south of the Bay of Bengal.

* `position`: where the camera is
* `direction`: where the camera is looking
* `up`: which way is "up", which determines how the camera is rotated
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|position|yes|[**Cartesian 3**](#cartesian-3)|| location of the camera.|
|direction|yes|[**Cartesian 3**](#cartesian-3)||The location camera is looking at.|
|up|yes|[**Cartesian 3**](#cartesian-3)||Which way is "up", which determines how the camera is rotated.|

For most purposes positioning this way is difficult for normal
humans. To see an example, move the camera to some location, click the "share" button (and choose to not use the
URL shortner), then URL-decode the URL you get.

```
**Example**
```json
"homeCamera": {
"west": 105.51019777628066,
"south": -39.61110094535454,
Expand All @@ -134,27 +158,27 @@ URL shortner), then URL-decode the URL you get.

#### Option 3: `positionHeading` (like an aircraft)

Setting `positionHeading` is useful for when you're showing a view from an aircraft or
satellite, and overrides Options 1 and 2.
Setting `positionHeading` is useful for when you're showing a view from an aircraft or satellite, and overrides Options 1 and 2.

It has the following attributes:
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|cameraLongitude|yes|**number**||Longitude of camera|
|cameraLatitude|yes|**number**||Latitude of camera|
|cameraHeight|yes|**number**||Height of camera above earth's surface, probably in metres|
|heading|yes|**number**||In degrees clockwise from north (90 is east)|
|pitch|yes|**number**||How much the camera is tilted, in degrees down from horizontal (-90 is straight down).|
|roll|yes|**number**||How much the camera is rotated left or right, in degrees.|

- `cameraLongitude`: longitude of camera
- `cameraLatitude`: latitude of camera
- `cameraHeight`: height of camera above earth's surface, probably in metres
- `heading`: in degrees clockwise from north (90 is east)
- `pitch`: how much the camera is tilted, in degrees down from horizontal (-90 is straight down)
- `roll`: how much the camera is rotated left or right, in degrees

```
**Example**
```json
"homeCamera": {
"positionHeading": {
"cameraLongitude": 145,
"cameraLatitude": -37,
"cameraHeight": 1000,
"heading": 0,
"pitch": -70,
"roll": 0,
"roll": 0
}
}
```
Expand All @@ -164,24 +188,56 @@ It has the following attributes:
`lookAt` is probably the most useful one for showing a feature on the
map, and overrides Options 1, 2, and 3.

It has these attributes:

- `targetLongitude`: The longitude to look at
- `targetLatitude`: The latitude to look at
- `targetHeight`: in meters above the WGS84 ellipsoid (positive is up)
- `heading`: in degrees clockwise from north
- `pitch`: in degrees down from horizontal (so negative values mean you're looking at the sky)
- `range`: in meters from the thing you're looking at

```
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|targetLongitude|yes|**number**||The longitude to look at.|
|targetLatitude|yes|**number**||The latitude to look at.|
|targetHeight|yes|**number**||In meters above the WGS84 ellipsoid (positive is up).|
|heading|yes|**number**||In degrees clockwise from north.|
|pitch|yes|**number**||How much the camera is tilted, in degrees down from horizontal (so negative values mean you're looking at the sky).|
|range|yes|**number**||In meters from the thing you're looking at.|

**Example**
```json
"homeCamera": {
"lookAt": {
"targetLongitude": 145,
"targetLatitude": 37,
"targetHeight": 0,
"heading": 0,
"pitch": -90,
"range": 1000,
"range": 1000
}
}
```

### Story

Definition of the story. This can be pretty complex to define for the standard user, the easiest way is to generate share url without url shortener.

|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|id|yes|**string**||Id of the story.|
|title|yes|**string**||Title of the story.|
|text|yes|**string**||Text of the story.|
|shareData|yes|[**ShareData**](#sharedata)|||

#### ShareData
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|version|yes|string|"8.0.0"|The version of share data.|
|initSources|yes|[**CatalogFileProperties**](#catalog-file-properties)

### `baseMaps`
Definition of the baseMap model.
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|item|yes|[**Catalog Item**](../connecting-to-data/catalog-items.md)||Catalog item defition to be used for the base map|
|image|yes|**string**||Path to an image file of the baseMap image to be shown in Map Settings|

### Cartesian 3
|Name|Required|Type|Default|Description|
|----|--------|----|-------|-----------|
|x|yes|**number**||The X component.|
|y|yes|**number**||The Y component.|
|z|yes|**number**||The Z component.|
55 changes: 55 additions & 0 deletions lib/Models/BaseMaps/BaseMapModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import CatalogMemberMixin from "../../ModelMixins/CatalogMemberMixin";
import { BaseMapViewModel } from "../../ViewModels/BaseMapViewModel";
import BingMapsCatalogItem from "../BingMapsCatalogItem";
import CatalogMemberFactory from "../CatalogMemberFactory";
import CommonStrata from "../CommonStrata";
import { BaseModel } from "../Model";
import Terria from "../Terria";
import upsertModelFromJson from "../upsertModelFromJson";
import MappableMixin from "../../ModelMixins/MappableMixin";

export interface BaseMapModel {
image: string;
item: BaseModel;
}

export function processBaseMaps(newBaseMaps: BaseMapModel[], terria: Terria) {
newBaseMaps.forEach(newBaseMap => {
const item = newBaseMap.item;
if (!item) {
console.log("basemap is missing the item property.");
return;
}
if (
terria.baseMaps.some(
baseMap => baseMap.mappable.uniqueId === (<any>newBaseMap.item).id
)
) {
return;
}

if (item.type === BingMapsCatalogItem.type) {
addBingMapsKey(item, terria);
}
const model = upsertModelFromJson(
CatalogMemberFactory,
terria,
"/basemap/",
CommonStrata.definition,
newBaseMap.item,
{
addModelToTerria: true
}
);
if (MappableMixin.isMixedInto(model)) {
if (CatalogMemberMixin.isMixedInto(model)) model.loadMetadata();
terria.baseMaps.push(new BaseMapViewModel(model, newBaseMap.image));
}
});
}

function addBingMapsKey(item: any, terria: Terria) {
if (!item.key) {
item.key = terria.configParameters.bingMapsKey;
}
}