Leaflet.hotline icon indicating copy to clipboard operation
Leaflet.hotline copied to clipboard

Support for React

Open luisjose24 opened this issue 4 years ago • 8 comments

Is it possible to add this plugin to react-leaflet?

luisjose24 avatar Oct 08 '20 22:10 luisjose24

This plugin is not supported anymore. It's best to just fork it.

klaftertief avatar Oct 09 '20 07:10 klaftertief

As it might be helpful for @luisjose24 and some others: Thats how I used leaflet-hotline with react-leaflet.

import { useMap } from "react-leaflet";
import L from "leaflet";

interface Props {
  data: number[][];
}

/**
 * Renderes a path on the map for the passed geojson file
 * that changes color according to the elevation.
 *
 * https://github.com/iosphere/Leaflet.hotline/
 */
export const ColoredPath: React.FC<Props> = (props: Props) => {
  const map = useMap();
  
  useEffect(() => {
    L.hotline(data, {
      // my options
    }).addTo(map);

    return () => {
      // To avoid having the path drawn twice on the map in some edge cases:
      map.remove();
    };
  }, []);

  return null;
};

leaflet-hotline.d.ts

import * as L from "leaflet";

declare module "leaflet" {
  export function hotline(data: number[][], options: any): any;
}

Then you can just use <ColoredPath data={data}/> within your react-leaflet map component.

Even though this repo is not supported for a long time now it works like a charm. I did not find anything more up to date.

lud-hu avatar Sep 13 '21 16:09 lud-hu

For anyone still looking in 2022, here is a way to pretty easily incorporate the hotline package with react-leaflet.

hotline.jsx import { createPathComponent } from "@react-leaflet/core" import L from "leaflet-hotline"

export const Hotline = createPathComponent(
  function createPolyline({ positions, ...options }, ctx) {
    const Hotline = L.hotline

    const instance = new Hotline(positions, options)
    return { instance, context: { ...ctx, overlayContainer: instance } }
  },
  function updatePolyline(layer, props, prevProps) {
    if (props.positions !== prevProps.positions) {
      layer.setLatLngs(props.positions)
    }
  }
)

Then you can just import it the same as you would a react-leaflet component import { Hotline } from "hotline"

stapleton524 avatar Apr 05 '22 19:04 stapleton524

Hi @stapleton524 ,

did you use this approach with react-leaflet v4? I can't get it to work right now. I just get a is not a constructor error...

lud-hu avatar Oct 03 '22 09:10 lud-hu

Hi @lud-hu,

I believe I was using react-leaflet v3 (3.2.2 specifically) when I was working on it. If it is possible to downgrade then that may help.

stapleton524 avatar Oct 03 '22 20:10 stapleton524

Thanks! I didn't get it to work with v4. But I've now ported it and wrapped it into a separate npm package for easy usage: https://www.npmjs.com/package/leaflet-hotline-react

lud-hu avatar Oct 06 '22 05:10 lud-hu

Hi, I managed to get it working with v4.

import React from "react"
import L from "leaflet"
import {
  createElementObject,
  createPathComponent,
  extendContext,
} from "@react-leaflet/core"
require("leaflet-hotline")

const HotlinePath = createPathComponent(createHotlinePath, updateHotlinePath)
function createHotlinePath(props, context) {
  const instance = L.hotline(props.positions, props.options)
  return createElementObject(instance, extendContext(context, { overlayContainer: instance }))
}
function updateHotlinePath(instance, props, prevProps) {
  if (props.center !== prevProps.center || props.size !== prevProps.size) {
    instance.setBounds(getBounds(props))
  }
  if (props.positions !== prevProps.positions || props.options !== prevProps.options) {
    instance.setLatLngs(props.positions)
  }
}
function getBounds(props) {
  return L.latLng(props.center).toBounds(props.size)
}

After that you can use it as usual with react. This also enables you to add a Tooltip and updates to the path.

<HotlinePath positions={<your_positions>} options={<hotline_options>}><tooltip_here></HotlinePath>

siimkas avatar Jul 28 '23 11:07 siimkas

For anyone stumbling across this, I have made a react package: https://github.com/peacefulotter/react-leaflet-hotline Docs and playground accessible at: https://react-leaflet-hotline.netlify.app/ Feel free to file an issue if you encounter one - I am planning to maintain the package! Also, a star is always welcome :pray:

peacefulotter avatar Mar 24 '24 13:03 peacefulotter