2

I have a map that displays a marker for every diferent public facilities in a city and I want to have a group of checkboxes to filter this facilities according to its typology, one checkbox for typology. Each typology will have multiple markers and the map will only show the checked ones.
I'm using react-leaflet v3.

This is what I tried to do:

<MapContainer center={[50,50]} zoom={13} scrollWheelZoom={true} whenCreated={setMap}>
            <TileLayer
                attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />     
            <LayersControl position='topright'>
                {typologies.map((typology, index) => (                    
                    <LayersControl.Overlay key={index} checked name={typology}>
                        {publicFacilities.filter((publicFacility) => publicFacility.typology == typology ).map((publicFacility) => (                            
                            <Marker key={publicFacility._id} position={publicFacility.coordinates} />
                        ))}  
                    </LayersControl.Overlay>
                ))}
            </LayersControl>                    
        </MapContainer> 

typologies is a list of strings and publicFacilities is a list of objects.

But with this method I get a checkbox for every single facility.

PauCasademont
  • 279
  • 4
  • 18
  • How does your data look like? `typologies` and `publicFacilities`. – kboul Feb 18 '21 at 17:49
  • `typologies` is a list of strings e.g. `["office", "sports" ... ]` and `publicFacilities` a list of objects e.g. `[ { _id: "123", name:"town hall", typology:"office", coordinates:[50,50] }, ... ]` – PauCasademont Feb 18 '21 at 18:04
  • It is [working](https://codesandbox.io/s/react-leaflet-layerscontroloverlay-with-multiple-markers-4l4sp?file=/src/App.js) for me – kboul Feb 18 '21 at 18:42
  • If you add another object in `publicFacilities` with typology = "office", then it will appear two checkboxes named office and I only want one checkbox for all the offices. – PauCasademont Feb 18 '21 at 18:47
  • This is new info for the question. You should clarify that to your post. But will it have the same markers or new ones?. If it has different markers comparing to the first you do you want to show them with a different checkbox or not? This is info you have to clarify in the question description. – kboul Feb 18 '21 at 18:48
  • It is already clarified that I only want want one checkbox for each typology. The markers are always the same ( I edited the code to put if it's easier to understand). I only want to show the facilities that its typology are marked. – PauCasademont Feb 18 '21 at 18:56

1 Answers1

1

You can use lodash groupBy to build your groups by typology.

Then use Layer Groups to have several Markers behave as an Overlay.

Something in the lines of:

const groupedByTypology = groupBy(publicFacilities, "typology");

return <LayersControl>
  {Object.keys(groupedByTypology).map(typology => (
    <LayersControl.Overlay key={typology} name={typology}>
      <LayerGroup>
        {groupedByTypology[typology].map(publicFacility => (
          <Marker key={publicFacility._id} position={publicFacility.coordinates} />
        ))}
      </LayerGroup>
    </LayersControl.Overlay>
  ))}
</LayersControl>
ghybs
  • 47,565
  • 6
  • 74
  • 99
  • Why use lodash? The LayerGroup alone will do what the original question asked. Is the performance difference with .filter() so significant that it justifies importing a new utility for this? – Sam Sep 24 '21 at 17:39
  • 1
    Hi @Sam, "_Is the performance difference with .filter() so significant_" in common cases no; it makes you walk your entire array as many times as your number of different values; whereas groupBy will do it in just 1 pass. But for few values and small array, we do not care. "_Why use lodash_" indeed it is very easy writing a groupBy equivalent with same performance. Now whether we should re-invent the wheel or rely on libraries, that is another debate. – ghybs Sep 25 '21 at 01:55