Skip to content

Agriculture-Intelligence/leaflet-editable-hook

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Leaflet Editable Hook

All Contributors

The purpose of this hook is to provide functionality for editing features on the map, such as drawing polylines, polygons, markers, rectangles, circles, and more.

Demo

https://leaflet-editable-hook.vercel.app/

Prerequisites

  • leaflet: "^1.9.4"
  • leaflet-editable: "^1.2.0"
  • react-leaflet: "^4.2.1"

Installation

Install with npm

  npm i leaflet-editable-hook

Documentation

See full documentation about Leaflet.Editable

Hook returned methods Returns Description
drawing() boolean Return true if any drawing action is ongoing.
stopDrawing() void When you need to stop any ongoing drawing, without needing to know which editor is active.
commitDrawing() void When you need to commit any ongoing drawing, without needing to know which editor is active.
startPolyline(<L.LatLng> latlng, options) L.Polyline Start drawing a Polyline. If latlng is given, a first point will be added. In any case, continuing on user click. If options is given, it will be passed to the Polyline class constructor.
startPolygon(<L.LatLng> latlng, options) L.Polygon Start drawing a Polygon. If latlng is given, a first point will be added. In any case, continuing on user click. If options is given, it will be passed to the Polygon class constructor.
startMarker(<L.LatLng> latlng, options) L.Marker Start adding a Marker. If latlng is given, the Marker will be shown first at this point. In any case, it will follow the user mouse, and will have a final latlng on next click (or touch). If options is given, it will be passed to the Marker class constructor.
startRectangle(<L.LatLng> latlng, options) L.Rectangle Start drawing a Rectangle. If latlng is given, the Rectangle anchor will be added. In any case, continuing on user drag. If options is given, it will be passed to the Rectangle class constructor.
startCircle(<L.LatLng> latlng, options) L.Circle Start drawing a Circle. If latlng is given, the Circle anchor will be added. In any case, continuing on user drag. If options is given, it will be passed to the Circle class constructor.
enableEdit(feature: L.Layer) void Enable editing, by creating an editor if not existing, and then calling enable on it.
disableEdit(feature: L.Layer) void Disable editing, also remove the editor property reference.
Events
onCreated
onEnable
onDisable
onEditing
onDragStart
onDrag
onDragEnd
onDrawingStart
onDrawingEnd
onDrawingCancel
onDrawingCommit
onDrawingMousedown
onDrawingMouseup
onDrawingClick
onDrawingMove
onDrawingClicked
onVertexNew
onVertexClick
onVertexClicked
onVertexRawclick
onVertexDeleted
onVertexCtrlclick
onVertexShiftclick
onVertexMetakeyclick
onVertexAltclick
onVertexContextmenu
onVertexMousedown
onVertexDrag
onVertexDragstart
onVertexDragend
onMiddlemarkerMousedown
onShapeNew
onShapeDelete
onShapeDeleted

Usage/Examples

import { useMap, Marker, Tooltip } from 'react-leaflet';
import { useState, useEffect } from 'react';
import * as turf from '@turf/turf';
import { useLeafletEditable } from 'leaflet-editable-hook';

function Ruler() {
  const map = useMap();
  const [ruler, setRuler] = useState(null);

  const onDrawingClicked = (e) => {
    const position = e.latlng;
    const latlngs = e.layer._latlngs;
    let length = 0;
    if (latlngs.length > 1) {
      const line = turf.lineString([...latlngs.map((item) => [item.lng, item.lat])]);
      length = turf.length(line, { units: 'kilometers' });
    }
    setRuler(<RulerMarker position={[position.lat, position.lng]} length={length} />);
  };

  const onVertexDrag = (e) => {
    const latlngs = e.layer._latlngs;
    let length = 0;
    if (latlngs.length > 1) {
      const line = turf.lineString([...latlngs.map((item) => [item.lng, item.lat])]);
      length = turf.length(line, { units: 'kilometers' });
    }
    setRuler(
      <RulerMarker
        position={[latlngs[latlngs.length - 1].lat, latlngs[latlngs.length - 1].lng]}
        length={length}
      />
    );
  };

  const { startPolyline } = useLeafletEditable({
    events: {
      onDrawingClicked,
      onVertexDrag,
    },
  });

  useEffect(() => {
    const polyline = startPolyline();
    return () => {
      map.removeLayer(polyline);
    };
  }, []);

  return ruler;
}

function RulerMarker({ position, length }) {
  return (
    <Marker
      position={position}
      icon={L.divIcon({
        html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill-opacity="0%">
            <title>circle-small</title>
            <path d="M12,10A2,2 0 0,0 10,12C10,13.11 10.9,14 12,14C13.11,14 14,13.11 14,12A2,2 0 0,0 12,10Z" />
            </svg>`,
        className: 'marker-icon',
        iconSize: [24, 24],
        popupAnchor: [0, -12],
      })}
    >
      <Tooltip permanent offset={[10, 0]} direction="right">
        {length.toFixed(3)} KM
      </Tooltip>
    </Marker>
  );
}

export default Ruler;

License

MIT

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Charles Richardson
Charles Richardson

πŸ’»
saiNaruUFL
saiNaruUFL

πŸ’»

This project follows the all-contributors specification. Contributions of any kind welcome!

About

Editable React Leaflet layers as a hook πŸƒπŸ—ΊοΈπŸͺ

Topics

Resources

License

Stars

Watchers

Forks

Languages

  • JavaScript 100.0%