mapa-gcba
Version:
Mapa Interactivo de la Ciudad de Buenos Aires
327 lines (326 loc) • 14.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const leaflet_1 = __importDefault(require("leaflet"));
const functions_1 = require("../config/tile-layers/functions");
const data_1 = require("../config/tile-layers/data");
const axios_1 = __importDefault(require("axios"));
const urls_1 = require("./../config/urls/urls");
class MapaInteractivo {
constructor(id, options = {}) {
this.getParamsOptions = () => {
return this.config.params;
};
this.setOptions = (options) => {
if (!options) {
return;
}
if (!this.config.params) {
this.config.params = {};
}
Object.keys(options).forEach((key) => {
const optionKey = key;
if (this.config.params === undefined) {
this.config.params = {};
}
const value = options[optionKey];
if (value !== undefined) {
this.config.params[optionKey] = value;
}
if (typeof options.onClick === 'function') {
this.map.off('click');
this.map.on('click', (func) => options.onClick(func));
}
if (typeof options.onContextMenu === 'function') {
this.map.off('contextmenu');
this.map.on('contextmenu', (func) => options.onContextMenu(func));
}
if (typeof options.onDblClick === 'function') {
this.map.off('dblclick');
this.map.on('dblclick', (func) => options.onDblClick(func));
}
});
this.applyOptions();
};
this.getReverseOptions = () => {
return this.config.reverseOptions;
};
this.setReverseOptions = (options) => {
if (!options) {
return;
}
Object.keys(options).forEach((key) => {
const optionKey = key;
if (this.config.reverseOptions === undefined) {
this.config.reverseOptions = {};
}
if (optionKey in this.config.reverseOptions) {
this.config.reverseOptions[optionKey] = options[optionKey];
}
});
};
this.applyOptions = () => {
const { params } = this.config;
if (params) {
if (params.center) {
this.map.setView(params.center, params.zoom !== undefined ? params.zoom : this.map.getZoom());
}
if (params.zoom !== undefined) {
this.map.setZoom(params.zoom);
}
if (params.minZoom !== undefined) {
this.map.setMinZoom(params.minZoom);
}
if (params.maxZoom !== undefined) {
this.map.setMaxZoom(params.maxZoom);
}
if (params.doubleClickZoom !== undefined) {
this.map.doubleClickZoom[params.doubleClickZoom ? "enable" : "disable"]();
}
if (params.dragging !== undefined) {
this.map.dragging[params.dragging ? "enable" : "disable"]();
}
if (params.scrollWheelZoom !== undefined) {
this.map.scrollWheelZoom[params.scrollWheelZoom ? "enable" : "disable"]();
}
if (params.touchZoom !== undefined) {
this.map.touchZoom[params.touchZoom ? "enable" : "disable"]();
}
if ('attributionControl' in params) {
if (params.attributionControl) {
if (!this.map.attributionControl) {
leaflet_1.default.control.attribution({}).addTo(this.map);
}
}
else {
if (this.map.attributionControl) {
this.map.removeControl(this.map.attributionControl);
}
}
}
if ('zoomControl' in params) {
if (params.zoomControl) {
if (!this.map.zoomControl) {
leaflet_1.default.control.zoom().addTo(this.map);
}
}
else {
if (this.map.zoomControl) {
this.map.removeControl(this.map.zoomControl);
}
}
}
}
};
this.copyCoordinates = (lat, lng, button) => {
const text = `${lat.toFixed(2)}, ${lng.toFixed(2)}`;
navigator.clipboard.writeText(text);
button.innerHTML = "✔";
button.style.backgroundColor = "#22c55e";
button.style.color = "#ffffff";
setTimeout(() => {
button.innerHTML = "Copiar";
button.style.backgroundColor = "#f5f5f5";
button.style.color = "black";
}, 2000);
};
this._onClick = (event) => {
this.cleanMap();
if (typeof this.config.onClick === "function") {
this.config.onClick(event);
}
};
this._onContextMenu = (event) => {
var _a;
this.cleanMap();
if (typeof this.config.onContextMenu === "function") {
this.config.onContextMenu(event);
}
const { lat, lng } = event.latlng;
this.map.setView([lat, lng], this.map.getZoom());
const marker = leaflet_1.default.marker([lat, lng])
.addTo(this.map)
.bindPopup(`
<div class="popup-coordinates-container">
<h5>Lat: ${lat.toFixed(2)}, Lng: ${lng.toFixed(2)}</h5>
<div class="copy-button-container">
<button id="copyButton" class="copy-button">Copiar</button>
</div>
</div>
`)
.openPopup();
const popupElement = (_a = marker.getPopup()) === null || _a === void 0 ? void 0 : _a.getElement();
const copyButton = popupElement === null || popupElement === void 0 ? void 0 : popupElement.querySelector("#copyButton");
if (copyButton) {
copyButton.addEventListener("click", () => this.copyCoordinates(lat, lng, copyButton));
}
setTimeout(() => {
this.map.removeLayer(marker);
}, 3000);
this.map.setView([lat, lng]);
};
this._onDblClick = (event) => {
var _a;
if (typeof this.config.onDblClick === "function") {
this.config.onDblClick(event);
}
if ((_a = this.config.reverseOptions) === null || _a === void 0 ? void 0 : _a.active) {
this.reverseGeocoding(event);
}
};
this.setMarkerView = (lat, lng, popupContent = "") => {
this.cleanMap();
this.map.whenReady(() => {
const marker = leaflet_1.default.marker([lat, lng]).addTo(this.map);
if (popupContent !== "") {
marker.bindPopup(popupContent).openPopup();
}
this.map.setView([lat, lng]);
});
};
this.reverseGeocoding = (e) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
this.cleanMap();
const { lat, lng } = e.latlng;
const radio = (_a = this.config.reverseOptions) === null || _a === void 0 ? void 0 : _a.radius;
const marker = leaflet_1.default.marker([lat, lng]);
try {
if (((_b = this.config.reverseOptions) === null || _b === void 0 ? void 0 : _b.type) === "address") {
const response = yield axios_1.default.get(`${urls_1.apiServiciosUrl}/coordenadas/reverse?x=${e.latlng.lng}&y=${e.latlng.lat}`);
const { data } = response.data;
marker.addTo(this.map);
marker.bindPopup(`
<div>
<div class="info-row">
<div class="label">Dirección: </div>
<strong><div class="value">${data.direccion}</div></strong>
</div>
<div class="info-row">
<div class="label">Barrio: </div>
<div class="value">${data.barrio}</div>
</div>
<div class="info-row">
<div class="label">Comuna: </div>
<div class="value">${data.comuna}</div>
</div>
<div class="info-row">
<div class="label">GKBA: </div>
<div class="value">${data.coordenada_y.toFixed(2)}, ${data.coordenada_x.toFixed(2)}</div>
</div>
</div>
`);
}
if (((_c = this.config.reverseOptions) === null || _c === void 0 ? void 0 : _c.type) === "places" || ((_d = this.config.reverseOptions) === null || _d === void 0 ? void 0 : _d.type) === "place") {
if (this.config.reverseOptions.radius == 0) {
console.error("Debe definir un radio");
}
const response = yield axios_1.default.get(`${urls_1.apiServiciosUrl}/lugares/reverse?x=${e.latlng.lng}&y=${e.latlng.lat}&radio=${radio}`);
marker.addTo(this.map);
const circle = leaflet_1.default.circle([lat, lng], {
color: "#bbb",
fillColor: "#fff",
fillOpacity: 0.5,
radius: radio,
weight: 1,
}).addTo(this.map);
const { data } = response.data;
data.map((place) => {
const { descripcion, direccion, coordenada_x, coordenada_y, distancia, } = place;
leaflet_1.default.marker([coordenada_y, coordenada_x], {
icon: leaflet_1.default.icon({
iconUrl: "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-yellow.png",
shadowUrl: "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png",
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41],
}),
})
.addTo(this.map)
.bindPopup(`
<h5>${descripcion}</h5>
<p>Dirección: ${direccion}</p>
<p>Distancia: ${distancia.toFixed(2)} m</p>
`);
});
const circleBounds = circle.getBounds();
this.map.fitBounds(circleBounds);
this.map.setView([lat, lng], this.map.getZoom());
}
}
catch (error) {
marker.addTo(this.map);
marker.bindPopup(error.response.data.error).openPopup();
}
});
this.config = Object.assign({}, data_1.defaultOptions, options);
this.config.params = this.config.params || {};
this.config.supportedLanguages = Object.keys(this.config.texts || []);
this.loadingControl = new leaflet_1.default.Control({
position: "bottomleft",
});
let loadingMessage = "Cargando...";
if (this.config.language !== undefined &&
this.config.texts !== undefined &&
this.config.texts[this.config.language] !== undefined) {
loadingMessage = this.config.texts[this.config.language].loadingMaps;
}
if (this.config.showLoadingControl) {
this.loadingControl.onAdd = () => {
const container = leaflet_1.default.DomUtil.create("div", "loading-control");
container.innerHTML = loadingMessage;
return container;
};
}
const params = Object.assign({}, this.config.params, options.params || {});
this.map = leaflet_1.default.map(id, params).setView(this.config.params.center || [-34.60762631005845, -58.445854986577395], this.config.params.zoom || 13);
if (this.config.showScaleControl) {
leaflet_1.default.control
.scale({
imperial: false,
})
.addTo(this.map);
}
if (this.config.showLoadingControl) {
this.loadingControl.addTo(this.map);
}
this.map.on("contextmenu", this._onContextMenu, this);
this.map.on("dblclick", this._onDblClick, this);
this.map.on("click", this._onClick, this);
const wmsLayer = (0, functions_1.tileLayerSelect)();
if (this.config.showLoadingControl) {
wmsLayer.on("load", () => {
this.map.removeControl(this.loadingControl);
});
}
wmsLayer.addTo(this.map);
}
setLanguage(language) {
if (this.config.supportedLanguages != undefined &&
this.config.supportedLanguages.indexOf(language) > -1) {
this.config.language = language;
}
}
cleanMap() {
this.map.eachLayer((layer) => {
if (layer instanceof leaflet_1.default.Marker) {
this.map.removeLayer(layer);
}
if (layer instanceof leaflet_1.default.Circle) {
this.map.removeLayer(layer);
}
});
}
}
exports.default = MapaInteractivo;