Commit 287033a627a21c20487d99d4637dcbde8517f044

Authored by lsagona
1 parent c4e00deb95
Exists in master

add vessel position to map

Showing 5 changed files with 54 additions and 21 deletions Inline Diff

src/app/component/import-vessels/import-vessels.component.ts View file @ 287033a
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; 1 1 import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {VesselsService} from '../../service/vessels.service'; 2 2 import {VesselsService} from '../../service/vessels.service';
import {Message} from '../../model/message'; 3 3 import {Message} from '../../model/message';
import {Vessels} from '../../model/vessels'; 4 4 import {Vessels} from '../../model/vessels';
5 5
@Component({ 6 6 @Component({
selector: 'app-import-vessels', 7 7 selector: 'app-import-vessels',
templateUrl: './import-vessels.component.html', 8 8 templateUrl: './import-vessels.component.html',
styleUrls: ['./import-vessels.component.scss'] 9 9 styleUrls: ['./import-vessels.component.scss']
}) 10 10 })
export class ImportVesselsComponent implements OnInit { 11 11 export class ImportVesselsComponent implements OnInit {
vessels: Vessels; 12 12 vessels: Vessels;
13 13
constructor(private vesselsService: VesselsService) { 14 14 constructor(private vesselsService: VesselsService) {
} 15 15 }
16 16
@ViewChild('fileDropRef', {static: false}) fileDropEl: ElementRef; 17 17 @ViewChild('fileDropRef', {static: false}) fileDropEl: ElementRef;
files: any[] = []; 18 18 files: any[] = [];
19 19
ngOnInit(): void { 20 20 ngOnInit(): void {
this.vesselsService.currentVessels.subscribe(vessels => this.vessels = vessels); 21 21 this.vesselsService.currentVessels.subscribe(vessels => this.vessels = vessels);
} 22 22 }
23 23
/** 24
* on file drop handler 25
*/ 26
onFileDropped($event): void { 27 24 onFileDropped($event): void {
this.prepareFilesList($event); 28 25 this.prepareFilesList($event);
} 29 26 }
30 27
/** 31
* handle file from browsing 32
*/ 33
fileBrowseHandler(files): void { 34 28 fileBrowseHandler(files): void {
this.prepareFilesList(files); 35 29 this.prepareFilesList(files);
} 36 30 }
37 31
/** 38
* Delete file from files list 39
* @param index (File index) 40
*/ 41
deleteFile(index: number): void { 42 32 deleteFile(index: number): void {
if (this.files[index].progress < 100) { 43 33 if (this.files[index].progress < 100) {
return; 44 34 return;
} 45 35 }
this.vessels = new Vessels(); 46 36 this.vessels = new Vessels();
this.vesselsService.changeVesselsSet(this.vessels); 47 37 this.vesselsService.changeVesselsSet(this.vessels);
this.files.splice(index, 1); 48 38 this.files.splice(index, 1);
} 49 39 }
50 40
51
uploadFiles(index: number): void { 52 41 uploadFiles(index: number): void {
const fileReader = new FileReader(); 53 42 const fileReader = new FileReader();
let nbLine: number; 54 43 let nbLine: number;
fileReader.onload = (e) => { 55 44 fileReader.onload = () => {
this.vessels = new Vessels(); 56 45 this.vessels = new Vessels();
const lines: string[] = (fileReader.result as string).split('\n'); 57 46 const lines: string[] = (fileReader.result as string).split('\n');
nbLine = lines.length; 58 47 nbLine = lines.length;
for (let line of lines) { 59 48 for (let line of lines) {
line = line.replace(/[^\x20-\x7F]/g, ''); 60 49 line = line.replace(/[^\x20-\x7F]/g, '');
const splitLine = line.split(','); 61 50 const splitLine = line.split(',');
if (isNaN(Number(splitLine[0])) || line === '') { 62 51 if (isNaN(Number(splitLine[0])) || line === '') {
continue; 63 52 continue;
} 64 53 }
const newMessage = new Message(splitLine); 65 54 const newMessage = new Message(splitLine);
this.vessels.addMessage(newMessage); 66 55 this.vessels.addMessage(newMessage);
} 67 56 }
this.vesselsService.changeVesselsSet(this.vessels); 68 57 this.vesselsService.changeVesselsSet(this.vessels);
}; 69 58 };
70 59
fileReader.onprogress = (e) => { 71 60 fileReader.onprogress = (e) => {
if (e.lengthComputable) { 72 61 if (e.lengthComputable) {
this.files[index].progress = Math.round(((e.loaded / e.total) * 100)); 73 62 this.files[index].progress = Math.round(((e.loaded / e.total) * 100));
} 74 63 }
}; 75 64 };
76 65
fileReader.readAsText(this.files[index]); 77 66 fileReader.readAsText(this.files[index]);
} 78 67 }
79 68
prepareFilesList(files: Array<any>): void { 80 69 prepareFilesList(files: Array<any>): void {
this.files = []; 81 70 this.files = [];
for (const item of files) { 82 71 for (const item of files) {
item.progress = 0; 83 72 item.progress = 0;
this.files.push(item); 84 73 this.files.push(item);
} 85 74 }
this.fileDropEl.nativeElement.value = ''; 86 75 this.fileDropEl.nativeElement.value = '';
this.uploadFiles(0); 87 76 this.uploadFiles(0);
} 88 77 }
src/app/component/list-vessel/list-vessel.component.ts View file @ 287033a
import {Component, OnInit} from '@angular/core'; 1 1 import {AfterViewInit, Component, OnInit} from '@angular/core';
import {VesselsService} from '../../service/vessels.service'; 2 2 import {VesselsService} from '../../service/vessels.service';
import {Vessels} from '../../model/vessels'; 3 3 import {Vessels} from '../../model/vessels';
4
declare var $: any; 4 5 declare var $: any;
5 6
@Component({ 6 7 @Component({
selector: 'app-list-vessel', 7 8 selector: 'app-list-vessel',
templateUrl: './list-vessel.component.html', 8 9 templateUrl: './list-vessel.component.html',
styleUrls: ['./list-vessel.component.scss'] 9 10 styleUrls: ['./list-vessel.component.scss']
}) 10 11 })
export class ListVesselComponent implements OnInit { 11 12 export class ListVesselComponent implements OnInit {
vessels: Vessels; 12 13 vessels: Vessels;
13 14
14
constructor(private vesselsService: VesselsService) { 15 15 constructor(private vesselsService: VesselsService) {
} 16 16 }
17 17
ngOnInit(): void { 18 18 ngOnInit(): void {
this.vesselsService.currentVessels.subscribe(vessels => { 19 19 this.vesselsService.currentVessels.subscribe(vessels => {
this.vessels = vessels; 20 20 setTimeout(() =>
21 this.vessels = vessels
22 );
}); 21 23 });
22 24
$(document).ready(() => { 23 25 $(document).ready(() => {
$('#myInput').on('keyup', function(): void { 24 26 $('#myInput').on('keyup', function(): void {
const value = $(this).val().toLowerCase(); 25 27 const value = $(this).val().toLowerCase();
$('#list-tab a').filter(function(): void { 26 28 $('#list-tab a').filter(function(): void {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1); 27 29 $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
}); 28 30 });
}); 29 31 });
}); 30 32 });
} 31 33 }
34
35 // ngAfterViewInit(): void {
36 // this.vesselsService.currentVessels.subscribe(vessels => {
37 // setTimeout(() =>
38 // this.vessels = vessels
39 // );
40 // });
src/app/component/map/map.component.ts View file @ 287033a
import { Component, OnInit } from '@angular/core'; 1 1 import {Component, OnInit} from '@angular/core';
import * as L from 'leaflet'; 2 2 import * as L from 'leaflet';
3 import {CircleMarker} from 'leaflet';
import {Vessels} from '../../model/vessels'; 3 4 import {Vessels} from '../../model/vessels';
import {VesselsService} from '../../service/vessels.service'; 4 5 import {VesselsService} from '../../service/vessels.service';
6 import {Message} from '../../model/message';
5 7
@Component({ 6 8 @Component({
selector: 'app-map', 7 9 selector: 'app-map',
templateUrl: './map.component.html', 8 10 templateUrl: './map.component.html',
styleUrls: ['./map.component.scss'] 9 11 styleUrls: ['./map.component.scss']
}) 10 12 })
export class MapComponent implements OnInit { 11 13 export class MapComponent implements OnInit {
vessels: Vessels; 12 14 vessels: Vessels;
15 public map: L.Map;
16 circleMarkers: Map<number, CircleMarker> = new Map<number, CircleMarker>();
13 17
constructor(private vesselsService: VesselsService) { } 14 18 constructor(private vesselsService: VesselsService) {
19 }
15 20
ngOnInit(): void { 16 21 ngOnInit(): void {
this.connectVesselObservable(); 17
this.initMap(); 18 22 this.initMap();
23 this.connectVesselObservable();
} 19 24 }
20 25
connectVesselObservable(): void { 21 26 connectVesselObservable(): void {
this.vesselsService.currentVessels.subscribe(vessels => { 22 27 this.vesselsService.currentVessels.subscribe(vessels => {
this.vessels = vessels; 23 28 this.vessels = vessels;
29 this.updateMap();
}); 24 30 });
} 25 31 }
26 32
initMap(): void { 27 33 initMap(): void {
const myMap = L.map('map').setView([0, 0], 1); 28 34 this.map = L.map('map', {
35 preferCanvas: true
36 }).setView([0, 0], 1);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { 29 37 L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: 'map' 30 38 attribution: 'map',
}).addTo(myMap); 31 39 }).addTo(this.map);
40 }
41
42 addCircleMarker(message: Message, color: string): void {
43 const circleMarker = L.circleMarker([+message.latitude, +message.longitude],
44 {
45 radius: 0.1,
46 color
47 }).addTo(this.map);
48 this.circleMarkers.set(Number(message.mmsi), circleMarker);
49 }
50
51 updateMap(): void {
52 let nbMessage = 0;
53 this.vessels.vessels.forEach(((vessel, key) => {
54 const color = vessel.getColor();
55 vessel.messages.forEach((message) => {
56 nbMessage++;
57 this.addCircleMarker(message, color);
58 });
59 }));
} 32 60 }
33 61
src/app/model/vessel.ts View file @ 287033a
import {Message} from './message'; 1 1 import {Message} from './message';
2 2
export class Vessel { 3 3 export class Vessel {
messages: Array<Message>; 4 4 messages: Array<Message>;
5 5
constructor(messages: Array<Message>) { 6 6 constructor(messages: Array<Message>) {
this.messages = messages; 7 7 this.messages = messages;
} 8 8 }
9 9
addMessage(message: Message): void { 10 10 addMessage(message: Message): void {
this.messages.push(message); 11 11 this.messages.push(message);
} 12 12 }
13 13
getMMSI(): string { 14 14 getMMSI(): string {
return this.messages[0].mmsi; 15 15 return this.messages[0].mmsi;
} 16 16 }
17 17
getName(): string { 18 18 getName(): string {
return this.messages[0].vesselName; 19 19 return this.messages[0].vesselName;
} 20 20 }
src/app/model/vessels.ts View file @ 287033a
import {Vessel} from './vessel'; 1 1 import {Vessel} from './vessel';
import {Message} from './message'; 2 2 import {Message} from './message';
3 import { delay } from 'rxjs/operators';
3 4
export class Vessels { 4 5 export class Vessels {
vessels: Map<number, Vessel>; 5 6 vessels: Map<number, Vessel>;
6 7
constructor() { 7 8 constructor() {
this.vessels = new Map<number, Vessel>(); 8 9 this.vessels = new Map<number, Vessel>();
} 9 10 }
10 11
addMessage(message: Message): void { 11 12 addMessage(message: Message): void {
if (!this.vessels.get(Number(message.mmsi))) { 12 13 if (!this.vessels.get(Number(message.mmsi))) {
this.vessels.set(Number(message.mmsi), new Vessel(new Array<Message>())); 13 14 this.vessels.set(Number(message.mmsi), new Vessel(new Array<Message>()));
} 14 15 }