Unverified Commit d2086316 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera Committed by GitHub
Browse files

Merge pull request #71 from vue-leaflet/l-grid-layer

L grid layer
parents ec27bfb6 4af9d12b
Loading
Loading
Loading
Loading
+89 −0
Original line number Diff line number Diff line
<script>
import { onMounted, onUnmounted, ref, inject, nextTick, h, render } from "vue";
import { remapEvents, propsBinder } from "../utils.js";
import {
  props as gridLayerProps,
  setup as gridLayerSetup,
} from "../functions/gridLayer";

export default {
  props: {
    ...gridLayerProps,
    childRender: {
      type: Function,
      required: true,
    },
  },
  setup(props, context) {
    const leafletRef = ref({});
    const tileComponents = ref({});
    const root = ref(null);
    const ready = ref(false);

    const addLayer = inject("addLayer");

    const { options, methods } = gridLayerSetup(props, leafletRef);

    onMounted(async () => {
      const { GridLayer, DomEvent, DomUtil } = await import(
        "leaflet/dist/leaflet-src.esm"
      );

      methods.onUnload = (e) => {
        const key = leafletRef.value._tileCoordsToKey(e.coords);
        if (tileComponents[key]) {
          tileComponents[key].innerHTML = "";
          tileComponents[key] = undefined;
        }
      };

      methods.setTileComponent = () => {
        leafletRef.value.redraw();
      };

      const GLayer = GridLayer.extend({
        createTile(coords) {
          const key = leafletRef.value._tileCoordsToKey(coords);
          tileComponents[key] = DomUtil.create("div");

          let vNode = h(
            { setup: props.childRender, props: ["coords"] },
            { coords }
          );
          render(vNode, tileComponents[key]);

          return tileComponents[key];
        },
      });

      leafletRef.value = new GLayer(options);

      const listeners = remapEvents(context.attrs);
      DomEvent.on(leafletRef.value, listeners);

      leafletRef.value.on("tileunload", methods.onUnload);

      propsBinder(methods, leafletRef.value, props);
      addLayer({
        ...props,
        ...methods,
        leafletObject: leafletRef.value,
      });
      ready.value = true;
      nextTick(() => context.emit("ready", leafletRef.value));
    });

    onUnmounted(() => {
      leafletRef.value.off("tileunload", methods.unLoad);
    });

    return { root, ready, leafletObject: leafletRef };
  },
  render() {
    if (this.ready) {
      return h("div", { style: { display: "none" }, ref: "root" });
    }
    return null;
  },
};
</script>
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ export { default as LControlScale } from "./LControlScale.vue";
export { default as LControlZoom } from "./LControlZoom.vue";
export { default as LFeatureGroup } from "./LFeatureGroup.vue";
export { default as LGeoJson } from "./LGeoJson.vue";
export { default as LGridLayer } from "./LGridLayer.vue";
export { default as LIcon } from "./LIcon.vue";
export { default as LLayerGroup } from "./LLayerGroup.vue";
export { default as LMap } from "./LMap.vue";
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
  <div class="main-wrapper">
    <div class="menu">
      <router-link to="/">Home</router-link>
      <router-link to="/grid-layer">GridLayer</router-link>
      <router-link to="/feature-group">Feature Group</router-link>
      <router-link to="/circle">Circle</router-link>
      <router-link to="/circle-marker">CircleMarker</router-link>
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import Home from "./views/Home.vue";

const routes = [
  { path: "/", component: Home },
  { path: "/grid-layer", component: () => import("./views/GridLayer.vue") },
  {
    path: "/feature-group",
    component: () => import("./views/FeatureGroup.vue"),
+34 −0
Original line number Diff line number Diff line
<template>
  <l-map ref="map" v-model:zoom="zoom" :center="[47.41322, -1.219482]">
    <l-tile-layer
      url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    ></l-tile-layer>
    <l-grid-layer :child-render="childRender"></l-grid-layer>
  </l-map>
</template>
<script>
import { h } from "vue";
import { LMap, LTileLayer, LGridLayer } from "./../../components";

export default {
  components: {
    LMap,
    LTileLayer,
    LGridLayer,
  },
  data() {
    return {
      zoom: 2,
      childRender: (props) => () => {
        return h(
          "div",
          { style: "border: 1px solid grey; height: 100%;" },
          `x: ${props.coords.x} y: ${props.coords.y} z: ${props.coords.z}`
        );
      },
    };
  },
};
</script>

<style></style>