nuxt-modules / leaflet

A Nuxt module to use Leaflet
https://leaflet.nuxtjs.org/
Apache License 2.0
115 stars 3 forks source link

Add support for Leaflet.draw #13

Closed egemenozkan closed 4 months ago

egemenozkan commented 6 months ago

Hello, Could you lead me to how to use leaflet draw with Nuxt-Leaflet ? Thank you in advance.

https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw

Gugustinette commented 5 months ago

I tried a few different ways, best thing I have so far is this :

<template>
  <div style="height:100vh; width:100vw">
    <ClientOnly>
      <!-- Load Leaflet Draw from cdn -->
      <link
        rel="stylesheet"
        href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"
      >
      <Script
        async
        src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"
      />
      <LMap
        ref="map"
        :zoom="6"
        :max-zoom="18"
        :center="[47.21322, -1.559482]"
        @ready="mapInitialized"
      >
        <LTileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution="&amp;copy; <a href=&quot;https://www.openstreetmap.org/&quot;>OpenStreetMap</a> contributors"
          layer-type="base"
          name="OpenStreetMap"
        />
      </LMap>
    </ClientOnly>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const map = ref(null)

// When the map is ready
const mapInitialized = () => {
  // Init the draw control
  // See https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw-feature
  const drawnItems = new L.FeatureGroup();
  map.value.leafletObject.addLayer(drawnItems);
  const drawControl = new L.Control.Draw({
      edit: {
          featureGroup: drawnItems
      }
  });
  map.value.leafletObject.addControl(drawControl);
}
</script>

But this is pretty bad honestly, seems like it work randomly depending on the order in which JS code is being executed. If leaflet-draw is loaded before the map, it works. Otherwise it throws an error.

I'm sure we can build better Nuxt magic here. 😕

Gugustinette commented 5 months ago

@egemenozkan Something like this should be more stable :

<template>
  <div style="height:100vh; width:100vw">
    <!-- Load Leaflet Draw CSS from cdn -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"
    >
    <LMap
      ref="map"
      :zoom="6"
      :max-zoom="18"
      :center="[47.21322, -1.559482]"
      @ready="mapInitialized"
    >
      <LTileLayer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        attribution="&amp;copy; <a href=&quot;https://www.openstreetmap.org/&quot;>OpenStreetMap</a> contributors"
        layer-type="base"
        name="OpenStreetMap"
      />
    </LMap>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const map = ref(null)

// When the map is ready
const mapInitialized = () => {
  // Load the Leaflet Draw script
  const script = document.createElement('script');
  script.src = 'https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js';
  script.async = true;
  // When it is loaded
  script.onload = () => {
    // Init the draw control
    // See https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw-feature
    const drawnItems = new L.FeatureGroup();
    map.value.leafletObject.addLayer(drawnItems);
    const drawControl = new L.Control.Draw({
        edit: {
            featureGroup: drawnItems
        }
    });
    map.value.leafletObject.addControl(drawControl);
  };
  // Append the script element to the DOM
  document.head.appendChild(script);
}
</script>
Gugustinette commented 4 months ago

So apparently, Leaflet.draw is not maintained anymore :

Which explains why it is such a mess to configure with modern tools. I tried many things but I can't make it work in a stable way.

Unless Leaflet.Draw is somehow revived, we won't support it. However, Leaflet-Geoman seems like a pretty decent alternative we should support : https://github.com/Gugustinette/Nuxt-Leaflet/issues/20 The Leaflet.Draw documentation will remain with a warning saying it is deprecated, and a redirection to Leaflet-Geoman.