diff --git a/angular.json b/angular.json index 472caa6..278b019 100644 --- a/angular.json +++ b/angular.json @@ -29,9 +29,13 @@ ], "styles": [ "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", + "./node_modules/leaflet/dist/leaflet.css", "src/styles.scss" ], - "scripts": [] + "scripts": [ + "./node_modules/leaflet/dist/leaflet.js", + "./node_modules/esri-leaflet/dist/esri-leaflet.js" + ] }, "configurations": { "production": { diff --git a/package.json b/package.json index 874ce64..94b91ff 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,12 @@ "@angular/pwa": "^0.800.4", "@angular/router": "~8.0.1", "@angular/service-worker": "~8.0.1", + "@types/leaflet": "^1.5.1", "bootstrap-scss": "^4.3.1", + "esri-leaflet": "^2.3.0", "firebase": "^6.3.0", "hammerjs": "^2.0.8", + "leaflet": "^1.5.1", "rxjs": "~6.4.0", "tslib": "^1.9.0", "zone.js": "~0.9.1" diff --git a/src/app/views/map/map.component.html b/src/app/views/map/map.component.html index 5d57b47..c8fa360 100644 --- a/src/app/views/map/map.component.html +++ b/src/app/views/map/map.component.html @@ -1,11 +1,5 @@ - - - - - - - +
diff --git a/src/app/views/map/map.component.scss b/src/app/views/map/map.component.scss index 00634f5..8d5c130 100644 --- a/src/app/views/map/map.component.scss +++ b/src/app/views/map/map.component.scss @@ -1,10 +1,10 @@ -.map { +#map { height: calc(100vh - 40px); } .palette { position: fixed; - z-index: 100; + z-index: 500; top: 50px; right: 15px; } @@ -12,14 +12,14 @@ .info { background-color: #00000050; position: fixed; - z-index: 100; + z-index: 500; bottom: 15px; left: 15px; } .gps { position: fixed; - z-index: 100; + z-index: 500; bottom: 15px; right: 15px; } diff --git a/src/app/views/map/map.component.ts b/src/app/views/map/map.component.ts index 4c75e8f..87981bf 100644 --- a/src/app/views/map/map.component.ts +++ b/src/app/views/map/map.component.ts @@ -1,4 +1,4 @@ -import {Component} from "@angular/core"; +import {Component, OnInit} from "@angular/core"; import {PhysicsService} from "../../services/physics/physics.service"; import {filter, skip, take} from "rxjs/operators"; import {MatBottomSheet, MatSnackBar} from "@angular/material"; @@ -8,7 +8,7 @@ import {BehaviorSubject} from "rxjs"; import {LatLngLiteral} from "@agm/core"; import {flyInRight, flyOutRight} from "../../animations"; -declare const google; +declare const L; @Component({ selector: 'map', @@ -16,7 +16,11 @@ declare const google; styleUrls: ['map.component.scss'], animations: [flyInRight, flyOutRight] }) -export class MapComponent { +export class MapComponent implements OnInit { + map; + + + drawColor: string; drawListener = []; mapApi: any; @@ -34,14 +38,14 @@ export class MapComponent { isNaN = isNaN; menu: ToolbarItem[][] = [[ - {name: 'compass', icon: 'explore', click: () => this.calibrate(), hidden: true}, + {name: 'compass', icon: 'explore', hidden: true}, ], [ - {name: 'marker', icon: 'room', toggle: true, individualToggle: true, click: () => this.addMarker()}, - {name: 'draw', icon: 'create', toggle: true, individualToggle: true, onEnabled: () => this.startDraw(), onDisabled: () => this.endDraw()}, - {name: 'measure', icon: 'straighten', toggle: true, individualToggle: true, click: () => this.measure()}, + {name: 'marker', icon: 'room', toggle: true, individualToggle: true}, + {name: 'draw', icon: 'create', toggle: true, individualToggle: true}, + {name: 'measure', icon: 'straighten', toggle: true, individualToggle: true}, {name: 'delete', icon: 'delete', toggle: true, individualToggle: true}, - {name: 'style', icon: 'terrain', enabled: true, toggle: true, onEnabled: () => this.style = 'terrain', onDisabled: () => this.style = 'satellite'}, - {name: 'compass', icon: 'explore', click: () => this.calibrate()} + {name: 'style', icon: 'terrain', enabled: true, toggle: true}, + {name: 'compass', icon: 'explore'} ], [ {name: 'messages', icon: 'chat', hidden: true}, {name: 'identity', icon: 'perm_identity', hidden: true}, @@ -51,7 +55,7 @@ export class MapComponent { constructor(public physicsService: PhysicsService, private snackBar: MatSnackBar, private bottomSheet: MatBottomSheet) { physicsService.info.pipe(filter(coord => !!coord)).subscribe(pos => { if(this.mapApi) { - if(!this.position) this.center(pos); + // if(!this.position) this.center(pos); this.position = pos; if(this.position.heading != null) { @@ -65,125 +69,130 @@ export class MapComponent { snackBar.open('Compass requires calibration', 'calibrate', { duration: 5000, panelClass: 'bg-warning,text-white' - }).onAction().subscribe(() => this.calibrate()); + }).onAction()/*.subscribe(() => this.calibrate());*/ }); } - addMarker() { - this.mapClick.pipe(skip(1), take(1)).subscribe(coords => { - this.menu[1][0].enabled = false; - let marker = new google.maps.Marker({ - map: this.mapApi, - position: {lat: coords.lat, lng: coords.lng} - }); - google.maps.event.addListener(marker, 'click', () => { - if(this.menu[1][3].enabled) marker.setMap(null) - }); - }); + ngOnInit() { + this.map = L.map('map', {attributionControl: false, zoomControl: false}).setView([37.75, -122.23], 10); + L.esri.basemapLayer('ImageryClarity').addTo(this.map); } - measure() { - let deg2rad = (deg) => deg * (Math.PI/180); - - let distanceInM = (lat1, lon1, lat2, lon2) => { - const R = 6371; // Radius of the earth in km - let dLat = deg2rad(lat2-lat1); // deg2rad below - let dLon = deg2rad(lon2-lon1); - let a = - Math.sin(dLat/2) * Math.sin(dLat/2) + - Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * - Math.sin(dLon/2) * Math.sin(dLon/2) - ; - let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); - return R * c * 1000 - }; - - let first; - this.mapClick.pipe(skip(1), take(2)).subscribe(coords => { - if(!first) { - first = coords; - } else { - this.menu[1][2].enabled = false; - - let line = new google.maps.Polyline({ - map: this.mapApi, - path: [first, coords], - strokeColor: '#f00', - icons: [{ - icon: {path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW}, - offset: '0%' - }, { - icon: {path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW}, - offset: '100%' - }] - }); - - let distance = distanceInM(first.lat, first.lng, coords.lat, coords.lng); - - let info = new google.maps.InfoWindow({ - content: distance >= 1000 ? `${Math.round(distance / 100) / 10} km` : `${Math.round(distance)} m`, - position: {lat: (first.lat + coords.lat) / 2, lng: (first.lng + coords.lng) / 2} - }); - info.open(this.mapApi); - - google.maps.event.addListener(line, 'click', () => { - if(this.menu[1][3].enabled) { - line.setMap(null); - info.setMap(null); - } - }); - - google.maps.event.addListener(info, 'click', () => { - if(this.menu[1][3].enabled) { - line.setMap(null); - info.setMap(null); - } - }); - } - }) - } - - calibrate() { - this.bottomSheet.open(CalibrateComponent, { - hasBackdrop: false, - disableClose: true - }); - } - - center(pos?) { - if(!pos) pos = this.position; - this.mapApi.setCenter({lat: pos.latitude, lng: pos.longitude}); - } - - startDraw() { - this.showPalette = true; - this.mapApi.setOptions({draggable: false}); - - let drawHander = () => { - let poly = new google.maps.Polyline({map: this.mapApi, clickable: true, strokeColor: this.drawColor}); - google.maps.event.addListener(poly, 'click', () => { - if(this.menu[1][3].enabled) poly.setMap(null); - }); - let moveListener = [ - google.maps.event.addListener(this.mapApi, 'touchmove', e => poly.getPath().push(e.latLng)), - google.maps.event.addListener(this.mapApi, 'mousemove', e => poly.getPath().push(e.latLng)) - ]; - google.maps.event.addListener(this.mapApi, 'touchend', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); - google.maps.event.addListener(this.mapApi, 'mouseup', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); - google.maps.event.addListener(poly, 'touchend', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); - google.maps.event.addListener(poly, 'mouseup', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); - }; - - this.drawListener = [ - google.maps.event.addDomListener(this.mapApi.getDiv(), 'touchstart', drawHander), - google.maps.event.addDomListener(this.mapApi.getDiv(), 'mousedown', drawHander) - ]; - } - - endDraw() { - this.showPalette = false; - this.mapApi.setOptions({draggable: true}); - this.drawListener.forEach(listener => google.maps.event.removeListener(listener)); - this.drawListener = []; - } + // addMarker() { + // this.mapClick.pipe(skip(1), take(1)).subscribe(coords => { + // this.menu[1][0].enabled = false; + // let marker = new google.maps.Marker({ + // map: this.mapApi, + // position: {lat: coords.lat, lng: coords.lng} + // }); + // google.maps.event.addListener(marker, 'click', () => { + // if(this.menu[1][3].enabled) marker.setMap(null) + // }); + // }); + // } + // + // measure() { + // let deg2rad = (deg) => deg * (Math.PI/180); + // + // let distanceInM = (lat1, lon1, lat2, lon2) => { + // const R = 6371; // Radius of the earth in km + // let dLat = deg2rad(lat2-lat1); // deg2rad below + // let dLon = deg2rad(lon2-lon1); + // let a = + // Math.sin(dLat/2) * Math.sin(dLat/2) + + // Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * + // Math.sin(dLon/2) * Math.sin(dLon/2) + // ; + // let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + // return R * c * 1000 + // }; + // + // let first; + // this.mapClick.pipe(skip(1), take(2)).subscribe(coords => { + // if(!first) { + // first = coords; + // } else { + // this.menu[1][2].enabled = false; + // + // let line = new google.maps.Polyline({ + // map: this.mapApi, + // path: [first, coords], + // strokeColor: '#f00', + // icons: [{ + // icon: {path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW}, + // offset: '0%' + // }, { + // icon: {path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW}, + // offset: '100%' + // }] + // }); + // + // let distance = distanceInM(first.lat, first.lng, coords.lat, coords.lng); + // + // let info = new google.maps.InfoWindow({ + // content: distance >= 1000 ? `${Math.round(distance / 100) / 10} km` : `${Math.round(distance)} m`, + // position: {lat: (first.lat + coords.lat) / 2, lng: (first.lng + coords.lng) / 2} + // }); + // info.open(this.mapApi); + // + // google.maps.event.addListener(line, 'click', () => { + // if(this.menu[1][3].enabled) { + // line.setMap(null); + // info.setMap(null); + // } + // }); + // + // google.maps.event.addListener(info, 'click', () => { + // if(this.menu[1][3].enabled) { + // line.setMap(null); + // info.setMap(null); + // } + // }); + // } + // }) + // } + // + // calibrate() { + // this.bottomSheet.open(CalibrateComponent, { + // hasBackdrop: false, + // disableClose: true + // }); + // } + // + // center(pos?) { + // if(!pos) pos = this.position; + // this.mapApi.setCenter({lat: pos.latitude, lng: pos.longitude}); + // } + // + // startDraw() { + // this.showPalette = true; + // this.mapApi.setOptions({draggable: false}); + // + // let drawHander = () => { + // let poly = new google.maps.Polyline({map: this.mapApi, clickable: true, strokeColor: this.drawColor}); + // google.maps.event.addListener(poly, 'click', () => { + // if(this.menu[1][3].enabled) poly.setMap(null); + // }); + // let moveListener = [ + // google.maps.event.addListener(this.mapApi, 'touchmove', e => poly.getPath().push(e.latLng)), + // google.maps.event.addListener(this.mapApi, 'mousemove', e => poly.getPath().push(e.latLng)) + // ]; + // google.maps.event.addListener(this.mapApi, 'touchend', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); + // google.maps.event.addListener(this.mapApi, 'mouseup', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); + // google.maps.event.addListener(poly, 'touchend', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); + // google.maps.event.addListener(poly, 'mouseup', () => moveListener.forEach(listener => google.maps.event.removeListener(listener))); + // }; + // + // this.drawListener = [ + // google.maps.event.addDomListener(this.mapApi.getDiv(), 'touchstart', drawHander), + // google.maps.event.addDomListener(this.mapApi.getDiv(), 'mousedown', drawHander) + // ]; + // } + // + // endDraw() { + // this.showPalette = false; + // this.mapApi.setOptions({draggable: true}); + // this.drawListener.forEach(listener => google.maps.event.removeListener(listener)); + // this.drawListener = []; + // } }