From 658f3d6e5b3eab31a15e0a610cf707b4ff4f5fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A9reck=20Lynch?= <50959537+drekss@users.noreply.github.com> Date: Mon, 23 Sep 2019 14:16:31 -0400 Subject: [PATCH] feat(geolocation): possibility to add a buffer to the geolocation (#394) --- .../geo/src/lib/map/shared/map.interface.ts | 8 ++++ packages/geo/src/lib/map/shared/map.ts | 35 +++++++++++++- .../src/lib/overlay/shared/overlay.utils.ts | 47 +++++++++++++++++-- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/packages/geo/src/lib/map/shared/map.interface.ts b/packages/geo/src/lib/map/shared/map.interface.ts index 98cdb32cdc..18a32770f4 100644 --- a/packages/geo/src/lib/map/shared/map.interface.ts +++ b/packages/geo/src/lib/map/shared/map.interface.ts @@ -4,6 +4,7 @@ export interface MapViewOptions { projection?: string; center?: [number, number]; geolocate?: boolean; + buffer?: Buffer; constrainRotation?: boolean | number; enableRotation?: boolean; @@ -46,3 +47,10 @@ export interface MapAttributionOptions { html?: string; collapsed: boolean; } + +export interface Buffer { + bufferRadius?: number; + bufferStroke?: [number, number, number, number]; + bufferFill?: [number, number, number, number]; + showBufferRadius?: boolean; +} diff --git a/packages/geo/src/lib/map/shared/map.ts b/packages/geo/src/lib/map/shared/map.ts index 08df8c5ad9..76797f89dd 100644 --- a/packages/geo/src/lib/map/shared/map.ts +++ b/packages/geo/src/lib/map/shared/map.ts @@ -8,6 +8,7 @@ import * as olproj from 'ol/proj'; import * as olproj4 from 'ol/proj/proj4'; import OlProjection from 'ol/proj/Projection'; import * as olinteraction from 'ol/interaction'; +import olCircle from 'ol/geom/Circle'; import proj4 from 'proj4'; import { BehaviorSubject, Subject, Subscription } from 'rxjs'; @@ -26,6 +27,7 @@ import { MapExtent } from './map.interface'; import { MapViewController } from './controllers/view'; +import { FeatureDataSource } from '../../datasource/shared/datasources/feature-datasource'; // TODO: This class is messy. Clearly define it's scope and the map browser's. // Move some stuff into controllers. @@ -35,9 +37,14 @@ export class IgoMap { public status$: Subject; public geolocation$ = new BehaviorSubject(undefined); public geolocationFeature: olFeature; + public bufferGeom: olCircle; + public bufferFeature: olFeature; + public buffer: Overlay; public overlay: Overlay; public viewController: MapViewController; + public bufferDataSource: FeatureDataSource; + private layerWatcher: LayerWatcher; private geolocation: olGeolocation; private geolocation$$: Subscription; @@ -104,6 +111,7 @@ export class IgoMap { }); this.viewController.setOlMap(this.ol); this.overlay = new Overlay(this); + this.buffer = new Overlay(this); } setTarget(id: string) { @@ -377,7 +385,29 @@ export class IgoMap { } this.geolocationFeature = new olFeature({ geometry }); this.geolocationFeature.setId('geolocationFeature'); - this.overlay.addFeature(this.geolocationFeature); + this.overlay.addOlFeature(this.geolocationFeature); + + if (this.ol.getView().options_.buffer) { + const bufferRadius = this.ol.getView().options_.buffer.bufferRadius; + const coordinates = geolocation.getPosition(); + this.bufferGeom = new olCircle(coordinates, bufferRadius); + const bufferStroke = this.ol.getView().options_.buffer.bufferStroke; + const bufferFill = this.ol.getView().options_.buffer.bufferFill; + + let bufferText; + if (this.ol.getView().options_.buffer.showBufferRadius) { + bufferText = bufferRadius.toString() + 'm'; + } else { + bufferText = ''; + } + + this.bufferFeature = new olFeature(this.bufferGeom); + this.bufferFeature.setId('bufferFeature'); + this.bufferFeature.set('bufferStroke', bufferStroke); + this.bufferFeature.set('bufferFill', bufferFill); + this.bufferFeature.set('bufferText', bufferText); + this.buffer.addOlFeature(this.bufferFeature); + } if (first) { this.viewController.zoomToExtent(extent); } @@ -405,6 +435,9 @@ export class IgoMap { private startGeolocation() { if (!this.geolocation) { this.geolocation = new olGeolocation({ + trackingOptions: { + enableHighAccuracy: true + }, projection: this.projection, tracking: true }); diff --git a/packages/geo/src/lib/overlay/shared/overlay.utils.ts b/packages/geo/src/lib/overlay/shared/overlay.utils.ts index 73e9a2c47c..3227b80d1c 100644 --- a/packages/geo/src/lib/overlay/shared/overlay.utils.ts +++ b/packages/geo/src/lib/overlay/shared/overlay.utils.ts @@ -26,12 +26,18 @@ export function createOverlayLayer(): VectorLayer { function createOverlayLayerStyle(): (olFeature: OlFeature) => olstyle.Style { const defaultStyle = createOverlayDefaultStyle(); const markerStyle = createOverlayMarkerStyle(); + let style; return (olFeature: OlFeature) => { - const geometryType = olFeature.getGeometry().getType(); - const style = geometryType === 'Point' ? markerStyle : defaultStyle; - style.getText().setText(olFeature.get('_mapTitle')); - return style; + if (olFeature.getId() === 'bufferFeature') { + style = createBufferStyle(olFeature.get('bufferStroke'), 2, olFeature.get('bufferFill'), olFeature.get('bufferText')); + return style; + } else { + const geometryType = olFeature.getGeometry().getType(); + style = geometryType === 'Point' ? markerStyle : defaultStyle; + style.getText().setText(olFeature.get('_mapTitle')); + return style; + } }; } @@ -98,3 +104,36 @@ export function createOverlayMarkerStyle(color = 'blue', text?): olstyle.Style { }) }); } + +function createBufferStyle( + strokeRGBA: [number, number, number, number] = [0, 161, 222, 1], + strokeWidth: number = 2, + fillRGBA: [number, number, number, number] = [0, 161, 222, 0.15], + bufferRadius? +): olstyle.Style { + const stroke = new olstyle.Stroke({ + width: strokeWidth, + color: strokeRGBA + }); + + const fill = new olstyle.Stroke({ + color: fillRGBA + }); + + return new olstyle.Style({ + stroke, + fill, + image: new olstyle.Circle({ + radius: 5, + stroke, + fill + }), + text: new olstyle.Text({ + font: '12px Calibri,sans-serif', + text: bufferRadius, + fill: new olstyle.Fill({ color: '#000' }), + stroke: new olstyle.Stroke({ color: '#fff', width: 3 }), + overflow: true + }) + }); +}