210 lines
6.2 KiB
JavaScript
210 lines
6.2 KiB
JavaScript
"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.<DotModel>} 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.<DotModel>} 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;
|
|
})(); |