Skip to content

Commit

Permalink
Add route county route. Rework geosearch.
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvarner committed Nov 27, 2024
1 parent 99e7ff6 commit d53f17e
Show file tree
Hide file tree
Showing 33 changed files with 944 additions and 988 deletions.
2 changes: 1 addition & 1 deletion app/components/layout/Loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const Loading = () => {
const navigation = useNavigation();
return (
<div
className={`absolute flex items-center text-center h-screen w-screen top-0 z-50 bg-black/50 pointer-events-none transition-opacity duration-700 opacity-${navigation.state == "loading" ? 100 : 0}`}
className={`absolute flex items-center text-center h-screen w-screen top-0 z-50 bg-black/50 transition-opacity duration-700 ${navigation.state == "loading" ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"}`}
>
<div className="relative grow text-6xl text-white">
<FontAwesomeIcon
Expand Down
10 changes: 3 additions & 7 deletions app/components/layout/RelatedRecords.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,12 @@ import RelatedMapLayers from "../relatedRecords/RelatedMapLayers";
import RelatedTopoQuads from "../relatedRecords/RelatedTopoQuads";

const RelatedRecords = () => {
const { place, manifestLabel } = useContext(PlaceContext);
const { full } = useContext(PlaceContext);
return (
<>
<RelatedPlaces />
{full && <RelatedPlaces />}
<RelatedVideos />
<RelatedPhotographs
manifest={place.manifests.find(
(manifest) => manifest.label === manifestLabel
)}
/>
<RelatedPhotographs />
<RelatedMapLayers />
<RelatedTopoQuads />
</>
Expand Down
13 changes: 10 additions & 3 deletions app/components/mapping/Counties.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { MapContext } from "~/contexts";
import { ClientOnly } from "remix-utils/client-only";
import PlacePopup from "./PlacePopup";
import PlacePopup from "./PlacePopup.client";
import { counties as countyStyle } from "~/mapStyles";
import PlaceTooltip from "./PlaceTooltip";
import { Link } from "@remix-run/react";
import type { MapGeoJSONFeature, MapMouseEvent } from "maplibre-gl";
import type { TCounty } from "~/types";
import type { ESPlace } from "~/esTypes";

const Counties = ({ counties }: { counties: TCounty[] }) => {
const Counties = ({ counties }: { counties: ESPlace[] }) => {
const { map } = useContext(MapContext);
const hoveredId = useRef<string | undefined>(undefined);
const [activeCounty, setActiveCounty] = useState<string | undefined>(
Expand Down Expand Up @@ -126,6 +127,12 @@ const Counties = ({ counties }: { counties: TCounty[] }) => {
location={popupLocation}
>
<h4 className="text-xl">{county.name}</h4>
<Link
to={`/counties/${county.slug}`}
className="text-blue-700 underline underline-offset-2 text-l block mt-2"
>
Explore
</Link>
</PlacePopup>
<PlaceTooltip
show={hoveredCounty == county.name}
Expand Down
2 changes: 1 addition & 1 deletion app/components/mapping/Islands.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import PlacePopup from "~/components/mapping/PlacePopup";
import PlacePopup from "~/components/mapping/PlacePopup.client";
import { MapContext } from "~/contexts";
import { ClientOnly } from "remix-utils/client-only";
import { Link } from "@remix-run/react";
Expand Down
147 changes: 15 additions & 132 deletions app/components/mapping/PlaceGeoJSON.tsx
Original file line number Diff line number Diff line change
@@ -1,151 +1,34 @@
import { useContext, useEffect } from "react";
import { MapContext, PlaceContext } from "~/contexts";
import { bbox } from "@turf/turf";
import { LngLatBounds } from "maplibre-gl";
import { pulsingDot } from "~/utils/pulsingDot";
import type { AddLayerObject, SourceSpecification } from "maplibre-gl";
// import PlacePopup from "../PlacePopup";
// import { ClientOnly } from "remix-utils/client-only";
import { singlePoint } from "~/mapStyles/geoJSON";
import { locationToFeatureCollection } from "~/utils/toFeatureCollection";
import type { SourceSpecification } from "maplibre-gl";

const PlaceGeoJSON = () => {
const { map } = useContext(MapContext);
const { place, geoJSON, setLayerSources, setActiveLayers, activeLayers } =
useContext(PlaceContext);
// const [showPopup, setShowPopup] = useState<boolean>(false);
const { place } = useContext(PlaceContext);

useEffect(() => {
if (!map) return;
const activeRasters = activeLayers.length > 0;
if (map.getLayer(`${place.uuid}-fill`)) {
map.setPaintProperty(
`${place.uuid}-fill`,
"fill-opacity",
activeRasters ? 0 : 0.25
);
}
if (map.getLayer(`${place.uuid}-outline`)) {
map.setPaintProperty(
`${place.uuid}-outline`,
"line-opacity",
activeRasters ? 0 : 0.5
);
}
}, [map, place, activeLayers]);

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

const firstSymbolId = map
.getStyle()
.layers.find((layer) => layer.type === "symbol")?.id;

const placeSource: SourceSpecification = {
const source: SourceSpecification = {
type: "geojson",
data: geoJSON,
};

if (!map.getSource(`${place.uuid}`)) {
map.addSource(place.uuid, placeSource);
}

const fillLayer: AddLayerObject = {
id: `${place.uuid}-fill`,
type: "fill",
source: place.uuid,
layout: {},
paint: {
"fill-color": "blue",
"fill-opacity": 0.25,
},
filter: ["==", "$type", "Polygon"],
};

if (!map.getLayer(fillLayer.id)) {
map.addLayer(fillLayer, firstSymbolId);
}

if (!map.getImage("pulsing-dot")) {
const dot = pulsingDot(map);
if (dot) {
map.addImage("pulsing-dot", dot, { pixelRatio: 2 });
}
}

const pointLayer: AddLayerObject = {
id: `${place.uuid}-point`,
type: "symbol",
source: `${place.uuid}`,
filter: ["==", "$type", "Point"],
layout: {
"icon-image": "pulsing-dot",
},
};

if (!map.getLayer(pointLayer.id)) {
map.addLayer(pointLayer);
}

const outlineLayer: AddLayerObject = {
id: `${place.uuid}-outline`,
type: "line",
source: place.uuid,
layout: {
"line-join": "round",
"line-cap": "round",
},
paint: {
"line-color": "blue",
"line-width": 2,
"line-opacity": 0.5,
},
filter: ["==", "$type", "Polygon"],
data: locationToFeatureCollection(place),
promoteId: "uuid",
};

if (!map.getLayer(outlineLayer.id)) {
map.addLayer(outlineLayer);
}

if (map.getLayer(`${place.uuid}-clusters`)) {
map.moveLayer(outlineLayer.id, `${place.uuid}-clusters`);
}
if (!map.getSource(`place-${place.uuid}`))
map.addSource(`place-${place.uuid}`, source);

const bounds = new LngLatBounds(
bbox(geoJSON) as [number, number, number, number]
);
const point = singlePoint(`place-${place.uuid}`, `place-${place.uuid}`, 16);
if (!map.getLayer(`place-${place.uuid}`)) map.addLayer(point);

map.fitBounds(bounds, { maxZoom: 15 });
setLayerSources((layerSources) => {
return { ...layerSources, [place.uuid]: placeSource };
map.flyTo({
center: place.location,
zoom: 16,
});
}, [map, place]);

return () => {
try {
if (!map) return;
if (map.getLayer(`${place.uuid}-fill`))
map.removeLayer(`${place.uuid}-fill`);
if (map.getLayer(`${place.uuid}-outline`))
map.removeLayer(`${place.uuid}-outline`);
if (map.getLayer(`${place.uuid}-point`))
map.removeLayer(`${place.uuid}-point`);
if (map.getSource(place.uuid)) map.removeSource(place.uuid);
} catch {}
};
}, [map, place, setActiveLayers, setLayerSources, geoJSON]);

// TODO: This is probably not needed?
// return (
// <ClientOnly>
// {() => (
// <PlacePopup
// location={}
// show={showPopup}
// onClose={() => setShowPopup(false)}
// >
// hello
// </PlacePopup>
// )}
// </ClientOnly>
// );
return null;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useNavigation } from "@remix-run/react";
import { createPortal } from "react-dom";
import { MapContext } from "~/contexts";
import type { ReactNode } from "react";
import type { Popup } from "maplibre-gl";
import type { Popup, LngLatBounds } from "maplibre-gl";

interface Props {
location: { lat: number; lon: number };
Expand Down Expand Up @@ -46,6 +46,7 @@ const PlacePopup = ({
showCloseButton = true,
}: PopupProps) => {
const popupRef = useRef<Popup | null>(null);
const previousBounds = useRef<LngLatBounds | undefined>(undefined);
const { map } = useContext(MapContext);

const [coordinates, setCoordinates] = useState<
Expand Down Expand Up @@ -79,6 +80,7 @@ const PlacePopup = ({

popupRef.current?.addTo(map);
if (zoomToFeature) {
previousBounds.current = map.getBounds();
map.flyTo({ center: coordinates, zoom: 15 });
}
}
Expand All @@ -94,6 +96,22 @@ const PlacePopup = ({
};
}, [show, map, coordinates, zoomToFeature, onClose]);

useEffect(() => {
// Zoom out to previous bounds only if previous bounds are larger than bounds
// when zoomed into active feature. This could maybe be accomplished by comparing
// zoom levels ¯\_(ツ)_/¯
if (
zoomToFeature &&
previousBounds.current &&
!show &&
map &&
!map.getBounds().contains(previousBounds.current.getSouthEast())
) {
map.fitBounds(previousBounds.current);
previousBounds.current = undefined;
}
}, [zoomToFeature, show, map]);

if (map && popContainerRef.current) {
return (
<>
Expand Down
25 changes: 16 additions & 9 deletions app/components/relatedRecords/RelatedMapLayers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@ import { PlaceContext } from "~/contexts";
const RelatedMapLayers = () => {
const { place } = useContext(PlaceContext);

return (
<RelatedSection title="Map Layers">
{place.map_layers.map((mapLayer) => {
return (
<WMSLayer key={`map-layer-${mapLayer.uuid}`} placeLayer={mapLayer} />
);
})}
</RelatedSection>
);
if (place.map_layers?.length > 0) {
return (
<RelatedSection title="Map Layers">
{place.map_layers.map((mapLayer) => {
return (
<WMSLayer
key={`map-layer-${mapLayer.uuid}`}
placeLayer={mapLayer}
/>
);
})}
</RelatedSection>
);
}

return null;
};

export default RelatedMapLayers;
23 changes: 16 additions & 7 deletions app/components/relatedRecords/RelatedPhotographs.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import { useEffect, useState } from "react";
import { useContext, useEffect, useState } from "react";
import { PlaceContext } from "~/contexts";
import RelatedSection from "./RelatedSection";
import PhotographModal from "../PhotographModal";
import type { TIIIFManifest, TIIIFBody, TPhotograph } from "~/types";
import type { ESManifests } from "~/esTypes";

interface Props {
manifest?: ESManifests;
}

const RelatedPhotographs = ({ manifest }: Props) => {
const RelatedPhotographs = () => {
const { place, full } = useContext(PlaceContext);
const [manifest, setManifest] = useState<ESManifests>();
const [photographs, setPhotographs] = useState<TPhotograph[]>();
const [activePhotograph, setActivePhotograph] = useState<TIIIFBody>();

useEffect(() => {
const manifestLabel = full ? "combined" : "photographs";
setManifest(
place.manifests.find(
(placeManifest) => placeManifest.label === manifestLabel
)
);
}, [place, full]);

useEffect(() => {
const fetchIIIF = async () => {
if (!manifest) return;
Expand All @@ -28,10 +36,11 @@ const RelatedPhotographs = ({ manifest }: Props) => {
})
);
};
fetchIIIF();
if (manifest) fetchIIIF();
}, [manifest]);

useEffect(() => {
console.log("🚀 ~ useEffect ~ photographs:", photographs);
if (!photographs) return;
setActivePhotograph(photographs[0].body);
}, [photographs]);
Expand Down
Loading

0 comments on commit d53f17e

Please sign in to comment.