<a name="Panoramax.utils.API"></a>

## Panoramax.utils.API
**Kind**: static class of <code>Panoramax.utils</code>  
**Emits**: [<code>ready</code>](#Panoramax.utils.API+event_ready), [<code>broken</code>](#Panoramax.utils.API+event_broken)  

* [.API](#Panoramax.utils.API)
    * [new API(endpoint, [options])](#new_Panoramax.utils.API_new)
    * _instance_
        * [.onceReady()](#Panoramax.utils.API+onceReady) ⇒ <code>Promise</code>
        * [.isReady()](#Panoramax.utils.API+isReady) ⇒ <code>boolean</code>
        * [.getAvailableFeatures()](#Panoramax.utils.API+getAvailableFeatures) ⇒ <code>Array.&lt;string&gt;</code>
        * [.getUnavailableFeatures()](#Panoramax.utils.API+getUnavailableFeatures) ⇒ <code>Array.&lt;string&gt;</code>
        * [.getSequenceItems(seqId, [next], [data], [limit])](#Panoramax.utils.API+getSequenceItems) ⇒ <code>Promise</code>
        * [.getPicturesAroundCoordinatesUrl(lat, lon, [factor], [limit], [seqId])](#Panoramax.utils.API+getPicturesAroundCoordinatesUrl) ⇒ <code>string</code>
        * [.getPicturesAroundCoordinates(lat, lon, [factor], [limit], [seqId])](#Panoramax.utils.API+getPicturesAroundCoordinates) ⇒ <code>Promise</code>
        * [.getPictureMetadataUrl(picId, [seqId])](#Panoramax.utils.API+getPictureMetadataUrl) ⇒ <code>string</code>
        * [.getMapStyle()](#Panoramax.utils.API+getMapStyle) ⇒ <code>Promise</code> \| <code>object</code>
        * [.getUserMapStyle(userId, [skipReadyCheck])](#Panoramax.utils.API+getUserMapStyle) ⇒ <code>Promise</code>
        * [.getPictureThumbnailURLForSequence(seqId, [seq])](#Panoramax.utils.API+getPictureThumbnailURLForSequence) ⇒ <code>Promise</code>
        * [.getPictureThumbnailURL(picId, [seqId])](#Panoramax.utils.API+getPictureThumbnailURL) ⇒ <code>Promise</code>
        * [.getRSSURL([bbox])](#Panoramax.utils.API+getRSSURL) ⇒ <code>string</code> \| <code>null</code>
        * [.getSequenceMetadataUrl(seqId)](#Panoramax.utils.API+getSequenceMetadataUrl) ⇒ <code>string</code>
        * [.getSequenceMetadata(seqId)](#Panoramax.utils.API+getSequenceMetadata) ⇒ <code>Promise</code>
        * [.getDataBbox()](#Panoramax.utils.API+getDataBbox) ⇒ <code>LngLatBoundsLike</code>
        * [.searchUsers(query)](#Panoramax.utils.API+searchUsers) ⇒ <code>Promise</code>
        * [.getUserName(userId)](#Panoramax.utils.API+getUserName) ⇒ <code>Promise</code>
        * [.sendReport(data)](#Panoramax.utils.API+sendReport) ⇒ <code>Promise</code>
        * [.sendPictureSemantics(picMeta, semanticsDiff)](#Panoramax.utils.API+sendPictureSemantics) ⇒ <code>Promise</code>
        * [.createPictureAnnotation(picMeta, shape, semanticsDiff)](#Panoramax.utils.API+createPictureAnnotation) ⇒ <code>Promise</code>
        * [.editPictureAnnotation(annotationId, semanticsDiff)](#Panoramax.utils.API+editPictureAnnotation) ⇒ <code>Promise</code>
        * [.deletePictureAnnotation(annotationId)](#Panoramax.utils.API+deletePictureAnnotation) ⇒ <code>Promise</code>
        * [.getAuthURL()](#Panoramax.utils.API+getAuthURL) ⇒ <code>Promise</code>
        * ["broken"](#Panoramax.utils.API+event_broken)
        * ["ready"](#Panoramax.utils.API+event_ready)
    * _static_
        * [.isValidHttpUrl(str)](#Panoramax.utils.API.isValidHttpUrl) ⇒ <code>boolean</code>
        * [.isIdValid(id)](#Panoramax.utils.API.isIdValid) ⇒ <code>boolean</code>

<a name="new_Panoramax.utils.API_new"></a>

### new API(endpoint, [options])
API contains various utility functions to communicate with Panoramax/STAC API


| Param | Type | Default | Description |
| --- | --- | --- | --- |
| endpoint | <code>string</code> |  | The endpoint. It corresponds to the <a href="https://github.com/radiantearth/stac-api-spec/blob/main/overview.md#example-landing-page">STAC landing page</a>, with all links describing the API capabilities. |
| [options] | <code>object</code> |  | Options |
| [options.style] | <code>string</code> \| <code>object</code> |  | General map style |
| [options.tiles] | <code>string</code> |  | API route serving pictures & sequences vector tiles |
| [options.skipReadLanding] | <code>boolean</code> | <code>false</code> | True to not call API landing page automatically |
| [options.fetch] | <code>object</code> |  | Set custom options for fetch calls made against API ([same syntax as fetch options parameter](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters)) |
| [options.users] | <code>Array.&lt;string&gt;</code> |  | List of initial user IDs to load map styles for |

<a name="Panoramax.utils.API+onceReady"></a>

### api.onceReady() ⇒ <code>Promise</code>
Resolves when the API is ready to be used.

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>string</code> "API is ready" when initialization is complete.  
**Reject**: <code>string</code> Error message  
<a name="Panoramax.utils.API+isReady"></a>

### api.isReady() ⇒ <code>boolean</code>
Checks if the API is ready to be used.

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>boolean</code> - True if the API is ready, false otherwise.  
<a name="Panoramax.utils.API+getAvailableFeatures"></a>

### api.getAvailableFeatures() ⇒ <code>Array.&lt;string&gt;</code>
List of available features offered by API

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>Array.&lt;string&gt;</code> - Keywords of enabled features  
<a name="Panoramax.utils.API+getUnavailableFeatures"></a>

### api.getUnavailableFeatures() ⇒ <code>Array.&lt;string&gt;</code>
List of unavailable features on API

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>Array.&lt;string&gt;</code> - Keywords of disabled features  
<a name="Panoramax.utils.API+getSequenceItems"></a>

### api.getSequenceItems(seqId, [next], [data], [limit]) ⇒ <code>Promise</code>
Get sequence GeoJSON representation

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> Sequence GeoJSON  
**Reject**: <code>Error</code> If API is not ready or for any network issue  

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| seqId | <code>string</code> |  | The sequence ID |
| [next] | <code>string</code> | <code>null</code> | The next link URL (only for internals) |
| [data] | <code>object</code> | <code></code> | The previous dataset (only for internals) |
| [limit] | <code>number</code> | <code></code> | How many items to retrieve (defaults to unset). If set, pages are not looked through. |

<a name="Panoramax.utils.API+getPicturesAroundCoordinatesUrl"></a>

### api.getPicturesAroundCoordinatesUrl(lat, lon, [factor], [limit], [seqId]) ⇒ <code>string</code>
Get full URL for listing pictures around a specific location

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>string</code> - The corresponding URL  

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| lat | <code>number</code> |  | Latitude |
| lon | <code>number</code> |  | Longitude |
| [factor] | <code>number</code> | <code>0.0005</code> | The radius to search around (in degrees) |
| [limit] | <code>number</code> |  | Max amount of pictures to retrieve |
| [seqId] | <code>string</code> |  | The sequence ID to filter on (by default, no filter) |

<a name="Panoramax.utils.API+getPicturesAroundCoordinates"></a>

### api.getPicturesAroundCoordinates(lat, lon, [factor], [limit], [seqId]) ⇒ <code>Promise</code>
Get list of pictures around a specific location

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> The GeoJSON feature collection  

| Param | Type | Description |
| --- | --- | --- |
| lat | <code>number</code> | Latitude |
| lon | <code>number</code> | Longitude |
| [factor] | <code>number</code> | The radius to search around (in degrees) |
| [limit] | <code>number</code> | Max amount of pictures to retrieve |
| [seqId] | <code>string</code> | The sequence ID to filter on (by default, no filter) |

<a name="Panoramax.utils.API+getPictureMetadataUrl"></a>

### api.getPictureMetadataUrl(picId, [seqId]) ⇒ <code>string</code>
Get full URL for retrieving a specific picture metadata

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>string</code> - The corresponding URL  
**Throws**:

- <code>Error</code> If API is not ready


| Param | Type | Description |
| --- | --- | --- |
| picId | <code>string</code> | The picture unique identifier |
| [seqId] | <code>string</code> | The sequence ID |

<a name="Panoramax.utils.API+getMapStyle"></a>

### api.getMapStyle() ⇒ <code>Promise</code> \| <code>object</code>
Get JSON style for general vector tiles

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>Promise</code> \| <code>object</code> - Promise if first load, MapLibre JSON style otherwise  
**Fulfil**: <code>object</code> The MapLibre JSON style  
**Reject**: <code>Error</code> If API is not ready, or no style defined.  
<a name="Panoramax.utils.API+getUserMapStyle"></a>

### api.getUserMapStyle(userId, [skipReadyCheck]) ⇒ <code>Promise</code>
Get JSON style for specific-user vector tiles

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> The MapLibre JSON style  
**Reject**: <code>Error</code> If API is not ready, or no style defined.  

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| userId | <code>string</code> |  | The user UUID |
| [skipReadyCheck] | <code>boolean</code> | <code>false</code> | Skip check for API readyness |

<a name="Panoramax.utils.API+getPictureThumbnailURLForSequence"></a>

### api.getPictureThumbnailURLForSequence(seqId, [seq]) ⇒ <code>Promise</code>
Get a picture thumbnail URL for a given sequence

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Throws**:

- <code>Error</code> If API is not ready

**Fulfil**: <code>string\|null</code> Promise resolving on the picture thumbnail URL, or null if not found  

| Param | Type | Description |
| --- | --- | --- |
| seqId | <code>string</code> | The sequence ID |
| [seq] | <code>object</code> | The sequence metadata (with links) if already loaded |

<a name="Panoramax.utils.API+getPictureThumbnailURL"></a>

### api.getPictureThumbnailURL(picId, [seqId]) ⇒ <code>Promise</code>
Get thumbnail URL for a specific picture

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Throws**:

- <code>Error</code> If API is not ready

**Fulfil**: <code>string\|null</code> The corresponding URL on resolve, or null if no thumbnail could be found  

| Param | Type | Description |
| --- | --- | --- |
| picId | <code>string</code> | The picture unique identifier |
| [seqId] | <code>string</code> | The sequence ID |

<a name="Panoramax.utils.API+getRSSURL"></a>

### api.getRSSURL([bbox]) ⇒ <code>string</code> \| <code>null</code>
Get the RSS feed URL with map parameters (if map is enabled)

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>string</code> \| <code>null</code> - The URL, or null if no RSS feed is available  
**Throws**:

- <code>Error</code> If API is not ready


| Param | Type | Description |
| --- | --- | --- |
| [bbox] | <code>LngLatBounds</code> | The map current bounding box, or null if not available |

<a name="Panoramax.utils.API+getSequenceMetadataUrl"></a>

### api.getSequenceMetadataUrl(seqId) ⇒ <code>string</code>
Get full URL for retrieving a specific sequence metadata

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>string</code> - The corresponding URL  
**Throws**:

- <code>Error</code> If API is not ready


| Param | Type | Description |
| --- | --- | --- |
| seqId | <code>string</code> | The sequence ID |

<a name="Panoramax.utils.API+getSequenceMetadata"></a>

### api.getSequenceMetadata(seqId) ⇒ <code>Promise</code>
Retrieve metadata for a specific sequence

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Throws**:

- <code>Error</code> If API is not ready

**Fulfil**: <code>object\|null</code> Sequence metadata  

| Param | Type | Description |
| --- | --- | --- |
| seqId | <code>string</code> | The sequence ID |

<a name="Panoramax.utils.API+getDataBbox"></a>

### api.getDataBbox() ⇒ <code>LngLatBoundsLike</code>
Get available data bounding box

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>LngLatBoundsLike</code> - The bounding box or null if not available  
**Throws**:

- <code>Error</code> If API is not ready

<a name="Panoramax.utils.API+searchUsers"></a>

### api.searchUsers(query) ⇒ <code>Promise</code>
Look for user ID based on user name query

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Throws**:

- <code>Error</code> If API is not ready or user search not available

**Fulfil**: <code>object\|null</code> List of potential users  

| Param | Type | Description |
| --- | --- | --- |
| query | <code>string</code> | The user name to look for |

<a name="Panoramax.utils.API+getUserName"></a>

### api.getUserName(userId) ⇒ <code>Promise</code>
Get user name based on its ID

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Throws**:

- <code>Error</code> If API is not ready

**Fulfil**: <code>string\|null</code> The user name (or null if not found)  

| Param | Type | Description |
| --- | --- | --- |
| userId | <code>string</code> | The user UUID |

<a name="Panoramax.utils.API+sendReport"></a>

### api.sendReport(data) ⇒ <code>Promise</code>
Send a report to API

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> The JSON API response  

| Param | Type | Description |
| --- | --- | --- |
| data | <code>object</code> | The input form data |

<a name="Panoramax.utils.API+sendPictureSemantics"></a>

### api.sendPictureSemantics(picMeta, semanticsDiff) ⇒ <code>Promise</code>
Send picture semantics change to origin API.

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> The JSON API response  

| Param | Type | Description |
| --- | --- | --- |
| picMeta | <code>object</code> | The picture metadata |
| semanticsDiff | <code>object</code> | The difference in semantics compared to original data |

<a name="Panoramax.utils.API+createPictureAnnotation"></a>

### api.createPictureAnnotation(picMeta, shape, semanticsDiff) ⇒ <code>Promise</code>
Create new annotation for a given picture on its origin API.

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> The JSON API response  

| Param | Type | Description |
| --- | --- | --- |
| picMeta | <code>object</code> | The picture metadata |
| shape | <code>object</code> | The annotation shape |
| semanticsDiff | <code>object</code> | The difference in semantics compared to original data |

<a name="Panoramax.utils.API+editPictureAnnotation"></a>

### api.editPictureAnnotation(annotationId, semanticsDiff) ⇒ <code>Promise</code>
Edit semantics of an existing annotation on its origin API.

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> The JSON API response  

| Param | Type | Description |
| --- | --- | --- |
| annotationId | <code>string</code> | The annotation UUID |
| semanticsDiff | <code>object</code> | The difference in semantics compared to original data |

<a name="Panoramax.utils.API+deletePictureAnnotation"></a>

### api.deletePictureAnnotation(annotationId) ⇒ <code>Promise</code>
Delete a single annotation on its origin API.

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>object</code> The JSON API response  

| Param | Type | Description |
| --- | --- | --- |
| annotationId | <code>string</code> | The annotation UUID |

<a name="Panoramax.utils.API+getAuthURL"></a>

### api.getAuthURL() ⇒ <code>Promise</code>
Get the URL for user to log-in.

**Kind**: instance method of [<code>API</code>](#Panoramax.utils.API)  
**Fulfil**: <code>string\|boolean</code> The log-in URL, or false if no login is available  
<a name="Panoramax.utils.API+event_broken"></a>

### "broken"
Event when API is broken.
This happens on any API loading or map styling issue.

**Kind**: event emitted by [<code>API</code>](#Panoramax.utils.API)  
**Properties**

| Name | Type | Description |
| --- | --- | --- |
| detail.error | <code>Error</code> | The original error |

<a name="Panoramax.utils.API+event_ready"></a>

### "ready"
Event when API is ready to use.
This happens after initial API read and map styles load.

**Kind**: event emitted by [<code>API</code>](#Panoramax.utils.API)  
<a name="Panoramax.utils.API.isValidHttpUrl"></a>

### API.isValidHttpUrl(str) ⇒ <code>boolean</code>
Checks URL string validity

**Kind**: static method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>boolean</code> - True if valid  

| Param | Type | Description |
| --- | --- | --- |
| str | <code>string</code> | The URL to check |

<a name="Panoramax.utils.API.isIdValid"></a>

### API.isIdValid(id) ⇒ <code>boolean</code>
Checks picture or sequence ID validity

**Kind**: static method of [<code>API</code>](#Panoramax.utils.API)  
**Returns**: <code>boolean</code> - True if valid  
**Throws**:

- <code>Error</code> If not valid


| Param | Type | Description |
| --- | --- | --- |
| id | <code>string</code> | The ID to check |

