Skip to content

Commit

Permalink
Feature Request: Move Map Markers #226
Browse files Browse the repository at this point in the history
  • Loading branch information
EddyVerbruggen committed Aug 14, 2018
1 parent ba54305 commit 3ab4492
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 68 deletions.
50 changes: 31 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,34 +276,46 @@ You can update the map style after you've loaded it.
```

### addMarkers
```js
var onTap = function(marker) {
console.log("Marker tapped with title: '" + marker.title + "'");
};
var onCalloutTap = function(marker) {
alert("Marker callout tapped with title: '" + marker.title + "'");

```typescript
const firstMarker = {
id: 2, // can be user in 'removeMarkers()'
lat: 52.3602160, // mandatory
lng: 4.8891680, // mandatory
title: 'One-line title here', // no popup unless set
subtitle: 'Infamous subtitle!',
// icon: 'res://cool_marker', // preferred way, otherwise use:
icon: 'http(s)://website/coolimage.png', // from the internet (see the note at the bottom of this readme), or:
iconPath: 'res/markers/home_marker.png',
selected: true, // makes the callout show immediately when the marker is added (note: only 1 marker can be selected at a time)
onTap: marker => console.log("Marker tapped with title: '" + marker.title + "'"),
onCalloutTap: marker => alert("Marker callout tapped with title: '" + marker.title + "'")
};

mapbox.addMarkers([
{
id: 2, // can be user in 'removeMarkers()'
lat: 52.3602160, // mandatory
lng: 4.8891680, // mandatory
title: 'One-line title here', // no popup unless set
subtitle: 'Infamous subtitle!',
// icon: 'res://cool_marker', // preferred way, otherwise use:
icon: 'http(s)://website/coolimage.png', // from the internet (see the note at the bottom of this readme), or:
iconPath: 'res/markers/home_marker.png',
selected: true, // makes the callout show immediately when the marker is added (note: only 1 marker can be selected at a time)
onTap: onTap,
onCalloutTap: onCalloutTap
},
firstMarker,
{
// more markers..
}
])
```

#### Updating markers
Plugin version 4.2.0 added the option to update makers. Just call `update` on the marker reference you created above.
You can update the following properties (all but the icon really):

```typescript
firstMarker.update({
lat: 52.3622160,
lng: 4.8911680,
title: 'One-line title here (UPDATE)',
subtitle: 'Updated subtitle',
selected: true, // this will trigger the callout upon update
onTap: (marker: MapboxMarker) => console.log(`UPDATED Marker tapped with title: ${marker.title}`),
onCalloutTap: (marker: MapboxMarker) => alert(`UPDATED Marker callout tapped with title: ${marker.title}`)
})
```

### removeMarkers
You can either remove all markers by not passing in an argument,
or remove specific marker id's (which you specified previously).
Expand Down
52 changes: 34 additions & 18 deletions demo/app/main-view-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,36 @@ export class HelloWorldModel extends Observable {
}

public doAddMarkers(): void {
const onTap = (marker: MapboxMarker) => {
console.log(`Marker tapped with title: ${marker.title}`);
const onTap = (marker: MapboxMarker) => console.log(`Marker tapped with title: ${marker.title}`);

const onCalloutTap = (marker: MapboxMarker) => alert(`Marker callout tapped with title: ${marker.title}`);

const firstMarker = <MapboxMarker>{
id: 2,
lat: 52.3602160,
lng: 4.8891680,
title: 'One-line title here', // no popup unless set
subtitle: 'With a res://icon-40 image',
icon: isIOS ? 'res://icon-40' : 'res://icon',
selected: false,
onTap,
onCalloutTap
};

const onCalloutTap = (marker: MapboxMarker) => {
alert(`Marker callout tapped with title: ${marker.title}`);
};
setTimeout(() => {
firstMarker.update({
lat: 52.3622160,
lng: 4.8911680,
title: 'One-line title here (UPDATE)',
subtitle: 'Updated subtitle',
selected: true,
onTap: (marker: MapboxMarker) => console.log(`UPDATED Marker tapped with title: ${marker.title}`),
onCalloutTap: (marker: MapboxMarker) => alert(`UPDATED Marker callout tapped with title: ${marker.title}`)
})
}, 8000);

this.mapbox.addMarkers([
firstMarker,
{
id: 2,
lat: 52.3602160,
Expand All @@ -133,8 +154,8 @@ export class HelloWorldModel extends Observable {
subtitle: 'With a res://icon-40 image',
icon: isIOS ? 'res://icon-40' : 'res://icon',
selected: false,
onTap: onTap,
onCalloutTap: onCalloutTap
onTap,
onCalloutTap
},
{
// this is a marker without a popup (because no title/subtitle are set)
Expand All @@ -152,8 +173,8 @@ export class HelloWorldModel extends Observable {
subtitle: 'And a one-liner here as well.',
iconPath: 'res/markers/home_marker.png',
selected: true,
onTap: onTap,
onCalloutTap: onCalloutTap
onTap,
onCalloutTap
},
{
id: 5,
Expand Down Expand Up @@ -197,12 +218,8 @@ export class HelloWorldModel extends Observable {
animated: true // default true
}
).then(
() => {
console.log("Viewport set");
},
(error: string) => {
console.log("mapbox doSetViewport error: " + error);
}
() => console.log("Viewport set"),
(error: string) => console.log("mapbox doSetViewport error: " + error)
);
}

Expand Down Expand Up @@ -235,16 +252,15 @@ export class HelloWorldModel extends Observable {
};
alert(alertOptions);
},
(error: string) => {
console.log("mapbox doDownloadAmsterdam error: " + error);
}
error => console.log("mapbox doDownloadAmsterdam error: " + error)
);

let alertOptions: AlertOptions = {
title: "Be patient",
message: "This takes a while, progress is logged via console.log",
okButtonText: "Understood"
};

alert(alertOptions);
}

Expand Down
30 changes: 30 additions & 0 deletions src/mapbox.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,36 @@ const _addMarkers = (markers: MapboxMarker[], nativeMap?) => {
if (marker.selected) {
theMap.mapboxMap.selectMarker(marker.android);
}

marker.update = (newSettings: MapboxMarker) => {
for (let m in _markers) {
let _marker: MapboxMarker = _markers[m];
if (marker.id === _marker.id) {
if (newSettings.onTap !== undefined) {
_marker.onTap = newSettings.onTap;
}
if (newSettings.onCalloutTap !== undefined) {
_marker.onCalloutTap = newSettings.onCalloutTap;
}
if (newSettings.title !== undefined) {
_marker.title = newSettings.title;
_marker.android.setTitle(newSettings.title);
}
if (newSettings.subtitle !== undefined) {
_marker.subtitle = newSettings.title;
_marker.android.setSnippet(newSettings.subtitle);
}
if (newSettings.lat && newSettings.lng) {
_marker.lat = newSettings.lat;
_marker.lng = newSettings.lng;
_marker.android.setPosition(new com.mapbox.mapboxsdk.geometry.LatLng(parseFloat(<any>newSettings.lat), parseFloat(<any>newSettings.lng)));
}
if (newSettings.selected) {
theMap.mapboxMap.selectMarker(_marker.android);
}
}
}
}
}
});
};
Expand Down
3 changes: 3 additions & 0 deletions src/mapbox.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ export interface MapboxMarker extends LatLng {
* Default false.
*/
selected?: boolean;
update?: (newSettings: MapboxMarker) => void;
ios?: any;
android?: any;
}

