Raruto / leaflet-rotate

Leaflet plugin that allows to add rotation functionality to map tiles
GNU General Public License v3.0
81 stars 23 forks source link

Vue 3 integration #39

Closed DSoftwareArtist closed 1 year ago

DSoftwareArtist commented 1 year ago

Is there any idea how can I implement this on Vue 3? @Raruto

Raruto commented 1 year ago

Hi Reamon,

it's not mandatory to bundle vendor files within your app.

Just in case, it could be something like the following:

// vendors
import L from 'leaflet';
import 'leaflet-rotate';

// app
var map = L.map('map', {
  center: [55, 10],
  zoom: 2,
  rotate: true,
  ...
});

👋 Raruto

DSoftwareArtist commented 1 year ago

@Raruto , I tried to translate this example into Vue 3 component. The map is loading but I got error in accessing the rotate method L.Rotate.debug(map) . Here's my TestMap.vue:

<template>
  <div id="map" style="height: 400px;"></div>
</template>

<script>
import { ref, onMounted } from 'vue'
import L from 'leaflet'
import 'leaflet-rotate'

export default {
  name: 'LeafletMap',
  setup () {
    const mapContainer = ref(null)

    onMounted(() => {
      const esri = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        id: 'mapbox.streets',
        maxZoom: 24,
        maxNativeZoom: 18,
        attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
      })
      const map = L.map('map', {
        center: [55, 10],
        zoom: 2,
        layers: [esri],
        worldCopyJump: true,
        rotate: true,
        rotateControl: {
          closeOnZeroBearing: false,
          position: 'bottomleft'
        },
        touchRotate: true
      })

      const places = {
        Kyiv: [50.5, 30.5],
        London: [51.51, -0.12],
        SanFrancisco: [37.77, -122.42],
        Washington: [38.91, -77.04],
        Trondheim: [63.41, 10.41]
      }
      const markers = []
      const markerIcon = L.icon({
        iconUrl: 'location.png',
        iconSize: [80, 80],
        iconAnchor: [40, 54]
      })
      const loremIpsum = '<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.</p><p>Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque.</p>'
      for (const i in places) {
        markers.push(L.marker(places[i], { draggable: true, icon: markerIcon }).bindPopup(
          '<b>' + i + '</b><br>' + loremIpsum).bindTooltip('<b>' + i + '</b>',
          markers.length ? {} : {
            direction: 'right',
            permanent: true
          }
        ).addTo(map))
      }
      L.circle([53, 4], 111111)
        .addTo(map)

      L.polygon([
        [48, -3],
        [50, -4],
        [52, 4]
      ]).addTo(map)

      L.rectangle([
        [60.81123, 25.71632],
        [60.81028, 25.73166],
        [60.7997, 25.72892],
        [60.80061, 25.71362]
      ]).addTo(map)

      console.log(L)
      // Display some debug info
      L.Rotate.debug(map) // <- I got some problem in here
    })

    return {
      mapContainer
    }
  }
}
</script>

Screenshot from 2023-08-29 15-52-45

Here's my package.json

{
  ...
  "dependencies": {
    ...
    "leaflet": "^1.9.3",
    "leaflet-rotate": "^0.2.8"
  },
  "devDependencies": {
    ...
    "leaflet": "^1.9.3"
  }
}

Do I missed something on my setup?

I also can't seem to find the Rotate method from the L object.

Screenshot from 2023-08-29 16-04-38

Raruto commented 1 year ago

Probably the L variable must be globally available, eg:

import L from 'leaflet';

globalThis.L = L; // you may also try: `window.L = L;`

...

import 'leaflet-rotate';

...

var map = L.map('map', {
  center: [55, 10],
  zoom: 2,
  rotate: true,
  ...
});

For more info:

👋 Raruto

DSoftwareArtist commented 1 year ago

@Raruto I tried it but it don't worked 😞 . I also cleared my browser cache but still no luck.

Raruto commented 1 year ago

I tried to translate this example into Vue 3 component. The map is loading but I got error in accessing the rotate method L.Rotate.debug(map):

import L from 'leaflet'
import 'leaflet-rotate'

...

// Display some debug info
L.Rotate.debug(map) // <- I got some problem in here

That file is not included in the full leaflet-rotate bundle:

https://github.com/Raruto/leaflet-rotate/blob/48e97a6408df7796b3e06e6d8eb0729eb504b1be/examples/leaflet-rotate.html#L20

If you want to do some debugging, you have to include it manually.

More or less like the following:

import 'leaflet-rotate';
import 'leaflet-rotate/lib/debug.js';

or

import './node_modules/leaflet-rotate/dist/leaflet-rotate-src.js';
import './node_modules/leaflet-rotate/lib/debug.js'

👋 Raruto

DSoftwareArtist commented 1 year ago

It worked! 🙇🏻

Thank you so much.

Raruto commented 1 year ago

@DSoftwareArtist ok, but please upload your final code so it will be easier for others to understand later

DSoftwareArtist commented 1 year ago

Working code:

<template>
  <div id="map" style="height: 400px;"></div>
</template>

<script>
import { ref, onMounted } from 'vue'
import L from 'leaflet'
import 'leaflet-rotate'
import 'leaflet-rotate/lib/debug.js'

export default {
  name: 'LeafletMap',
  setup () {
    const mapContainer = ref(null)

    onMounted(() => {
      const esri = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        id: 'mapbox.streets',
        maxZoom: 24,
        maxNativeZoom: 18,
        attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
      })
      const map = L.map('map', {
        center: [55, 10],
        zoom: 2,
        layers: [esri],
        worldCopyJump: true,
        rotate: true,
        rotateControl: {
          closeOnZeroBearing: false,
          position: 'bottomleft'
        },
        touchRotate: true
      })

      const places = {
        Kyiv: [50.5, 30.5],
        London: [51.51, -0.12],
        SanFrancisco: [37.77, -122.42],
        Washington: [38.91, -77.04],
        Trondheim: [63.41, 10.41]
      }
      const markers = []
      const markerIcon = L.icon({
        iconUrl: 'your-icon.png',
        iconSize: [80, 80],
        iconAnchor: [40, 54]
      })
      const loremIpsum = '<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.</p><p>Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque.</p>'
      for (const i in places) {
        markers.push(L.marker(places[i], { draggable: true, icon: markerIcon }).bindPopup(
          '<b>' + i + '</b><br>' + loremIpsum).bindTooltip('<b>' + i + '</b>',
          markers.length ? {} : {
            direction: 'right',
            permanent: true
          }
        ).addTo(map))
      }
      L.circle([53, 4], 111111)
        .addTo(map)

      L.polygon([
        [48, -3],
        [50, -4],
        [52, 4]
      ]).addTo(map)

      L.rectangle([
        [60.81123, 25.71632],
        [60.81028, 25.73166],
        [60.7997, 25.72892],
        [60.80061, 25.71362]
      ]).addTo(map)

      L.Rotate.debug(map)
    })

    return {
      mapContainer
    }
  }
}
</script>