import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; import { ConfirmationService, MenuItem, MessageService } from 'primeng/api'; import { Extent } from 'ol/extent'; import { Group, Tile, Vector as VectorLayer } from 'ol/layer'; import { OSM, TileWMS, Vector as VectorSource } from 'ol/source'; import GeoJSON from 'ol/format/GeoJSON'; import { transform, transformExtent } from 'ol/proj'; import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'; import View from 'ol/View'; import { Unit } from '../../../shared/api/endpoints/models/unit'; import { Lastpos } from '../../../shared/api/endpoints/models/lastpos'; import { Drivers } from '../../../shared/api/endpoints/models/drivers'; import { GeneralInfo } from '../../../shared/api/endpoints/models/general-info'; import { Sensor } from '../../../shared/api/endpoints/models/sensor'; import { HsConfig, HsMapService, HsLayerManagerService, HsLayerEditorService, HsEventBusService } from 'hslayers-ng'; import { environment } from '../../../../environments/environment'; import Geometry from 'ol/geom/Geometry'; @Component({ selector: 'app-map', templateUrl: './map.component.html', styleUrls: ['./map.component.scss'] }) export class MapComponent implements OnInit, OnDestroy, OnChanges { @Input('units') units: Array<{ drivers?: Drivers; generalInfo?: GeneralInfo; holder?: any; lastpos?: Lastpos; sensors?: Array; unit?: Unit }>; mapReady: boolean = false; dataReady: boolean = false; unitsLayer: VectorLayer>; constructor( private confirmationService: ConfirmationService, private messageService: MessageService, public HsConfig: HsConfig, public HsMapService: HsMapService, public HsLayerManagerService: HsLayerManagerService, public HsLayerEditorService: HsLayerEditorService, public HsEventBusService: HsEventBusService ) { this.HsConfig.update({ assetsPath: environment.hslayersAssetsPath, popUpDisplay: 'click', proxyPrefix: window.location.hostname.includes('localhost') ? `${window.location.protocol}//${window.location.hostname}:8085/` : '/proxy/', box_layers: [ new Group({ properties: { title: 'Base layer', }, layers: [ new Tile({ source: new OSM(), visible: true, properties: { title: 'OpenStreetMap', base: true, removable: false } }) ] }) ], //default_layers: this.loadLayers(), componentsEnabled: { sidebar: false, toolbar: false, guiOverlay: true, drawToolbar: false, searchToolbar: false, measureToolbar: false, sensors: false, crossfilter: false, geolocationButton: false, tracking: false, mapControls: true, basemapGallery: true }, panelsEnabled: { info: false, //(true by default), layermanager: false }, sidebarPosition: 'invisible', queryPoint: 'hidden', default_view: new View({ maxZoom: 17 // center: [1873444.3416929364, 6286508.646897761], // Latitude longitude to Spherical Mercator // extent: [1871197.0792499082, 6282949.4051418, 1873509.6915773677, 6287134.61866585], // multiWorld: false, // zoom: 6 }) }); } ngOnInit(): void { } ngOnChanges(changes: SimpleChanges): void { if (changes['units']) { //this.dataReady = true; //if (this.mapReady) this.HsMapService.loaded().then((map) => { this.initMap(); let unitsExtent: Extent = this.unitsLayer.getSource().getExtent(); this.HsMapService.map.getView().fit(unitsExtent, { size: this.HsMapService.map.getSize() }); this.HsMapService.map.on("pointermove", function (evt) { var hit = this.forEachFeatureAtPixel(evt.pixel, function (feature, layer) { return true; }); if (hit) { this.getTargetElement().style.cursor = 'pointer'; } else { this.getTargetElement().style.cursor = ''; } }); }); } } /** * Unsubscribe after leaving */ ngOnDestroy(): void { } initMap(): void { this.unitsLayer = this.initUnitsLayer(this.HsMapService.map); this.HsMapService.map.addLayer(this.unitsLayer); // this.HsMapService.map.on('click', function (evt) { // var feature = this.HsMapService.map.forEachFeatureAtPixel(evt.pixel, // function (feature) { // return feature; // }); // if (feature) { // let unitId = feature.getProperties()['unitId']; // window.open('/#/dashboard / unit /' + unitId); // } // }) } /** * Crete vector layer from units positions */ initUnitsLayer(map: any): any { var geoJsonUnits = { 'type': 'FeatureCollection', 'crs': { 'type': 'name', 'properties': { 'name': 'EPSG:3857', } } }; geoJsonUnits['features'] = this.units ? this.units.filter(u => (u.lastpos.position.x > 0)).map(u => this.getUnitPos(u.lastpos, u.unit)) : []; const vectorSource = new VectorSource({ features: new GeoJSON().readFeatures(geoJsonUnits), }); vectorSource.on('addfeature', function () { map.getView().fit(vectorSource.getExtent()); }); const vectorLayer = new VectorLayer({ source: vectorSource, style: this.styleFunction, properties: { popUp: { displayFunction: function (feature) { return ` `; } // attributes: [ // { // attribute: 'id', // label: 'Unit ID' // }, // { // attribute: 'online', // label: 'Online', // displayFunction: function (val) { // return ''; // } // }, // { // attribute: 'test', // label: 'test' // }, // { // attribute: 'id', // label: 'Detail', // displayFunction: function (val) { // return 'open unit detail...'; // } // } // ] } } }); return vectorLayer; } styleFunction(feature: any): Style { return new Style({ image: new CircleStyle({ radius: 5, fill: new Fill({ color: 'red' }), stroke: new Stroke({ color: 'blue', width: 2 }) }) }) } getUnitPos(pos: Lastpos, unit: Unit): any { return { "type": "Feature", "geometry": { "type": "Point", "coordinates": [pos.position.x, pos.position.y] }, "properties": { "id": unit.unitId, "title": unit.description, "online": pos.attributes.is_online, "moving": pos.attributes.is_moving } } } }