- add npm packages: "@fortawesome/angular-fontawesome, @fortawesome/fontawesome-svg-core, @fortawesome/free-solid-svg-icons

- add locate.service.ts, map-cache.service.ts
- add mapCache Service to map component
- notes
This commit is contained in:
Arno Kaimbacher 2021-09-08 14:40:57 +02:00
parent df3561235d
commit feab502c1d
21 changed files with 239 additions and 36 deletions

View file

@ -38,7 +38,7 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/geomon.viewer",
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",

View file

@ -183,4 +183,11 @@ npm install --save bulma
// "ng": "ng",
// "start": "ng serve",
// "build": "ng build",
// "watch": "ng build --watch --configuration development",
// "watch": "ng build --watch --configuration development",
font awesome with angular:
https://www.npmjs.com/package/@fortawesome/angular-fontawesome
npm install @fortawesome/fontawesome-svg-core
npm install @fortawesome/free-solid-svg-icons
npm install @fortawesome/angular-fontawesome@latest

77
package-lock.json generated
View file

@ -14,6 +14,9 @@
"@angular/platform-browser": "^12.1.4",
"@angular/platform-browser-dynamic": "^12.1.4",
"@angular/router": "^12.2.3",
"@fortawesome/angular-fontawesome": "^0.9.0",
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@helgoland/core": "^12.0.0-beta.1",
"@helgoland/depiction": "^12.0.0-beta.1",
"@helgoland/map": "^12.0.0-beta.1",
@ -3108,6 +3111,51 @@
"node": ">=10.0.0"
}
},
"node_modules/@fortawesome/angular-fontawesome": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@fortawesome/angular-fontawesome/-/angular-fontawesome-0.9.0.tgz",
"integrity": "sha512-pJNJqxRTJChkUtywbqRuJRpmK/WNwqFqeN/GMmJmy3gHeCnWQ4SG0BwPJqaWqhi4gqII5dADijGts6wqeusxeQ==",
"dependencies": {
"tslib": "^2.2.0"
},
"peerDependencies": {
"@angular/core": "^12.0.0",
"@fortawesome/fontawesome-svg-core": "^1.2.27"
}
},
"node_modules/@fortawesome/fontawesome-common-types": {
"version": "0.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz",
"integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==",
"hasInstallScript": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/fontawesome-svg-core": {
"version": "1.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz",
"integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==",
"hasInstallScript": true,
"dependencies": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-solid-svg-icons": {
"version": "5.15.4",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz",
"integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==",
"hasInstallScript": true,
"dependencies": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@gar/promisify": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz",
@ -21713,6 +21761,35 @@
"integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==",
"dev": true
},
"@fortawesome/angular-fontawesome": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@fortawesome/angular-fontawesome/-/angular-fontawesome-0.9.0.tgz",
"integrity": "sha512-pJNJqxRTJChkUtywbqRuJRpmK/WNwqFqeN/GMmJmy3gHeCnWQ4SG0BwPJqaWqhi4gqII5dADijGts6wqeusxeQ==",
"requires": {
"tslib": "^2.2.0"
}
},
"@fortawesome/fontawesome-common-types": {
"version": "0.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz",
"integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg=="
},
"@fortawesome/fontawesome-svg-core": {
"version": "1.2.36",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz",
"integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
}
},
"@fortawesome/free-solid-svg-icons": {
"version": "5.15.4",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz",
"integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.36"
}
},
"@gar/promisify": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz",

View file

