vue-geojson-view-ts 1.3.17 → 1.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +321 -321
- package/dist/components/MapSearchAddress.vue.d.ts +1 -1
- package/dist/data/bolivia.geojson +2084 -2084
- package/dist/data/cities/be.geojson +246 -246
- package/dist/data/cities/cbba.geojson +165 -165
- package/dist/data/cities/ch.geojson +170 -170
- package/dist/data/cities/lp.geojson +314 -314
- package/dist/data/cities/or.geojson +253 -253
- package/dist/data/cities/pd.geojson +164 -164
- package/dist/data/cities/pt.geojson +379 -379
- package/dist/data/cities/sc.geojson +224 -224
- package/dist/data/cities/tj.geojson +86 -86
- package/dist/pin.svg +4 -4
- package/dist/style.css +1 -1
- package/dist/vite-env.d.ts +1 -1
- package/dist/vue-geojson-view-ts.js +15372 -14023
- package/dist/vue-geojson-view-ts.umd.cjs +65 -49
- package/package.json +78 -78
- package/src/components/CoordinatesVerifyPolygon.vue +86 -86
- package/src/components/MapHeatComponent.vue +664 -664
- package/src/components/MapSearchAddress.vue +309 -309
- package/src/components/MapView.vue +715 -716
|
@@ -1,716 +1,715 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="map-container" :style="`height:${configurationMap?.height}`">
|
|
3
|
-
<div :id="idMap" style="height: 100%"></div>
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script lang="ts">
|
|
8
|
-
import { defineComponent } from "vue";
|
|
9
|
-
import { markerDefault } from "../helpers/imgBase64";
|
|
10
|
-
import homeIconUrl from "../assets/home.png";
|
|
11
|
-
import endIconUrl from "../assets/end.png";
|
|
12
|
-
import trackingIconUrl from "../assets/tracking.png";
|
|
13
|
-
import * as L from "leaflet";
|
|
14
|
-
import "leaflet-draw";
|
|
15
|
-
import "leaflet/dist/leaflet.css";
|
|
16
|
-
import "leaflet-draw/dist/leaflet.draw.css";
|
|
17
|
-
import drawLocales from "leaflet-draw-locales";
|
|
18
|
-
import axios from "axios";
|
|
19
|
-
import "leaflet.fullscreen/Control.FullScreen.css";
|
|
20
|
-
import "leaflet.fullscreen";
|
|
21
|
-
import gpsIcon from "../assets/gps.svg";
|
|
22
|
-
import sateliteIcon from "../assets/satelite.svg";
|
|
23
|
-
|
|
24
|
-
declare global {
|
|
25
|
-
interface Window {
|
|
26
|
-
type: boolean;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
L.Edit.Circle = L.Edit.CircleMarker.extend({
|
|
31
|
-
_createResizeMarker: function () {
|
|
32
|
-
var center = this._shape.getLatLng(),
|
|
33
|
-
resizemarkerPoint = this._getResizeMarkerPoint(center);
|
|
34
|
-
|
|
35
|
-
this._resizeMarkers = [];
|
|
36
|
-
this._resizeMarkers.push(
|
|
37
|
-
this._createMarker(resizemarkerPoint, this.options.resizeIcon)
|
|
38
|
-
);
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
_getResizeMarkerPoint: function (latlng: any) {
|
|
42
|
-
var delta = this._shape._radius * Math.cos(Math.PI / 4),
|
|
43
|
-
point = this._map.project(latlng);
|
|
44
|
-
return this._map.unproject([point.x + delta, point.y - delta]);
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
_resize: function (latlng: any) {
|
|
48
|
-
var moveLatLng = this._moveMarker.getLatLng();
|
|
49
|
-
var radius;
|
|
50
|
-
|
|
51
|
-
if (L.GeometryUtil.isVersion07x()) {
|
|
52
|
-
radius = moveLatLng.distanceTo(latlng);
|
|
53
|
-
} else {
|
|
54
|
-
radius = this._map.distance(moveLatLng, latlng);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// **** This fixes the cicle resizing ****
|
|
58
|
-
this._shape.setRadius(radius);
|
|
59
|
-
|
|
60
|
-
this._map.fire(L.Draw.Event.EDITRESIZE, { layer: this._shape });
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
export default defineComponent({
|
|
65
|
-
name: "MapView",
|
|
66
|
-
props: {
|
|
67
|
-
loadPolygon: Boolean,
|
|
68
|
-
reverseCoordinatesPolygon: Boolean,
|
|
69
|
-
dataPolygon: Object,
|
|
70
|
-
configurationMap: Object as any,
|
|
71
|
-
coordinatesMap: Array,
|
|
72
|
-
getGeoJSON: Function,
|
|
73
|
-
getCoodMarker: Function,
|
|
74
|
-
isSatelite: Boolean,
|
|
75
|
-
},
|
|
76
|
-
data() {
|
|
77
|
-
return {
|
|
78
|
-
idMap: "",
|
|
79
|
-
mapRender: null as L.Map | null,
|
|
80
|
-
markerRender: null as L.Marker | null,
|
|
81
|
-
renderCoordinates: this.coordinatesMap,
|
|
82
|
-
renderGeojson: this.dataPolygon as any,
|
|
83
|
-
markerIcon: {
|
|
84
|
-
iconUrl: markerDefault,
|
|
85
|
-
iconSize: [25, 41],
|
|
86
|
-
iconAnchor: [12, 41],
|
|
87
|
-
},
|
|
88
|
-
layersFeatureGroup: null as any,
|
|
89
|
-
featuresData: null as any,
|
|
90
|
-
currentTileLayer: null as L.TileLayer | null,
|
|
91
|
-
isSatelliteView: false,
|
|
92
|
-
};
|
|
93
|
-
},
|
|
94
|
-
mounted() {
|
|
95
|
-
this.makeid(10);
|
|
96
|
-
this.renderMap();
|
|
97
|
-
},
|
|
98
|
-
methods: {
|
|
99
|
-
createSatelliteControl(): L.Control {
|
|
100
|
-
const SatelliteControl = L.Control.extend({
|
|
101
|
-
onAdd: (map: L.Map) => {
|
|
102
|
-
const container = L.DomUtil.create(
|
|
103
|
-
"div",
|
|
104
|
-
"leaflet-control-draw leaflet-bar leaflet-control"
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
const satelliteButton = L.DomUtil.create(
|
|
108
|
-
"a",
|
|
109
|
-
"leaflet-draw-draw-satellite",
|
|
110
|
-
container
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
satelliteButton.href = "#";
|
|
114
|
-
satelliteButton.title = this.isSatelliteView
|
|
115
|
-
? "Vista Normal"
|
|
116
|
-
: "Vista Satélite";
|
|
117
|
-
|
|
118
|
-
// Usar el mismo estilo que los otros botones de draw
|
|
119
|
-
satelliteButton.style.backgroundImage = this.isSatelliteView
|
|
120
|
-
? `url(${gpsIcon})`
|
|
121
|
-
: `url(${sateliteIcon})`;
|
|
122
|
-
satelliteButton.style.backgroundPosition = "center";
|
|
123
|
-
satelliteButton.style.backgroundRepeat = "no-repeat";
|
|
124
|
-
satelliteButton.style.backgroundSize = "20px 20px";
|
|
125
|
-
|
|
126
|
-
L.DomEvent.disableClickPropagation(satelliteButton);
|
|
127
|
-
L.DomEvent.on(
|
|
128
|
-
satelliteButton,
|
|
129
|
-
"click",
|
|
130
|
-
this.toggleSatelliteView,
|
|
131
|
-
this
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
return container;
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
return new SatelliteControl({ position: "topleft" });
|
|
139
|
-
},
|
|
140
|
-
toggleSatelliteView(): void {
|
|
141
|
-
if (!this.mapRender || !this.currentTileLayer) return;
|
|
142
|
-
|
|
143
|
-
this.isSatelliteView = !this.isSatelliteView;
|
|
144
|
-
|
|
145
|
-
// Remover la capa actual
|
|
146
|
-
this.mapRender.removeLayer(this.currentTileLayer as unknown as L.Layer);
|
|
147
|
-
|
|
148
|
-
// Agregar la nueva capa
|
|
149
|
-
if (this.isSatelliteView) {
|
|
150
|
-
this.currentTileLayer = L.tileLayer(
|
|
151
|
-
"https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg?key=t8mWT2ozs1JWBqMZOnZr",
|
|
152
|
-
{
|
|
153
|
-
attribution:
|
|
154
|
-
'© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
155
|
-
}
|
|
156
|
-
);
|
|
157
|
-
} else {
|
|
158
|
-
this.currentTileLayer = L.tileLayer(
|
|
159
|
-
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
160
|
-
{
|
|
161
|
-
attribution:
|
|
162
|
-
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this.currentTileLayer.addTo(this.mapRender as L.Map);
|
|
168
|
-
|
|
169
|
-
// Actualizar el ícono del control satelital
|
|
170
|
-
const satelliteButtons = document.querySelectorAll(
|
|
171
|
-
".leaflet-draw-draw-satellite"
|
|
172
|
-
);
|
|
173
|
-
satelliteButtons.forEach((button) => {
|
|
174
|
-
const htmlButton = button as HTMLElement;
|
|
175
|
-
htmlButton.style.backgroundImage = this.isSatelliteView
|
|
176
|
-
? `url(${gpsIcon})`
|
|
177
|
-
: `url(${sateliteIcon})`;
|
|
178
|
-
htmlButton.title = this.isSatelliteView
|
|
179
|
-
? "Vista Normal"
|
|
180
|
-
: "Vista Satélite";
|
|
181
|
-
});
|
|
182
|
-
},
|
|
183
|
-
getLayersFeaturesInGeoJson() {
|
|
184
|
-
const geojson = L.geoJSON().addTo(this.mapRender as any);
|
|
185
|
-
this.featuresData.eachLayer((layer: any) => {
|
|
186
|
-
geojson.addLayer(layer);
|
|
187
|
-
});
|
|
188
|
-
const geojsonString = [geojson.toGeoJSON()]; //JSON.stringify([geojson.toGeoJSON()]);
|
|
189
|
-
return geojsonString;
|
|
190
|
-
},
|
|
191
|
-
triggerSaveEdit(): void {
|
|
192
|
-
const buttons =
|
|
193
|
-
document.getElementsByClassName(
|
|
194
|
-
"leaflet-draw-actions leaflet-draw-actions-top"
|
|
195
|
-
) ||
|
|
196
|
-
document.getElementsByClassName(
|
|
197
|
-
"leaflet-draw-actions leaflet-draw-actions-top leaflet-draw-actions-bottom"
|
|
198
|
-
);
|
|
199
|
-
buttons[0]?.querySelector("li")?.querySelector("a")?.click();
|
|
200
|
-
},
|
|
201
|
-
makeid(length: number): void {
|
|
202
|
-
let result = "";
|
|
203
|
-
const characters = "abcdefghijklmnopqrstuvwxyz";
|
|
204
|
-
const charactersLength = characters.length;
|
|
205
|
-
let counter = 0;
|
|
206
|
-
while (counter < length) {
|
|
207
|
-
result += characters.charAt(
|
|
208
|
-
Math.floor(Math.random() * charactersLength)
|
|
209
|
-
);
|
|
210
|
-
counter += 1;
|
|
211
|
-
}
|
|
212
|
-
this.idMap = result;
|
|
213
|
-
},
|
|
214
|
-
renderMap(): void {
|
|
215
|
-
drawLocales("es");
|
|
216
|
-
setTimeout(() => {
|
|
217
|
-
if (this.loadPolygon) {
|
|
218
|
-
this.viewMap();
|
|
219
|
-
} else {
|
|
220
|
-
this.createMap();
|
|
221
|
-
}
|
|
222
|
-
}, 500);
|
|
223
|
-
},
|
|
224
|
-
createMap(): void {
|
|
225
|
-
const iconDefaultMarket = this.configurationMap
|
|
226
|
-
? this.configurationMap.iconMarker
|
|
227
|
-
? this.configurationMap.iconMarker
|
|
228
|
-
: this.markerIcon
|
|
229
|
-
: this.markerIcon;
|
|
230
|
-
window.type = true;
|
|
231
|
-
const map = L.map(this.idMap, { fullscreenControl: true } as any).setView(
|
|
232
|
-
[
|
|
233
|
-
this.renderCoordinates ? (this.renderCoordinates[0] as number) : 0,
|
|
234
|
-
this.renderCoordinates ? (this.renderCoordinates[1] as number) : 0,
|
|
235
|
-
],
|
|
236
|
-
this.renderCoordinates ? (this.renderCoordinates[2] as number) : 0
|
|
237
|
-
);
|
|
238
|
-
this.mapRender = map;
|
|
239
|
-
|
|
240
|
-
// Inicializar con la vista correcta según el prop
|
|
241
|
-
this.isSatelliteView = this.isSatelite || false;
|
|
242
|
-
if (this.isSatelliteView) {
|
|
243
|
-
this.currentTileLayer = L.tileLayer(
|
|
244
|
-
"https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg?key=t8mWT2ozs1JWBqMZOnZr",
|
|
245
|
-
{
|
|
246
|
-
attribution:
|
|
247
|
-
'© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
248
|
-
}
|
|
249
|
-
);
|
|
250
|
-
} else {
|
|
251
|
-
this.currentTileLayer = L.tileLayer(
|
|
252
|
-
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
253
|
-
{
|
|
254
|
-
attribution:
|
|
255
|
-
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
256
|
-
}
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
this.currentTileLayer.addTo(map);
|
|
260
|
-
|
|
261
|
-
// Agregar el control satelital si está habilitado
|
|
262
|
-
if (this.isSatelite !== undefined) {
|
|
263
|
-
const satelliteControl = this.createSatelliteControl();
|
|
264
|
-
map.addControl(satelliteControl);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
map.setZoom(this.configurationMap?.maxZoom);
|
|
268
|
-
if (this.configurationMap.renderMarker) {
|
|
269
|
-
const marker = L.marker(
|
|
270
|
-
[
|
|
271
|
-
this.renderCoordinates ? (this.renderCoordinates[0] as number) : 0,
|
|
272
|
-
this.renderCoordinates ? (this.renderCoordinates[1] as number) : 0,
|
|
273
|
-
],
|
|
274
|
-
{
|
|
275
|
-
icon: L.icon(iconDefaultMarket),
|
|
276
|
-
draggable: this.configurationMap.dragMarker,
|
|
277
|
-
}
|
|
278
|
-
).addTo(map);
|
|
279
|
-
this.markerRender = marker;
|
|
280
|
-
if (this.getCoodMarker) {
|
|
281
|
-
marker.on("dragend", (event) => {
|
|
282
|
-
const updatedCoordinates = event.target.getLatLng();
|
|
283
|
-
const lat = updatedCoordinates.lat;
|
|
284
|
-
const lng = updatedCoordinates.lng;
|
|
285
|
-
if (this.getCoodMarker) this.getCoodMarker(lat, lng);
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
const featuresData = L.featureGroup();
|
|
290
|
-
this.featuresData = featuresData;
|
|
291
|
-
const featureGroup = featuresData.addTo(map);
|
|
292
|
-
let contextEdit = {
|
|
293
|
-
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
294
|
-
edit: false,
|
|
295
|
-
remove: this.configurationMap?.editFigures.remove,
|
|
296
|
-
};
|
|
297
|
-
if (this.configurationMap?.editFigures.edit) {
|
|
298
|
-
contextEdit = {
|
|
299
|
-
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
300
|
-
...this.configurationMap?.editFigures.edit,
|
|
301
|
-
remove: this.configurationMap?.editFigures.remove,
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
const drawControl = new L.Control.Draw({
|
|
305
|
-
position: "topleft",
|
|
306
|
-
draw: {
|
|
307
|
-
polygon: this.configurationMap?.createFigures.polygon,
|
|
308
|
-
circle: false, //this.configurationMap?.createFigures.circle,
|
|
309
|
-
rectangle: this.configurationMap?.createFigures.rectangle
|
|
310
|
-
? {
|
|
311
|
-
shapeOptions: {
|
|
312
|
-
color: "blue",
|
|
313
|
-
},
|
|
314
|
-
}
|
|
315
|
-
: false,
|
|
316
|
-
marker: this.configurationMap?.createFigures.marker
|
|
317
|
-
? {
|
|
318
|
-
icon: L.icon(iconDefaultMarket),
|
|
319
|
-
}
|
|
320
|
-
: false,
|
|
321
|
-
polyline: this.configurationMap?.createFigures.polyline
|
|
322
|
-
? {
|
|
323
|
-
shapeOptions: {
|
|
324
|
-
color: "blue",
|
|
325
|
-
},
|
|
326
|
-
}
|
|
327
|
-
: false,
|
|
328
|
-
circlemarker: this.configurationMap?.createFigures.multipoint,
|
|
329
|
-
},
|
|
330
|
-
edit: contextEdit as any,
|
|
331
|
-
});
|
|
332
|
-
map.addControl(drawControl);
|
|
333
|
-
|
|
334
|
-
map.on("draw:created", (event: any) => {
|
|
335
|
-
const layer = event.layer;
|
|
336
|
-
featureGroup.addLayer(layer);
|
|
337
|
-
let geojson = layer.toGeoJSON();
|
|
338
|
-
// *** AGREGADO: Manejo especial para CircleMarker (convertir a MultiPoint) ***
|
|
339
|
-
if (event.layerType === "circlemarker") {
|
|
340
|
-
// Convertir CircleMarker a formato MultiPoint para consistencia
|
|
341
|
-
geojson = {
|
|
342
|
-
type: "Feature",
|
|
343
|
-
geometry: {
|
|
344
|
-
type: "MultiPoint",
|
|
345
|
-
coordinates: [geojson.geometry.coordinates],
|
|
346
|
-
},
|
|
347
|
-
properties: {
|
|
348
|
-
...geojson.properties,
|
|
349
|
-
pointType: "multipoint",
|
|
350
|
-
style: {
|
|
351
|
-
color:
|
|
352
|
-
this.configurationMap?.createFigures?.multipoint?.color ||
|
|
353
|
-
"green",
|
|
354
|
-
fillColor:
|
|
355
|
-
this.configurationMap?.createFigures?.multipoint?.fillColor ||
|
|
356
|
-
"green",
|
|
357
|
-
fillOpacity:
|
|
358
|
-
this.configurationMap?.createFigures?.multipoint
|
|
359
|
-
?.fillOpacity || 0.8,
|
|
360
|
-
radius:
|
|
361
|
-
this.configurationMap?.createFigures?.multipoint?.radius || 6,
|
|
362
|
-
weight:
|
|
363
|
-
this.configurationMap?.createFigures?.multipoint?.weight || 2,
|
|
364
|
-
},
|
|
365
|
-
},
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
if (this.getGeoJSON) this.getGeoJSON([geojson]);
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
map.on("draw:edited", (event: any) => {
|
|
372
|
-
const layers = event.layers;
|
|
373
|
-
layers.eachLayer((layer: any) => {
|
|
374
|
-
const geojson = layer.toGeoJSON();
|
|
375
|
-
if (this.getGeoJSON) this.getGeoJSON([geojson]);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
},
|
|
379
|
-
viewMap(): void {
|
|
380
|
-
const iconDefaultMarket = this.configurationMap
|
|
381
|
-
? this.configurationMap.iconMarker
|
|
382
|
-
? this.configurationMap.iconMarker
|
|
383
|
-
: this.markerIcon
|
|
384
|
-
: this.markerIcon;
|
|
385
|
-
window.type = true;
|
|
386
|
-
const map = L.map(this.idMap, { fullscreenControl: true } as any).setView(
|
|
387
|
-
[
|
|
388
|
-
this.renderCoordinates ? (this.renderCoordinates[0] as number) : 0,
|
|
389
|
-
this.renderCoordinates ? (this.renderCoordinates[1] as number) : 0,
|
|
390
|
-
],
|
|
391
|
-
this.renderCoordinates ? (this.renderCoordinates[2] as number) : 0
|
|
392
|
-
);
|
|
393
|
-
this.mapRender = map;
|
|
394
|
-
|
|
395
|
-
// Inicializar con la vista correcta según el prop
|
|
396
|
-
this.isSatelliteView = this.isSatelite || false;
|
|
397
|
-
if (this.isSatelliteView) {
|
|
398
|
-
this.currentTileLayer = L.tileLayer(
|
|
399
|
-
"https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg?key=t8mWT2ozs1JWBqMZOnZr",
|
|
400
|
-
{
|
|
401
|
-
attribution:
|
|
402
|
-
'© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
403
|
-
}
|
|
404
|
-
);
|
|
405
|
-
} else {
|
|
406
|
-
this.currentTileLayer = L.tileLayer(
|
|
407
|
-
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
408
|
-
{
|
|
409
|
-
attribution:
|
|
410
|
-
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
411
|
-
}
|
|
412
|
-
);
|
|
413
|
-
}
|
|
414
|
-
this.currentTileLayer.addTo(map);
|
|
415
|
-
|
|
416
|
-
// Agregar el control satelital si está habilitado
|
|
417
|
-
if (this.isSatelite !== undefined) {
|
|
418
|
-
const satelliteControl = this.createSatelliteControl();
|
|
419
|
-
map.addControl(satelliteControl);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
map.setZoom(this.configurationMap?.maxZoom);
|
|
423
|
-
const featuresData = L.featureGroup();
|
|
424
|
-
this.featuresData = featuresData;
|
|
425
|
-
const featureGroup = featuresData.addTo(map);
|
|
426
|
-
let contextEdit = {
|
|
427
|
-
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
428
|
-
edit: false,
|
|
429
|
-
remove: this.configurationMap?.editFigures.remove,
|
|
430
|
-
};
|
|
431
|
-
if (this.configurationMap?.editFigures.edit) {
|
|
432
|
-
contextEdit = {
|
|
433
|
-
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
434
|
-
...this.configurationMap?.editFigures.edit,
|
|
435
|
-
remove: this.configurationMap?.editFigures.remove,
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
const renderGeojson = this.renderGeojson;
|
|
440
|
-
if (renderGeojson && renderGeojson.length) {
|
|
441
|
-
renderGeojson.forEach((item: any) => {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
feature.geometry.type === "
|
|
447
|
-
feature.geometry.type === "
|
|
448
|
-
feature.geometry.type === "
|
|
449
|
-
feature.geometry.type === "
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
L.geoJson(feature, {
|
|
453
|
-
pointToLayer: this.getPointToLayer.bind(this),
|
|
454
|
-
onEachFeature: function (feature, layer) {
|
|
455
|
-
featureGroup.addLayer(layer);
|
|
456
|
-
// Mostrar popup para Point
|
|
457
|
-
if (feature.geometry.type === "Point") {
|
|
458
|
-
var popupContent = self.getPopupContent(feature);
|
|
459
|
-
layer.bindPopup(popupContent);
|
|
460
|
-
}
|
|
461
|
-
// Mostrar popup para Polygon y MultiPolygon al hacer clic
|
|
462
|
-
else if (
|
|
463
|
-
feature.geometry.type === "Polygon" ||
|
|
464
|
-
feature.geometry.type === "MultiPolygon"
|
|
465
|
-
) {
|
|
466
|
-
var tooltipContent =
|
|
467
|
-
self.getPolygonTooltipContent(feature);
|
|
468
|
-
layer.bindPopup(tooltipContent);
|
|
469
|
-
}
|
|
470
|
-
},
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
} else if (item.type === "Feature") {
|
|
475
|
-
if (
|
|
476
|
-
item.geometry.type === "Polygon" ||
|
|
477
|
-
item.geometry.type === "MultiPolygon" ||
|
|
478
|
-
item.geometry.type === "LineString" ||
|
|
479
|
-
item.geometry.type === "MultiLineString" ||
|
|
480
|
-
item.geometry.type === "Point"
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
feature.geometry.type === "
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
const
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
if (tipo ===
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
)
|
|
627
|
-
|
|
628
|
-
const
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const
|
|
664
|
-
const
|
|
665
|
-
const
|
|
666
|
-
const
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
html
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
this.
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
this.
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="map-container" :style="`height:${configurationMap?.height}`">
|
|
3
|
+
<div :id="idMap" style="height: 100%"></div>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { defineComponent } from "vue";
|
|
9
|
+
import { markerDefault } from "../helpers/imgBase64";
|
|
10
|
+
import homeIconUrl from "../assets/home.png";
|
|
11
|
+
import endIconUrl from "../assets/end.png";
|
|
12
|
+
import trackingIconUrl from "../assets/tracking.png";
|
|
13
|
+
import * as L from "leaflet";
|
|
14
|
+
import "leaflet-draw";
|
|
15
|
+
import "leaflet/dist/leaflet.css";
|
|
16
|
+
import "leaflet-draw/dist/leaflet.draw.css";
|
|
17
|
+
import drawLocales from "leaflet-draw-locales";
|
|
18
|
+
import axios from "axios";
|
|
19
|
+
import "leaflet.fullscreen/Control.FullScreen.css";
|
|
20
|
+
import "leaflet.fullscreen";
|
|
21
|
+
import gpsIcon from "../assets/gps.svg";
|
|
22
|
+
import sateliteIcon from "../assets/satelite.svg";
|
|
23
|
+
|
|
24
|
+
declare global {
|
|
25
|
+
interface Window {
|
|
26
|
+
type: boolean;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
L.Edit.Circle = L.Edit.CircleMarker.extend({
|
|
31
|
+
_createResizeMarker: function () {
|
|
32
|
+
var center = this._shape.getLatLng(),
|
|
33
|
+
resizemarkerPoint = this._getResizeMarkerPoint(center);
|
|
34
|
+
|
|
35
|
+
this._resizeMarkers = [];
|
|
36
|
+
this._resizeMarkers.push(
|
|
37
|
+
this._createMarker(resizemarkerPoint, this.options.resizeIcon)
|
|
38
|
+
);
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
_getResizeMarkerPoint: function (latlng: any) {
|
|
42
|
+
var delta = this._shape._radius * Math.cos(Math.PI / 4),
|
|
43
|
+
point = this._map.project(latlng);
|
|
44
|
+
return this._map.unproject([point.x + delta, point.y - delta]);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
_resize: function (latlng: any) {
|
|
48
|
+
var moveLatLng = this._moveMarker.getLatLng();
|
|
49
|
+
var radius;
|
|
50
|
+
|
|
51
|
+
if (L.GeometryUtil.isVersion07x()) {
|
|
52
|
+
radius = moveLatLng.distanceTo(latlng);
|
|
53
|
+
} else {
|
|
54
|
+
radius = this._map.distance(moveLatLng, latlng);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// **** This fixes the cicle resizing ****
|
|
58
|
+
this._shape.setRadius(radius);
|
|
59
|
+
|
|
60
|
+
this._map.fire(L.Draw.Event.EDITRESIZE, { layer: this._shape });
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export default defineComponent({
|
|
65
|
+
name: "MapView",
|
|
66
|
+
props: {
|
|
67
|
+
loadPolygon: Boolean,
|
|
68
|
+
reverseCoordinatesPolygon: Boolean,
|
|
69
|
+
dataPolygon: Object,
|
|
70
|
+
configurationMap: Object as any,
|
|
71
|
+
coordinatesMap: Array,
|
|
72
|
+
getGeoJSON: Function,
|
|
73
|
+
getCoodMarker: Function,
|
|
74
|
+
isSatelite: Boolean,
|
|
75
|
+
},
|
|
76
|
+
data() {
|
|
77
|
+
return {
|
|
78
|
+
idMap: "",
|
|
79
|
+
mapRender: null as L.Map | null,
|
|
80
|
+
markerRender: null as L.Marker | null,
|
|
81
|
+
renderCoordinates: this.coordinatesMap,
|
|
82
|
+
renderGeojson: this.dataPolygon as any,
|
|
83
|
+
markerIcon: {
|
|
84
|
+
iconUrl: markerDefault,
|
|
85
|
+
iconSize: [25, 41],
|
|
86
|
+
iconAnchor: [12, 41],
|
|
87
|
+
},
|
|
88
|
+
layersFeatureGroup: null as any,
|
|
89
|
+
featuresData: null as any,
|
|
90
|
+
currentTileLayer: null as L.TileLayer | null,
|
|
91
|
+
isSatelliteView: false,
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
mounted() {
|
|
95
|
+
this.makeid(10);
|
|
96
|
+
this.renderMap();
|
|
97
|
+
},
|
|
98
|
+
methods: {
|
|
99
|
+
createSatelliteControl(): L.Control {
|
|
100
|
+
const SatelliteControl = L.Control.extend({
|
|
101
|
+
onAdd: (map: L.Map) => {
|
|
102
|
+
const container = L.DomUtil.create(
|
|
103
|
+
"div",
|
|
104
|
+
"leaflet-control-draw leaflet-bar leaflet-control"
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const satelliteButton = L.DomUtil.create(
|
|
108
|
+
"a",
|
|
109
|
+
"leaflet-draw-draw-satellite",
|
|
110
|
+
container
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
satelliteButton.href = "#";
|
|
114
|
+
satelliteButton.title = this.isSatelliteView
|
|
115
|
+
? "Vista Normal"
|
|
116
|
+
: "Vista Satélite";
|
|
117
|
+
|
|
118
|
+
// Usar el mismo estilo que los otros botones de draw
|
|
119
|
+
satelliteButton.style.backgroundImage = this.isSatelliteView
|
|
120
|
+
? `url(${gpsIcon})`
|
|
121
|
+
: `url(${sateliteIcon})`;
|
|
122
|
+
satelliteButton.style.backgroundPosition = "center";
|
|
123
|
+
satelliteButton.style.backgroundRepeat = "no-repeat";
|
|
124
|
+
satelliteButton.style.backgroundSize = "20px 20px";
|
|
125
|
+
|
|
126
|
+
L.DomEvent.disableClickPropagation(satelliteButton);
|
|
127
|
+
L.DomEvent.on(
|
|
128
|
+
satelliteButton,
|
|
129
|
+
"click",
|
|
130
|
+
this.toggleSatelliteView,
|
|
131
|
+
this
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return container;
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return new SatelliteControl({ position: "topleft" });
|
|
139
|
+
},
|
|
140
|
+
toggleSatelliteView(): void {
|
|
141
|
+
if (!this.mapRender || !this.currentTileLayer) return;
|
|
142
|
+
|
|
143
|
+
this.isSatelliteView = !this.isSatelliteView;
|
|
144
|
+
|
|
145
|
+
// Remover la capa actual
|
|
146
|
+
this.mapRender.removeLayer(this.currentTileLayer as unknown as L.Layer);
|
|
147
|
+
|
|
148
|
+
// Agregar la nueva capa
|
|
149
|
+
if (this.isSatelliteView) {
|
|
150
|
+
this.currentTileLayer = L.tileLayer(
|
|
151
|
+
"https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg?key=t8mWT2ozs1JWBqMZOnZr",
|
|
152
|
+
{
|
|
153
|
+
attribution:
|
|
154
|
+
'© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
} else {
|
|
158
|
+
this.currentTileLayer = L.tileLayer(
|
|
159
|
+
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
160
|
+
{
|
|
161
|
+
attribution:
|
|
162
|
+
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.currentTileLayer.addTo(this.mapRender as L.Map);
|
|
168
|
+
|
|
169
|
+
// Actualizar el ícono del control satelital
|
|
170
|
+
const satelliteButtons = document.querySelectorAll(
|
|
171
|
+
".leaflet-draw-draw-satellite"
|
|
172
|
+
);
|
|
173
|
+
satelliteButtons.forEach((button) => {
|
|
174
|
+
const htmlButton = button as HTMLElement;
|
|
175
|
+
htmlButton.style.backgroundImage = this.isSatelliteView
|
|
176
|
+
? `url(${gpsIcon})`
|
|
177
|
+
: `url(${sateliteIcon})`;
|
|
178
|
+
htmlButton.title = this.isSatelliteView
|
|
179
|
+
? "Vista Normal"
|
|
180
|
+
: "Vista Satélite";
|
|
181
|
+
});
|
|
182
|
+
},
|
|
183
|
+
getLayersFeaturesInGeoJson() {
|
|
184
|
+
const geojson = L.geoJSON().addTo(this.mapRender as any);
|
|
185
|
+
this.featuresData.eachLayer((layer: any) => {
|
|
186
|
+
geojson.addLayer(layer);
|
|
187
|
+
});
|
|
188
|
+
const geojsonString = [geojson.toGeoJSON()]; //JSON.stringify([geojson.toGeoJSON()]);
|
|
189
|
+
return geojsonString;
|
|
190
|
+
},
|
|
191
|
+
triggerSaveEdit(): void {
|
|
192
|
+
const buttons =
|
|
193
|
+
document.getElementsByClassName(
|
|
194
|
+
"leaflet-draw-actions leaflet-draw-actions-top"
|
|
195
|
+
) ||
|
|
196
|
+
document.getElementsByClassName(
|
|
197
|
+
"leaflet-draw-actions leaflet-draw-actions-top leaflet-draw-actions-bottom"
|
|
198
|
+
);
|
|
199
|
+
buttons[0]?.querySelector("li")?.querySelector("a")?.click();
|
|
200
|
+
},
|
|
201
|
+
makeid(length: number): void {
|
|
202
|
+
let result = "";
|
|
203
|
+
const characters = "abcdefghijklmnopqrstuvwxyz";
|
|
204
|
+
const charactersLength = characters.length;
|
|
205
|
+
let counter = 0;
|
|
206
|
+
while (counter < length) {
|
|
207
|
+
result += characters.charAt(
|
|
208
|
+
Math.floor(Math.random() * charactersLength)
|
|
209
|
+
);
|
|
210
|
+
counter += 1;
|
|
211
|
+
}
|
|
212
|
+
this.idMap = result;
|
|
213
|
+
},
|
|
214
|
+
renderMap(): void {
|
|
215
|
+
drawLocales("es");
|
|
216
|
+
setTimeout(() => {
|
|
217
|
+
if (this.loadPolygon) {
|
|
218
|
+
this.viewMap();
|
|
219
|
+
} else {
|
|
220
|
+
this.createMap();
|
|
221
|
+
}
|
|
222
|
+
}, 500);
|
|
223
|
+
},
|
|
224
|
+
createMap(): void {
|
|
225
|
+
const iconDefaultMarket = this.configurationMap
|
|
226
|
+
? this.configurationMap.iconMarker
|
|
227
|
+
? this.configurationMap.iconMarker
|
|
228
|
+
: this.markerIcon
|
|
229
|
+
: this.markerIcon;
|
|
230
|
+
window.type = true;
|
|
231
|
+
const map = L.map(this.idMap, { fullscreenControl: true } as any).setView(
|
|
232
|
+
[
|
|
233
|
+
this.renderCoordinates ? (this.renderCoordinates[0] as number) : 0,
|
|
234
|
+
this.renderCoordinates ? (this.renderCoordinates[1] as number) : 0,
|
|
235
|
+
],
|
|
236
|
+
this.renderCoordinates ? (this.renderCoordinates[2] as number) : 0
|
|
237
|
+
);
|
|
238
|
+
this.mapRender = map;
|
|
239
|
+
|
|
240
|
+
// Inicializar con la vista correcta según el prop
|
|
241
|
+
this.isSatelliteView = this.isSatelite || false;
|
|
242
|
+
if (this.isSatelliteView) {
|
|
243
|
+
this.currentTileLayer = L.tileLayer(
|
|
244
|
+
"https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg?key=t8mWT2ozs1JWBqMZOnZr",
|
|
245
|
+
{
|
|
246
|
+
attribution:
|
|
247
|
+
'© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
} else {
|
|
251
|
+
this.currentTileLayer = L.tileLayer(
|
|
252
|
+
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
253
|
+
{
|
|
254
|
+
attribution:
|
|
255
|
+
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
256
|
+
}
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
this.currentTileLayer.addTo(map);
|
|
260
|
+
|
|
261
|
+
// Agregar el control satelital si está habilitado
|
|
262
|
+
if (this.isSatelite !== undefined) {
|
|
263
|
+
const satelliteControl = this.createSatelliteControl();
|
|
264
|
+
map.addControl(satelliteControl);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
map.setZoom(this.configurationMap?.maxZoom);
|
|
268
|
+
if (this.configurationMap.renderMarker) {
|
|
269
|
+
const marker = L.marker(
|
|
270
|
+
[
|
|
271
|
+
this.renderCoordinates ? (this.renderCoordinates[0] as number) : 0,
|
|
272
|
+
this.renderCoordinates ? (this.renderCoordinates[1] as number) : 0,
|
|
273
|
+
],
|
|
274
|
+
{
|
|
275
|
+
icon: L.icon(iconDefaultMarket),
|
|
276
|
+
draggable: this.configurationMap.dragMarker,
|
|
277
|
+
}
|
|
278
|
+
).addTo(map);
|
|
279
|
+
this.markerRender = marker;
|
|
280
|
+
if (this.getCoodMarker) {
|
|
281
|
+
marker.on("dragend", (event) => {
|
|
282
|
+
const updatedCoordinates = event.target.getLatLng();
|
|
283
|
+
const lat = updatedCoordinates.lat;
|
|
284
|
+
const lng = updatedCoordinates.lng;
|
|
285
|
+
if (this.getCoodMarker) this.getCoodMarker(lat, lng);
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const featuresData = L.featureGroup();
|
|
290
|
+
this.featuresData = featuresData;
|
|
291
|
+
const featureGroup = featuresData.addTo(map);
|
|
292
|
+
let contextEdit = {
|
|
293
|
+
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
294
|
+
edit: false,
|
|
295
|
+
remove: this.configurationMap?.editFigures.remove,
|
|
296
|
+
};
|
|
297
|
+
if (this.configurationMap?.editFigures.edit) {
|
|
298
|
+
contextEdit = {
|
|
299
|
+
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
300
|
+
...this.configurationMap?.editFigures.edit,
|
|
301
|
+
remove: this.configurationMap?.editFigures.remove,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const drawControl = new L.Control.Draw({
|
|
305
|
+
position: "topleft",
|
|
306
|
+
draw: {
|
|
307
|
+
polygon: this.configurationMap?.createFigures.polygon,
|
|
308
|
+
circle: false, //this.configurationMap?.createFigures.circle,
|
|
309
|
+
rectangle: this.configurationMap?.createFigures.rectangle
|
|
310
|
+
? {
|
|
311
|
+
shapeOptions: {
|
|
312
|
+
color: "blue",
|
|
313
|
+
},
|
|
314
|
+
}
|
|
315
|
+
: false,
|
|
316
|
+
marker: this.configurationMap?.createFigures.marker
|
|
317
|
+
? {
|
|
318
|
+
icon: L.icon(iconDefaultMarket),
|
|
319
|
+
}
|
|
320
|
+
: false,
|
|
321
|
+
polyline: this.configurationMap?.createFigures.polyline
|
|
322
|
+
? {
|
|
323
|
+
shapeOptions: {
|
|
324
|
+
color: "blue",
|
|
325
|
+
},
|
|
326
|
+
}
|
|
327
|
+
: false,
|
|
328
|
+
circlemarker: this.configurationMap?.createFigures.multipoint,
|
|
329
|
+
},
|
|
330
|
+
edit: contextEdit as any,
|
|
331
|
+
});
|
|
332
|
+
map.addControl(drawControl);
|
|
333
|
+
|
|
334
|
+
map.on("draw:created", (event: any) => {
|
|
335
|
+
const layer = event.layer;
|
|
336
|
+
featureGroup.addLayer(layer);
|
|
337
|
+
let geojson = layer.toGeoJSON();
|
|
338
|
+
// *** AGREGADO: Manejo especial para CircleMarker (convertir a MultiPoint) ***
|
|
339
|
+
if (event.layerType === "circlemarker") {
|
|
340
|
+
// Convertir CircleMarker a formato MultiPoint para consistencia
|
|
341
|
+
geojson = {
|
|
342
|
+
type: "Feature",
|
|
343
|
+
geometry: {
|
|
344
|
+
type: "MultiPoint",
|
|
345
|
+
coordinates: [geojson.geometry.coordinates],
|
|
346
|
+
},
|
|
347
|
+
properties: {
|
|
348
|
+
...geojson.properties,
|
|
349
|
+
pointType: "multipoint",
|
|
350
|
+
style: {
|
|
351
|
+
color:
|
|
352
|
+
this.configurationMap?.createFigures?.multipoint?.color ||
|
|
353
|
+
"green",
|
|
354
|
+
fillColor:
|
|
355
|
+
this.configurationMap?.createFigures?.multipoint?.fillColor ||
|
|
356
|
+
"green",
|
|
357
|
+
fillOpacity:
|
|
358
|
+
this.configurationMap?.createFigures?.multipoint
|
|
359
|
+
?.fillOpacity || 0.8,
|
|
360
|
+
radius:
|
|
361
|
+
this.configurationMap?.createFigures?.multipoint?.radius || 6,
|
|
362
|
+
weight:
|
|
363
|
+
this.configurationMap?.createFigures?.multipoint?.weight || 2,
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (this.getGeoJSON) this.getGeoJSON([geojson]);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
map.on("draw:edited", (event: any) => {
|
|
372
|
+
const layers = event.layers;
|
|
373
|
+
layers.eachLayer((layer: any) => {
|
|
374
|
+
const geojson = layer.toGeoJSON();
|
|
375
|
+
if (this.getGeoJSON) this.getGeoJSON([geojson]);
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
},
|
|
379
|
+
viewMap(): void {
|
|
380
|
+
const iconDefaultMarket = this.configurationMap
|
|
381
|
+
? this.configurationMap.iconMarker
|
|
382
|
+
? this.configurationMap.iconMarker
|
|
383
|
+
: this.markerIcon
|
|
384
|
+
: this.markerIcon;
|
|
385
|
+
window.type = true;
|
|
386
|
+
const map = L.map(this.idMap, { fullscreenControl: true } as any).setView(
|
|
387
|
+
[
|
|
388
|
+
this.renderCoordinates ? (this.renderCoordinates[0] as number) : 0,
|
|
389
|
+
this.renderCoordinates ? (this.renderCoordinates[1] as number) : 0,
|
|
390
|
+
],
|
|
391
|
+
this.renderCoordinates ? (this.renderCoordinates[2] as number) : 0
|
|
392
|
+
);
|
|
393
|
+
this.mapRender = map;
|
|
394
|
+
|
|
395
|
+
// Inicializar con la vista correcta según el prop
|
|
396
|
+
this.isSatelliteView = this.isSatelite || false;
|
|
397
|
+
if (this.isSatelliteView) {
|
|
398
|
+
this.currentTileLayer = L.tileLayer(
|
|
399
|
+
"https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg?key=t8mWT2ozs1JWBqMZOnZr",
|
|
400
|
+
{
|
|
401
|
+
attribution:
|
|
402
|
+
'© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
403
|
+
}
|
|
404
|
+
);
|
|
405
|
+
} else {
|
|
406
|
+
this.currentTileLayer = L.tileLayer(
|
|
407
|
+
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
408
|
+
{
|
|
409
|
+
attribution:
|
|
410
|
+
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
411
|
+
}
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
this.currentTileLayer.addTo(map);
|
|
415
|
+
|
|
416
|
+
// Agregar el control satelital si está habilitado
|
|
417
|
+
if (this.isSatelite !== undefined) {
|
|
418
|
+
const satelliteControl = this.createSatelliteControl();
|
|
419
|
+
map.addControl(satelliteControl);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
map.setZoom(this.configurationMap?.maxZoom);
|
|
423
|
+
const featuresData = L.featureGroup();
|
|
424
|
+
this.featuresData = featuresData;
|
|
425
|
+
const featureGroup = featuresData.addTo(map);
|
|
426
|
+
let contextEdit = {
|
|
427
|
+
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
428
|
+
edit: false,
|
|
429
|
+
remove: this.configurationMap?.editFigures.remove,
|
|
430
|
+
};
|
|
431
|
+
if (this.configurationMap?.editFigures.edit) {
|
|
432
|
+
contextEdit = {
|
|
433
|
+
featureGroup: featureGroup, // Crea un nuevo grupo de capas para los polígonos
|
|
434
|
+
...this.configurationMap?.editFigures.edit,
|
|
435
|
+
remove: this.configurationMap?.editFigures.remove,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const renderGeojson = this.renderGeojson;
|
|
440
|
+
if (renderGeojson && renderGeojson.length) {
|
|
441
|
+
renderGeojson.forEach((item: any) => {
|
|
442
|
+
const self = this;
|
|
443
|
+
if (item.type === "FeatureCollection") {
|
|
444
|
+
item.features.forEach((feature: any) => {
|
|
445
|
+
if (
|
|
446
|
+
feature.geometry.type === "Polygon" ||
|
|
447
|
+
feature.geometry.type === "MultiPolygon" ||
|
|
448
|
+
feature.geometry.type === "LineString" ||
|
|
449
|
+
feature.geometry.type === "MultiLineString" ||
|
|
450
|
+
feature.geometry.type === "Point"
|
|
451
|
+
) {
|
|
452
|
+
L.geoJson(feature, {
|
|
453
|
+
pointToLayer: this.getPointToLayer.bind(this),
|
|
454
|
+
onEachFeature: function (feature, layer) {
|
|
455
|
+
featureGroup.addLayer(layer);
|
|
456
|
+
// Mostrar popup para Point
|
|
457
|
+
if (feature.geometry.type === "Point") {
|
|
458
|
+
var popupContent = self.getPopupContent(feature);
|
|
459
|
+
layer.bindPopup(popupContent);
|
|
460
|
+
}
|
|
461
|
+
// Mostrar popup para Polygon y MultiPolygon al hacer clic
|
|
462
|
+
else if (
|
|
463
|
+
feature.geometry.type === "Polygon" ||
|
|
464
|
+
feature.geometry.type === "MultiPolygon"
|
|
465
|
+
) {
|
|
466
|
+
var tooltipContent =
|
|
467
|
+
self.getPolygonTooltipContent(feature);
|
|
468
|
+
layer.bindPopup(tooltipContent);
|
|
469
|
+
}
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
} else if (item.type === "Feature") {
|
|
475
|
+
if (
|
|
476
|
+
item.geometry.type === "Polygon" ||
|
|
477
|
+
item.geometry.type === "MultiPolygon" ||
|
|
478
|
+
item.geometry.type === "LineString" ||
|
|
479
|
+
item.geometry.type === "MultiLineString" ||
|
|
480
|
+
item.geometry.type === "Point"
|
|
481
|
+
) {
|
|
482
|
+
L.geoJson(item, {
|
|
483
|
+
pointToLayer: this.getPointToLayer.bind(this),
|
|
484
|
+
onEachFeature: function (feature, layer) {
|
|
485
|
+
featureGroup.addLayer(layer);
|
|
486
|
+
// Mostrar popup para Point
|
|
487
|
+
if (feature.geometry.type === "Point") {
|
|
488
|
+
var popupContent = self.getPopupContent(feature);
|
|
489
|
+
layer.bindPopup(popupContent);
|
|
490
|
+
}
|
|
491
|
+
// Mostrar popup para Polygon y MultiPolygon al hacer clic
|
|
492
|
+
else if (
|
|
493
|
+
feature.geometry.type === "Polygon" ||
|
|
494
|
+
feature.geometry.type === "MultiPolygon"
|
|
495
|
+
) {
|
|
496
|
+
var tooltipContent = self.getPolygonTooltipContent(feature);
|
|
497
|
+
layer.bindPopup(tooltipContent);
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
const bounds = featureGroup.getBounds();
|
|
505
|
+
map.fitBounds(bounds);
|
|
506
|
+
}
|
|
507
|
+
const drawControl = new L.Control.Draw({
|
|
508
|
+
position: "topleft",
|
|
509
|
+
draw: {
|
|
510
|
+
polygon: this.configurationMap?.createFigures.polygon,
|
|
511
|
+
circle: false, //this.configurationMap?.createFigures.circle,
|
|
512
|
+
rectangle: this.configurationMap?.createFigures.rectangle
|
|
513
|
+
? {
|
|
514
|
+
shapeOptions: {
|
|
515
|
+
color: "blue",
|
|
516
|
+
},
|
|
517
|
+
}
|
|
518
|
+
: false,
|
|
519
|
+
marker: this.configurationMap?.createFigures.marker
|
|
520
|
+
? {
|
|
521
|
+
icon: L.icon(iconDefaultMarket),
|
|
522
|
+
}
|
|
523
|
+
: false,
|
|
524
|
+
polyline: this.configurationMap?.createFigures.polyline
|
|
525
|
+
? {
|
|
526
|
+
shapeOptions: {
|
|
527
|
+
color: "blue",
|
|
528
|
+
},
|
|
529
|
+
}
|
|
530
|
+
: false,
|
|
531
|
+
circlemarker: this.configurationMap?.createFigures.multipoint,
|
|
532
|
+
},
|
|
533
|
+
edit: contextEdit as any,
|
|
534
|
+
});
|
|
535
|
+
map.addControl(drawControl);
|
|
536
|
+
|
|
537
|
+
map.on("draw:created", (event: any) => {
|
|
538
|
+
const layer = event.layer;
|
|
539
|
+
featureGroup.addLayer(layer);
|
|
540
|
+
let geojson = layer.toGeoJSON();
|
|
541
|
+
// *** AGREGADO: Manejo especial para CircleMarker (convertir a MultiPoint) ***
|
|
542
|
+
if (event.layerType === "circlemarker") {
|
|
543
|
+
// Convertir CircleMarker a formato MultiPoint para consistencia
|
|
544
|
+
geojson = {
|
|
545
|
+
type: "Feature",
|
|
546
|
+
geometry: {
|
|
547
|
+
type: "MultiPoint",
|
|
548
|
+
coordinates: [geojson.geometry.coordinates],
|
|
549
|
+
},
|
|
550
|
+
properties: {
|
|
551
|
+
...geojson.properties,
|
|
552
|
+
pointType: "multipoint",
|
|
553
|
+
style: {
|
|
554
|
+
color:
|
|
555
|
+
this.configurationMap?.createFigures?.multipoint?.color ||
|
|
556
|
+
"green",
|
|
557
|
+
fillColor:
|
|
558
|
+
this.configurationMap?.createFigures?.multipoint?.fillColor ||
|
|
559
|
+
"green",
|
|
560
|
+
fillOpacity:
|
|
561
|
+
this.configurationMap?.createFigures?.multipoint
|
|
562
|
+
?.fillOpacity || 0.8,
|
|
563
|
+
radius:
|
|
564
|
+
this.configurationMap?.createFigures?.multipoint?.radius || 6,
|
|
565
|
+
weight:
|
|
566
|
+
this.configurationMap?.createFigures?.multipoint?.weight || 2,
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
if (this.getGeoJSON) this.getGeoJSON(geojson);
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
map.on("draw:edited", (event: any) => {
|
|
575
|
+
const layers = event.layers;
|
|
576
|
+
layers.eachLayer((layer: any) => {
|
|
577
|
+
const geojson = layer.toGeoJSON();
|
|
578
|
+
if (this.getGeoJSON) this.getGeoJSON(geojson);
|
|
579
|
+
});
|
|
580
|
+
});
|
|
581
|
+
},
|
|
582
|
+
getPointToLayer(feature: any, latlng: any) {
|
|
583
|
+
const geometryType = feature.geometry?.type;
|
|
584
|
+
|
|
585
|
+
// Point: icono según properties.tipo
|
|
586
|
+
if (geometryType === "Point") {
|
|
587
|
+
const tipo = feature.properties?.tipo;
|
|
588
|
+
const firstIcon = L.icon({
|
|
589
|
+
iconUrl: homeIconUrl,
|
|
590
|
+
iconSize: [38, 38],
|
|
591
|
+
iconAnchor: [16, 41],
|
|
592
|
+
});
|
|
593
|
+
const lastIcon = L.icon({
|
|
594
|
+
iconUrl: endIconUrl,
|
|
595
|
+
iconSize: [38, 38],
|
|
596
|
+
iconAnchor: [16, 41],
|
|
597
|
+
});
|
|
598
|
+
const pointerIcon = L.icon({
|
|
599
|
+
iconUrl: trackingIconUrl,
|
|
600
|
+
iconSize: [38, 38],
|
|
601
|
+
iconAnchor: [16, 41],
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
let icon = pointerIcon;
|
|
605
|
+
if (tipo === 0) icon = firstIcon;
|
|
606
|
+
else if (tipo === 1) icon = lastIcon;
|
|
607
|
+
|
|
608
|
+
return L.marker(latlng, { icon });
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Otros tipos: icono por defecto
|
|
612
|
+
return L.marker(latlng);
|
|
613
|
+
},
|
|
614
|
+
async searchAddress(query: string) {
|
|
615
|
+
const address = await axios.get(
|
|
616
|
+
location.protocol + "//nominatim.openstreetmap.org/search?",
|
|
617
|
+
{
|
|
618
|
+
params: {
|
|
619
|
+
//query
|
|
620
|
+
q: query,
|
|
621
|
+
limit: 1,
|
|
622
|
+
format: "json",
|
|
623
|
+
},
|
|
624
|
+
}
|
|
625
|
+
);
|
|
626
|
+
if (address.data.length === 1) {
|
|
627
|
+
const lat = parseFloat(address.data[0].lat);
|
|
628
|
+
const lng = parseFloat(address.data[0].lon);
|
|
629
|
+
const coord = { lng, lat };
|
|
630
|
+
this.setCoordinates({ ...coord, moveMarker: true });
|
|
631
|
+
return address.data[0];
|
|
632
|
+
}
|
|
633
|
+
return address.data;
|
|
634
|
+
},
|
|
635
|
+
setCoordinates({
|
|
636
|
+
lat,
|
|
637
|
+
lng,
|
|
638
|
+
}: {
|
|
639
|
+
lat: number;
|
|
640
|
+
lng: number;
|
|
641
|
+
moveMarker?: boolean;
|
|
642
|
+
}): void {
|
|
643
|
+
if (this.mapRender) {
|
|
644
|
+
const newCenter = L.latLng(lat, lng);
|
|
645
|
+
this.mapRender.panTo(newCenter, { animate: true, duration: 0.5 });
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
getPopupContent(feature: any): string {
|
|
649
|
+
// Puedes personalizar el contenido del popup aquí
|
|
650
|
+
const props = feature.properties || {};
|
|
651
|
+
// Solo toma en cuenta descripcion y fechaHoraLlegada
|
|
652
|
+
const descripcion = props.descripcion || "";
|
|
653
|
+
const fechaHoraLlegada = props.fechaHoraLlegada || "";
|
|
654
|
+
// url de la foto
|
|
655
|
+
const fotoId = props.fotoId || "";
|
|
656
|
+
|
|
657
|
+
const formatIsoPreserve = (iso: string): string => {
|
|
658
|
+
const d = new Date(iso);
|
|
659
|
+
if (isNaN(d.getTime())) return iso; // fallback: devolver la cadena original si no es válida
|
|
660
|
+
const pad = (n: number) => n.toString().padStart(2, "0");
|
|
661
|
+
// Usar métodos UTC para evitar que el navegador convierta a la zona local
|
|
662
|
+
const day = pad(d.getUTCDate());
|
|
663
|
+
const month = pad(d.getUTCMonth() + 1);
|
|
664
|
+
const year = d.getUTCFullYear();
|
|
665
|
+
const hours = pad(d.getUTCHours());
|
|
666
|
+
const minutes = pad(d.getUTCMinutes());
|
|
667
|
+
const seconds = pad(d.getUTCSeconds());
|
|
668
|
+
return `${day}-${month}-${year} ${hours}:${minutes}:${seconds}`;
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
// Formatear fecha a dd-MM-yyyy hh:mm:ss
|
|
672
|
+
let fechaFormateada = "";
|
|
673
|
+
if (fechaHoraLlegada) {
|
|
674
|
+
/* const fecha = new Date(fechaHoraLlegada);
|
|
675
|
+
const pad = (n: number) => n.toString().padStart(2, "0");
|
|
676
|
+
fechaFormateada = `${pad(fecha.getDate())}-${pad(
|
|
677
|
+
fecha.getMonth() + 1
|
|
678
|
+
)}-${fecha.getFullYear()} ${pad(fecha.getHours())}:${pad(
|
|
679
|
+
fecha.getMinutes()
|
|
680
|
+
)}:${pad(fecha.getSeconds())}`; */
|
|
681
|
+
fechaFormateada = formatIsoPreserve(fechaHoraLlegada);
|
|
682
|
+
}
|
|
683
|
+
let html = "<div>";
|
|
684
|
+
if (fotoId) {
|
|
685
|
+
html += `<img src="${fotoId}" style="width: 200px; height: auto; margin-bottom: 5px;"><br>`;
|
|
686
|
+
}
|
|
687
|
+
html += `<b>Descripción:</b> ${descripcion}<br>`;
|
|
688
|
+
if (fechaFormateada) {
|
|
689
|
+
html += `<b>Fecha Hora Llegada:</b> ${fechaFormateada}<br>`;
|
|
690
|
+
}
|
|
691
|
+
html += "</div>";
|
|
692
|
+
return html;
|
|
693
|
+
},
|
|
694
|
+
getPolygonTooltipContent(feature: any): string {
|
|
695
|
+
const props = feature.properties || {};
|
|
696
|
+
const descripcion = props.descripcion || props.name || "Sin descripción";
|
|
697
|
+
|
|
698
|
+
return `<div style="font-weight: bold; padding: 5px;">${descripcion}</div>`;
|
|
699
|
+
},
|
|
700
|
+
},
|
|
701
|
+
watch: {
|
|
702
|
+
coordinatesMap(newVal) {
|
|
703
|
+
this.renderCoordinates = newVal;
|
|
704
|
+
if (this.mapRender && this.markerRender) {
|
|
705
|
+
const newLatLng = L.latLng([newVal[0], newVal[1]]);
|
|
706
|
+
this.mapRender.setView([newVal[0], newVal[1]], newVal[2]);
|
|
707
|
+
this.markerRender.setLatLng(newLatLng);
|
|
708
|
+
}
|
|
709
|
+
},
|
|
710
|
+
dataPolygon(newVal) {
|
|
711
|
+
this.renderGeojson = newVal;
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
});
|
|
715
|
+
</script>
|