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

WIP: fallback to marker associated with style if one is not specified #181

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Radar.initialize('prj_test_pk_...', { /* options */ });

Add the following script in your `html` file
```html
<script src="https://js.radar.com/v4.4.1/radar.min.js"></script>
<script src="https://js.radar.com/v4.5.0-beta.0/radar.min.js"></script>
```

Then initialize the Radar SDK
Expand All @@ -73,8 +73,8 @@ To create a map, first initialize the Radar SDK with your publishable key. Then
```html
<html>
<head>
<link href="https://js.radar.com/v4.4.1/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.4.1/radar.min.js"></script>
<link href="https://js.radar.com/v4.5.0-beta.0/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.5.0-beta.0/radar.min.js"></script>
</head>

<body>
Expand All @@ -98,8 +98,8 @@ To create an autocomplete input, first initialize the Radar SDK with your publis
```html
<html>
<head>
<link href="https://js.radar.com/v4.4.1/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.4.1/radar.min.js"></script>
<link href="https://js.radar.com/v4.5.0-beta.0/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.5.0-beta.0/radar.min.js"></script>
</head>

<body>
Expand Down Expand Up @@ -130,8 +130,8 @@ To power [geofencing](https://radar.com/documentation/geofencing/overview) exper
```html
<html>
<head>
<link href="https://js.radar.com/v4.4.1/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.4.1/radar.min.js"></script>
<link href="https://js.radar.com/v4.5.0-beta.0/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.5.0-beta.0/radar.min.js"></script>
</head>

<body>
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "radar-sdk-js",
"version": "4.4.1",
"version": "4.5.0-beta.0",
"description": "Web Javascript SDK for Radar, location infrastructure for mobile and web apps.",
"homepage": "https://radar.com",
"type": "module",
Expand Down
11 changes: 11 additions & 0 deletions src/ui/RadarMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const getStyle = (options: RadarOptions, mapOptions: RadarMapOptions) => {
class RadarMap extends maplibregl.Map {
_markers: RadarMarker[] = [];
_features: RadarMapFeature[] = [];
_defaultMarker?: string;

constructor(radarMapOptions: RadarMapOptions) {
const config = Config.get();
Expand Down Expand Up @@ -152,6 +153,16 @@ class RadarMap extends maplibregl.Map {
};
this.on('resize', onResize);
this.on('load', onResize);

// parse radar metadata from style
this.on('style.load', () => {
const style = this.getStyle();
const metadata: any = style.metadata || {};

if (metadata['radar:marker']) { // default marker associated with custom style
this._defaultMarker = metadata['radar:marker'];
}
});
}

addMarker(marker: RadarMarker) {
Expand Down
170 changes: 95 additions & 75 deletions src/ui/RadarMarker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const defaultMarkerOptions: RadarMarkerOptions = {
};

class RadarMarker extends maplibregl.Marker {
_options: RadarMarkerOptions;
_map!: RadarMap;

constructor(markerOptions: RadarMarkerOptions) {
Expand All @@ -107,83 +108,11 @@ class RadarMarker extends maplibregl.Marker {

super(maplibreOptions);

this._options = markerOptions;

// handle marker images (Radar marker, or custom URL)
if (markerOptions.marker || markerOptions.url) {
const originalElement = this._element.cloneNode(true);
this._element.childNodes.forEach((child) => {
child.remove();
});

const onSuccess = (blob: Blob) => {
const markerObject = URL.createObjectURL(blob);
this._element.replaceChildren(createImageElement({
width: markerOptions.width,
height: markerOptions.height,
url: markerObject,
}));
};

const onError = (err: any) => {
Logger.error(`Could not load marker: ${err.message} - falling back to default marker`);
IMAGE_CACHE.set(markerOptions.url as string, 'failed'); // mark as failed
this._element.replaceChildren(...Array.from(originalElement.childNodes));
}

// custom URL image
if (markerOptions.url) {
const loadImage = () => { // fetch marker data from URL
fetch(markerOptions.url as string)
.then(res => {
if (res.status === 200) {
res.blob()
.then((data) => {
IMAGE_CACHE.set(markerOptions.url as string, data); // cache data
onSuccess(data);
})
.catch(onError);
} else {
onError(new Error(res.statusText));
}
})
.catch(onError)
};

// attempt to use cached data, otherwise fetch marker image data from URL
useCachedImage(markerOptions.url)
.then(onSuccess)
.catch((reason: 'miss' | 'timedout' | 'failed' | Error) => {
if (reason !== 'miss') {
Logger.debug(`RadarMarker: cache lookup for ${markerOptions.url}: ${reason}`);
}
loadImage();
});
}

// Radar hosted image
if (markerOptions.marker) {
const loadMarker = () => {
Http.request({
method: 'GET',
version: 'maps',
path: `markers/${markerOptions.marker}`,
responseType: 'blob',
})
.then(({ data }) => {
IMAGE_CACHE.set(markerOptions.url as string, data); // cache data
onSuccess(data)
})
.catch(onError);
};

useCachedImage(markerOptions.marker as string)
.then(onSuccess)
.catch((reason: 'miss' | 'timedout' | 'failed' | Error) => {
if (reason !== 'miss') {
Logger.debug(`RadarMarker: cache lookup for ${markerOptions.marker} ${reason}`);
}
loadMarker();
});
}
this.getCustomImage(markerOptions);
}

// handle deprecated popup options
Expand Down Expand Up @@ -238,7 +167,98 @@ class RadarMarker extends maplibregl.Marker {
}
}

// load marker image from a URL or as a Radar asset (custom styles)
getCustomImage(markerOptions: RadarMarkerOptions) {
const originalElement = this._element.cloneNode(true);
this._element.childNodes.forEach((child) => {
child.remove();
});

const onSuccess = (blob: Blob) => {
const markerObject = URL.createObjectURL(blob);
this._element.replaceChildren(createImageElement({
width: markerOptions.width,
height: markerOptions.height,
url: markerObject,
}));
};

const onError = (err: any) => {
Logger.error(`Could not load marker: ${err.message} - falling back to default marker`);
IMAGE_CACHE.set(markerOptions.url as string, 'failed'); // mark as failed
this._element.replaceChildren(...Array.from(originalElement.childNodes));
}

// custom URL image
if (markerOptions.url) {
const loadImage = () => { // fetch marker data from URL
fetch(markerOptions.url as string)
.then(res => {
if (res.status === 200) {
res.blob()
.then((data) => {
IMAGE_CACHE.set(markerOptions.url as string, data); // cache data
onSuccess(data);
})
.catch(onError);
} else {
onError(new Error(res.statusText));
}
})
.catch(onError)
};

// attempt to use cached data, otherwise fetch marker image data from URL
useCachedImage(markerOptions.url)
.then(onSuccess)
.catch((reason: 'miss' | 'timedout' | 'failed' | Error) => {
if (reason !== 'miss') {
Logger.debug(`RadarMarker: cache lookup for ${markerOptions.url}: ${reason}`);
}
loadImage();
});
}

// Radar hosted image
if (markerOptions.marker) {
const loadMarker = () => {
Http.request({
method: 'GET',
version: 'maps',
path: `markers/${markerOptions.marker}`,
responseType: 'blob',
})
.then(({ data }) => {
IMAGE_CACHE.set(markerOptions.marker as string, data); // cache data
onSuccess(data)
})
.catch(onError);
};

useCachedImage(markerOptions.marker as string)
.then(onSuccess)
.catch((reason: 'miss' | 'timedout' | 'failed' | Error) => {
if (reason !== 'miss') {
Logger.debug(`RadarMarker: cache lookup for ${markerOptions.marker} ${reason}`);
}
loadMarker();
});
}
}

addTo(map: RadarMap) {
// use default marker associated with map style, if none is provided in options
// (and custom style has an associated marker)
const markerOptions = this._options;
if (!markerOptions.url && !markerOptions.marker && !markerOptions.color) {
if (map._defaultMarker) {
this.getCustomImage({
...markerOptions,
marker: map._defaultMarker,
});
}
}

map.addMarker(this);
return super.addTo(map);
}
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default '4.4.1';
export default '4.5.0-beta.0';