Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a custom Leaflet layer control in React

I'm attempting to completely recreate or reorganize the functionality of the LayersControl component in its own separate panel using react-leaflet.

I have several filtered into their own and it works fine, but I'd like to customize the look and location of the Control element.

I've hosted the current version of my Leaflet app on github pages here. You can see the control on the right, which is the basic Leaflet control, but I'd like to the Icon on the left (the layers icon) to accomplish the same thing instead with custom react components.

Just wondering if anyone can point me in the right direction to beginning to accomplish this!

This is my current render for my react-leaflet map:

render() {

      const types = [...new Set(data.map(loc => loc.type))];

      const group = types.map(type =>
        data.filter(loc => loc.type === type)
        .map(({id, lat, lng, name}) =>
          <LayersControl.Overlay name={startCase(toLower(type))}>
            <LayerGroup>
            <Marker key={id} position={[lat, lng]} icon=
              {locationIcon}>
              <Tooltip permanent direction="bottom" opacity={.6}>
                  {name}
              </Tooltip>
          </Marker>
            </LayerGroup>
          </LayersControl.Overlay>
          ));

      return (
        <>
        <ControlPanel />
        <Map
        zoomControl={false}
        center={this.state.center}
        zoom={this.state.zoom}
        maxBounds={this.state.maxBounds}
        maxZoom={10}
        >
          <LayersControl>
            <TileLayer
              url='https://cartocdn-gusc.global.ssl.fastly.net//ramirocartodb/api/v1/map/named/tpl_756aec63_3adb_48b6_9d14_331c6cbc47cf/all/{z}/{x}/{y}.png'
            />
            <ZoomControl position="topright" />
           {group}
          </LayersControl>
        </Map>
        </>
      );
    }
like image 425
geeberry Avatar asked Oct 15 '25 18:10

geeberry


1 Answers

So theres still a few bugs in this but i've managed get most of the way (self taught react) using material UI as an example, can be seen in this sandbox link:

https://codesandbox.io/embed/competent-edison-wt5pl?fontsize=14

The general bassis is that we extend MapControl which means we have to define createLeafletElement, this has to return a generic leaflet (not react) control from the original javascript leaflet package. Essentially making a div with the domutil provided by leaflet and then portaling our react components through that div with react portals.

Again with another class extension we extend some of the classes provided by react-leaflet for layers, i pulled it out and just made a generic layer that you could define a group for, that way you could render any layer (polygon, baselayer etc) and specify the group to tell it where to go in the layer control i.e no need for specific components or overlays. As we are extending the class we need implement and pass down the methods we want to use, like addLayer, remove layer etc. During these implementations i've just added them to state to track what layers are active and such.

Not sure if there are better practices throughout everything i've implemented but this is definitely a start, hopefully in the right direction.

Bugs - The first layer in each group won't turn on correctly without the 2nd item ticked, something to do with state i think but didn't have the time to track it down

like image 159
Dylan Zemek Avatar answered Oct 17 '25 09:10

Dylan Zemek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!