export interface SetZoomLevelOptions {
Expand Down
75 changes: 45 additions & 30 deletions src/mapbox.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,18 +288,15 @@ export class Mapbox extends MapboxCommon implements MapboxApi {
try {
const theMap = nativeMap || _mapbox.mapView;
let markersToRemove: Array<MGLAnnotation> = [];
for (let m in _markers) {
let marker = _markers[m];
_markers.forEach(marker => {
if (!ids || (marker.id && ids.indexOf(marker.id) > -1)) {
markersToRemove.push(marker.ios);
}
}
});

// remove markers from cache
if (ids) {
_markers = _markers.filter((marker) => {
return ids.indexOf(marker.id) < 0;
});
_markers = _markers.filter(marker => ids.indexOf(marker.id) < 0);
} else {
_markers = [];
}
Expand Down Expand Up @@ -448,9 +445,7 @@ export class Mapbox extends MapboxCommon implements MapboxApi {
}

const coordinateArray = [];
for (const p in points) {
coordinateArray.push([points[p].lng, points[p].lat]);
}
points.forEach(point => coordinateArray.push([point.lng, point.lat]));

const polygonID = "polygon_" + (options.id || new Date().getTime());

Expand Down Expand Up @@ -495,9 +490,7 @@ export class Mapbox extends MapboxCommon implements MapboxApi {
}

const coordinateArray = [];
for (const p in points) {
coordinateArray.push([points[p].lng, points[p].lat]);
}
points.forEach(point => coordinateArray.push([point.lng, point.lat]));

const polylineID = "polyline_" + (options.id || new Date().getTime());

Expand Down Expand Up @@ -953,11 +946,13 @@ const _addObserver = (eventName, callback) => {
eventName, null, utils.ios.getter(NSOperationQueue, NSOperationQueue.mainQueue), callback);
};

const _downloadImage = (marker) => {
const _downloadImage = marker => {
return new Promise((resolve, reject) => {
console.log(">> _downloadImage");
// to cache..
if (_markerIconDownloadCache[marker.icon]) {
marker.iconDownloaded = _markerIconDownloadCache[marker.icon];
console.log(">> marker.iconDownloaded: " + marker.iconDownloaded);
resolve(marker);
return;
}
Expand All @@ -974,24 +969,19 @@ const _downloadImage = (marker) => {
});
};

const _downloadMarkerImages = (markers) => {
const _downloadMarkerImages = (markers: Array<MapboxMarker>) => {
let iterations = [];
let result = [];
for (let i = 0; i < markers.length; i++) {
let marker = markers[i];
markers.forEach(marker => {
if (marker.icon && marker.icon.startsWith("http")) {
let p = _downloadImage(marker).then((mark) => {
result.push(mark);
});
let p = _downloadImage(marker).then(mark => result.push(mark));
iterations.push(p);
} else {
result.push(marker);
}
}

return Promise.all(iterations).then((output) => {
return result;
});

return Promise.all(iterations).then(() => result);
};

const _addMarkers = (markers: MapboxMarker[], nativeMap?) => {
Expand All @@ -1005,9 +995,8 @@ const _addMarkers = (markers: MapboxMarker[], nativeMap?) => {
}
let theMap: MGLMapView = nativeMap || _mapbox.mapView;

_downloadMarkerImages(markers).then((updatedMarkers: any) => {
for (let m in updatedMarkers) {
let marker = updatedMarkers[m];
_downloadMarkerImages(markers).then((updatedMarkers: Array<MapboxMarker>) => {
updatedMarkers.forEach(marker => {
let lat = marker.lat;
let lng = marker.lng;
let point = MGLPointAnnotation.new();
Expand All @@ -1023,7 +1012,34 @@ const _addMarkers = (markers: MapboxMarker[], nativeMap?) => {
}

marker.ios = point;
}

marker.update = (newSettings: MapboxMarker) => {
_markers.forEach(_marker => {
if (marker.id === _marker.id) {
if (newSettings.onTap !== undefined) {
_marker.onTap = newSettings.onTap;
}
if (newSettings.onCalloutTap !== undefined) {
_marker.onCalloutTap = newSettings.onCalloutTap;
}
if (newSettings.title !== undefined) {
_marker.ios.title = _marker.title = newSettings.title;
}
if (newSettings.subtitle !== undefined) {
_marker.ios.subtitle = _marker.subtitle = newSettings.subtitle;
}
if (newSettings.lat && newSettings.lng) {
_marker.lat = newSettings.lat;
_marker.lng = newSettings.lng;
_marker.ios.coordinate = CLLocationCoordinate2DMake(newSettings.lat, newSettings.lng);
}
if (newSettings.selected) {
theMap.selectAnnotationAnimated(_marker.ios, false);
}
}
});
}
});
});
};

Expand Down Expand Up @@ -1054,11 +1070,11 @@ class MGLMapViewDelegateImpl extends NSObject implements MGLMapViewDelegate {
}

mapViewDidFailLoadingMapWithError(mapView: MGLMapView, error: NSError): void {
console.log("mapViewDidFailLoadingMapWithError: " + error);
// console.log("mapViewDidFailLoadingMapWithError: " + error);
}

mapViewDidChangeUserTrackingModeAnimated(mapView: MGLMapView, mode: MGLUserTrackingMode, animated: boolean): void {
console.log("mapViewDidChangeUserTrackingModeAnimated: " + mode);
// console.log("mapViewDidChangeUserTrackingModeAnimated: " + mode);
}

// fired when the marker icon is about to be rendered - return null for the default icon
Expand Down Expand Up @@ -1113,7 +1129,6 @@ class MGLMapViewDelegateImpl extends NSObject implements MGLMapViewDelegate {

// fired when a marker is tapped
mapViewDidSelectAnnotation(mapView: MGLMapView, annotation: MGLAnnotation): void {
// console.log(">>>>> mapViewDidSelectAnnotation " + annotation.class() + " @ " + new Date().getTime());
let cachedMarker = this.getTappedMarkerDetails(annotation);
if (cachedMarker && cachedMarker.onTap) {
cachedMarker.onTap(cachedMarker);
Expand Down
2 changes: 1 addition & 1 deletion src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nativescript-mapbox",
"version": "4.1.2",
"version": "4.2.0",
"description": "Native Maps, by Mapbox.",
"main": "mapbox",
"typings": "index.d.ts",
Expand Down

0 comments on commit 3ab4492

Please sign in to comment.