"use strict"; import {EventModel} from "./EventModel.ecma.js"; /** * @typedef {import("./RouteModel.ecma.js").RouteModel} RouteModel */ /** * @class * @constructor * @param {!RouteModel} route * @param {!number} x * @param {!number} y * @param {!number} i * @param {!Array.} dots * @returns {void} * @access public * @statix */ export const DotModel = (function(){ /** * @constructs DotModel * @param {!RouteModel} route * @param {!number} x * @param {!number} y * @param {!number} i * @param {!Array.} dots * @returns {void} * @access private * @statix */ const DotModel = function(route, longitude, latitude, i){ /** @type {DotModel} */ const self = this; /** @type {RouteModel} */ this.route = route; /** @type {number} */ this.i = i; /** @type {number} */ this.longitude = longitude; /** @type {number} */ this.latitude = latitude; /** @type {any|null} */ this.marker = null; /** @type {any|null} */ this.line = null; /** @type {number} */ this.distance = 0; /** @type {EventModel} */ this.on_change = new EventModel(); /** @type {EventModel} */ this.on_click = new EventModel(); /** @type {EventModel} */ this.on_drop = new EventModel(); /** * @returns {void} * @access private */ const constructor = () => { route.routes_maker.map.driver.add_dot(self); self.on_click.add(() => { self.remove(); }); self.on_drop.add((_, longitude, latitude) => { self.longitude = longitude; self.latitude = latitude; self.route.routes_maker.map.driver.redraw_dot_lines(self); self.recalculate_distance(); }); self.recalculate_distance(); // self.marker.addTo(map); // dots.length && (self.line = L.polyline([dots[dots.length - 1].get_dot(), self.get_dot()]).addTo(self.map)); // self.marker.on("click", event => { // self.remove(); // }); // self.marker.on("dragend", event => { // /** @type {L.LatLng} */ // const coordenates = event.target.getLatLng(); // self.longitude = coordenates.lng; // self.latitude = coordenates.lat; // self.remove_lines_linked(); // self.i < self.dots.length - 1 && (self.dots[self.i + 1].line = L.polyline([ // self.dots[self.i + 1].get_dot(), // self.get_dot() // ])).addTo(self.map); // self.i && (self.dots[self.i].line = L.polyline([ // self.get_dot(), // self.dots[self.i - 1].get_dot() // ])).addTo(self.map); // self.recalculate_distance(); // }); // self.recalculate_distance(); }; /** * @returns {[number, number]} * @access public */ this.get_point = () => [self.latitude, self.longitude]; // /** // * @returns {void} // * @access public // */ // this.remove_line = () => { // if(self.line){ // self.map.removeLayer(self.line); // self.line = null; // }; // }; // /** // * @returns {void} // * @access public // */ // self.remove_lines_linked = () => { // /** @type {number} */ // const l = self.dots.length; // [self.i, self.i + 1].forEach(i => { // i && i < l && self.dots[i].remove_line(); // }); // }; /** * @returns {void} * @access public */ this.remove = () => { const not_unique = self.i && self.i + 1 < route.dots.length; route.routes_maker.map.driver.remove_dot(self); route.dots.splice(self.i, 1); route.dots.slice(self.i).forEach(dot => { dot.i --; }); not_unique && route.routes_maker.map.driver.redraw_dot_lines(route.dots[self.i]); not_unique && route.dots[self.i].recalculate_distance(); // self.remove_lines_linked(); // self.i && self.i < self.dots.length - 1 && (self.dots[self.i + 1].line = L.polyline([ // self.dots[self.i + 1].get_dot(), // self.dots[self.i - 1].get_dot() // ])).addTo(self.map); // self.dots.splice(self.i, 1); // console.log(["A", self.distance]); // self.dots[self.i + 1].recalculate_distance(); // console.log(["B", self.distance]); // self.map.removeLayer(self.marker); // self.dots.slice(self.i).forEach(dot => { // dot.i --; // }); }; /** * @returns {void} * @access public */ this.recalculate_distance = () => { /** @type {number} */ const origin = self.distance || 0; if(self.i){ /** @type {DotModel} */ const previous = route.dots[self.i - 1], /** @type {number} */ pi_radians = Math.PI / 180, /** @type {number} */ angle = ( Math.sin((self.latitude - previous.latitude) * pi_radians / 2) ** 2 + Math.cos(self.latitude * pi_radians) * Math.cos(previous.latitude * pi_radians) * Math.sin((self.longitude - previous.longitude) * pi_radians / 2) ** 2 ); self.distance = DotModel.EARTH_RADIUS * 2 * Math.atan2(angle ** .5, (1 - angle) ** .5); }else self.distance = 0; origin != self.distance && self.on_change.execute(self); }; constructor(); }; /** @type {number} */ DotModel.EARTH_RADIUS = 6371000; return DotModel; })();