Skip to content

Commit

Permalink
Added Map to Homepage
Browse files Browse the repository at this point in the history
  • Loading branch information
CVVSAI committed Jul 12, 2024
1 parent 9afd7a7 commit 7ab6236
Showing 1 changed file with 115 additions and 14 deletions.
129 changes: 115 additions & 14 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,121 @@
import type { MetaFunction } from "@remix-run/node";
import IntroModal from "app/components/layout/IntroModal";
import Sidebar from "~/components/layout/Sidebar";

export const meta: MetaFunction = () => {
return [
{ title: "Georgia Coast Atlas" },
{ name: "description", content: "Welcome to Remix!" },
];
import { useState, useEffect, useCallback } from "react";
import { useLoaderData } from "@remix-run/react";
import { ClientOnly } from "remix-utils/client-only";
import Map from "~/components/Map.client";
import { islands } from "~/config";
import { fetchPlaceRecord } from "~/data/coredata";
import { toFeatureCollection } from "~/utils/toFeatureCollection";
import type { FeatureCollection } from "geojson";
import type { TCoreDataPlaceRecord } from "~/types";
import type { LoaderFunction } from "@remix-run/node";
import maplibregl from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";

export const loader: LoaderFunction = async () => {
const islandDataPromises = islands.map(island =>
fetchPlaceRecord(island.coreDataId)
.then(data => data?.place)
.catch(() => undefined)
);

const islandData = await Promise.all(islandDataPromises);
const validIslandData: TCoreDataPlaceRecord[] = islandData.filter((data): data is TCoreDataPlaceRecord => data !== undefined);
const geoJSON = toFeatureCollection(validIslandData);

return { geoJSON };
};

export default function Index() {
const [map, setMap] = useState<maplibregl.Map | undefined>(undefined);
const [mapLoaded, setMapLoaded] = useState<boolean>(false);
const { geoJSON } = useLoaderData<{ geoJSON: FeatureCollection }>();

const handleMouseEnter = useCallback(() => {
if (map) map.getCanvas().style.cursor = 'pointer';
}, [map]);

const handleMouseLeave = useCallback(() => {
if (map) map.getCanvas().style.cursor = '';
}, [map]);

const handleClick = useCallback((e: maplibregl.MapMouseEvent & { features?: maplibregl.MapGeoJSONFeature[] }) => {
if (!map) return;
if (e.features && e.features.length > 0) {
const coordinates = e.lngLat;
const name = e.features[0].properties?.name;

while (Math.abs(e.lngLat.lng - coordinates.lng) > 180) {
coordinates.lng += e.lngLat.lng > coordinates.lng ? 360 : -360;
}

new maplibregl.Popup()
.setLngLat(coordinates)
.setHTML(name)
.addTo(map);
}
}, [map]);

useEffect(() => {
if (!map || !mapLoaded || !geoJSON) return;

if (map.getSource("islands")) return;

map.addSource("islands", {
type: "geojson",
data: geoJSON,
});

map.addLayer({
id: "islands-fill",
type: "fill",
source: "islands",
layout: {},
paint: {
"fill-color": "blue",
"fill-opacity": 0.25,
},
});

map.addLayer({
id: "islands-outline",
type: "line",
source: "islands",
layout: {
"line-join": "round",
"line-cap": "round",
},
paint: {
"line-color": "blue",
"line-width": 2,
"line-opacity": 0.5,
},
});

map.on('mouseenter', 'islands-fill', handleMouseEnter);
map.on('mouseleave', 'islands-fill', handleMouseLeave);
map.on('click', 'islands-fill', handleClick);

return () => {
if (map.getLayer("islands-fill")) map.removeLayer("islands-fill");
if (map.getLayer("islands-outline")) map.removeLayer("islands-outline");
if (map.getSource("islands")) map.removeSource("islands");
map.off('mouseenter', 'islands-fill', handleMouseEnter);
map.off('mouseleave', 'islands-fill', handleMouseLeave);
map.off('click', 'islands-fill', handleClick);
};
}, [map, mapLoaded, geoJSON, handleMouseEnter, handleMouseLeave, handleClick]);

return (
<div>
<IntroModal />
<Sidebar />
{}
<div className="w-full h-full">
<ClientOnly>
{() => (
<Map
map={map}
setMap={setMap}
setMapLoaded={setMapLoaded}
/>
)}
</ClientOnly>
</div>
);
}
}

0 comments on commit 7ab6236

Please sign in to comment.