Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/pages/dashboard/dashboard.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
</button>

<button class="button is-rounded is-icon-left has-text-white drone-status-active-icon"
style="margin-left: 15px !important;" (click)=mapService.saveSearchArea()
style="margin-left: 15px !important;" (click)=droneService.updateZones()
[attr.disabled]="mapService.polygonExists? null: ''">
<span class="icon">
<fa-icon [icon]="faEdit"></fa-icon>
Expand Down
2 changes: 1 addition & 1 deletion src/app/services/api-base.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
export interface ApiBaseInterface<T, ID> {
getAll(): Observable<T[]>;
get(id: ID): Observable<T>;
post(t: T): Observable<T>;
post(t: T): Observable<T[]>;
put(id: ID, t: T): Observable<T>;
delete(id: ID): Observable<any>;
}
4 changes: 2 additions & 2 deletions src/app/services/api-base.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export abstract class ApiBaseService<T, ID> implements ApiBaseInterface<T, ID> {
);
}

post(t: T): Observable<T> {
return this.httpClient.post<T>(this.apiUrl, t).pipe(
post(t: any): Observable<T[]> {
return this.httpClient.post<T[]>(this.apiUrl, t).pipe(
catchError((error) => {
this.handleServerError(error);
throw error;
Expand Down
33 changes: 33 additions & 0 deletions src/app/services/drone.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,37 @@ describe('DroneService', () => {
it('should be created', () => {
expect(service).toBeTruthy();
});

it('should return the correct color CSS class', () => {
expect(service.getDroneColor(0)).toBe('drone-status-idle');
expect(service.getDroneColor(1)).toBe('drone-status-idle');
expect(service.getDroneColor(2)).toBe('drone-status-active');
expect(service.getDroneColor(3)).toBe('drone-status-active');
expect(service.getDroneColor(4)).toBe('drone-status-active');
expect(service.getDroneColor(5)).toBe('drone-status-active');
expect(service.getDroneColor(6)).toBe('drone-status-active');
expect(service.getDroneColor(440)).toBe('drone-status-error');
});

it('should return the correct icon CSS class', () => {
expect(service.getDroneIconColor(0)).toBe('drone-status-idle-icon');
expect(service.getDroneIconColor(1)).toBe('drone-status-idle-icon');
expect(service.getDroneIconColor(2)).toBe('drone-status-active-icon');
expect(service.getDroneIconColor(3)).toBe('drone-status-active-icon');
expect(service.getDroneIconColor(4)).toBe('drone-status-active-icon');
expect(service.getDroneIconColor(5)).toBe('drone-status-active-icon');
expect(service.getDroneIconColor(6)).toBe('drone-status-active-icon');
expect(service.getDroneIconColor(440)).toBe('drone-status-error-icon');
});

it('should check if the livefeed is disabled', () => {
expect(service.isLivefeedDisabled(0)).toBeTrue();
expect(service.isLivefeedDisabled(1)).toBeTrue();
expect(service.isLivefeedDisabled(2)).toBeFalse();
expect(service.isLivefeedDisabled(3)).toBeFalse();
expect(service.isLivefeedDisabled(4)).toBeFalse();
expect(service.isLivefeedDisabled(5)).toBeFalse();
expect(service.isLivefeedDisabled(6)).toBeFalse();
expect(service.isLivefeedDisabled(440)).toBeTrue();
});
});
114 changes: 18 additions & 96 deletions src/app/services/drone.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { ApiBaseService } from './api-base.service';
import { SearchService } from './search.service';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { ZoneService } from './zone.service';
import { MapService } from './map.service';

@Injectable({
providedIn: 'root',
Expand All @@ -28,14 +30,15 @@ export class DroneService extends ApiBaseService<Drone, string> {
constructor(
protected toastService: ToastrService,
protected httpClient: HttpClient,
protected zoneService: ZoneService,
protected mapService: MapService,
private searchService: SearchService
) {
// Setup base api.
super(`${environment.api.baseUrl}/drones`, httpClient, toastService);

// Run updateDrones at the given interval (source).
this.subscription = this.source.subscribe((val) => this.updateDrones());
this.updateZones();
}

/**
Expand Down Expand Up @@ -65,6 +68,10 @@ export class DroneService extends ApiBaseService<Drone, string> {
}

private getRandomZoneColor(): string {
if (this.usedZoneColors.length === 6) {
this.usedZoneColors = [];
}

for (const color in ZoneColors) {
if (!this.usedZoneColors.includes(color)) {
this.usedZoneColors.push(color);
Expand All @@ -74,102 +81,17 @@ export class DroneService extends ApiBaseService<Drone, string> {
}

public updateZones(): void {
this.droneZones.push({
droneUuid: 'test1',
zoneColor: this.getRandomZoneColor(),
area: [
{
lat: 57.0530047355616,
lng: 9.918189775054937
},
{
lat: 57.0560504891736,
lng: 9.92136551052857
},
{
lat: 57.05489523273066,
lng: 9.924541246002203
},
{
lat: 57.05549036932661,
lng: 9.925270806854254
},
{
lat: 57.05510528203023,
lng: 9.9271161666565
},
{
lat: 57.050962423680616,
lng: 9.923468362396246
},
{
lat: 57.0518610547464,
lng: 9.920807611053473
},
],
path: [
{
lat: 57.054244204977,
lng: 9.920750783506284
},
{
lat: 57.05361403889979,
lng: 9.922553227964292
},
{
lat: 57.05308889233257,
lng: 9.924398587766538
}
]
});
this.droneZones.push({
droneUuid: 'test2',
zoneColor: this.getRandomZoneColor(),
area: [
{
lat: 57.05504997175444,
lng: 9.927763159339168
},
{
lat: 57.05077872940066,
lng: 9.924115355078914
},
{
lat: 57.050136833578975,
lng: 9.926497156684139
},
{
lat: 57.04985673010699,
lng: 9.92623966461871
},
{
lat: 57.04912144844144,
lng: 9.929522688452938
},
{
lat: 57.05391802367947,
lng: 9.93370693451617
}
],
path: [
{
lat: 57.05263375930009,
lng: 9.92684476238812
},
{
lat: 57.052225301829054,
lng: 9.928475545469174
},
{
lat: 57.05191020299586,
lng: 9.930149243894467
},
{
lat: 57.05180516945729,
lng: 9.93158690792645
},
]
// Get polygon points.
const polygon = this.mapService.getPolygonPaths();

this.zoneService.post(polygon).subscribe((res) => {
this.droneZones = res;
for (const zone of this.droneZones) {
zone.zoneColor = this.getRandomZoneColor();
}
});
this.mapService.clearMap();
this.toastService.success('The search area has been successfully updated!', 'Success');
}

public launchSearch(): void {
Expand Down
15 changes: 5 additions & 10 deletions src/app/services/map.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { ToastrService } from 'ngx-toastr';
import { DroneService } from './drone.service';

@Injectable({
providedIn: 'root'
Expand All @@ -26,7 +27,8 @@ export class MapService {
drawingMode: 'polygon'
};

constructor(private toastService: ToastrService) { }
constructor(
private toastService: ToastrService) { }

/**
* Centers the map from given parameters.
Expand Down Expand Up @@ -56,24 +58,17 @@ export class MapService {
if (this.polygon) {
const vertices = this.polygon.getPaths().getArray()[0];
const paths = [];
vertices.getArray().forEach((xy: { lat: () => any; lng: () => any; }) => {
vertices.getArray().forEach((xy: { lat: () => number; lng: () => number; }) => {
const latLng = {
lat: xy.lat(),
lng: xy.lng()
};
paths.push(JSON.stringify(latLng));
paths.push(latLng);
});
return paths;
}
else {
return [];
}
}

public saveSearchArea(): void {
this.clearMap();
// TODO: Put request

this.toastService.success('The search area has been successfully updated!', 'Success');
}
}
20 changes: 20 additions & 0 deletions src/app/services/zone.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ToastrModule, ToastrService } from 'ngx-toastr';
import { ZoneService } from './zone.service';

describe('ZoneService', () => {
let service: ZoneService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [ToastrModule.forRoot(), HttpClientTestingModule],
providers: [ToastrService]
});
service = TestBed.inject(ZoneService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
20 changes: 20 additions & 0 deletions src/app/services/zone.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ToastrService } from 'ngx-toastr';
import { environment } from 'src/environments/environment';
import { DroneZone } from '../models/drone-zone.model';
import { ApiBaseService } from './api-base.service';

@Injectable({
providedIn: 'root'
})
export class ZoneService extends ApiBaseService<DroneZone, string> {

constructor(
protected toastService: ToastrService,
protected httpClient: HttpClient
) {
// Setup base api.
super(`${environment.api.baseUrl}/search`, httpClient, toastService);
}
}