Skip to content

Commit

Permalink
Merge pull request #7 from Hanka8/tk/map-test
Browse files Browse the repository at this point in the history
feat: enhance map and bird data handling
  • Loading branch information
Hanka8 authored Nov 20, 2024
2 parents 670ab69 + 87e11d8 commit ebad89d
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 97 deletions.
22 changes: 11 additions & 11 deletions src/components/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ const Index: React.FC = () => {
latitude,
longitude,
}) => {
const response = await fetch(
`https://api.ebird.org/v2/data/obs/geo/recent?dist=${radius}&back=30&includeProvisional=true&lat=${Number(latitude)}&lng=${Number(longitude)}`,
{
headers: {
"X-eBirdApiToken": import.meta.env.VITE_API_KEY_EBIRD,
},
}
);
const data = await response.json();
return data;
const response = await fetch(
`https://api.ebird.org/v2/data/obs/geo/recent?dist=${radius}&back=30&includeProvisional=true&lat=${Number(latitude)}&lng=${Number(longitude)}`,
{
headers: {
"X-eBirdApiToken": import.meta.env.VITE_API_KEY_EBIRD,
},
}
);
const data = await response.json();
return data;
};

const {
Expand All @@ -74,7 +74,7 @@ const Index: React.FC = () => {
return (
<div className="text-gray-800 bg-green-50 flex flex-col items-center min-h-screen">
<h3 className="text-5xl m-8 text-green-700">Birds around you</h3>
<InteractiveMap latitude={latitude} longitude={longitude} setLatitude={setLatitude} setLongitude={setLongitude} data={data}/>
<InteractiveMap latitude={latitude} longitude={longitude} setLatitude={setLatitude} setLongitude={setLongitude} data={data} />
<div className="m-2 p-4 pb-8 bg-green-100">
<FormGeolocation
latitude={latitude}
Expand Down
185 changes: 99 additions & 86 deletions src/components/InteractiveMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,112 +28,125 @@ const InteractiveMap: React.FC<InteractiveMapProps> = ({
const [modalContent, setModalContent] = useState<string>("");

const mapRef = useRef<HTMLDivElement | null>(null);
const mapInstanceRef = useRef<Map | null>(null);
const vectorSourceRef = useRef<VectorSource | null>(null);

useEffect(() => {
if (!latitude || !longitude) return;
if (!mapInstanceRef.current && mapRef.current) {
const coordinates = fromLonLat([
parseFloat(longitude),
parseFloat(latitude),
]);

const coordinates = fromLonLat([
parseFloat(longitude),
parseFloat(latitude),
]);
const vectorSource = new VectorSource();
vectorSourceRef.current = vectorSource;

const map = new Map({
target: mapRef.current || undefined,
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: coordinates,
zoom: 12,
}),
});

// Add main marker for the central location
const marker = new Feature({
geometry: new Point(coordinates),
});

marker.setStyle(
new Style({
image: new Icon({
src: "https://openlayers.org/en/latest/examples/data/icon.png",
scale: 0.75,
}),
})
);

const circleFeature = new Feature({
geometry: new Circle(coordinates, radius * 1000),
});

circleFeature.setStyle(
new Style({
stroke: new Stroke({
color: "rgba(0, 128, 0, 0.8)",
width: 2,
}),
fill: new Fill({
color: "rgba(0, 255, 0, 0.2)",
const vectorLayer = new VectorLayer({
source: vectorSource,
});

const map = new Map({
target: mapRef.current,
layers: [
new TileLayer({
source: new OSM(),
}),
vectorLayer,
],
view: new View({
center: coordinates,
zoom: 12,
}),
})
);
});

const vectorSource = new VectorSource({
features: [marker, circleFeature],
});
map.on("singleclick", (event) => {
const clickedFeature = map.forEachFeatureAtPixel(
event.pixel,
(feature) => feature
);

if (clickedFeature) {
const description = clickedFeature.get("description");
if (description) {
setModalContent(description);
setModalOpen(true);
}
} else {
const clickedCoordinate = toLonLat(event.coordinate);
setLatitude(clickedCoordinate[1].toFixed(2));
setLongitude(clickedCoordinate[0].toFixed(2));
}
});

mapInstanceRef.current = map;
}
}, [longitude, latitude, setLatitude, setLongitude]);

data?.forEach((bird) => {
const birdCoordinates = fromLonLat([bird.lng, bird.lat]);
const birdMarker = new Feature({
geometry: new Point(birdCoordinates),


useEffect(() => {
if (vectorSourceRef.current && latitude && longitude) {
const coordinates = fromLonLat([
parseFloat(longitude),
parseFloat(latitude),
]);

const vectorSource = vectorSourceRef.current;
vectorSource.clear();

const marker = new Feature({
geometry: new Point(coordinates),
});

birdMarker.setStyle(
marker.setStyle(
new Style({
image: new Icon({
src: birdIcon,
src: "https://openlayers.org/en/latest/examples/data/icon.png",
scale: 0.75,
color: "rgba(255, 0, 0, 0.8)",
}),
})
);

birdMarker.set("description", `Bird Name: ${bird.comName}`);
vectorSource.addFeature(birdMarker);
});

const markerLayer = new VectorLayer({
source: vectorSource,
});

map.addLayer(markerLayer);
const circleFeature = new Feature({
geometry: new Circle(coordinates, radius * 1000),
});

// Add click event listener to the map
map.on("singleclick", (event) => {
const clickedFeature = map.forEachFeatureAtPixel(
event.pixel,
(feature) => {
return feature;
}
circleFeature.setStyle(
new Style({
stroke: new Stroke({
color: "rgba(0, 128, 0, 0.8)",
width: 2,
}),
fill: new Fill({
color: "rgba(0, 255, 0, 0.2)",
}),
})
);

if (clickedFeature) {
const description = clickedFeature.get("description");
if (description) {
setModalContent(description); // Set the content for the modal
setModalOpen(true); // Open the modal
}
} else {
const clickedCoordinate = toLonLat(event.coordinate); // Convert to longitude/latitude
setLatitude(clickedCoordinate[1].toFixed(2));
setLongitude(clickedCoordinate[0].toFixed(2));
}
});

return () => map.setTarget(undefined);
}, [latitude, longitude, data, setLatitude, setLongitude]);
vectorSource.addFeatures([marker, circleFeature]);

data?.forEach((bird) => {
const birdCoordinates = fromLonLat([bird.lng, bird.lat]);
const birdMarker = new Feature({
geometry: new Point(birdCoordinates),
});

birdMarker.setStyle(
new Style({
image: new Icon({
src: birdIcon,
scale: 0.75,
color: "rgba(255, 0, 0, 0.8)",
}),
})
);

birdMarker.set("description", `Bird Name: ${bird.comName}`);
vectorSource.addFeature(birdMarker);
});
}
}, [latitude, longitude, data]);

return (
<div className="w-full h-32rem">
Expand Down

0 comments on commit ebad89d

Please sign in to comment.