199 lines
5.3 KiB
JavaScript
199 lines
5.3 KiB
JavaScript
"use strict";
|
|
|
|
import {EventModel} from "./EventModel.ecma.js";
|
|
|
|
/**
|
|
* @class
|
|
* @constructor
|
|
* @param {!L.Map} map
|
|
* @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 {!L.Map} map
|
|
* @param {!number} x
|
|
* @param {!number} y
|
|
* @param {!number} i
|
|
* @param {!Array.<DotModel>} dots
|
|
* @returns {void}
|
|
* @access private
|
|
* @statix
|
|
*/
|
|
const DotModel = function(map, x, y, i, dots){
|
|
|
|
/** @type {DotModel} */
|
|
const self = this;
|
|
|
|
/** @type {Array.<L.Map>} */
|
|
this.map = map;
|
|
/** @type {number} */
|
|
this.i = i;
|
|
/** @type {number} */
|
|
this.x = x;
|
|
/** @type {number} */
|
|
this.y = y;
|
|
/** @type {L.Marker} */
|
|
this.marker = L.marker([y, x], {draggable : true});
|
|
/** @type {L.Pulyline|null} */
|
|
this.line = null;
|
|
/** @type {Array.<DotModel>} */
|
|
this.dots = dots;
|
|
/** @type {number} */
|
|
this.distance = 0;
|
|
|
|
/** @type {EventModel} */
|
|
this.on_change = new EventModel();
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const constructor = () => {
|
|
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.x = coordenates.lng;
|
|
self.y = 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 {Object.<string, number>}
|
|
* @access public
|
|
*/
|
|
this.get_leaflet_coordenates = () => ({
|
|
lat : self.y,
|
|
lng : self.x
|
|
});
|
|
|
|
/**
|
|
* @returns {Object.<string, number>}
|
|
* @access public
|
|
*/
|
|
this.get_coordenates = () => ({
|
|
latitude : self.y,
|
|
longitude : self.x
|
|
});
|
|
|
|
/**
|
|
* @returns {[string, number]}
|
|
* @access public
|
|
*/
|
|
this.get_dot = () => [self.y, self.x];
|
|
|
|
/**
|
|
* @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 = () => {
|
|
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 = self.dots[self.i - 1],
|
|
/** @type {number} */
|
|
pi_radians = Math.PI / 180,
|
|
/** @type {number} */
|
|
angle = (
|
|
Math.sin((self.y - previous.y) * pi_radians / 2) ** 2 +
|
|
Math.cos(self.y * pi_radians) * Math.cos(previous.y * pi_radians) *
|
|
Math.sin((self.x - previous.x) * 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;
|
|
})(); |