Reputation: 1926
Are there any resources showing a search box implementation with react-leaflet?
I'd like to have my map pins populate upon a search result that would query and retrieve my existing data.
ie:
const names = [
{name: 'Joe', location: '40.734621, -73.989341 '},
{name: 'Seth', location: '45.77621, -73.789654 '},
]
Then, after searching for Joe or Seth, the map would populate with the location coordinates.
I found examples for leaflet.js but couldn't find any examples spun with react-leaflet.
Upvotes: 7
Views: 14031
Reputation: 227
Solution That Worked while Using MapContainer. Leaflet.GeoSearch
npm i leaflet-geosearch
The Use the following the code.
import { useEffect } from "react";
// Search Location
import { GeoSearchControl, OpenStreetMapProvider } from "leaflet-geosearch";
import { useMap, MapContainer } from "react-leaflet";
/**
* Search Location
*/
const SearchLocation = (props) => {
// Get access to leaflet map
const { provider } = props;
// Get search control
const searchControl = new GeoSearchControl({
provider: provider,
});
// Access Leaflet Map
const map = useMap(props);
useEffect(() => {
// Add searchControl to Leaflet map
map.addControl(searchControl);
return () => map.removeControl(searchControl);
});
return null; // Do not render any thing
}
// Call SearchLocation in MyMap
const MyMap = () => {
// ...
return (
<MapContainer>
<SearchLocation provider={new OpenStreetMapProvider()} />
{/* ... */}
</MapContainer>
);
};
Upvotes: 1
Reputation: 41
import { Map} from 'react-leaflet'
import { OpenStreetMapProvider, GeoSearchControl } from 'leaflet-geosearch'
// make new leaflet element
const Search = (props) => {
const map = useMap() // access to leaflet map
const { provider } = props
useEffect(() => {
const searchControl = new GeoSearchControl({
provider,
})
map.addControl(searchControl) // this is how you add a control in vanilla leaflet
return () => map.removeControl(searchControl)
}, [props])
return null // don't want anything to show up from this comp
}
export default function Map() {
return (
<MapContainer {...otherProps}>
{...otherChildren}
<Search provider={new OpenStreetMapProvider()} />
</MapContainer >
)
}
This is if you are using MapContainer instead of map
Upvotes: 4
Reputation: 6027
I think I found a much easier way of doing this without needing to create and extend a class.
import { Map, useLeaflet } from 'react-leaflet'
import { OpenStreetMapProvider, GeoSearchControl } from 'leaflet-geosearch'
// make new leaflet element
const Search = (props) => {
const { map } = useLeaflet() // access to leaflet map
const { provider } = props
useEffect(() => {
const searchControl = new GeoSearchControl({
provider,
})
map.addControl(searchControl) // this is how you add a control in vanilla leaflet
return () => map.removeControl(searchControl)
}, [props])
return null // don't want anything to show up from this comp
}
export default function Map() {
return (
<Map {...otherProps}>
{...otherChildren}
<Search provider={new OpenStreetMapProvider()} />
</Map>
)
}
Upvotes: 7
Reputation: 2311
Take a look at leaflet-geosearch
Install it with npm install --save leaflet-geosearch
Then you just need to build a component with it:
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';
class Search extends MapControl {
createLeafletElement() {
return GeoSearchControl({
provider: new OpenStreetMapProvider(),
style: 'bar',
showMarker: true,
showPopup: false,
autoClose: true,
retainZoomLevel: false,
animateZoom: true,
keepResult: false,
searchLabel: 'search'
});
}
}
export default Search;
And use your component in your Map:
render() {
return (
<Map>
(...)
<Search />
</Map>
);
}
Upvotes: 7