From 4b025d1dba6bbdf7d129f2b1edd7860e9b4715b8 Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Tue, 3 Dec 2019 21:55:33 +0100 Subject: [PATCH] Allow map apis to update track with new positions --- js/src/mapapi/api_gmaps.js | 27 +++++++++++++++++--------- js/src/mapapi/api_openlayers.js | 34 +++++++++++++++++---------------- js/test/api_gmaps.test.js | 24 +++++++++++------------ js/test/api_openlayers.test.js | 8 ++++---- 4 files changed, 52 insertions(+), 41 deletions(-) diff --git a/js/src/mapapi/api_gmaps.js b/js/src/mapapi/api_gmaps.js index 46cb7ab..5414e98 100644 --- a/js/src/mapapi/api_gmaps.js +++ b/js/src/mapapi/api_gmaps.js @@ -129,7 +129,7 @@ export default class GoogleMapsApi { * @param {boolean} update Should fit bounds if true */ displayTrack(track, update) { - if (!track) { + if (!track || !track.hasPositions) { return; } // init polyline @@ -139,15 +139,25 @@ export default class GoogleMapsApi { strokeWeight: config.strokeWeight }; // noinspection JSCheckFunctionSignatures - const poly = new google.maps.Polyline(polyOptions); - poly.setMap(this.map); - const path = poly.getPath(); + let poly; const latlngbounds = new google.maps.LatLngBounds(); - let i = 0; - for (const position of track.positions) { + if (this.polies.length) { + poly = this.polies[0]; + for (let i = 0; i < this.markers.length; i++) { + latlngbounds.extend(this.markers[i].getPosition()); + } + } else { + poly = new google.maps.Polyline(polyOptions); + poly.setMap(this.map); + this.polies.push(poly); + } + const path = poly.getPath(); + const start = this.markers.length; + for (let i = start; i < track.length; i++) { // set marker - this.setMarker(i++, track); + this.setMarker(i, track); // update polyline + const position = track.positions[i]; const coordinates = new google.maps.LatLng(position.latitude, position.longitude); if (track.continuous) { path.push(coordinates); @@ -156,7 +166,7 @@ export default class GoogleMapsApi { } if (update) { this.map.fitBounds(latlngbounds); - if (i === 1) { + if (track.length === 1) { // only one point, zoom out const zListener = google.maps.event.addListenerOnce(this.map, 'bounds_changed', function () { @@ -169,7 +179,6 @@ export default class GoogleMapsApi { }, 2000); } } - this.polies.push(poly); } /** diff --git a/js/src/mapapi/api_openlayers.js b/js/src/mapapi/api_openlayers.js index 44069d6..05f0444 100644 --- a/js/src/mapapi/api_openlayers.js +++ b/js/src/mapapi/api_openlayers.js @@ -416,25 +416,27 @@ export default class OpenLayersApi { * @param {boolean} update Should fit bounds if true */ displayTrack(track, update) { - if (!track) { + if (!track || !track.hasPositions) { return; } - let i = 0; - const lineString = new ol.geom.LineString([]); - for (const position of track.positions) { - // set marker - this.setMarker(i++, track); - if (track.continuous) { - // update polyline + const start = this.layerMarkers ? this.layerMarkers.getSource().getFeatures().length : 0; + for (let i = start; i < track.length; i++) { + this.setMarker(i, track); + } + if (track.continuous) { + let lineString; + if (this.layerTrack && this.layerTrack.getSource().getFeatures().length) { + lineString = this.layerTrack.getSource().getFeatures()[0].getGeometry(); + } else { + lineString = new ol.geom.LineString([]); + const lineFeature = new ol.Feature({ geometry: lineString }); + this.layerTrack.getSource().addFeature(lineFeature); + } + for (let i = start; i < track.length; i++) { + const position = track.positions[i]; lineString.appendCoordinate(ol.proj.fromLonLat([ position.longitude, position.latitude ])); } } - if (lineString.getLength() > 0) { - const lineFeature = new ol.Feature({ - geometry: lineString - }); - this.layerTrack.getSource().addFeature(lineFeature); - } let extent = this.layerMarkers.getSource().getExtent(); @@ -497,14 +499,14 @@ export default class OpenLayersApi { const position = track.positions[id]; let iconStyle = this.markerStyles.normal; if (position.hasComment() || position.hasImage()) { - if (id === track.positions.length - 1) { + if (id === track.length - 1) { iconStyle = this.markerStyles.stopExtra; } else if (id === 0) { iconStyle = this.markerStyles.startExtra; } else { iconStyle = this.markerStyles.extra; } - } else if (id === track.positions.length - 1) { + } else if (id === track.length - 1) { iconStyle = this.markerStyles.stop; } else if (id === 0) { iconStyle = this.markerStyles.start; diff --git a/js/test/api_gmaps.test.js b/js/test/api_gmaps.test.js index 57339a8..a833042 100644 --- a/js/test/api_gmaps.test.js +++ b/js/test/api_gmaps.test.js @@ -215,17 +215,17 @@ describe('Google Maps map API tests', () => { api.displayTrack(track, false); // then expect(api.polies.length).toBe(1); - expect(api.polies[0].path.length).toBe(track.positions.length); - expect(api.setMarker).toHaveBeenCalledTimes(track.positions.length); + expect(api.polies[0].path.length).toBe(track.length); + expect(api.setMarker).toHaveBeenCalledTimes(track.length); expect(api.setMarker).toHaveBeenCalledWith(0, track); expect(api.setMarker).toHaveBeenCalledWith(1, track); expect(google.maps.Polyline).toHaveBeenCalledTimes(1); expect(google.maps.Polyline).toHaveBeenCalledWith(expectedPolyOptions); - expect(google.maps.LatLng.calls.mostRecent().args[0]).toEqual(track.positions[track.positions.length - 1].latitude); - expect(google.maps.LatLng.calls.mostRecent().args[1]).toEqual(track.positions[track.positions.length - 1].longitude); - expect(google.maps.LatLngBounds.prototype.extend).toHaveBeenCalledTimes(track.positions.length); - expect(google.maps.LatLngBounds.prototype.extend.calls.mostRecent().args[0].latitude).toEqual(track.positions[track.positions.length - 1].latitude); - expect(google.maps.LatLngBounds.prototype.extend.calls.mostRecent().args[0].longitude).toEqual(track.positions[track.positions.length - 1].longitude); + expect(google.maps.LatLng.calls.mostRecent().args[0]).toEqual(track.positions[track.length - 1].latitude); + expect(google.maps.LatLng.calls.mostRecent().args[1]).toEqual(track.positions[track.length - 1].longitude); + expect(google.maps.LatLngBounds.prototype.extend).toHaveBeenCalledTimes(track.length); + expect(google.maps.LatLngBounds.prototype.extend.calls.mostRecent().args[0].latitude).toEqual(track.positions[track.length - 1].latitude); + expect(google.maps.LatLngBounds.prototype.extend.calls.mostRecent().args[0].longitude).toEqual(track.positions[track.length - 1].longitude); }); it('should construct non-continuous track markers without polyline', () => { @@ -238,7 +238,7 @@ describe('Google Maps map API tests', () => { // then expect(api.polies.length).toBe(1); expect(api.polies[0].path.length).toBe(0); - expect(api.setMarker).toHaveBeenCalledTimes(track.positions.length); + expect(api.setMarker).toHaveBeenCalledTimes(track.length); }); it('should fit bounds if update without zoom (should not add listener for "bounds_changed")', () => { @@ -253,8 +253,8 @@ describe('Google Maps map API tests', () => { api.displayTrack(track, true); // then expect(api.polies.length).toBe(1); - expect(api.polies[0].path.length).toBe(track.positions.length); - expect(api.setMarker).toHaveBeenCalledTimes(track.positions.length); + expect(api.polies[0].path.length).toBe(track.length); + expect(api.setMarker).toHaveBeenCalledTimes(track.length); expect(google.maps.Map.prototype.fitBounds).toHaveBeenCalledTimes(1); expect(google.maps.event.addListenerOnce).not.toHaveBeenCalled(); expect(setTimeout).not.toHaveBeenCalled(); @@ -272,8 +272,8 @@ describe('Google Maps map API tests', () => { api.displayTrack(track, true); // then expect(api.polies.length).toBe(1); - expect(api.polies[0].path.length).toBe(track.positions.length); - expect(api.setMarker).toHaveBeenCalledTimes(track.positions.length); + expect(api.polies[0].path.length).toBe(track.length); + expect(api.setMarker).toHaveBeenCalledTimes(track.length); expect(google.maps.Map.prototype.fitBounds).toHaveBeenCalledTimes(1); expect(google.maps.event.addListenerOnce.calls.mostRecent().args[1]).toBe('bounds_changed'); expect(setTimeout).toHaveBeenCalledTimes(1); diff --git a/js/test/api_openlayers.test.js b/js/test/api_openlayers.test.js index 60c8565..08bab25 100644 --- a/js/test/api_openlayers.test.js +++ b/js/test/api_openlayers.test.js @@ -261,13 +261,13 @@ describe('Openlayers map API tests', () => { }); // then expect(api.layerTrack.getSource().getFeatures().length).toBe(1); - expect(api.setMarker).toHaveBeenCalledTimes(track.positions.length); + expect(api.setMarker).toHaveBeenCalledTimes(track.length); expect(api.setMarker).toHaveBeenCalledWith(0, track); expect(api.setMarker).toHaveBeenCalledWith(1, track); expect(api.fitToExtent).not.toHaveBeenCalled(); // noinspection JSUnusedAssignment expect(zoomControl.extent).toEqual(api.layerMarkers.getSource().getExtent()); - expect(api.layerTrack.getSource().getFeatures()[0].getGeometry().getCoordinates().length).toEqual(track.positions.length); + expect(api.layerTrack.getSource().getFeatures()[0].getGeometry().getCoordinates().length).toEqual(track.length); }); it('should construct non-continuous track markers without track layer', () => { @@ -290,7 +290,7 @@ describe('Openlayers map API tests', () => { }); // then expect(api.layerTrack.getSource().getFeatures().length).toBe(0); - expect(api.setMarker).toHaveBeenCalledTimes(track.positions.length); + expect(api.setMarker).toHaveBeenCalledTimes(track.length); expect(api.setMarker).toHaveBeenCalledWith(0, track); expect(api.setMarker).toHaveBeenCalledWith(1, track); expect(api.fitToExtent).not.toHaveBeenCalled(); @@ -318,7 +318,7 @@ describe('Openlayers map API tests', () => { }); // then expect(api.layerTrack.getSource().getFeatures().length).toBe(1); - expect(api.setMarker).toHaveBeenCalledTimes(track.positions.length); + expect(api.setMarker).toHaveBeenCalledTimes(track.length); expect(api.setMarker).toHaveBeenCalledWith(0, track); expect(api.setMarker).toHaveBeenCalledWith(1, track); expect(api.fitToExtent).toHaveBeenCalledWith(markersExtent);