abn-osmvue 0.1.0
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/LICENSE +21 -0
- package/README.md +426 -0
- package/dist/abn-osmvue.cjs +1 -0
- package/dist/abn-osmvue.js +367 -0
- package/dist/abn-osmvue.umd.js +1 -0
- package/dist/style.css +1 -0
- package/dist/types.d.ts +71 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 abaniconetworks
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# abn-osmvue
|
|
2
|
+
|
|
3
|
+
Librería de componentes Vue 2/Vue 3 para integrar mapas de OpenStreetMap. Basada en [Leaflet.js](https://leafletjs.com/) y compatible con ambas versiones de Vue gracias a [vue-demi](https://github.com/vueuse/vue-demi).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Instalación
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install abn-osmvue leaflet
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> Leaflet debe instalarse como dependencia directa de tu proyecto.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Registro
|
|
18
|
+
|
|
19
|
+
### Vue 3
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
// main.js
|
|
23
|
+
import { createApp } from 'vue'
|
|
24
|
+
import AbnOsmVue from 'abn-osmvue'
|
|
25
|
+
import 'abn-osmvue/dist/style.css'
|
|
26
|
+
import 'leaflet/dist/leaflet.css'
|
|
27
|
+
|
|
28
|
+
const app = createApp(App)
|
|
29
|
+
app.use(AbnOsmVue)
|
|
30
|
+
app.mount('#app')
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Vue 2
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
// main.js
|
|
37
|
+
import Vue from 'vue'
|
|
38
|
+
import AbnOsmVue from 'abn-osmvue'
|
|
39
|
+
import 'abn-osmvue/dist/style.css'
|
|
40
|
+
import 'leaflet/dist/leaflet.css'
|
|
41
|
+
|
|
42
|
+
Vue.use(AbnOsmVue)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Registro local (ambas versiones)
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { OsmMap, OsmMapEmbed } from 'abn-osmvue'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Componentes
|
|
54
|
+
|
|
55
|
+
### `<OsmMap>`
|
|
56
|
+
|
|
57
|
+
Renderiza un mapa interactivo usando Leaflet. Es el componente principal de la librería.
|
|
58
|
+
|
|
59
|
+
#### Props
|
|
60
|
+
|
|
61
|
+
| Prop | Tipo | Default | Requerido | Descripción |
|
|
62
|
+
|---|---|---|---|---|
|
|
63
|
+
| `lat` | `Number` | — | ✅ | Latitud del centro / pin |
|
|
64
|
+
| `lng` | `Number` | — | ✅ | Longitud del centro / pin |
|
|
65
|
+
| `zoom` | `Number` | `13` | — | Nivel de zoom inicial (1–19) |
|
|
66
|
+
| `minZoom` | `Number` | `1` | — | Zoom mínimo permitido |
|
|
67
|
+
| `maxZoom` | `Number` | `19` | — | Zoom máximo permitido |
|
|
68
|
+
| `height` | `String` | `'400px'` | — | Alto del contenedor (cualquier unidad CSS) |
|
|
69
|
+
| `width` | `String` | `'100%'` | — | Ancho del contenedor |
|
|
70
|
+
| `tileLayer` | `String` | `'osm'` | — | Proveedor de capa base (ver tabla de capas) |
|
|
71
|
+
| `tileUrl` | `String` | `null` | — | URL de teselas personalizada (sobreescribe `tileLayer`) |
|
|
72
|
+
| `tileOptions` | `Object` | `{}` | — | Opciones adicionales para el tile layer de Leaflet |
|
|
73
|
+
| `tileFilter` | `String` | `null` | — | Filtro CSS aplicado a las teselas (`'grayscale'`, `'invert'`, `'sepia'`, o valor CSS arbitrario) |
|
|
74
|
+
| `showMarker` | `Boolean` | `true` | — | Mostrar u ocultar el marcador en lat/lng |
|
|
75
|
+
| `markerIcon` | `String` | `null` | — | URL de imagen personalizada para el pin |
|
|
76
|
+
| `markerIconSize` | `Array` | `[32, 32]` | — | Tamaño del icono en píxeles `[width, height]` |
|
|
77
|
+
| `markerAnchor` | `Array` | `null` | — | Punto de anclaje del icono. Default: centro-base |
|
|
78
|
+
| `markerPopup` | `String` | `null` | — | HTML que aparece en popup al hacer clic en el pin |
|
|
79
|
+
| `controls` | `String\|Array` | `'all'` | — | Controles visibles (ver tabla de controles) |
|
|
80
|
+
| `draggable` | `Boolean` | `true` | — | Permitir arrastrar el mapa |
|
|
81
|
+
| `scrollWheelZoom` | `Boolean` | `true` | — | Zoom con scroll del ratón |
|
|
82
|
+
| `doubleClickZoom` | `Boolean` | `true` | — | Zoom con doble clic |
|
|
83
|
+
| `attributionControl` | `Boolean` | `true` | — | Mostrar atribución de OSM (requerida por licencia) |
|
|
84
|
+
|
|
85
|
+
#### Eventos
|
|
86
|
+
|
|
87
|
+
| Evento | Payload | Descripción |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| `map-ready` | `{ map: L.Map }` | El mapa ha sido inicializado |
|
|
90
|
+
| `click` | `{ latlng, originalEvent }` | Clic en el mapa |
|
|
91
|
+
| `zoom-change` | `{ zoom: Number }` | El nivel de zoom cambió |
|
|
92
|
+
| `move-end` | `{ center: L.LatLng }` | El mapa dejó de moverse |
|
|
93
|
+
| `marker-click` | `{ latlng }` | Clic en el marcador |
|
|
94
|
+
|
|
95
|
+
#### Métodos (vía `ref`)
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
const mapRef = ref(null)
|
|
99
|
+
|
|
100
|
+
mapRef.value.flyTo(lat, lng, zoom) // Animar desplazamiento al punto
|
|
101
|
+
mapRef.value.setView(lat, lng, zoom) // Centrar sin animación
|
|
102
|
+
mapRef.value.getLeafletMap() // Instancia L.Map raw para uso avanzado
|
|
103
|
+
mapRef.value.addMarker({ lat, lng, icon, iconSize, iconAnchor, popup })
|
|
104
|
+
mapRef.value.clearMarkers() // Eliminar todos los marcadores extra
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Slot `overlay`
|
|
108
|
+
|
|
109
|
+
Permite superponer contenido personalizado sobre el mapa:
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<OsmMap :lat="40.41" :lng="-3.70">
|
|
113
|
+
<template #overlay>
|
|
114
|
+
<div class="mi-panel">Contenido encima del mapa</div>
|
|
115
|
+
</template>
|
|
116
|
+
</OsmMap>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### `<OsmMapEmbed>`
|
|
122
|
+
|
|
123
|
+
Genera un `<iframe>` apuntando a un mapa de OpenStreetMap embebido. Útil cuando no se quiere cargar Leaflet en el bundle del cliente.
|
|
124
|
+
|
|
125
|
+
#### Props
|
|
126
|
+
|
|
127
|
+
| Prop | Tipo | Default | Requerido | Descripción |
|
|
128
|
+
|---|---|---|---|---|
|
|
129
|
+
| `lat` | `Number` | — | ✅ | Latitud |
|
|
130
|
+
| `lng` | `Number` | — | ✅ | Longitud |
|
|
131
|
+
| `zoom` | `Number` | `13` | — | Nivel de zoom |
|
|
132
|
+
| `height` | `String` | `'400px'` | — | Alto del iframe |
|
|
133
|
+
| `width` | `String` | `'100%'` | — | Ancho del iframe |
|
|
134
|
+
| `markerLat` | `Number` | igual que `lat` | — | Latitud del marcador (si difiere del centro) |
|
|
135
|
+
| `markerLng` | `Number` | igual que `lng` | — | Longitud del marcador |
|
|
136
|
+
| `embedSrc` | `String` | auto-generado | — | URL iframe completa personalizada |
|
|
137
|
+
| `title` | `String` | `'Mapa'` | — | Atributo `title` del iframe (accesibilidad) |
|
|
138
|
+
| `sandbox` | `String` | `null` | — | Valor del atributo `sandbox` del iframe |
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Capas de mapa (`tileLayer`)
|
|
143
|
+
|
|
144
|
+
| Valor | Proveedor | API key | Descripción |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `'osm'` | OpenStreetMap Mapnik | No | Capa estándar OSM (default) |
|
|
147
|
+
| `'osm-hot'` | OSM Humanitarian | No | Estilo humanitario, alto contraste |
|
|
148
|
+
| `'carto-light'` | CartoDB Positron | No | Blanco y gris, minimalista |
|
|
149
|
+
| `'carto-dark'` | CartoDB Dark Matter | No | Fondo oscuro |
|
|
150
|
+
| `'carto-voyager'` | CartoDB Voyager | No | Colorida y moderna, buena alternativa gratuita |
|
|
151
|
+
| `'opentopomap'` | OpenTopoMap | No | Topográfica (máx. zoom 17) |
|
|
152
|
+
| `'esri-satellite'` | Esri World Imagery | Sí ⚠️ | Satélite |
|
|
153
|
+
| `'stadia-alidade'` | Stadia Maps | Sí ⚠️ | Estilo limpio moderno |
|
|
154
|
+
|
|
155
|
+
### ⚠️ Capas que requieren API key
|
|
156
|
+
|
|
157
|
+
**Stadia Maps** (`'stadia-alidade'`)
|
|
158
|
+
Requiere una API key para uso en producción. El plan gratuito cubre proyectos no comerciales con tráfico moderado.
|
|
159
|
+
→ Obtén tu clave en [stadiamaps.com/auth/signup](https://stadiamaps.com/auth/signup)
|
|
160
|
+
|
|
161
|
+
```html
|
|
162
|
+
<OsmMap
|
|
163
|
+
tile-url="https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png?api_key=TU_API_KEY"
|
|
164
|
+
:tile-options="{ maxZoom: 20, attribution: '© Stadia Maps © OpenStreetMap contributors' }"
|
|
165
|
+
/>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Esri World Imagery** (`'esri-satellite'`)
|
|
169
|
+
Requiere una cuenta de ArcGIS. El uso sin cuenta puede infringir sus términos de servicio en producción.
|
|
170
|
+
→ Información en [developers.arcgis.com](https://developers.arcgis.com)
|
|
171
|
+
|
|
172
|
+
```html
|
|
173
|
+
<OsmMap
|
|
174
|
+
tile-url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}?token=TU_TOKEN"
|
|
175
|
+
:tile-options="{ maxZoom: 18, attribution: 'Tiles © Esri' }"
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Para URL propia, usar `tile-url`:
|
|
180
|
+
|
|
181
|
+
```html
|
|
182
|
+
<OsmMap
|
|
183
|
+
:lat="40.41" :lng="-3.70"
|
|
184
|
+
tile-url="https://mi-servidor/{z}/{x}/{y}.png"
|
|
185
|
+
:tile-options="{ maxZoom: 18, attribution: '© Mi empresa' }"
|
|
186
|
+
/>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Filtros de color (`tileFilter`)
|
|
190
|
+
|
|
191
|
+
| Valor | Efecto |
|
|
192
|
+
|---|---|
|
|
193
|
+
| `null` | Sin filtro (default) |
|
|
194
|
+
| `'grayscale'` | Escala de grises |
|
|
195
|
+
| `'invert'` | Colores invertidos (útil para dark mode) |
|
|
196
|
+
| `'sepia'` | Tono sepia |
|
|
197
|
+
| `String` | Valor CSS `filter` arbitrario, ej: `'hue-rotate(180deg) saturate(0.5)'` |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Sistema de controles (`controls`)
|
|
202
|
+
|
|
203
|
+
| Valor | Resultado |
|
|
204
|
+
|---|---|
|
|
205
|
+
| `'all'` | Zoom + escala + atribución |
|
|
206
|
+
| `'zoom'` | Solo botones de zoom (+/−) |
|
|
207
|
+
| `'none'` | Sin controles |
|
|
208
|
+
| `Array` | Lista explícita: `['zoom', 'scale']` |
|
|
209
|
+
|
|
210
|
+
Valores válidos en array: `'zoom'`, `'scale'`, `'attribution'`.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Ejemplos
|
|
215
|
+
|
|
216
|
+
### Vue 3 — Mapa básico
|
|
217
|
+
|
|
218
|
+
```vue
|
|
219
|
+
<template>
|
|
220
|
+
<OsmMap :lat="40.4168" :lng="-3.7038" />
|
|
221
|
+
</template>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Vue 3 — Mapa personalizado con eventos
|
|
225
|
+
|
|
226
|
+
```vue
|
|
227
|
+
<template>
|
|
228
|
+
<OsmMap
|
|
229
|
+
:lat="40.4168"
|
|
230
|
+
:lng="-3.7038"
|
|
231
|
+
:zoom="15"
|
|
232
|
+
height="500px"
|
|
233
|
+
tile-layer="carto-light"
|
|
234
|
+
tile-filter="grayscale"
|
|
235
|
+
marker-popup="<b>Madrid</b><br>Centro"
|
|
236
|
+
controls="zoom"
|
|
237
|
+
:scroll-wheel-zoom="false"
|
|
238
|
+
@map-ready="onReady"
|
|
239
|
+
@click="onClick"
|
|
240
|
+
@marker-click="onMarkerClick"
|
|
241
|
+
/>
|
|
242
|
+
</template>
|
|
243
|
+
|
|
244
|
+
<script setup>
|
|
245
|
+
const onReady = ({ map }) => console.log('Mapa listo', map)
|
|
246
|
+
const onClick = ({ latlng }) => console.log('Clic en', latlng)
|
|
247
|
+
const onMarkerClick = ({ latlng }) => console.log('Marcador clicado', latlng)
|
|
248
|
+
</script>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Vue 3 — Control programático vía ref
|
|
252
|
+
|
|
253
|
+
```vue
|
|
254
|
+
<template>
|
|
255
|
+
<OsmMap ref="mapRef" :lat="40.4168" :lng="-3.7038" />
|
|
256
|
+
<button @click="volarABarcelona">Ir a Barcelona</button>
|
|
257
|
+
<button @click="añadirPin">Añadir pin</button>
|
|
258
|
+
</template>
|
|
259
|
+
|
|
260
|
+
<script setup>
|
|
261
|
+
import { ref } from 'vue'
|
|
262
|
+
|
|
263
|
+
const mapRef = ref(null)
|
|
264
|
+
|
|
265
|
+
function volarABarcelona() {
|
|
266
|
+
mapRef.value.flyTo(41.3874, 2.1686, 14)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function añadirPin() {
|
|
270
|
+
mapRef.value.addMarker({
|
|
271
|
+
lat: 41.3874,
|
|
272
|
+
lng: 2.1686,
|
|
273
|
+
popup: '<b>Barcelona</b>',
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
</script>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Vue 3 — Slot overlay
|
|
280
|
+
|
|
281
|
+
```vue
|
|
282
|
+
<template>
|
|
283
|
+
<OsmMap :lat="40.4168" :lng="-3.7038" height="500px">
|
|
284
|
+
<template #overlay>
|
|
285
|
+
<div style="position: absolute; top: 10px; right: 10px; background: white; padding: 8px; border-radius: 4px;">
|
|
286
|
+
Panel personalizado
|
|
287
|
+
</div>
|
|
288
|
+
</template>
|
|
289
|
+
</OsmMap>
|
|
290
|
+
</template>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Vue 3 — Mapa estático sin controles
|
|
294
|
+
|
|
295
|
+
```vue
|
|
296
|
+
<template>
|
|
297
|
+
<OsmMap
|
|
298
|
+
:lat="40.4168"
|
|
299
|
+
:lng="-3.7038"
|
|
300
|
+
controls="none"
|
|
301
|
+
:draggable="false"
|
|
302
|
+
:scroll-wheel-zoom="false"
|
|
303
|
+
:double-click-zoom="false"
|
|
304
|
+
/>
|
|
305
|
+
</template>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Vue 3 — Iframe embebido
|
|
309
|
+
|
|
310
|
+
```vue
|
|
311
|
+
<template>
|
|
312
|
+
<OsmMapEmbed
|
|
313
|
+
:lat="40.4168"
|
|
314
|
+
:lng="-3.7038"
|
|
315
|
+
:zoom="14"
|
|
316
|
+
height="400px"
|
|
317
|
+
title="Ubicación de nuestra oficina"
|
|
318
|
+
/>
|
|
319
|
+
</template>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Vue 2 — Mapa básico
|
|
323
|
+
|
|
324
|
+
```vue
|
|
325
|
+
<template>
|
|
326
|
+
<osm-map :lat="40.4168" :lng="-3.7038" />
|
|
327
|
+
</template>
|
|
328
|
+
|
|
329
|
+
<script>
|
|
330
|
+
export default {
|
|
331
|
+
name: 'MiComponente',
|
|
332
|
+
}
|
|
333
|
+
</script>
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Vue 2 — Mapa personalizado con eventos
|
|
337
|
+
|
|
338
|
+
```vue
|
|
339
|
+
<template>
|
|
340
|
+
<osm-map
|
|
341
|
+
:lat="40.4168"
|
|
342
|
+
:lng="-3.7038"
|
|
343
|
+
:zoom="15"
|
|
344
|
+
height="500px"
|
|
345
|
+
tile-layer="carto-light"
|
|
346
|
+
tile-filter="grayscale"
|
|
347
|
+
marker-popup="<b>Madrid</b><br>Centro"
|
|
348
|
+
controls="zoom"
|
|
349
|
+
:scroll-wheel-zoom="false"
|
|
350
|
+
@map-ready="onReady"
|
|
351
|
+
@click="onClick"
|
|
352
|
+
/>
|
|
353
|
+
</template>
|
|
354
|
+
|
|
355
|
+
<script>
|
|
356
|
+
export default {
|
|
357
|
+
methods: {
|
|
358
|
+
onReady({ map }) {
|
|
359
|
+
console.log('Mapa listo', map)
|
|
360
|
+
},
|
|
361
|
+
onClick({ latlng }) {
|
|
362
|
+
console.log('Clic en', latlng)
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
}
|
|
366
|
+
</script>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Vue 2 — Control programático vía ref
|
|
370
|
+
|
|
371
|
+
```vue
|
|
372
|
+
<template>
|
|
373
|
+
<div>
|
|
374
|
+
<osm-map ref="mapRef" :lat="40.4168" :lng="-3.7038" />
|
|
375
|
+
<button @click="volarABarcelona">Ir a Barcelona</button>
|
|
376
|
+
</div>
|
|
377
|
+
</template>
|
|
378
|
+
|
|
379
|
+
<script>
|
|
380
|
+
export default {
|
|
381
|
+
methods: {
|
|
382
|
+
volarABarcelona() {
|
|
383
|
+
this.$refs.mapRef.flyTo(41.3874, 2.1686, 14)
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
}
|
|
387
|
+
</script>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Vue 2 — Iframe embebido
|
|
391
|
+
|
|
392
|
+
```vue
|
|
393
|
+
<template>
|
|
394
|
+
<osm-map-embed
|
|
395
|
+
:lat="40.4168"
|
|
396
|
+
:lng="-3.7038"
|
|
397
|
+
:zoom="14"
|
|
398
|
+
height="400px"
|
|
399
|
+
title="Nuestra ubicación"
|
|
400
|
+
/>
|
|
401
|
+
</template>
|
|
402
|
+
|
|
403
|
+
<script>
|
|
404
|
+
export default {
|
|
405
|
+
name: 'MiMapa',
|
|
406
|
+
}
|
|
407
|
+
</script>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Consideraciones de licencia
|
|
413
|
+
|
|
414
|
+
- **OpenStreetMap** requiere atribución visible. No desactivar `attribution-control` en producción salvo que uses un tile server propio con su propia atribución.
|
|
415
|
+
- Las capas de terceros (CartoDB, Stadia, Esri) tienen sus propios términos de servicio. Revisa su documentación antes de usarlas en producción.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## Hoja de ruta
|
|
420
|
+
|
|
421
|
+
- [ ] Soporte para múltiples marcadores (`markers: Array<{lat, lng, icon?, popup?}>`)
|
|
422
|
+
- [ ] Dibujar polilíneas y polígonos
|
|
423
|
+
- [ ] Clustering de marcadores (via Leaflet.markercluster)
|
|
424
|
+
- [ ] Plugin de geolocalización
|
|
425
|
+
- [ ] Modo offline con teselas locales
|
|
426
|
+
- [ ] Storybook con ejemplos interactivos
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b=require("vue-demi"),k=require("leaflet"),m=require("vue"),T={osm:{url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',maxZoom:19}},"osm-hot":{url:"https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Tiles style by <a href="https://www.hotosm.org/" target="_blank">Humanitarian OpenStreetMap Team</a>',maxZoom:19}},"carto-light":{url:"https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',subdomains:"abcd",maxZoom:20}},"carto-dark":{url:"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',subdomains:"abcd",maxZoom:20}},"esri-satellite":{url:"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",options:{attribution:"Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community",maxZoom:18}},"stadia-alidade":{url:"https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://stadiamaps.com/">Stadia Maps</a>, © <a href="https://openmaptiles.org/">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',maxZoom:20}},"carto-voyager":{url:"https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',subdomains:"abcd",maxZoom:20}},opentopomap:{url:"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",options:{attribution:'Map data: © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="https://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)',maxZoom:17}}},F={grayscale:"grayscale(100%)",invert:"invert(100%)",sepia:"sepia(100%)"};function Y(){function e(t,r,o,n){let a,l={};if(r)a=r,l={...o};else{const i=T[t]||T.osm;a=i.url,l={...i.options,...o}}const s=k.tileLayer(a,l);if(n){const i=F[n]||n;s.on("tileload",u=>{u.tile.style.filter=i})}return s}return{createTileLayer:e}}function H(){const e=[];function t(a,l,s){if(!a)return null;const i=l||[32,32],u=s||[i[0]/2,i[1]];return k.icon({iconUrl:a,iconSize:i,iconAnchor:u,popupAnchor:[0,-u[1]]})}function r(a,l,s,i,u,M,p,y){const d=t(i,u,M),f=d?{icon:d}:{},w=k.marker([l,s],f).addTo(a);return p&&w.bindPopup(p),w.on("click",S=>{y({latlng:S.latlng})}),w}function o(a,{lat:l,lng:s,icon:i,iconSize:u,iconAnchor:M,popup:p}={}){const y=t(i,u,M),d=y?{icon:y}:{},f=k.marker([l,s],d).addTo(a);return p&&f.bindPopup(p),e.push(f),f}function n(a){e.forEach(l=>a.removeLayer(l)),e.length=0}return{createMainMarker:r,addMarker:o,clearMarkers:n}}const z={zoom:e=>{e.zoomControl||k.control.zoom().addTo(e)},scale:e=>{k.control.scale().addTo(e)},attribution:e=>{e.attributionControl||k.control.attribution().addTo(e)}};function X(){function e(t,r){if(t.zoomControl.remove(),r!=="none"){if(r==="all"){Object.values(z).forEach(o=>o(t));return}if(r==="zoom"){z.zoom(t);return}Array.isArray(r)&&r.forEach(o=>{z[o]&&z[o](t)})}}return{applyControls:e}}function J(e){let t=null,r=null;const{createTileLayer:o}=Y(),{createMainMarker:n,addMarker:a,clearMarkers:l}=H(),{applyControls:s}=X();function i(c,h){const{lat:g,lng:O,zoom:C,minZoom:_,maxZoom:A,tileLayer:$,tileUrl:Z,tileOptions:B,tileFilter:N,showMarker:I,markerIcon:P,markerIconSize:R,markerAnchor:V,markerPopup:G,controls:q,draggable:U,scrollWheelZoom:j,doubleClickZoom:W,attributionControl:D}=h;t=k.map(c,{center:[g,O],zoom:C,minZoom:_,maxZoom:A,dragging:U,scrollWheelZoom:j,doubleClickZoom:W,attributionControl:D,zoomControl:!0}),o($,Z,B,N).addTo(t),s(t,q),I&&(r=n(t,g,O,P,R,V,G,v=>e("marker-click",v))),t.on("click",v=>{e("click",{latlng:v.latlng,originalEvent:v.originalEvent})}),t.on("zoomend",()=>{e("zoom-change",{zoom:t.getZoom()})}),t.on("moveend",()=>{e("move-end",{center:t.getCenter()})}),e("map-ready",{map:t})}function u(){t&&(t.remove(),t=null,r=null)}function M(c,h,g){t==null||t.flyTo([c,h],g)}function p(c,h,g){t==null||t.setView([c,h],g)}function y(){return t}function d(c){return t?a(t,c):null}function f(){t&&l(t)}function w(c){t&&(r&&(t.removeLayer(r),r=null),c.showMarker&&(r=n(t,c.lat,c.lng,c.markerIcon,c.markerIconSize,c.markerAnchor,c.markerPopup,h=>e("marker-click",h))))}function S(c,h,g){t==null||t.setView([c,h],g,{animate:!1})}return{initMap:i,destroyMap:u,flyTo:M,setView:p,getLeafletMap:y,addMarker:d,clearMarkers:f,updateMarker:w,updateView:S}}const x=(e,t)=>{const r=e.__vccOpts||e;for(const[o,n]of t)r[o]=n;return r},K=b.defineComponent({name:"OsmMap",props:{lat:{type:Number,required:!0},lng:{type:Number,required:!0},zoom:{type:Number,default:13},minZoom:{type:Number,default:1},maxZoom:{type:Number,default:19},height:{type:String,default:"400px"},width:{type:String,default:"100%"},tileLayer:{type:String,default:"osm"},tileUrl:{type:String,default:null},tileOptions:{type:Object,default:()=>({})},tileFilter:{type:String,default:null},showMarker:{type:Boolean,default:!0},markerIcon:{type:String,default:null},markerIconSize:{type:Array,default:()=>[32,32]},markerAnchor:{type:Array,default:null},markerPopup:{type:String,default:null},controls:{type:[String,Array],default:"all"},draggable:{type:Boolean,default:!0},scrollWheelZoom:{type:Boolean,default:!0},doubleClickZoom:{type:Boolean,default:!0},attributionControl:{type:Boolean,default:!0}},emits:["map-ready","click","zoom-change","move-end","marker-click"],setup(e,{emit:t,expose:r}){const o=b.ref(null),{initMap:n,destroyMap:a,flyTo:l,setView:s,getLeafletMap:i,addMarker:u,clearMarkers:M,updateMarker:p,updateView:y}=J(t);b.onMounted(()=>{n(o.value,e)}),b.onBeforeUnmount(()=>{a()}),b.watch(()=>[e.lat,e.lng,e.zoom],([f,w,S])=>{y(f,w,S)}),b.watch(()=>[e.showMarker,e.markerIcon,e.markerIconSize,e.markerAnchor,e.markerPopup],()=>{p(e)});const d={flyTo:l,setView:s,getLeafletMap:i,addMarker:u,clearMarkers:M};return r&&r(d),{mapEl:o,...d}}}),Q={ref:"mapEl",class:"abn-osmvue-map"},ee={key:0,class:"abn-osmvue-overlay"};function te(e,t,r,o,n,a){return m.openBlock(),m.createElementBlock("div",{class:"abn-osmvue-wrapper",style:m.normalizeStyle({height:e.height,width:e.width})},[m.createElementVNode("div",Q,null,512),e.$slots.overlay?(m.openBlock(),m.createElementBlock("div",ee,[m.renderSlot(e.$slots,"overlay")])):m.createCommentVNode("",!0)],4)}const E=x(K,[["render",te]]),re=b.defineComponent({name:"OsmMapEmbed",props:{lat:{type:Number,required:!0},lng:{type:Number,required:!0},zoom:{type:Number,default:13},height:{type:String,default:"400px"},width:{type:String,default:"100%"},markerLat:{type:Number,default:null},markerLng:{type:Number,default:null},embedSrc:{type:String,default:null},title:{type:String,default:"Mapa"},sandbox:{type:String,default:null}},setup(e){return{iframeSrc:b.computed(()=>{if(e.embedSrc)return e.embedSrc;const r=e.markerLat??e.lat,o=e.markerLng??e.lng,n=.01*Math.pow(2,13-e.zoom),a=e.lng-n,l=e.lat-n*.6,s=e.lng+n,i=e.lat+n*.6;return`https://www.openstreetmap.org/export/embed.html?bbox=${`${a},${l},${s},${i}`}&layer=mapnik&marker=${r},${o}`})}}}),oe=["src","width","height","title","sandbox"];function ae(e,t,r,o,n,a){return m.openBlock(),m.createElementBlock("iframe",{src:e.iframeSrc,width:e.width,height:e.height,title:e.title,sandbox:e.sandbox||void 0,class:"abn-osmvue-embed",frameborder:"0",scrolling:"no",marginheight:"0",marginwidth:"0",allowfullscreen:""},null,8,oe)}const L=x(re,[["render",ae]]),ne={install(e){e.component("OsmMap",E),e.component("OsmMapEmbed",L)}};exports.OsmMap=E;exports.OsmMapEmbed=L;exports.default=ne;
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { defineComponent as L, ref as Y, onMounted as D, onBeforeUnmount as H, watch as O, computed as X } from "vue-demi";
|
|
2
|
+
import g from "leaflet";
|
|
3
|
+
import { openBlock as v, createElementBlock as z, normalizeStyle as J, createElementVNode as K, renderSlot as Q, createCommentVNode as ee } from "vue";
|
|
4
|
+
const T = {
|
|
5
|
+
osm: {
|
|
6
|
+
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
7
|
+
options: {
|
|
8
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
9
|
+
maxZoom: 19
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"osm-hot": {
|
|
13
|
+
url: "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
|
|
14
|
+
options: {
|
|
15
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Tiles style by <a href="https://www.hotosm.org/" target="_blank">Humanitarian OpenStreetMap Team</a>',
|
|
16
|
+
maxZoom: 19
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"carto-light": {
|
|
20
|
+
url: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
|
|
21
|
+
options: {
|
|
22
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
|
23
|
+
subdomains: "abcd",
|
|
24
|
+
maxZoom: 20
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"carto-dark": {
|
|
28
|
+
url: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
|
|
29
|
+
options: {
|
|
30
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
|
31
|
+
subdomains: "abcd",
|
|
32
|
+
maxZoom: 20
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"esri-satellite": {
|
|
36
|
+
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
|
37
|
+
options: {
|
|
38
|
+
attribution: "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community",
|
|
39
|
+
maxZoom: 18
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"stadia-alidade": {
|
|
43
|
+
url: "https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png",
|
|
44
|
+
options: {
|
|
45
|
+
attribution: '© <a href="https://stadiamaps.com/">Stadia Maps</a>, © <a href="https://openmaptiles.org/">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
46
|
+
maxZoom: 20
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"carto-voyager": {
|
|
50
|
+
url: "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
|
|
51
|
+
options: {
|
|
52
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
|
53
|
+
subdomains: "abcd",
|
|
54
|
+
maxZoom: 20
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
opentopomap: {
|
|
58
|
+
url: "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
59
|
+
options: {
|
|
60
|
+
attribution: 'Map data: © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="https://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)',
|
|
61
|
+
maxZoom: 17
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, te = {
|
|
65
|
+
grayscale: "grayscale(100%)",
|
|
66
|
+
invert: "invert(100%)",
|
|
67
|
+
sepia: "sepia(100%)"
|
|
68
|
+
};
|
|
69
|
+
function re() {
|
|
70
|
+
function e(t, r, o, n) {
|
|
71
|
+
let a, l = {};
|
|
72
|
+
if (r)
|
|
73
|
+
a = r, l = { ...o };
|
|
74
|
+
else {
|
|
75
|
+
const i = T[t] || T.osm;
|
|
76
|
+
a = i.url, l = { ...i.options, ...o };
|
|
77
|
+
}
|
|
78
|
+
const c = g.tileLayer(a, l);
|
|
79
|
+
if (n) {
|
|
80
|
+
const i = te[n] || n;
|
|
81
|
+
c.on("tileload", (u) => {
|
|
82
|
+
u.tile.style.filter = i;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return c;
|
|
86
|
+
}
|
|
87
|
+
return { createTileLayer: e };
|
|
88
|
+
}
|
|
89
|
+
function oe() {
|
|
90
|
+
const e = [];
|
|
91
|
+
function t(a, l, c) {
|
|
92
|
+
if (!a) return null;
|
|
93
|
+
const i = l || [32, 32], u = c || [i[0] / 2, i[1]];
|
|
94
|
+
return g.icon({
|
|
95
|
+
iconUrl: a,
|
|
96
|
+
iconSize: i,
|
|
97
|
+
iconAnchor: u,
|
|
98
|
+
popupAnchor: [0, -u[1]]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function r(a, l, c, i, u, b, m, h) {
|
|
102
|
+
const p = t(i, u, b), d = p ? { icon: p } : {}, k = g.marker([l, c], d).addTo(a);
|
|
103
|
+
return m && k.bindPopup(m), k.on("click", (M) => {
|
|
104
|
+
h({ latlng: M.latlng });
|
|
105
|
+
}), k;
|
|
106
|
+
}
|
|
107
|
+
function o(a, { lat: l, lng: c, icon: i, iconSize: u, iconAnchor: b, popup: m } = {}) {
|
|
108
|
+
const h = t(i, u, b), p = h ? { icon: h } : {}, d = g.marker([l, c], p).addTo(a);
|
|
109
|
+
return m && d.bindPopup(m), e.push(d), d;
|
|
110
|
+
}
|
|
111
|
+
function n(a) {
|
|
112
|
+
e.forEach((l) => a.removeLayer(l)), e.length = 0;
|
|
113
|
+
}
|
|
114
|
+
return { createMainMarker: r, addMarker: o, clearMarkers: n };
|
|
115
|
+
}
|
|
116
|
+
const S = {
|
|
117
|
+
zoom: (e) => {
|
|
118
|
+
e.zoomControl || g.control.zoom().addTo(e);
|
|
119
|
+
},
|
|
120
|
+
scale: (e) => {
|
|
121
|
+
g.control.scale().addTo(e);
|
|
122
|
+
},
|
|
123
|
+
attribution: (e) => {
|
|
124
|
+
e.attributionControl || g.control.attribution().addTo(e);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
function ae() {
|
|
128
|
+
function e(t, r) {
|
|
129
|
+
if (t.zoomControl.remove(), r !== "none") {
|
|
130
|
+
if (r === "all") {
|
|
131
|
+
Object.values(S).forEach((o) => o(t));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (r === "zoom") {
|
|
135
|
+
S.zoom(t);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
Array.isArray(r) && r.forEach((o) => {
|
|
139
|
+
S[o] && S[o](t);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return { applyControls: e };
|
|
144
|
+
}
|
|
145
|
+
function ne(e) {
|
|
146
|
+
let t = null, r = null;
|
|
147
|
+
const { createTileLayer: o } = re(), { createMainMarker: n, addMarker: a, clearMarkers: l } = oe(), { applyControls: c } = ae();
|
|
148
|
+
function i(s, f) {
|
|
149
|
+
const {
|
|
150
|
+
lat: y,
|
|
151
|
+
lng: x,
|
|
152
|
+
zoom: C,
|
|
153
|
+
minZoom: E,
|
|
154
|
+
maxZoom: _,
|
|
155
|
+
tileLayer: $,
|
|
156
|
+
tileUrl: Z,
|
|
157
|
+
tileOptions: N,
|
|
158
|
+
tileFilter: I,
|
|
159
|
+
showMarker: B,
|
|
160
|
+
markerIcon: P,
|
|
161
|
+
markerIconSize: R,
|
|
162
|
+
markerAnchor: V,
|
|
163
|
+
markerPopup: G,
|
|
164
|
+
controls: U,
|
|
165
|
+
draggable: q,
|
|
166
|
+
scrollWheelZoom: W,
|
|
167
|
+
doubleClickZoom: j,
|
|
168
|
+
attributionControl: F
|
|
169
|
+
} = f;
|
|
170
|
+
t = g.map(s, {
|
|
171
|
+
center: [y, x],
|
|
172
|
+
zoom: C,
|
|
173
|
+
minZoom: E,
|
|
174
|
+
maxZoom: _,
|
|
175
|
+
dragging: q,
|
|
176
|
+
scrollWheelZoom: W,
|
|
177
|
+
doubleClickZoom: j,
|
|
178
|
+
attributionControl: F,
|
|
179
|
+
zoomControl: !0
|
|
180
|
+
}), o($, Z, N, I).addTo(t), c(t, U), B && (r = n(
|
|
181
|
+
t,
|
|
182
|
+
y,
|
|
183
|
+
x,
|
|
184
|
+
P,
|
|
185
|
+
R,
|
|
186
|
+
V,
|
|
187
|
+
G,
|
|
188
|
+
(w) => e("marker-click", w)
|
|
189
|
+
)), t.on("click", (w) => {
|
|
190
|
+
e("click", { latlng: w.latlng, originalEvent: w.originalEvent });
|
|
191
|
+
}), t.on("zoomend", () => {
|
|
192
|
+
e("zoom-change", { zoom: t.getZoom() });
|
|
193
|
+
}), t.on("moveend", () => {
|
|
194
|
+
e("move-end", { center: t.getCenter() });
|
|
195
|
+
}), e("map-ready", { map: t });
|
|
196
|
+
}
|
|
197
|
+
function u() {
|
|
198
|
+
t && (t.remove(), t = null, r = null);
|
|
199
|
+
}
|
|
200
|
+
function b(s, f, y) {
|
|
201
|
+
t == null || t.flyTo([s, f], y);
|
|
202
|
+
}
|
|
203
|
+
function m(s, f, y) {
|
|
204
|
+
t == null || t.setView([s, f], y);
|
|
205
|
+
}
|
|
206
|
+
function h() {
|
|
207
|
+
return t;
|
|
208
|
+
}
|
|
209
|
+
function p(s) {
|
|
210
|
+
return t ? a(t, s) : null;
|
|
211
|
+
}
|
|
212
|
+
function d() {
|
|
213
|
+
t && l(t);
|
|
214
|
+
}
|
|
215
|
+
function k(s) {
|
|
216
|
+
t && (r && (t.removeLayer(r), r = null), s.showMarker && (r = n(
|
|
217
|
+
t,
|
|
218
|
+
s.lat,
|
|
219
|
+
s.lng,
|
|
220
|
+
s.markerIcon,
|
|
221
|
+
s.markerIconSize,
|
|
222
|
+
s.markerAnchor,
|
|
223
|
+
s.markerPopup,
|
|
224
|
+
(f) => e("marker-click", f)
|
|
225
|
+
)));
|
|
226
|
+
}
|
|
227
|
+
function M(s, f, y) {
|
|
228
|
+
t == null || t.setView([s, f], y, { animate: !1 });
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
initMap: i,
|
|
232
|
+
destroyMap: u,
|
|
233
|
+
flyTo: b,
|
|
234
|
+
setView: m,
|
|
235
|
+
getLeafletMap: h,
|
|
236
|
+
addMarker: p,
|
|
237
|
+
clearMarkers: d,
|
|
238
|
+
updateMarker: k,
|
|
239
|
+
updateView: M
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const A = (e, t) => {
|
|
243
|
+
const r = e.__vccOpts || e;
|
|
244
|
+
for (const [o, n] of t)
|
|
245
|
+
r[o] = n;
|
|
246
|
+
return r;
|
|
247
|
+
}, ie = L({
|
|
248
|
+
name: "OsmMap",
|
|
249
|
+
props: {
|
|
250
|
+
lat: { type: Number, required: !0 },
|
|
251
|
+
lng: { type: Number, required: !0 },
|
|
252
|
+
zoom: { type: Number, default: 13 },
|
|
253
|
+
minZoom: { type: Number, default: 1 },
|
|
254
|
+
maxZoom: { type: Number, default: 19 },
|
|
255
|
+
height: { type: String, default: "400px" },
|
|
256
|
+
width: { type: String, default: "100%" },
|
|
257
|
+
tileLayer: { type: String, default: "osm" },
|
|
258
|
+
tileUrl: { type: String, default: null },
|
|
259
|
+
tileOptions: { type: Object, default: () => ({}) },
|
|
260
|
+
tileFilter: { type: String, default: null },
|
|
261
|
+
showMarker: { type: Boolean, default: !0 },
|
|
262
|
+
markerIcon: { type: String, default: null },
|
|
263
|
+
markerIconSize: { type: Array, default: () => [32, 32] },
|
|
264
|
+
markerAnchor: { type: Array, default: null },
|
|
265
|
+
markerPopup: { type: String, default: null },
|
|
266
|
+
controls: { type: [String, Array], default: "all" },
|
|
267
|
+
draggable: { type: Boolean, default: !0 },
|
|
268
|
+
scrollWheelZoom: { type: Boolean, default: !0 },
|
|
269
|
+
doubleClickZoom: { type: Boolean, default: !0 },
|
|
270
|
+
attributionControl: { type: Boolean, default: !0 }
|
|
271
|
+
},
|
|
272
|
+
emits: ["map-ready", "click", "zoom-change", "move-end", "marker-click"],
|
|
273
|
+
setup(e, { emit: t, expose: r }) {
|
|
274
|
+
const o = Y(null), {
|
|
275
|
+
initMap: n,
|
|
276
|
+
destroyMap: a,
|
|
277
|
+
flyTo: l,
|
|
278
|
+
setView: c,
|
|
279
|
+
getLeafletMap: i,
|
|
280
|
+
addMarker: u,
|
|
281
|
+
clearMarkers: b,
|
|
282
|
+
updateMarker: m,
|
|
283
|
+
updateView: h
|
|
284
|
+
} = ne(t);
|
|
285
|
+
D(() => {
|
|
286
|
+
n(o.value, e);
|
|
287
|
+
}), H(() => {
|
|
288
|
+
a();
|
|
289
|
+
}), O(
|
|
290
|
+
() => [e.lat, e.lng, e.zoom],
|
|
291
|
+
([d, k, M]) => {
|
|
292
|
+
h(d, k, M);
|
|
293
|
+
}
|
|
294
|
+
), O(
|
|
295
|
+
() => [e.showMarker, e.markerIcon, e.markerIconSize, e.markerAnchor, e.markerPopup],
|
|
296
|
+
() => {
|
|
297
|
+
m(e);
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
const p = { flyTo: l, setView: c, getLeafletMap: i, addMarker: u, clearMarkers: b };
|
|
301
|
+
return r && r(p), { mapEl: o, ...p };
|
|
302
|
+
}
|
|
303
|
+
}), le = {
|
|
304
|
+
ref: "mapEl",
|
|
305
|
+
class: "abn-osmvue-map"
|
|
306
|
+
}, se = {
|
|
307
|
+
key: 0,
|
|
308
|
+
class: "abn-osmvue-overlay"
|
|
309
|
+
};
|
|
310
|
+
function ce(e, t, r, o, n, a) {
|
|
311
|
+
return v(), z("div", {
|
|
312
|
+
class: "abn-osmvue-wrapper",
|
|
313
|
+
style: J({ height: e.height, width: e.width })
|
|
314
|
+
}, [
|
|
315
|
+
K("div", le, null, 512),
|
|
316
|
+
e.$slots.overlay ? (v(), z("div", se, [
|
|
317
|
+
Q(e.$slots, "overlay")
|
|
318
|
+
])) : ee("", !0)
|
|
319
|
+
], 4);
|
|
320
|
+
}
|
|
321
|
+
const ue = /* @__PURE__ */ A(ie, [["render", ce]]), me = L({
|
|
322
|
+
name: "OsmMapEmbed",
|
|
323
|
+
props: {
|
|
324
|
+
lat: { type: Number, required: !0 },
|
|
325
|
+
lng: { type: Number, required: !0 },
|
|
326
|
+
zoom: { type: Number, default: 13 },
|
|
327
|
+
height: { type: String, default: "400px" },
|
|
328
|
+
width: { type: String, default: "100%" },
|
|
329
|
+
markerLat: { type: Number, default: null },
|
|
330
|
+
markerLng: { type: Number, default: null },
|
|
331
|
+
embedSrc: { type: String, default: null },
|
|
332
|
+
title: { type: String, default: "Mapa" },
|
|
333
|
+
sandbox: { type: String, default: null }
|
|
334
|
+
},
|
|
335
|
+
setup(e) {
|
|
336
|
+
return { iframeSrc: X(() => {
|
|
337
|
+
if (e.embedSrc) return e.embedSrc;
|
|
338
|
+
const r = e.markerLat ?? e.lat, o = e.markerLng ?? e.lng, n = 0.01 * Math.pow(2, 13 - e.zoom), a = e.lng - n, l = e.lat - n * 0.6, c = e.lng + n, i = e.lat + n * 0.6;
|
|
339
|
+
return `https://www.openstreetmap.org/export/embed.html?bbox=${`${a},${l},${c},${i}`}&layer=mapnik&marker=${r},${o}`;
|
|
340
|
+
}) };
|
|
341
|
+
}
|
|
342
|
+
}), pe = ["src", "width", "height", "title", "sandbox"];
|
|
343
|
+
function de(e, t, r, o, n, a) {
|
|
344
|
+
return v(), z("iframe", {
|
|
345
|
+
src: e.iframeSrc,
|
|
346
|
+
width: e.width,
|
|
347
|
+
height: e.height,
|
|
348
|
+
title: e.title,
|
|
349
|
+
sandbox: e.sandbox || void 0,
|
|
350
|
+
class: "abn-osmvue-embed",
|
|
351
|
+
frameborder: "0",
|
|
352
|
+
scrolling: "no",
|
|
353
|
+
marginheight: "0",
|
|
354
|
+
marginwidth: "0",
|
|
355
|
+
allowfullscreen: ""
|
|
356
|
+
}, null, 8, pe);
|
|
357
|
+
}
|
|
358
|
+
const fe = /* @__PURE__ */ A(me, [["render", de]]), be = {
|
|
359
|
+
install(e) {
|
|
360
|
+
e.component("OsmMap", ue), e.component("OsmMapEmbed", fe);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
export {
|
|
364
|
+
ue as OsmMap,
|
|
365
|
+
fe as OsmMapEmbed,
|
|
366
|
+
be as default
|
|
367
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(p,m){typeof exports=="object"&&typeof module<"u"?m(exports,require("vue-demi"),require("leaflet"),require("vue")):typeof define=="function"&&define.amd?define(["exports","vue-demi","leaflet","vue"],m):(p=typeof globalThis<"u"?globalThis:p||self,m(p.AbnOsmVue={},p.VueDemi,p.L,p.Vue))})(this,function(p,m,b,d){"use strict";const x={osm:{url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',maxZoom:19}},"osm-hot":{url:"https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Tiles style by <a href="https://www.hotosm.org/" target="_blank">Humanitarian OpenStreetMap Team</a>',maxZoom:19}},"carto-light":{url:"https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',subdomains:"abcd",maxZoom:20}},"carto-dark":{url:"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',subdomains:"abcd",maxZoom:20}},"esri-satellite":{url:"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",options:{attribution:"Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community",maxZoom:18}},"stadia-alidade":{url:"https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://stadiamaps.com/">Stadia Maps</a>, © <a href="https://openmaptiles.org/">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',maxZoom:20}},"carto-voyager":{url:"https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",options:{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',subdomains:"abcd",maxZoom:20}},opentopomap:{url:"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",options:{attribution:'Map data: © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="https://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)',maxZoom:17}}},v={grayscale:"grayscale(100%)",invert:"invert(100%)",sepia:"sepia(100%)"};function $(){function e(t,r,o,n){let a,l={};if(r)a=r,l={...o};else{const i=x[t]||x.osm;a=i.url,l={...i.options,...o}}const c=b.tileLayer(a,l);if(n){const i=v[n]||n;c.on("tileload",u=>{u.tile.style.filter=i})}return c}return{createTileLayer:e}}function L(){const e=[];function t(a,l,c){if(!a)return null;const i=l||[32,32],u=c||[i[0]/2,i[1]];return b.icon({iconUrl:a,iconSize:i,iconAnchor:u,popupAnchor:[0,-u[1]]})}function r(a,l,c,i,u,w,f,k){const h=t(i,u,w),y=h?{icon:h}:{},S=b.marker([l,c],y).addTo(a);return f&&S.bindPopup(f),S.on("click",O=>{k({latlng:O.latlng})}),S}function o(a,{lat:l,lng:c,icon:i,iconSize:u,iconAnchor:w,popup:f}={}){const k=t(i,u,w),h=k?{icon:k}:{},y=b.marker([l,c],h).addTo(a);return f&&y.bindPopup(f),e.push(y),y}function n(a){e.forEach(l=>a.removeLayer(l)),e.length=0}return{createMainMarker:r,addMarker:o,clearMarkers:n}}const z={zoom:e=>{e.zoomControl||b.control.zoom().addTo(e)},scale:e=>{b.control.scale().addTo(e)},attribution:e=>{e.attributionControl||b.control.attribution().addTo(e)}};function Z(){function e(t,r){if(t.zoomControl.remove(),r!=="none"){if(r==="all"){Object.values(z).forEach(o=>o(t));return}if(r==="zoom"){z.zoom(t);return}Array.isArray(r)&&r.forEach(o=>{z[o]&&z[o](t)})}}return{applyControls:e}}function B(e){let t=null,r=null;const{createTileLayer:o}=$(),{createMainMarker:n,addMarker:a,clearMarkers:l}=L(),{applyControls:c}=Z();function i(s,g){const{lat:M,lng:_,zoom:j,minZoom:W,maxZoom:F,tileLayer:Y,tileUrl:H,tileOptions:X,tileFilter:J,showMarker:K,markerIcon:Q,markerIconSize:D,markerAnchor:ee,markerPopup:te,controls:re,draggable:oe,scrollWheelZoom:ae,doubleClickZoom:ne,attributionControl:ie}=g;t=b.map(s,{center:[M,_],zoom:j,minZoom:W,maxZoom:F,dragging:oe,scrollWheelZoom:ae,doubleClickZoom:ne,attributionControl:ie,zoomControl:!0}),o(Y,H,X,J).addTo(t),c(t,re),K&&(r=n(t,M,_,Q,D,ee,te,T=>e("marker-click",T))),t.on("click",T=>{e("click",{latlng:T.latlng,originalEvent:T.originalEvent})}),t.on("zoomend",()=>{e("zoom-change",{zoom:t.getZoom()})}),t.on("moveend",()=>{e("move-end",{center:t.getCenter()})}),e("map-ready",{map:t})}function u(){t&&(t.remove(),t=null,r=null)}function w(s,g,M){t==null||t.flyTo([s,g],M)}function f(s,g,M){t==null||t.setView([s,g],M)}function k(){return t}function h(s){return t?a(t,s):null}function y(){t&&l(t)}function S(s){t&&(r&&(t.removeLayer(r),r=null),s.showMarker&&(r=n(t,s.lat,s.lng,s.markerIcon,s.markerIconSize,s.markerAnchor,s.markerPopup,g=>e("marker-click",g))))}function O(s,g,M){t==null||t.setView([s,g],M,{animate:!1})}return{initMap:i,destroyMap:u,flyTo:w,setView:f,getLeafletMap:k,addMarker:h,clearMarkers:y,updateMarker:S,updateView:O}}const E=(e,t)=>{const r=e.__vccOpts||e;for(const[o,n]of t)r[o]=n;return r},N=m.defineComponent({name:"OsmMap",props:{lat:{type:Number,required:!0},lng:{type:Number,required:!0},zoom:{type:Number,default:13},minZoom:{type:Number,default:1},maxZoom:{type:Number,default:19},height:{type:String,default:"400px"},width:{type:String,default:"100%"},tileLayer:{type:String,default:"osm"},tileUrl:{type:String,default:null},tileOptions:{type:Object,default:()=>({})},tileFilter:{type:String,default:null},showMarker:{type:Boolean,default:!0},markerIcon:{type:String,default:null},markerIconSize:{type:Array,default:()=>[32,32]},markerAnchor:{type:Array,default:null},markerPopup:{type:String,default:null},controls:{type:[String,Array],default:"all"},draggable:{type:Boolean,default:!0},scrollWheelZoom:{type:Boolean,default:!0},doubleClickZoom:{type:Boolean,default:!0},attributionControl:{type:Boolean,default:!0}},emits:["map-ready","click","zoom-change","move-end","marker-click"],setup(e,{emit:t,expose:r}){const o=m.ref(null),{initMap:n,destroyMap:a,flyTo:l,setView:c,getLeafletMap:i,addMarker:u,clearMarkers:w,updateMarker:f,updateView:k}=B(t);m.onMounted(()=>{n(o.value,e)}),m.onBeforeUnmount(()=>{a()}),m.watch(()=>[e.lat,e.lng,e.zoom],([y,S,O])=>{k(y,S,O)}),m.watch(()=>[e.showMarker,e.markerIcon,e.markerIconSize,e.markerAnchor,e.markerPopup],()=>{f(e)});const h={flyTo:l,setView:c,getLeafletMap:i,addMarker:u,clearMarkers:w};return r&&r(h),{mapEl:o,...h}}}),I={ref:"mapEl",class:"abn-osmvue-map"},V={key:0,class:"abn-osmvue-overlay"};function P(e,t,r,o,n,a){return d.openBlock(),d.createElementBlock("div",{class:"abn-osmvue-wrapper",style:d.normalizeStyle({height:e.height,width:e.width})},[d.createElementVNode("div",I,null,512),e.$slots.overlay?(d.openBlock(),d.createElementBlock("div",V,[d.renderSlot(e.$slots,"overlay")])):d.createCommentVNode("",!0)],4)}const A=E(N,[["render",P]]),R=m.defineComponent({name:"OsmMapEmbed",props:{lat:{type:Number,required:!0},lng:{type:Number,required:!0},zoom:{type:Number,default:13},height:{type:String,default:"400px"},width:{type:String,default:"100%"},markerLat:{type:Number,default:null},markerLng:{type:Number,default:null},embedSrc:{type:String,default:null},title:{type:String,default:"Mapa"},sandbox:{type:String,default:null}},setup(e){return{iframeSrc:m.computed(()=>{if(e.embedSrc)return e.embedSrc;const r=e.markerLat??e.lat,o=e.markerLng??e.lng,n=.01*Math.pow(2,13-e.zoom),a=e.lng-n,l=e.lat-n*.6,c=e.lng+n,i=e.lat+n*.6;return`https://www.openstreetmap.org/export/embed.html?bbox=${`${a},${l},${c},${i}`}&layer=mapnik&marker=${r},${o}`})}}}),G=["src","width","height","title","sandbox"];function q(e,t,r,o,n,a){return d.openBlock(),d.createElementBlock("iframe",{src:e.iframeSrc,width:e.width,height:e.height,title:e.title,sandbox:e.sandbox||void 0,class:"abn-osmvue-embed",frameborder:"0",scrolling:"no",marginheight:"0",marginwidth:"0",allowfullscreen:""},null,8,G)}const C=E(R,[["render",q]]),U={install(e){e.component("OsmMap",A),e.component("OsmMapEmbed",C)}};p.OsmMap=A,p.OsmMapEmbed=C,p.default=U,Object.defineProperties(p,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.abn-osmvue-wrapper{position:relative;display:block}.abn-osmvue-map{width:100%;height:100%}.abn-osmvue-overlay{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1000}.abn-osmvue-overlay>*{pointer-events:auto}.abn-osmvue-embed{display:block;border:none}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { DefineComponent } from 'vue-demi'
|
|
2
|
+
import * as L from 'leaflet'
|
|
3
|
+
|
|
4
|
+
export interface OsmMapProps {
|
|
5
|
+
lat: number
|
|
6
|
+
lng: number
|
|
7
|
+
zoom?: number
|
|
8
|
+
minZoom?: number
|
|
9
|
+
maxZoom?: number
|
|
10
|
+
height?: string
|
|
11
|
+
width?: string
|
|
12
|
+
tileLayer?: 'osm' | 'osm-hot' | 'carto-light' | 'carto-dark' | 'carto-voyager' | 'opentopomap' | 'esri-satellite' | 'stadia-alidade'
|
|
13
|
+
tileUrl?: string | null
|
|
14
|
+
tileOptions?: Record<string, unknown>
|
|
15
|
+
tileFilter?: 'grayscale' | 'invert' | 'sepia' | string | null
|
|
16
|
+
showMarker?: boolean
|
|
17
|
+
markerIcon?: string | null
|
|
18
|
+
markerIconSize?: [number, number]
|
|
19
|
+
markerAnchor?: [number, number] | null
|
|
20
|
+
markerPopup?: string | null
|
|
21
|
+
controls?: 'all' | 'zoom' | 'none' | Array<'zoom' | 'scale' | 'attribution'>
|
|
22
|
+
draggable?: boolean
|
|
23
|
+
scrollWheelZoom?: boolean
|
|
24
|
+
doubleClickZoom?: boolean
|
|
25
|
+
attributionControl?: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface OsmMapEmits {
|
|
29
|
+
(e: 'map-ready', payload: { map: L.Map }): void
|
|
30
|
+
(e: 'click', payload: { latlng: L.LatLng; originalEvent: MouseEvent }): void
|
|
31
|
+
(e: 'zoom-change', payload: { zoom: number }): void
|
|
32
|
+
(e: 'move-end', payload: { center: L.LatLng }): void
|
|
33
|
+
(e: 'marker-click', payload: { latlng: L.LatLng }): void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface OsmMapExpose {
|
|
37
|
+
flyTo(lat: number, lng: number, zoom?: number): void
|
|
38
|
+
setView(lat: number, lng: number, zoom?: number): void
|
|
39
|
+
getLeafletMap(): L.Map | null
|
|
40
|
+
addMarker(options: {
|
|
41
|
+
lat: number
|
|
42
|
+
lng: number
|
|
43
|
+
icon?: string
|
|
44
|
+
iconSize?: [number, number]
|
|
45
|
+
iconAnchor?: [number, number]
|
|
46
|
+
popup?: string
|
|
47
|
+
}): L.Marker | null
|
|
48
|
+
clearMarkers(): void
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface OsmMapEmbedProps {
|
|
52
|
+
lat: number
|
|
53
|
+
lng: number
|
|
54
|
+
zoom?: number
|
|
55
|
+
height?: string
|
|
56
|
+
width?: string
|
|
57
|
+
markerLat?: number | null
|
|
58
|
+
markerLng?: number | null
|
|
59
|
+
embedSrc?: string | null
|
|
60
|
+
title?: string
|
|
61
|
+
sandbox?: string | null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export declare const OsmMap: DefineComponent<OsmMapProps>
|
|
65
|
+
export declare const OsmMapEmbed: DefineComponent<OsmMapEmbedProps>
|
|
66
|
+
|
|
67
|
+
declare const plugin: {
|
|
68
|
+
install(app: unknown): void
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default plugin
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "abn-osmvue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vue 2/Vue 3 component library for OpenStreetMap powered by Leaflet",
|
|
5
|
+
"author": "ABN",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"files": ["dist"],
|
|
8
|
+
"main": "./dist/abn-osmvue.cjs",
|
|
9
|
+
"module": "./dist/abn-osmvue.js",
|
|
10
|
+
"types": "./dist/types.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/abn-osmvue.js",
|
|
14
|
+
"require": "./dist/abn-osmvue.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./dist/style.css": "./dist/style.css"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "vite",
|
|
20
|
+
"build": "vite build && vue-demi-switch 3 && cp src/types.d.ts dist/types.d.ts",
|
|
21
|
+
"build:vue2": "vue-demi-switch 2 && vite build",
|
|
22
|
+
"preview": "vite preview"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"vue": "^2.7.0 || ^3.0.0"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"leaflet": "^1.9.0",
|
|
29
|
+
"vue-demi": "^0.14.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@vitejs/plugin-vue": "^5.0.0",
|
|
33
|
+
"vite": "^5.0.0",
|
|
34
|
+
"vite-plugin-dts": "^3.0.0",
|
|
35
|
+
"vue": "^3.4.0"
|
|
36
|
+
}
|
|
37
|
+
}
|