react-leaflet#Map JavaScript Examples
The following examples show how to use
react-leaflet#Map.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: App.answer.js From launchtime-workshop with MIT License | 6 votes |
function App() {
return (
<Layout>
{ /**
* @lesson-02-answer Exercise 2
* After importing our Map and TileLayer components,
* we set up the position we want our Map to center on
* as well as our default zoom level. With our map, we
* can add our TileLayer where we load OpenStreetMap
* for our basemap.
*/ }
<Map center={[38.907132, -77.036546]} zoom={12}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution="© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
/>
</Map>
</Layout>
);
}
Example #2
Source File: AddGeoJSON.js From react-sample-projects with MIT License | 6 votes |
AddGeoJSON = () => {
const mapRef = useRef();
useEffect(() => {
const { current = {} } = mapRef;
const { leafletElement: map } = current;
if (!map) return;
const parkGeojson = new L.GeoJSON(nationalParks, {
onEachFeature: (feature = {}, layer) => {
const { properties = {} } = feature;
const { Name } = properties;
layer.bindPopup(`<p>${Name}</p>`);
},
});
parkGeojson.addTo(map);
return () => {};
}, [mapRef]);
return (
<Map ref={mapRef} center={[39.5, -98.35]} zoom={5}>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
</Map>
);
}
Example #3
Source File: MapView.js From resilience-app with GNU General Public License v3.0 | 6 votes |
function MapView(props) {
const position = [props.values.lat, props.values.long];
return (
<Map center={position} zoom={15} style={MapStyle} className="data-test-leaflet-mapview">
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
<Marker position={position}>
<Popup>Start from here</Popup>
</Marker>
</Map>
);
}
Example #4
Source File: ViewMap.jsx From real-estate-site with MIT License | 6 votes |
render() {
if (this.state.updated) {
const position = [this.props.lat, this.props.lon];
return (
<Map
center={position}
zoom={this.state.zoom}
style={{ height: "400px" }}
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>{this.props.pointer}</Popup>
</Marker>
</Map>
);
} else {
return <h4>Loading Map. Please wait.</h4>;
}
}
Example #5
Source File: index.js From freemeals.uk with MIT License | 6 votes |
function ProviderMap({ mapProps, markers }) {
return (
<MapContainer>
<div>
<Map
center={mapProps.coords}
zoom={mapProps.zoom}
className="leaflet-map"
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{markers}
</Map>
</div>
</MapContainer>
);
}
Example #6
Source File: MyMap.js From viade_en1b with MIT License | 5 votes |
myMap = (center, positions, style) => {
return (
<div
data-testid="mymap-container"
//id="mapContainer"
className={style ? style : "leaflet-container"}
>
<Map
data-testid="mymap-map"
zoomControl={false}
center={center}
zoom={14}
>
<LayersControl position="topleft">
<LayersControl.BaseLayer
checked="false"
name="OpenStreetMap.BlackAndWhite"
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png"
/>
</LayersControl.BaseLayer>
<LayersControl.BaseLayer checked="true" name="OpenStreetMap.Mapnik">
<TileLayer
data-testid="mymap-tilelayer"
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
</LayersControl.BaseLayer>
<FullScreenControl position="topright"></FullScreenControl>
</LayersControl>
<Polyline
data-testid="mymap-polyline"
color={"var(--color-primary)"}
positions={positions}
></Polyline>
</Map>
</div>
);
}
Example #7
Source File: Maps.js From covidAnalytics with MIT License | 5 votes |
render() {
return (
<div className="cardContainer">
<Card>
<CardBody>
<CardTitle tag="h4" className=" mb-2 mb-xl-2 font-weight-bold">
Mapa Rio Grande do Sul
</CardTitle>
</CardBody>
<Map center={center} zoom={7} maxZoom={9}>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<MarkerClusterGroup>
{array_obj_confirmed.map(({lat, lng, nome, confirmed, pop_estimada, data}, index) => (
<Marker position={[lat, lng]} key={index} icon={new L.NumberedDivIcon({number: confirmed})} attribution="confirmed" >
<Popup minWidth={250}>
<div className="popUp-container">
<div className="popUp-title">{nome}</div>
<div className="popUp-body">
<ul>
<li><FontAwesomeIcon icon={faVirus}/> Casos confirmados: {confirmed}</li>
<li><FontAwesomeIcon icon={faUser}/> População Estimada 2019: {pop_estimada}</li>
<li><FontAwesomeIcon icon={faCalendar}/> Data da ultima atualização: {data}</li>
</ul>
</div>
</div>
</Popup>
</Marker>
))}
</MarkerClusterGroup>
</Map>
</Card>
</div>
);
}
Example #8
Source File: MapComponent.jsx From Website with MIT License | 5 votes |
export default function TestMap() {
const click = (e) => {
console.info(e.latlng);
};
const [allExhibitors, setAllExhibitors] = useState([]);
const [searchedExhibitors, setSearchedExhibitors] = useState([]);
useEffect(() => {
const loadExhibitors = async () => {
if (allExhibitors.length > 0) return;
const response = await fetch(
"https://p18.jexpo.se/larv/exhibitors?getAttributes=true&filter=[%22workspace:2020%22,%22published:true%22]",
);
if (response.ok) {
const json = await response.json();
const sorted = json.results.sort((a, b) => {
return a.name.toUpperCase() > b.name.toUpperCase() ? 1 : -1;
});
setAllExhibitors(sorted);
//TEMP
const placedExhibitors = sorted.filter((e) => {
return e?.profile?.booth;
});
setSearchedExhibitors(placedExhibitors);
} else {
alert("Fetching exhibitors error");
}
};
loadExhibitors();
}, [allExhibitors.length]);
const getCoordinates = (booth) => {
const c = coordinates[booth];
const ca = [c.lat, c.lng];
return ca;
};
return (
<Map center={[65.617721, 22.14452]} zoom={18} onClick={click} maxZoom={21}>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<ImageOverlay
url={fairArea}
bounds={[
[65.618571, 22.1426872],
[65.616855, 22.145657],
]}
/>
{searchedExhibitors.map((exhibitor) => (
<Marker
key={exhibitor.id}
position={getCoordinates(exhibitor.profile.booth)}
icon={transparentIcon}
>
<Popup>{exhibitor.name}</Popup>
</Marker>
))}
</Map>
);
}
Example #9
Source File: MapGeojsonMarkers.jsx From Zulu with MIT License | 5 votes |
render() {
var center = [this.state.lat, this.state.lng];
const basemapsDict = {
dark: " https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png",
osm: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
hot: "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
}
return (
<Map zoom={this.state.zoom} center={center}>
<div className="leaflet-bottom leaflet-right buttons-container">
<Container>
<Fab
color="primary"
aria-label="edit"
tooltip="Add a new story!"
onClick={this.showModal}>
<FaPlus />
</Fab>
</Container>
</div>
{
<Modal position={[this.state.lat, this.state.lng]} show={this.state.showModal} onHide={this.closeModal.bind(this)}>
<form onSubmit={this.handleSubmit}>
<h3> Add your Story. </h3>
<label>
<br />
Title:
<br />
<input name="storyTitle" type="text" defaultValue={this.state.storyTitle} onChange={this.handleChange} />
<br />
</label>
<label>
<br />
Body:<br />
<textarea name="storyBody" defaultValue={this.state.storyBody} onChange={this.handleChange} />
<br />
</label>
<label>
<br />
Add a photo: (optional) <br />
<input type="file" style={{ marginRight: "-95px" }} ref={this.fileInput} />
<br />
</label>
<br />
<br />
<input type="submit" value="Submit" />
</form>
</Modal>}
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url={basemapsDict[this.state.basemap]}
/>
<Basemap basemap={this.state.basemap} onChange={this.onBMChange} />
<GeojsonLayer lat={center[0]} lng={center[1]} maxDist={5000} cluster={true} />
<GeoWikipediaLayer lat={center[0]} lng={center[1]} maxDist={5000} cluster={true} />
<Marker position={center} icon={MyLocationIcon}>
<Popup>
<div>Your Location - latitude: {Number(this.state.lat).toFixed(4)} - longitude: {Number(this.state.lng).toFixed(4)}</div>
</Popup>
</Marker>
</Map>
);
}
Example #10
Source File: App.answer.js From launchtime-workshop with MIT License | 5 votes |
function App() {
/**
* @lesson-04-answer
* When working between Leaflet and React Leaflet, some
* collisions occur which we need to iron out by adding
* a fix correct the location of our Marker images
* See https://github.com/PaulLeCam/react-leaflet/issues/453#issuecomment-410450387
*/
useEffect(() => {
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: require( 'leaflet/dist/images/marker-icon-2x.png' ),
iconUrl: require( 'leaflet/dist/images/marker-icon.png' ),
shadowUrl: require( 'leaflet/dist/images/marker-shadow.png' ),
});
}, []);
return (
<Layout>
<Map center={[38.907132, -77.036546]} zoom={12}>
<TileLayer
url={`https://api.mapbox.com/styles/v1/${MAPBOX_USERID}/${MAPBOX_STYLEID}/tiles/256/{z}/{x}/{y}@2x?access_token=${MAPBOX_API_KEY}`}
attribution="Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>"
/>
{ /**
* @lesson-04-answer
* Using the Marker and Popup component, we can both
* add a new Marker to the location we choose to show
* a specific location and attach a Popup to that Marker
* so we can add some context to the Marker.
*/ }
<Marker position={[38.888369, -77.019900]}>
<Popup>Smithsonian National Air and Space Museum</Popup>
</Marker>
</Map>
</Layout>
);
}
Example #11
Source File: MapView.jsx From resilience-app with GNU General Public License v3.0 | 5 votes |
Overview = ({ currentMission, missions, org, setSelectedMission, volunteers }) => {
const classes = useStyles();
const position = { lat: org.location?.lat, lng: org.location?.lng };
const [viewport, setViewport] = useState({
center: position,
zoom: 12,
});
let filtered = missions?.filter((mission) => {
return mission?.deliveryLocation?.lat && mission?.deliveryLocation?.lng;
});
const { groups, singleMissions } = Mission.getAllGroups(filtered);
const sortedMissions = {
groupUid: "",
groupDisplayName: "Single Missions",
missions: singleMissions,
};
groups.push(sortedMissions);
useEffect(() => {
if (currentMission && currentMission.deliveryLocation) {
setViewport({ ...viewport, center: currentMission.deliveryLocation });
}
// eslint-disable-next-line
}, [currentMission]);
return (
<Box height="100%">
<Map
viewport={viewport}
onViewportChanged={setViewport}
className={`${classes.map} data-test-leaftleft-map`}
>
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
{filtered?.map((mission) => (
<MissionMarker
mission={mission}
currentUid={currentMission?.uid}
setSelectedMission={setSelectedMission}
groups={groups}
volunteers={volunteers}
/>
))}
</Map>
</Box>
);
}
Example #12
Source File: Map.js From 1km.co.il with MIT License | 5 votes |
MapElement = styled(Map)`
width: 100%;
height: 100%;
grid-column: 1 / -1;
grid-row: 1 / -1;
`
Example #13
Source File: DroneControl.js From DMS_React with GNU Affero General Public License v3.0 | 5 votes |
DroneControl = props => {
const classes = useStyles();
const state = {
lat: 26.818123,
lng: 87.281345,
zoom: 17,
};
const drone = new Icon({
iconUrl: Green,
iconSize: [25, 25]
});
return <Grid container className={classes.root} >
<Map
center={[state.lat, state.lng]}
zoom={state.zoom}
style={{ width: '100%', height: '100%', zIndex: 0 }}
zoomControl={false}
>
<Grid container className={classes.data}>
<Grid item xs={3}>
<DroneData />
</Grid>
<Grid item xs={3}>
</Grid>
<Grid item xs={3}>
</Grid>
<Grid item xs={3} container alignItems='flex-end' >
<AttitudeIndicator size={120} roll={30} pitch={0} showBox={false} />
<HeadingIndicator size={120} heading={0} showBox={false} />
</Grid>
</Grid>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<RotatedMarker icon={drone} position={[state.lat, state.lng]} rotationAngle={70} rotationOrigin={'center'}/>
</Map>
</Grid>
}
Example #14
Source File: eventList.js From DengueStop with Apache License 2.0 | 5 votes |
LocationModal = (props) => {
const [isOpen, setIsOpen] = useState(false);
const setLocationModal = props.setLocationModal;
const position = [props.latitude, props.longitude];
useEffect(() => {
setIsOpen(props.isOpen);
});
return (
<MDBModal
isOpen={isOpen}
toggle={() => setLocationModal(false)}
className="modal-notify modal-info text-white"
size="md"
>
<MDBModalHeader>Event Location</MDBModalHeader>
<MDBModalBody>
<MDBRow>
<MDBCol>
<Map
className="map-container"
center={position}
zoom={17}
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>Reported Location</Popup>
</Marker>
</Map>
</MDBCol>
</MDBRow>
</MDBModalBody>
<MDBModalFooter>
<MDBBtn
color="secondary"
onClick={() => setLocationModal(false)}
>
Close
</MDBBtn>
</MDBModalFooter>
</MDBModal>
);
}
Example #15
Source File: App.answer.js From launchtime-workshop with MIT License | 4 votes |
function App() {
const mapRef = useRef();
useEffect(() => {
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: require( 'leaflet/dist/images/marker-icon-2x.png' ),
iconUrl: require( 'leaflet/dist/images/marker-icon.png' ),
shadowUrl: require( 'leaflet/dist/images/marker-shadow.png' ),
});
}, []);
useEffect(() => {
const { current = {} } = mapRef;
const { leafletElement: map } = current;
if ( !map ) return;
map.eachLayer((layer = {}) => {
const { options } = layer;
const { name } = options;
if ( name !== 'Mapbox' ) {
map.removeLayer(layer);
};
});
/**
* @lesson-07-answer
* We were able to use the onEachFeature option on the Leaflet GeoJSON
* instance add a custom function that lets us both create a new popup
* and bind it to our marker layer. We have to use an HTML string to
* do this as it's not interfacing directly with React
*/
const geoJson = new L.GeoJSON(locations, {
onEachFeature: (feature = {}, layer) => {
const { properties = {} } = feature;
const { name, delivery, tags, phone, website } = properties;
const popup = L.popup();
const html = `
<div class="restaurant-popup">
<h3>${name}</h3>
<ul>
<li>
${tags.join(', ')}
</li>
<li>
<strong>Delivery:</strong> ${delivery ? 'Yes' : 'No'}
</li>
<li>
<strong>Phone:</strong> ${phone}
</li>
<li>
<strong>Website:</strong> <a href="${website}">${website}</a>
</li>
</ul>
</div>
`;
popup.setContent(html)
layer.bindPopup(popup);
}
});
geoJson.addTo(map);
}, [mapRef]);
return (
<Layout>
<Map ref={mapRef} center={[38.907132, -77.036546]} zoom={12}>
<TileLayer
url={`https://api.mapbox.com/styles/v1/${MAPBOX_USERID}/${MAPBOX_STYLEID}/tiles/256/{z}/{x}/{y}@2x?access_token=${MAPBOX_API_KEY}`}
attribution="Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>"
/>
</Map>
</Layout>
);
}
Example #16
Source File: Map.js From india-maps with MIT License | 4 votes |
// to aggregate data by state+country and sum up metrics
export default function MapContainer(props) {
const {
setDashboardData,
setRootData,
setPan,
pan
} = props;
const [indiaData, setIndiaData] = useState(null);
const [stateData, setStateData] = useState(null);
const [countrySummary, setCountrySummary] = useState(null);
const [districtData, setDistrictData] = useState(null);
const [internationalData, setInternationalData] = useState([]);
const [countryStats, setCountryStats] = useState(null);
const [worldStats, setWorldStats] = useState(null);
const [viewTestCenters, setViewTestCenters] = useState(false);
const [showInfoHead, setShowInfoHead] = useState(true);
const [firstLoad, setFirstLoad] = useState(true);
const [mapPan, setMapPan] = useState(pan);
useEffect(()=>{
setMapPan(pan)
console.log("Pan: " + JSON.stringify(pan.geoJson))
},[pan])
useEffect(()=>{
setRootData({data: internationalData})
},[internationalData])
useEffect(() => {
fetch("https://stats.coronasafe.live/covid_data_json/kerala_covid_data.json")
.then(res => res.json())
.then(
result => {
console.log("Received Response" + result);
setDistrictData(result);
}
);
fetch("https://stats.coronasafe.live/covid_data_json/other_countries_covid_data.json")
.then(res => res.json())
.then(
result => {
setInternationalData(result.reduce((acc,cur) => {
return {
...acc,
[cur.Country]:{
geojson_feature: JSON.parse(cur.geo_json_feature.split("'").join("\"")),
confirmed: cur['Confirmed'],
deceased: cur['Deaths'],
recovered: cur['Recovered'],
active: cur['Active'],
latitude: cur['Lat'],
longitude: cur['Long_']
}
}
},{}));
}
);
}, []);
const findRadius = cases => {
return (Math.cbrt(cases)) * 1500
}
const geoJSONStyle = (feature) => {return {
color: '#FFFFFF',
weight: 1,
fillOpacity: 0.5,
fillColor: '#A73829',
}}
const renderTooltip = (feature) => {
return `Details Unavailable`
}
const onEachFeature = (feature, layer) => {
const tooltipChildren = renderTooltip(feature);
const popupContent = `<Popup> ${tooltipChildren} </Popup>`
layer.bindPopup(popupContent)
}
const focusLocation = (latlng) => {
const [closest,closestData] = findClosest(latlng, internationalData);
const newGeo = closestData.geojson_feature
setPan({geoJson:newGeo, location:closest})
setDashboardData({...closestData, name: closest})
}
return (
<Map
className="h-full w-full md:w-4/5 fixed"
center={mapPan.position}
zoom={mapPan.zoom}
minZoom={2}
maxBounds={[[-85,-180],[85,180]]}
onClick={e=>{focusLocation(e.latlng)}}
onMoveend={e=>{focusLocation(e.target.getCenter())}}
>
{
mapPan.geoJson &&
<GeoJSON
key={mapPan.location}
data={mapPan.geoJson}
style={geoJSONStyle}
onEachFeature={onEachFeature}
/>
}
<TileLayer
attribution='&copy <a href="https://carto.com">Carto</a>'
url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
/>
{districtData &&
Object.entries(districtData.data).map(([location,data]) =>
// console.log(location.state + "|" + JSON.stringify(indiaData.stateData[location.state]))
<Circle
key={location}
center={[data.latitude, data.longitude]}
fillColor="#d14f69"
fillOpacity={0.6}
stroke={false}
radius={15000 + findRadius(data.active)}
/>
)}
{Object.entries(internationalData).map(([country,location], index) => {
if (location.country_region === "India") {
if (countryStats === null) setCountryStats(location);
return null;
}
return (
<Circle
key={
country
}
center={{lat: location.latitude, lng: location.longitude}}
fillColor="#d14f69"
fillOpacity={0.6}
stroke={false}
radius={15000 + findRadius(location.confirmed)}
onMouseOver={e => {
e.target.openPopup();
}}
>
<Popup>
{country}
{location.confirmed}
{/* <h3>
{location.province_state
? location.province_state
: location.country_region}
</h3>
{location.province_state && (
<span>
{location.country_region}
<br />
</span>
)}
Cases: {location.confirmed}
Cured/Discharged: {location.recovered}
Deaths: {location.deaths}
<hr />
Last Update: {location.last_update}
<br /> */}
</Popup>
</Circle>
);
})}
{viewTestCenters &&
testCenters.map(testCenter => {
return (
<Marker
key={testCenter.institution}
position={[testCenter.latitude, testCenter.longitude]}
onMouseOver={e => {
e.target.openPopup();
}}
>
<Popup>
<h3>{testCenter.institution}</h3>
<a
href={
"https://www.google.com/maps/search/?api=1&query=" +
testCenter.institution +
"&query_place_id=" +
testCenter.place_id
}
target="_blank"
rel="noopener noreferrer"
>
Open in Maps
</a>
</Popup>
</Marker>
);
})}
</Map>
);
}
Example #17
Source File: index.js From pi-weather-station with MIT License | 4 votes |
WeatherMap = ({ zoom, dark }) => {
const MAP_CLICK_DEBOUNCE_TIME = 200; //ms
const {
setMapPosition,
panToCoords,
setPanToCoords,
browserGeo,
mapGeo,
mapApiKey,
getMapApiKey,
markerIsVisible,
animateWeatherMap,
} = useContext(AppContext);
const mapRef = useRef();
const mapClickHandler = useCallback(
debounce((e) => {
const { lat: latitude, lng: longitude } = e.latlng;
const newCoords = { latitude, longitude };
setMapPosition(newCoords);
}, MAP_CLICK_DEBOUNCE_TIME),
[setMapPosition]
);
const [mapTimestamps, setMapTimestamps] = useState(null);
const [mapTimestamp, setMapTimestamp] = useState(null);
const [currentMapTimestampIdx, setCurrentMapTimestampIdx] = useState(0);
const MAP_TIMESTAMP_REFRESH_FREQUENCY = 1000 * 60 * 10; //update every 10 minutes
const MAP_CYCLE_RATE = 1000; //ms
const getMapApiKeyCallback = useCallback(() => getMapApiKey(), [
getMapApiKey,
]);
useEffect(() => {
getMapApiKeyCallback().catch((err) => {
console.log("err!", err);
});
const updateTimeStamps = () => {
getMapTimestamps()
.then((res) => {
setMapTimestamps(res);
})
.catch((err) => {
console.log("err", err);
});
};
const mapTimestampsInterval = setInterval(
updateTimeStamps,
MAP_TIMESTAMP_REFRESH_FREQUENCY
);
updateTimeStamps(); //initial update
return () => {
clearInterval(mapTimestampsInterval);
};
}, []); // eslint-disable-line react-hooks/exhaustive-deps
// Pan the screen to a a specific location when `panToCoords` is updated with grid coordinates
useEffect(() => {
if (panToCoords && mapRef.current) {
const { leafletElement } = mapRef.current;
leafletElement.panTo([panToCoords.latitude, panToCoords.longitude]);
setPanToCoords(null); //reset back to null so we can observe a change next time its fired for the same coords
}
}, [panToCoords, mapRef]); // eslint-disable-line react-hooks/exhaustive-deps
const { latitude, longitude } = browserGeo || {};
useEffect(() => {
if (mapTimestamps) {
setMapTimestamp(mapTimestamps[currentMapTimestampIdx]);
}
}, [currentMapTimestampIdx, mapTimestamps]);
// cycle through weather maps when animated is enabled
useEffect(() => {
if (mapTimestamps) {
if (animateWeatherMap) {
const interval = setInterval(() => {
let nextIdx;
if (currentMapTimestampIdx + 1 >= mapTimestamps.length) {
nextIdx = 0;
} else {
nextIdx = currentMapTimestampIdx + 1;
}
setCurrentMapTimestampIdx(nextIdx);
}, MAP_CYCLE_RATE);
return () => {
clearInterval(interval);
};
} else {
setCurrentMapTimestampIdx(mapTimestamps.length - 1);
}
}
}, [currentMapTimestampIdx, animateWeatherMap, mapTimestamps]);
if (!hasVal(latitude) || !hasVal(longitude) || !zoom || !mapApiKey) {
return (
<div className={`${styles.noMap} ${dark ? styles.dark : styles.light}`}>
<div>Cannot retrieve map data.</div>
<div>Did you enter an API key?</div>
</div>
);
}
const markerPosition = mapGeo ? [mapGeo.latitude, mapGeo.longitude] : null;
return (
<Map
ref={mapRef}
center={[latitude, longitude]}
zoom={zoom}
style={{ width: "100%", height: "100%" }}
attributionControl={false}
touchZoom={true}
dragging={true}
fadeAnimation={false}
onClick={mapClickHandler}
>
<AttributionControl position={"bottomleft"} />
<TileLayer
attribution='© <a href="https://www.mapbox.com/feedback/">Mapbox</a>'
url={`https://api.mapbox.com/styles/v1/mapbox/${
dark ? "dark-v10" : "light-v10"
}/tiles/{z}/{x}/{y}?access_token={apiKey}`}
apiKey={mapApiKey}
/>
{mapTimestamp ? (
<TileLayer
attribution='<a href="https://www.rainviewer.com/">RainViewer</a>'
url={`https://tilecache.rainviewer.com/v2/radar/${mapTimestamp}/{size}/{z}/{x}/{y}/{color}/{smooth}_{snow}.png`}
opacity={0.3}
size={512}
color={6} // https://www.rainviewer.com/api.html#colorSchemes
smooth={1}
snow={1}
/>
) : null}
{markerIsVisible && markerPosition ? (
<Marker position={markerPosition} opacity={0.65}></Marker>
) : null}
</Map>
);
}
Example #18
Source File: AddressAutocomplete.jsx From resilience-app with GNU General Public License v3.0 | 4 votes |
/**
*
* @param {address: "string", lat: number, lng: number} defaultLocation,
* refer to Location in scheme.jsx, this location will just show up in the map
* if it is defined, even if the address and the marker are mismatched.
* Once a new address are input though the marker and the address should be correct once again
*
*/
export default function AddressAutocomplete({
defaultLocation,
disabled,
error,
label,
onChangeLocation,
required,
showMap,
}) {
const classes = useStyles();
const [location, dispatchLocation] = useReducer(
locationReducer,
initLocationState(defaultLocation)
);
useGoogleMapAPI();
const handleInputChange = (_, value, reason) => {
if (reason === "input") {
dispatchLocation({
type: "setInput",
input: value,
});
} else if (reason === "clear") {
dispatchLocation({ type: "clear" });
onChangeLocation(null);
}
};
const handleAutoChange = (request) => {
let address = "";
let lat = 0;
let lng = 0;
if (geocoderService.current && request) {
fetchLatLng({ ...request }, (place) => {
if (place[0]) {
address = place[0].formatted_address;
lat = place[0].geometry.location.lat();
lng = place[0].geometry.location.lng();
dispatchLocation({
type: "setLocation",
address,
lat,
lng,
});
onChangeLocation({
address,
lat,
lng,
});
}
});
} else {
dispatchLocation({ type: "clear" });
onChangeLocation({
address,
lat,
lng,
});
}
};
const fetchLatLng = useMemo(
() =>
throttle((request, callback) => {
geocoderService.current.geocode(request, callback);
}, 200),
[]
);
const fetchPlacePredictions = useMemo(
() =>
throttle((request, callback) => {
autocompleteService.current.getPlacePredictions(request, callback);
}, 200),
[]
);
useEffect(() => {
if (!defaultLocation) return;
const { address, lat, lng } = defaultLocation;
dispatchLocation({ type: "setLocation", address, lat, lng });
}, [defaultLocation]);
useEffect(() => {
let active = true;
if (!autocompleteService.current && window.google) {
autocompleteService.current = new window.google.maps.places.AutocompleteService();
geocoderService.current = new window.google.maps.Geocoder();
}
if (!autocompleteService.current) {
return undefined;
}
if (location.input === "") {
dispatchLocation({ type: "clearOptions" });
return undefined;
}
fetchPlacePredictions({ input: location.input }, (results) => {
if (active) {
dispatchLocation({
type: "setOptions",
options: results || [],
});
}
});
return () => {
active = false;
};
}, [location.input, fetchPlacePredictions]);
return (
<>
<Autocomplete
value={location.input}
id="google-map-demo"
style={{ width: "100%" }}
getOptionLabel={(option) => (typeof option === "string" ? option : option.description)}
filterOptions={(x) => x}
options={location.options}
autoComplete
disabled={disabled}
includeInputInList
getOptionSelected={(option, value) => {
return option.description === value;
}}
onChange={(_, place) => place?.place_id && handleAutoChange({ placeId: place.place_id })}
onInputChange={handleInputChange}
renderInput={(params) => (
<TextField
{...params}
label={label}
variant="outlined"
fullWidth
error={error}
required={required}
/>
)}
renderOption={(option) => {
const matches = option.structured_formatting.main_text_matched_substrings;
const parts = parse(
option.structured_formatting.main_text,
matches.map((match) => [match.offset, match.offset + match.length])
);
return (
<Grid container alignItems="center">
<Grid item>
<LocationOnIcon className={classes.icon} />
</Grid>
<Grid item xs>
{parts.map((part, index) => (
<span key={index} style={{ fontWeight: part.highlight ? 700 : 400 }}>
{part.text}
</span>
))}
<Typography variant="body2" color="textSecondary">
{option.structured_formatting.secondary_text}
</Typography>
</Grid>
</Grid>
);
}}
/>
{showMap && (
<>
<Box className={classes.mapHelperTextWrapper}>
<small>Drag the marker to correct address</small>
</Box>
<Box className={classes.mapWrapper}>
<Box className={disabled ? classes.disabledMap : ""}></Box>
<Map
className={classes.map}
center={location.lat ? [location.lat, location.lng] : [0, 0]}
zoom={location.zoom}
>
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
{location.lat && (
<Marker
position={location.lat ? [location.lat, location.lng] : [0, 0]}
draggable={true}
riseOnHover={true}
onMoveend={(e) => {
handleAutoChange({
location: e.target._latlng,
});
}}
/>
)}
</Map>
</Box>
</>
)}
</>
);
}
Example #19
Source File: MissionView.js From DMS_React with GNU Affero General Public License v3.0 | 4 votes |
MissionView = props => {
const dispatch = useDispatch();
const classes = useStyles();
const modalStyle = getModalStyle();
const [openMissionList, setOpenMissionList] = React.useState(false);
const [draggable, setDraggable] = React.useState(false);
const [create, setCreate] = React.useState(false);
const [currWaypointIndex, setCurrWaypointIndex] = React.useState(0);
const [action, setAction] = React.useState("create");
const openMissionDetail = useSelector(({ mission }) => mission.missionDetail);
const state = {
lat: 26.818123,
lng: 87.281345,
zoom: 17,
}
const initialMissionDetail = { name: '', radius: null, speed: null, home: '', destination: '', waypoints: [] };
const [missionDetail, setMissionDetail] = React.useState({ name: '', radius: null, speed: null, home: '', destination: '', waypoints: [] });
//to update the localstate by the missionDetails sourced from server
useEffect(() => {
if (openMissionDetail !== null) {
setMissionDetail(openMissionDetail);
setCreate(true);
}
}, [openMissionDetail]);
//close the modal after choosing the mission
const handleCloseMission = () => {
setAction('create');
setOpenMissionList(false);
};
//callback function to update position after the marker is dragged
const updatePosition = (event, index) => {
if (event.target !== undefined && event.target !== null) {
console.log(event.target.getLatLng());
const m = { ...missionDetail };
m.waypoints[index].lat = event.target.getLatLng().lat;
m.waypoints[index].lng = event.target.getLatLng().lng;
setMissionDetail(m);
}
}
//callback function for placing markers on the map and update the latitude and longitude of the waypoint
const handleClick = (event) => {
if (create) {
if (event.latlng !== undefined && event.latlng !== null) {
console.log(event.latlng);
const m = { ...missionDetail };
m.waypoints.push({
altitude: 0, radius: 0,
action: 'waypoint', lat: event.latlng.lat,
lng: event.latlng.lng
});
// console.log(mission, m);
setCurrWaypointIndex(m.waypoints.length - 1);
setMissionDetail(m);
}
}
}
//on create mission
const startMissionCreation = () => {
setDraggable(true);
setCreate(true);
setAction('create');
}
//callback function for click on confirm button
const createUpdateMission = () => {
console.log("Create Mission");
setCreate(false);
setDraggable(false);
setMissionDetail(initialMissionDetail);
dispatch(actions.createUpdateMission(missionDetail,action));
setAction('create');
}
//callback function for change in parameter of a particular waypoint provided by index
const onChange = (event, key) => {
console.log(event.target.value, key);
console.log(currWaypointIndex);
const m = {
...missionDetail,
};
m.waypoints[currWaypointIndex] = {
...m.waypoints[currWaypointIndex],
[key]: event.target.value
}
console.log(m.waypoints[currWaypointIndex]);
setMissionDetail(m);
}
//callback function for updating the change in details other than waypoints
const onChangeMission = (event, key) => {
const m = {
...missionDetail,
[key]: event.target.value
};
console.log("value of m", m)
setMissionDetail(m);
}
//callback function for click on a marker
const onClick = (index) => {
console.log("Marker Clicked", index);
setCurrWaypointIndex(index);
console.log(index, currWaypointIndex, "current waypoint")
}
//open mission list in a modal
const openMission = () => {
setOpenMissionList(true);
}
//set the mission details and waypoints to intial value of empty
const onCancel = () => {
setAction('create');
setCreate(false);
setDraggable(false);
setMissionDetail(initialMissionDetail);
}
const selectMission = (missionId) => {
setAction('edit');
console.log(missionId);
dispatch(actions.getMission(missionId));
setOpenMissionList(false);
}
return (
<Grid container className={classes.root}>
<Grid item xs={3}>
<MissionData data-test="missionData"
action={action} //touched
onCancel={onCancel}
onChangeMission={onChangeMission} //done
onChange={onChange} //done
createUpdateMission={createUpdateMission}
mission={missionDetail} //done
waypoint={missionDetail.waypoints[currWaypointIndex]}
onCreateMission={startMissionCreation}
openMission={openMission} //done
create={create} //done
/>
</Grid>
<Grid item xs={9}>
<Map
center={[state.lat, state.lng]}
zoom={state.zoom}
style={{ width: '100%', height: '100%' }}
zoomControl={false}
onClick={handleClick} data-test="mapComp"
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{missionDetail !== null && missionDetail !== undefined ?
missionDetail.waypoints.map((miss, i, array) => {
// console.log(miss);
return (<span key={i}><Marker
draggable={draggable}
onDragend={(event) => updatePosition(event, i)}
position={[miss.lat, miss.lng]}
data-test="markerComp"
onClick={() => onClick(i)}>
<Popup minWidth={90}>
<span >
<span>{miss.action} </span>
<br />
<span>Alt: {miss.altitude}m</span><br />
</span>
</Popup>
</Marker>
{/* for lines between markers */}
{array[i - 1] ? <Polyline weight={1} positions={[
[array[i - 1].lat, array[i - 1].lng], [array[i].lat, array[i].lng],
]} color={'red'} /> : null}
}
</span>
)
}) : null
}
<ZoomControl position="topright" />
</Map>
</Grid>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={classes.modal}
open={openMissionList}
onClose={handleCloseMission}
closeAfterTransition
data-test="modalComp"
>
<Fade in={openMissionList}>
<div className={classes.paper} style={modalStyle}>
<MissionList abort={handleCloseMission} select={selectMission} data-test="missionList" />
</div>
</Fade>
</Modal>
</Grid>)
}
Example #20
Source File: eventList.js From DengueStop with Apache License 2.0 | 4 votes |
NewEventModal = (props) => {
const isOpen = props.isOpen;
const setIsOpen = props.setIsOpen;
const [startDate, setStartDate] = useState(new Date());
const mapCenter = [7.9, 80.747452];
const [eventCoord, setEventCood] = useState([7.9, 80.747452]);
const [mapTouched, setMapTouched] = useState(false);
const eventService = new EventService();
useEffect(() => {
setIsOpen(props.isOpen);
});
const addNewEvent = (eventData) => {
var eventObject = eventData;
eventObject.start_time = startDate.getTime();
eventObject.location_lat = eventCoord[0];
eventObject.location_long = eventCoord[1];
console.log(eventObject);
eventService
.createEvent(eventObject)
.then((res) => {
console.log(res);
NotificationManager.success(
"Event Created Successfully",
"Success",
5000
);
setIsOpen(false);
})
.catch((err) => {
console.log(err);
NotificationManager.error(
"Event Creation Failed. Please Try Again",
"Failed",
5000
);
});
};
const validateForm = () => {
return !mapTouched;
};
const changeCoordinateOnClick = (event) => {
setMapTouched(true);
const lat = event.latlng.lat;
const long = event.latlng.lng;
setEventCood([lat, long]);
};
const changeCoordinateOnDrag = (event) => {
setMapTouched(true);
const lat = event.target._latlng.lat;
const long = event.target._latlng.lng;
setEventCood([lat, long]);
};
const NewEventSchema = Yup.object().shape({
name: Yup.string()
.min(2, "Too Short!")
.max(45, "Too Long!")
.required("Required"),
venue: Yup.string()
.min(2, "Too Short!")
.max(45, "Too Long!")
.required("Required"),
coordinator_name: Yup.string()
.min(2, "Too Short!")
.max(45, "Too Long!")
.required("Required"),
coordinator_contact: Yup.string()
.min(10, "Number too Short!")
.max(10, "Number too Long!")
.required("Required"),
description: Yup.string()
.min(5, "Too Short!")
.max(500, "Too Long!")
.required("Required"),
});
return (
<MDBModal size="lg" isOpen={isOpen} toggle={() => setIsOpen(false)}>
<Formik
initialValues={{
name: "",
venue: "",
duration: 0,
coordinator_name: "",
coordinator_contact: "",
description: "",
}}
validationSchema={NewEventSchema}
onSubmit={(values, { setSubmitting }) => {
addNewEvent(values);
setSubmitting(false);
}}
validate={(values) => {
const errors = {};
if (values.duration <= 0) {
errors.duration = "Duration should be more than 0";
}
return errors;
}}
>
{({ errors, touched }) => (
<Form>
<MDBModalHeader>Add New Event</MDBModalHeader>
<MDBModalBody>
<MDBRow>
<MDBCol>
<div className="form-group">
<label>Event Name</label>
<Field
name="name"
type="text"
className="form-control"
/>
{errors.name && touched.name ? (
<p className="event-form-invalid-text">
{errors.name}
</p>
) : null}
</div>
</MDBCol>
<MDBCol>
<div className="form-group">
<label>Event Venue</label>
<Field
name="venue"
type="text"
className="form-control"
/>
{errors.venue && touched.venue ? (
<p className="event-form-invalid-text">
{errors.venue}
</p>
) : null}
</div>
</MDBCol>
</MDBRow>
<MDBRow>
<MDBCol>
<div className="form-group">
<label>Event Date/Time</label>
<br />
<DatePicker
minDate={new Date()}
className="event-date-picker form-control"
dateFormat="MMMM d, yyyy h:mm aa"
selected={startDate}
showTimeSelect
onChange={(date) =>
setStartDate(date)
}
></DatePicker>
</div>
</MDBCol>
<MDBCol>
<div className="form-group">
<label>Duration</label>
<Field
name="duration"
type="number"
className="form-control"
/>
{errors.duration && touched.duration ? (
<p className="event-form-invalid-text">
{errors.duration}
</p>
) : null}
</div>
</MDBCol>
</MDBRow>
<MDBRow>
<MDBCol>
<div className="form-group">
<label>Event Coordinator Name</label>
<Field
name="coordinator_name"
type="text"
className="form-control"
/>
{errors.coordinator_name &&
touched.coordinator_name ? (
<p className="event-form-invalid-text">
{errors.coordinator_name}
</p>
) : null}
</div>
</MDBCol>
<MDBCol>
<div className="form-group">
<label>Event Coordinator Contact</label>
<Field
name="coordinator_contact"
type="text"
className="form-control"
/>
{errors.coordinator_contact &&
touched.coordinator_contact ? (
<p className="event-form-invalid-text">
{errors.coordinator_contact}
</p>
) : null}
</div>
</MDBCol>
</MDBRow>
<MDBRow>
<MDBCol>
<div className="form-group">
<label>Event Description</label>
<Field
component="textarea"
name="description"
type="text"
className="form-control"
/>
{errors.description &&
touched.description ? (
<p className="event-form-invalid-text">
{errors.description}
</p>
) : null}
</div>
</MDBCol>
</MDBRow>
<MDBRow>
<MDBCol>
<p className="text-center">
Mark the event location on the map below
</p>
<Map
className="map-container"
onclick={(event) =>
changeCoordinateOnClick(event)
}
center={mapCenter}
zoom={7}
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker
draggable={true}
ondragend={(event) =>
changeCoordinateOnDrag(event)
}
position={eventCoord}
>
<Popup>Event Location</Popup>
</Marker>
</Map>
</MDBCol>
</MDBRow>
</MDBModalBody>
<MDBModalFooter>
<MDBBtn
type="submit"
disabled={validateForm()}
color="primary"
>
Save Event
</MDBBtn>
<MDBBtn
color="secondary"
onClick={() => setIsOpen(false)}
>
Close
</MDBBtn>
</MDBModalFooter>
</Form>
)}
</Formik>
</MDBModal>
);
}
Example #21
Source File: index.js From freemeals.uk with MIT License | 4 votes |
function SelectedPane() {
const history = useHistory();
const { data, selectedIndex, setSelectedIndex, filteredData } = React.useContext(
AppContext
);
const [selectedProvider, setSelectedProvider] = useState([]);
useEffect(() => {
if(!!data && selectedIndex != null) {
const providerData = filteredData !== null ? filteredData : data;
setSelectedProvider(providerData[selectedIndex]);
}
}, [selectedIndex, data, filteredData]);
const mode = "list";
const customIcon = L.icon({
iconUrl: "https://unpkg.com/[email protected]/dist/images/marker-icon.png",
iconSize: [35, 46],
iconAnchor: [17, 46],
});
const handleCloseClick = () => {
setSelectedIndex(null);
history.push(`/`);
};
const buildAvailiblityString = (provider) => {
const days = selectedProvider[OFFER_DAYS];
const openTime = selectedProvider[OPEN_TIME];
const closeTime = selectedProvider[CLOSE_TIME];
return `${!!days ? `${days}: ` : ""}${!!openTime ? openTime : ""}${
!!closeTime ? `- ${closeTime}` : ""
}`;
};
const verifyUrl = (url) => {
return url && url.startsWith("http");
};
return !data || selectedIndex == null ? null : (
<SelectedPaneContainer isMapMode={mode === "map"}>
<ProviderHeader>
<HeaderTopRow>
<ProviderName>{selectedProvider[NAME]}</ProviderName>
<CloseButton onClick={handleCloseClick}>
<IconClose />
</CloseButton>
</HeaderTopRow>
<a
href={`https://www.google.co.uk/maps/place/${buildAddressString(
selectedProvider
)}`}
target="_blank"
rel="noopener noreferrer"
>
{buildAddressString(selectedProvider)}
</a>
</ProviderHeader>
<div style={{ height: "50%", width: "100%" }}>
{selectedProvider["latitude"] && selectedProvider["longitude"] ? (
<Map
center={[
selectedProvider["latitude"],
selectedProvider["longitude"],
]}
zoom={20}
className="leaflet-map"
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker
position={[selectedProvider.latitude, selectedProvider.longitude]}
icon={customIcon}
/>
</Map>
) : null}
</div>
{buildAvailiblityString(selectedProvider)}
{selectedProvider[URL] && (
<Block>
<a href={selectedProvider[URL]}>{selectedProvider[URL]}</a>
</Block>
)}
{selectedProvider[OFFERS] && (
<Block>
<SectionHeading>What's available?</SectionHeading>
<span>{selectedProvider[OFFERS]}</span>
</Block>
)}
{selectedProvider[INSTRUCTIONS] && (
<Block>
<SectionHeading>How to claim</SectionHeading>
{selectedProvider[INSTRUCTIONS]}
</Block>
)}
<small>
{verifyUrl(selectedProvider[PROVIDER_SOURCE_URL]) ? (
<>
<strong>Source</strong>:{" "}
<a href={selectedProvider[PROVIDER_SOURCE_URL]}>
{selectedProvider[PROVIDER_SOURCE_URL]}
</a>
</>
) : null}
</small>
</SelectedPaneContainer>
);
}