@ -7,8 +7,6 @@
"test": "echo \"Error: no test specified\" && exit 1",
"prod": "rm -rf dist && webpack --progress --config webpack.production.js",
"dev": "webpack serve --config webpack.development.js --content-base=./ --hot --progress --port 4200"
},
"keywords": [
"geomonitoring",
@ -52,6 +50,9 @@
"@angular/platform-browser": "^12.1.4",
"@angular/platform-browser-dynamic": "^12.1.4",
"@angular/router": "^12.2.3",
"@fortawesome/angular-fontawesome": "^0.9.0",
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@helgoland/core": "^12.0.0-beta.1",
"@helgoland/depiction": "^12.0.0-beta.1",
"@helgoland/map": "^12.0.0-beta.1",

View file

@ -8,7 +8,7 @@
<nav class="navbar has-shadow" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="" href="http://geomon.geologie.ac.at/" target="_blank">
<img src="assets/Tethys-icon.png">
<img src="assets/geomon_logo.png">
</a>
<a role="button" id="menu-icon" class="navbar-burger" aria-label="menu" aria-expanded="false"
data-target="navbarBasicExample">

View file

@ -17,9 +17,9 @@ import { HttpService } from "./services/http.service";
import { StationService } from "./services/station.service";
import { MessagesComponent } from './messages/messages.component';
import { MessageService } from "./services/message.service";
// import { HelgolandMapModule } from '@helgoland/map';
// import { LocateService } from '@helgoland/map';
import { MapCache } from '../common/components/services/map-cache.service';
// import { LocateService } from '@helgoland/map';
// import { MapCache } from '@helgoland/map';
// siehe https://52north.github.io/helgoland-toolbox/additional-documentation/how-tos/integrate-a-map-component.html
// https://52north.github.io/helgoland-toolbox/components/LocateControlComponent.html#source
@ -28,6 +28,7 @@ import { MessageService } from "./services/message.service";
// DatasetApiInterface, ApiV3InterfaceService, SplittedDataDatasetApiInterface, DatasetApiV3Connector, HelgolandServicesConnector
// } from '@helgoland/core';
// import { HelgolandCoreModule } from "@helgoland/core";
// import { HelgolandMapModule } from '@helgoland/map';
// import 'core-js';
@ -37,7 +38,7 @@ import { MessageService } from "./services/message.service";
// imports: Other modules whose exported classes are needed by component templates declared in this NgModule.
imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule],
providers: [
MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService
MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService, MapCache
// {
// provide: DatasetApiInterface,
// useClass: SplittedDataDatasetApiInterface,

View file

@ -3,6 +3,8 @@ import { Map, Control, MapOptions, LatLngBoundsExpression, tileLayer, TileLayer
// import { MarkerService } from '../services/marker.service';
import { LayerOptions, LayerMap } from './map-options';
import { MapCache } from '../../common/components/services/map-cache.service';
const DEFAULT_BASE_LAYER_NAME = 'BaseLayer';
const DEFAULT_BASE_LAYER_URL = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
const DEFAULT_BASE_LAYER_ATTRIBUTION = '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors';
@ -62,7 +64,7 @@ export abstract class BaseMapComponent implements OnChanges, OnInit {
protected map: Map;
protected zoomControl: Control.Zoom;
constructor() { }
constructor(protected mapCache: MapCache) { }
// constructor(private markerService: MarkerService) { }
// constructor(markerService: MarkerService) {
// this.markerService = markerService;
@ -88,7 +90,7 @@ export abstract class BaseMapComponent implements OnChanges, OnInit {
center: [48.208174, 16.373819],
zoom: 3
});
this.mapCache.setMap(this.mapId, this.map);
this.onMapInitializedEvent.emit(this.mapId);
if (this.baseMaps && this.baseMaps.size > 0) {
this.baseMaps.forEach((layerOptions, key) => this.addBaseMap(layerOptions));

View file

@ -4,4 +4,5 @@
</div>
</div> -->
<div [attr.id]="mapId" class="map-container mapDesktop">
<gba-locate-button [mapId]="mapId"></gba-locate-button>
</div>

View file

@ -5,6 +5,7 @@ import { MarkerService } from '../services/marker.service';
import { DatasetApiService } from '../services/dataset-api.service';
import { BaseMapComponent } from './base-map.component';
import { PopupService } from '../services/popup.service';
import { MapCache } from '../../common/components/services/map-cache.service';
@Component({
selector: 'app-map',
@ -16,8 +17,7 @@ export class MapComponent
extends BaseMapComponent
implements OnChanges, AfterViewInit {
/**
* @input The serviceUrl, where the selection should be loaded.
*/
@ -43,10 +43,11 @@ export class MapComponent
// constructor() { }
constructor(
protected mapCache: MapCache,
protected markerService: MarkerService,
private popupService: PopupService,
protected datasetApiService: DatasetApiService) {
super();
super(mapCache);
this.markerFeatureGroup = new FeatureGroup();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

BIN
src/assets/geomon_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

View file

@ -1,12 +1,18 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
// import { HelgolandCoreModule } from '@helgoland/core';
// import { HelgolandMapModule } from '@helgoland/map';
import { LocateButtonComponent } from './locate-button/locate-button.component';
// import { LocateService } from '@helgoland/map';
// import { MapCache } from '@helgoland/map';
import { MapCache } from './services/map-cache.service';
import { LocateService } from './services/locate.service';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
// import { HelgolandMapModule, LocateService } from '@helgoland/map';
@NgModule({
imports: [
CommonModule,
CommonModule, FontAwesomeModule
],
declarations: [
LocateButtonComponent,
@ -15,7 +21,9 @@ import { LocateButtonComponent } from './locate-button/locate-button.component';
LocateButtonComponent,
],
providers: [
providers: [
// LocateService,
MapCache, LocateService
]
})
export class ComponentsModule { }

View file

@ -3,7 +3,8 @@
<i class="fa fa-map-marker-alt"></i>
</button>
</div> -->
<button (click)="test()">
</button>
<div class="gba-control-locate btn-group-vertical btn-group-sm map-control">
<button type="button" class="button is-small" (click)="locateUser()" [ngClass]="isToggled ? 'is-primary': 'is-active'">
<fa-icon [icon]="faSearchLocation"></fa-icon>
</button>
</div>

View file

@ -0,0 +1,17 @@
.gba-control-locate button {
width: 30px;
height: 30px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
border-radius: 4px;
// display: block;
text-align: center;
color: black;
position: absolute;
left: 10px;
top: 80px;
z-index: 999;
}

View file

@ -1,25 +1,38 @@
import { Component, Input } from '@angular/core';
import { Required } from '@helgoland/core';
import { MapCache } from '../services/map-cache.service';
import { LocateService } from '../services/locate.service';
import { faSearchLocation, faMapPin } from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'helgoland-locate-button',
selector: 'gba-locate-button',
templateUrl: './locate-button.component.html',
styleUrls: ['./locate-button.component.scss']
})
export class LocateButtonComponent {
export class LocateButtonComponent {
/**
* Connect map id.
*/
@Input() @Required public mapId: string;
faSearchLocation = faSearchLocation;
@Input()
public mapId: string;
constructor(
) { }
public isToggled = false;
test() {}
constructor(
protected locateService: LocateService,
protected mapCache: MapCache
) {
// super(mapCache);
}
public locateUser() {
this.isToggled = !this.isToggled;
if (this.isToggled) {
this.locateService.startLocate(this.mapId);
// alert('toggled');
} else {
this.locateService.stopLocate(this.mapId);
// alert('not toggled');
}
}
}

View file

@ -0,0 +1,49 @@
import { Injectable } from '@angular/core';
import * as L from 'leaflet';
import { MapCache } from './map-cache.service';
const LOCATION_FOUND_EVENT = 'locationfound';
const LOCATION_ERROR = 'locationerror';
const LOCATED_MARKER_ID = 'located';
@Injectable()
export class LocateService {
constructor(
protected mapCache: MapCache
) { }
public startLocate(id: string) {
const map = this.mapCache.getMap(id);
map.on(LOCATION_FOUND_EVENT, (evt: L.LocationEvent) => {
this.removeMarker(map);
const marker = L.marker(evt.latlng).addTo(map);
marker.options.title = LOCATED_MARKER_ID;
});
map.on(LOCATION_ERROR, (error) => {
console.error(error);
});
map.locate({
watch: true,
setView: true,
timeout: 30000
});
}
public stopLocate(id: string) {
const map = this.mapCache.getMap(id);
map.stopLocate();
map.off(LOCATION_FOUND_EVENT);
this.removeMarker(map);
}
private removeMarker(map: L.Map) {
map.eachLayer((entry) => {
if (entry instanceof L.Marker && entry.options.title === LOCATED_MARKER_ID) {
map.removeLayer(entry);
}
});
}
}

View file

@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import * as L from 'leaflet';
@Injectable()
export class MapCache {
private mapCache: Map<string, any> = new Map<string, any>();
public getMap(id: string): L.Map {
return this.mapCache.get(id);
}
public setMap(id: string, map: L.Map) {
this.mapCache.set(id, map);
}
public hasMap(id: string): boolean {
return this.mapCache.has(id);
}
public deleteMap(id: string): boolean {
return this.mapCache.delete(id);
}
}

View file

@ -5,7 +5,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A Basic HTML5 Template</title>
<title>Geomonitoring GBA</title>
<base href="/">
<meta name="description" content="A simple HTML5 Template for new projects.">
<meta name="author" content="Arno Kaimbacher">
@ -18,7 +18,7 @@
<link rel="icon" href="src/favicon.ico">
<link rel="icon" href="favicon.ico">
<!-- <link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png"> -->