Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/trigger-website.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Trigger Website Build

on:
release:
types: [published]

jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Trigger ODINv2.Website build
# NOTE: Cross-repo dispatch requires a Personal Access Token (PAT) with
# "repo" scope stored as a repository secret named WEBSITE_DISPATCH_TOKEN.
# The default GITHUB_TOKEN does not have permission to dispatch events
# to other repositories.
run: |
curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${{ secrets.WEBSITE_DISPATCH_TOKEN }}" \
https://api.github.com/repos/syncpoint/ODINv2.Website/dispatches \
-d '{"event_type":"release-published","client_payload":{"tag":"${{ github.event.release.tag_name }}"}}'
1 change: 1 addition & 0 deletions docs-src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
site/
33 changes: 33 additions & 0 deletions docs-src/docs/features/collaboration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Real-Time Collaboration

ODIN supports real-time collaboration through the [Matrix](https://matrix.org) protocol. Multiple ODIN instances can share layers and synchronise changes in real time.

## How It Works

Collaboration in ODIN operates at the **layer level**. When you share a layer, it becomes available to other ODIN users connected to the same Matrix server. Changes to features within shared layers are replicated automatically.

Matrix is a federated, open protocol — you can use public Matrix servers or host your own for full control over your data.

## Sharing a Layer

1. Select the layer you want to share in the sidebar
2. Open the **Sharing** panel from the Properties Panel
3. Configure the Matrix server connection
4. Invite collaborators

## Permissions

Shared layers support different permission levels:

| Power Level | Access |
|------------|--------|
| 0 | Read-only access |
| 25 | Read and write (create/edit features) |
| 50 | Change layer name and settings |
| 100 | Full control (creator) |

A shared layer is **read-only by default**. Permissions for individual users can be changed at any time by the layer owner.

## Community

Join the ODIN community on Matrix: [#ODIN.Community:syncpoint.io](https://matrix.to/#/#ODIN.Community:syncpoint.io)
148 changes: 148 additions & 0 deletions docs-src/docs/features/elevation-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Elevation Data and Elevation Profile

ODIN supports RGB-encoded terrain tiles for displaying elevation data. When configured, elevation information is shown at the cursor position and can be used to generate elevation profiles along lines.

## Setting Up Elevation Data

Elevation data is provided through tile services that encode elevation values in the RGB channels of each pixel (Mapbox Terrain-RGB format). ODIN supports three tile service types as terrain sources:

- **XYZ** — direct `{z}/{x}/{y}` tile URL
- **TileJSON** — a single TileJSON endpoint
- **TileJSON Discovery** — a server (e.g. [mbtileserver](https://github.com/consbio/mbtileserver)) that exposes multiple tilesets, any of which can individually be marked as terrain

### Step 1: Add a Terrain Tile Service

1. Press `Ctrl+N` followed by `T` to create a new tile service
2. In the **URL** field, enter the address of your terrain tile server
3. Press `Tab` or click outside the field to confirm

ODIN automatically detects the service type from the URL response.

### Step 2: Mark as Terrain Data

**For XYZ and TileJSON services:**

1. In the tile service properties, enable the **RGB-encoded terrain data** checkbox
2. This tells ODIN to interpret the tile pixels as elevation values instead of displaying them as a visible map layer

**For TileJSON Discovery services:**

A discovery endpoint may expose multiple tilesets — some may be regular map tiles, others may contain elevation data. Terrain is configured per tileset:

1. In the layer list, select the tileset that contains elevation data
2. Enable the **RGB-encoded terrain data** checkbox
3. Repeat for any additional terrain tilesets

Each discovered tileset can be independently marked as terrain or left as a regular map layer.

The terrain layer will be active but invisible on the map. Elevation values are decoded using the Mapbox Terrain-RGB formula:

```
elevation = -10000 + (R * 65536 + G * 256 + B) * 0.1
```

### Step 3: Verify

Once configured, the current elevation is displayed in the on-screen display (bottom-right corner) as you move the cursor over the map.

## Elevation Profile

The Elevation Profile tool generates a chart showing elevation (Y-axis) vs. distance (X-axis) along a line. It works independently of the current map viewport — even parts of the line that extend beyond the visible area are sampled correctly.

### Creating an Elevation Profile

There are two ways to create an elevation profile:

#### Option A: From a Selected Feature

1. Select an existing feature with a LineString geometry on the map
2. Open the measure dropdown in the toolbar (ruler icon)
3. Click **Elevation Profile**
4. The profile chart appears at the bottom of the screen

#### Option B: By Drawing a Line

1. Make sure no LineString feature is selected
2. Open the measure dropdown and click **Elevation Profile**
3. Draw a line on the map by clicking to place points
4. Double-click to finish the line
5. The profile chart appears at the bottom of the screen

### Reading the Profile Chart

The chart displays:

- **X-axis**: Distance along the line (in meters or kilometers)
- **Y-axis**: Elevation (in meters), auto-scaled to the data range
- **Orange filled area**: The elevation curve along the line
- **Dashed vertical lines**: Segment boundaries (see below)

#### Header Statistics

The header bar shows summary statistics for the profile:

| Statistic | Description |
|-----------|-------------|
| **Min** | Lowest elevation along the line |
| **Max** | Highest elevation along the line |
| **Dist** | Total geodesic length of the line |
| **↑** | Total ascent (cumulative elevation gain) |
| **↓** | Total descent (cumulative elevation loss) |

#### Segment Markers

When the profile is based on a line with multiple segments (more than two vertices), dashed vertical lines appear in the chart at the distance where each segment boundary (vertex) is located. These markers help you correlate specific sections of the profile with the corresponding segments of the line on the map. For example, if your line follows a road with several waypoints, each marker shows where one segment ends and the next begins.

#### Hover Interaction

- Move the mouse over the chart to see a crosshair with the exact elevation and distance at that position
- A corresponding orange marker appears on the map, showing the geographic location of the hovered point
- Moving the mouse off the chart removes the marker

### Editing the Profile Line

#### Drawn Lines

Lines drawn with the Elevation Profile tool are immediately editable:

- **Move a vertex**: Click and drag an existing vertex
- **Add a vertex**: Click on a segment between vertices
- **Remove a vertex**: Alt-click (Option-click on macOS) on a vertex

The elevation profile recalculates automatically after each edit.

#### Selected Features

When the profile is based on a selected feature from the map, edits made to that feature through ODIN's standard modify tool are also reflected in the profile. The chart updates automatically when the geometry changes.

### Closing the Profile

Click the **X** button in the profile panel header. This also removes the line highlight and hover marker from the map.

## Tips

- The Elevation Profile button in the toolbar is only enabled when at least one terrain tile service is configured
- Disabling the last terrain source automatically closes any open elevation profile
- You can create multiple profiles in sequence — each new profile replaces the previous one
- For best results, use a terrain tile service that covers the area of your line
- Terrain tiles are cached in memory (up to 200 tiles), so revisiting the same area is fast
- The tool automatically uses the highest available zoom level of the terrain service, regardless of how far you are zoomed in on the map

## Troubleshooting

| Problem | Solution |
|---------|----------|
| Elevation Profile is greyed out in the menu | No terrain tile service is configured. Add a tile service (XYZ, TileJSON, or TileJSON Discovery) and enable "RGB-encoded terrain data" |
| Profile chart is empty or shows gaps | The line extends beyond the terrain tile coverage area. Gaps indicate coordinates where no elevation data is available |
| No elevation shown at cursor position | Verify the terrain tile service is correctly configured and the server is accessible |
| Profile doesn't update after editing | Edits trigger a debounced recalculation (300ms delay). Wait briefly for the profile to refresh |

## Terrain Tile Sources

Any tile server providing Mapbox Terrain-RGB encoded tiles is compatible. Supported configurations:

- **Direct XYZ URL** — standard `{z}/{x}/{y}` tile endpoint
- **TileJSON endpoint** — a URL serving a [TileJSON](https://github.com/mapbox/tilejson-spec) document with a `tiles` array
- **TileJSON Discovery server** — a server like [mbtileserver](https://github.com/consbio/mbtileserver) that lists multiple tilesets; individual tilesets can be marked as terrain independently

In all cases, tiles must be served with CORS headers (`Access-Control-Allow-Origin`) enabled.
47 changes: 47 additions & 0 deletions docs-src/docs/features/mgrs-graticule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# MGRS Graticule

ODIN provides a Military Grid Reference System (MGRS) coordinate grid overlay for the map. The grid is rendered as a vector layer and adapts its level of detail based on the current zoom level.

## Enabling the MGRS Grid

1. Open the **View** menu
2. Select **Graticules → MGRS**

The MGRS grid overlay appears on the map. WGS84 and MGRS graticules are mutually exclusive — enabling one disables the other.

## Grid Levels

The graticule renders three levels of detail based on the map resolution:

| Level | Grid Spacing | Visible When | Content |
|-------|-------------|--------------|---------|
| Grid Zone Designation (GZD) | 6° × 8° | Always | Zone boundaries and labels (e.g. `33U`) |
| 100 km Squares | 100 km | Resolution ≤ ~1200 m/px | Grid lines and two-letter square identifiers (e.g. `WP`) |
| 10 km Squares | 10 km | Resolution ≤ ~120 m/px | Fine grid lines with numeric labels |

## About MGRS

MGRS is based on the Universal Transverse Mercator (UTM) projection. UTM divides the world into 60 zones (each 6° wide) and lettered latitude bands (each 8° tall, from 80°S to 84°N). Within each zone, locations are identified by 100 km square letters and numeric easting/northing offsets.

### Example MGRS Coordinate

```
33U WP 12345 67890
```

- `33U` — Grid Zone Designation (zone 33, band U)
- `WP` — 100 km square identifier
- `12345 67890` — Easting and northing within the square (1 m precision)

## Styling

- **GZD boundaries** — Thicker stroke with zone labels at the centre of each visible zone
- **100 km grid lines** — Medium stroke with square letter labels
- **10 km grid lines** — Thin stroke with numeric labels
- All lines use a neutral colour to avoid interfering with map content

## Limitations

- UTM special zones (Norway, Svalbard) use standard 6° boundaries
- Polar regions (UPS) are not supported
- Grid levels finer than 10 km (1 km, 100 m) are not yet available
133 changes: 133 additions & 0 deletions docs-src/docs/features/shapes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Shapes — Lines, Polygons, and Text

ODIN supports custom shapes that are not part of the military symbology standard.
These are plain geometric features — lines, polygons, and text labels — that you can
freely place on the map and style to your liking.

## Drawing Shapes

All shape tools are available from the **Shapes dropdown** in the toolbar
(the icon with the geometric shape outline).

![Shapes dropdown menu](img/shapes-dropdown.jpg)
*The Shapes dropdown offers three drawing tools: Line, Polygon, and Text.*

### Drawing a Line

1. Click the **Shapes** dropdown in the toolbar.
2. Select **Draw Line**.
3. Click on the map to place each vertex of the line.
4. **Double-click** to finish the line.

The line appears with a default black stroke (width 2).

### Drawing a Polygon

1. Click the **Shapes** dropdown in the toolbar.
2. Select **Draw Polygon**.
3. Click on the map to place each vertex of the polygon.
4. **Double-click** to close and finish the polygon.

The polygon appears with a black outline and no fill by default.

### Placing Text

1. Click the **Shapes** dropdown in the toolbar.
2. Select **Place Text**.
3. Click on the map where you want the text to appear.

A text label reading "Text" is placed at the clicked position.
You can immediately edit it in the properties panel.

## Editing Shapes

Select any shape on the map or in the sidebar to open its **Properties Panel**.

### Line Properties

| Property | Description |
|---|---|
| **Line Color** | Color of the line stroke. Choose from the palette or leave undefined. |
| **Line Width** | Thickness from S (1px) to XXXL (6px). |
| **Line Style** | Solid, Dashed, or Dotted. |

### Polygon Properties

Polygons have all the line properties above, plus:

| Property | Description |
|---|---|
| **Fill Color** | Interior fill color. Leave undefined for no fill. |
| **Fill Opacity** | Transparency of the fill, from 0 (transparent) to 1 (opaque). |

### Text Properties

The text properties panel has two sections:

#### Text Input

A text area where you can type or paste your content.
A simple **Markdown** dialect is supported:

```
# Heading
## Subheading
- Bullet point
* Another bullet point
Plain text on multiple lines
```

- `#` creates a large, bold heading
- `##` creates a medium, bold subheading
- `-` or `*` at the start of a line creates a bullet list item
- Everything else is rendered as plain text

![Text shape with markdown](img/shapes-text-markdown.jpg)
*A text shape using markdown for structured annotations. The properties panel on the right shows the text input and style options.*

#### Style Options

| Property | Description |
|---|---|
| **Text Color** | Color of the text. Default: black. |
| **Background Color** | Color of the text box background. Default: white. |
| **Background Opacity** | Transparency of the background, from 0 (fully transparent) to 1 (opaque). Default: 0.8. |
| **Font Size** | Base font size from 10px to 32px. Headings scale proportionally. |
| **Rotation** | Rotate the text label from 0° to 359°. Use the slider for fine control. |
| **Text Scale** | Click **"Use current view as full size"** to set the current zoom level as the reference. The text will appear at full size at this zoom level and shrink proportionally when zoomed out. |

## Zoom Behavior (Text)

Text labels scale with the map zoom level:

- At the **reference zoom** (set when the text was created, or adjusted via the button),
the text appears at full size.
- When **zooming out**, the text shrinks proportionally so it does not cover the map.
- The text never shrinks below 15% of its original size.
- When **zooming in** beyond the reference level, the text stays at full size
(it does not grow larger).

This ensures text labels are readable at the zoom level they were designed for,
without cluttering the map at overview zoom levels.

## Sidebar Tags

Shapes are tagged in the sidebar for easy filtering:

- **SHAPE** — all shape features
- **LINE** — line shapes
- **POLYGON** — polygon shapes
- **TEXT** — text shapes

Use the tag search to quickly filter for specific shape types.

## Tips

- **Text as map annotations:** Use text shapes to add context to your map —
unit names, phase labels, terrain notes, or any free-form information.
- **Transparent backgrounds:** Set background opacity to 0 for text that
floats directly on the map without a box.
- **Rotated labels:** Use rotation to align text with roads, borders, or
other linear features on the map.
- **Markdown headings:** Use `#` headings for titles and `-` lists for
structured annotations like task organizations or key terrain lists.
Loading