road-map.component.ts 6.07 KB
import {Component, Input, AfterViewInit, ViewChild} from '@angular/core';
import * as L from 'leaflet';
import { Way } from '../models/way';
import {WayPolyline} from "../models/way-polyline";
import {NodeMarker} from "../models/node-marker";
import {Node} from "../models/node";
import {RoadService} from "../services/road.service";
import {TdExpansionPanelComponent} from "@covalent/core/expansion-panel/expansion-panel.component";

@Component({
    // tslint:disable-next-line:component-selector
    selector: 'road-map',
    templateUrl: 'road-map.component.html',
})
export class RoadMapComponent implements AfterViewInit {
    protected isVisible: boolean = false;
    protected isNodesVisible: boolean = false;
    protected isLegend: boolean = false;
    protected isExpanded: boolean = false;
    protected map: L.Map;
    protected ways: Way[] = [];
    protected legend: string;
    protected legendSummary: string;
    @Input() identificator: string = 'mapID';

    constructor(
        protected service: RoadService
    ) {}

    public ngAfterViewInit(): void {
        this.map = L.map(this.identificator).setView([51.505, -0.09], 13);
        L.tileLayer('https://a.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 18,
        }).addTo(this.map);
        let controls: L.Control = new L.Control({
            position: 'topright'
        });
        controls.onAdd = function (map: L.Map): HTMLElement {
            return L.DomUtil.create('md-icon', 'material-icons mat-icon');
        };
        controls.addTo(this.map);
    }
    public showMap(): void {
        this.isVisible = true;
    }
    public getHeight(): string {
        return this.isVisible ? '100%' : '100%';
    }
    public setWays(ways: Way[]): void {
        this.ways = this.ways.concat(ways);
        this.showWays(ways);
    }
    protected showWays(ways: Way[]): void {
        let minLat: number = 0;
        let maxLat: number = 0;
        let minLon: number = 0;
        let maxLon: number = 0;
        ways.forEach((way) => {
            let nodes: L.LatLng[] = [];
            way.nodes.forEach((node) => {
                if (minLat == 0) {
                    minLat = node.lat;
                    maxLat = node.lat;
                } else {
                    minLat = (minLat > node.lat)?node.lat:minLat;
                    maxLat = (maxLat < node.lat)?node.lat:maxLat;
                }
                if (minLon == 0) {
                    minLon = node.lon;
                    maxLon = node.lon;
                } else {
                    minLon = (minLon > node.lon)?node.lon:minLon;
                    maxLon = (maxLon < node.lon)?node.lon:maxLon;
                }
                let latLng = node.getLatLng();
                node.marker = new NodeMarker(latLng);
                node.marker.node = node;
                nodes.push(latLng);
            });
            way.polyline = new WayPolyline(nodes, {color: 'red'});
            way.polyline.way = way;
            way.polyline.addTo(this.map).on('click', (event) => {
                console.log(event);
                this.service.getRoadByWay(event.target.way.id).then(road => {
                    this.setWaySummary(way);
                    this.showLegend(road, 'Дорога');
                });
            });
        });
        this.map.fitBounds([
            [minLat, minLon],
            [maxLat, maxLon]
        ]);
        this.showMap();
    }
    protected showNodes(): void {
        this.ways.forEach(way => {
            way.nodes.forEach(node => {
                node.marker.addTo(this.map).on('click', (event) => {
                    this.service.getRoadByNode(event.target.node.id).then(road => {
                        this.setNodeSummary(node);
                        this.showLegend(road, 'Дорога');
                    });
                    console.log(event);
                });
            });
        });
    }
    protected hideNodes(): void {
        this.ways.forEach(way => {
            way.nodes.forEach(node => {
                node.marker.remove();
            });
        });
    }
    protected toggleNodes(): void {
        if (this.isNodesVisible) {
            this.hideNodes();
            this.isNodesVisible = false;
        } else {
            this.showNodes();
            this.isNodesVisible = true
        }
    }
    protected toggleLegend(): void {
        this.isLegend = !this.isLegend;
    }
    protected showLegend(model: Object, name: string): void {
        let result: string = '';
        result += '<h3>Информация об объекте ' + name;
        if (model.hasOwnProperty('id')) {
            result += ' (id: ' + model['id'] + ')';
        }
        result += '</h3><ul>';
        for (let property in model) {
            result += '<li><strong>' + property + '</strong>: ' + (model[property]?model[property]:'Не указано') + '</li>';
        }
        result += '</ul>';
        this.isLegend = true;
        this.legend = result;
    }
    protected setNodeSummary(node: Node): void {
        let result: string = '<p>Вы нажали на точку с ID = ' + node.id + '.</p>';
        result += '<p>Координаты точки: lat = ' + node.lat + ', lon = ' + node.lon + '.</p>';
        this.legendSummary = result;
    }
    protected setWaySummary(way: Way): void {
        let result: string = '<p>Вы нажали на линию с ID = ' + way.id + '.</p>';
        result += '<p>Количество точек на линии: ' + way.nodes.length + '.</p>';
        this.legendSummary = result;
    }
    protected setLegend(legend: string) {
        this.legend = legend;
        this.isLegend = true;
    }
    public clearWays(): void {
        this.ways.forEach(way => {
            way.nodes.forEach(node => {
                node.marker.remove();
            });
            way.polyline.remove();
        });
        this.ways = [];
        this.legend = undefined;
        this.isLegend = false;
        this.isNodesVisible = false;
    }
    protected collapsedEvent() {
        this.isExpanded = false;
    }
    protected expandedEvent() {
        this.isExpanded = true;
    }
}