Skip to content

Commit

Permalink
Implement fly to on selection for CCD, CD, and project layers with ne…
Browse files Browse the repository at this point in the history
…w FlyToGeoJsonExtension

Co-authored-by: horatio <[email protected]>
  • Loading branch information
TylerMatteo and horatiorosa committed Aug 21, 2024
1 parent 9049b5a commit 328101b
Show file tree
Hide file tree
Showing 9 changed files with 13,086 additions and 15,519 deletions.
5 changes: 5 additions & 0 deletions app/components/atlas.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
useCityCouncilDistrictsLayer,
useCommunityDistrictLayer,
useCityCouncilDistrictLayer,
useCapitalProjectBudgetedGeoJsonLayer,
} from "./layers";
import type { MapView, MapViewState } from "@deck.gl/core";

Expand All @@ -27,6 +28,8 @@ const MIN_ZOOM = 10;

export function Atlas() {
const capitalProjectsLayer = useCapitalProjectsLayer();
const capitalProjectBudgetedGeoJsonLayer =
useCapitalProjectBudgetedGeoJsonLayer();
const communityDistrictsLayer = useCommunityDistrictsLayer();
const communityDistrictLayer = useCommunityDistrictLayer();
const cityCouncilDistrictsLayer = useCityCouncilDistrictsLayer();
Expand Down Expand Up @@ -56,6 +59,7 @@ export function Atlas() {
viewState={viewState}
onViewStateChange={({ viewState: newViewState }) => {
setViewState({
...newViewState,
longitude: Math.min(
-73.6311,
Math.max(-74.3308, newViewState.longitude),
Expand All @@ -70,6 +74,7 @@ export function Atlas() {
style={{ height: "100vh", width: "100vw" }}
layers={[
capitalProjectsLayer,
capitalProjectBudgetedGeoJsonLayer,
communityDistrictsLayer,
communityDistrictLayer,
cityCouncilDistrictsLayer,
Expand Down
1 change: 1 addition & 0 deletions app/components/layers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { useCommunityDistrictsLayer } from "./useCommunityDistrictsLayer.client"
export { useCommunityDistrictLayer } from "./useCommunityDistrictLayer.client";
export { useCityCouncilDistrictsLayer } from "./useCityCouncilDistrictsLayer.client";
export { useCityCouncilDistrictLayer } from "./useCityCouncilDistrictLayer.client";
export { useCapitalProjectBudgetedGeoJsonLayer } from "./useCapitalProjectBudgetedGeoJsonLayer.client";
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GeoJsonLayer } from "@deck.gl/layers";
import { CapitalProjectBudgetedGeoJson } from "~/gen";
import { useParams } from "@remix-run/react";
import { FlyToGeoJsonExtension } from "../../extensions";

export function useCapitalProjectBudgetedGeoJsonLayer() {
const { managingCode, capitalProjectId } = useParams();

return new GeoJsonLayer<CapitalProjectBudgetedGeoJson>({
id: "capitalProjectBudgetedGeoJson",
data:
managingCode === undefined || capitalProjectId === undefined
? []
: `${import.meta.env.VITE_ZONING_API_URL}/api/capital-projects/${managingCode}/${capitalProjectId}/geojson`,
pickable: true,
getFillColor: ({ id }) => {
switch (id) {
case `${managingCode}${capitalProjectId}`:
return [56, 178, 172, 166];
default:
return [217, 107, 39, 166];
}
},
getPointRadius: 5,
getLineColor: [255, 255, 255, 255],
getLineWidth: 1,
updateTriggers: {
getFillColor: [managingCode, capitalProjectId],
getPointColor: [managingCode, capitalProjectId],
},
extensions: [new FlyToGeoJsonExtension()],
});
}
2 changes: 2 additions & 0 deletions app/components/layers/useCityCouncilDistrictLayer.client.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { GeoJsonLayer } from "@deck.gl/layers";
import { useParams } from "@remix-run/react";
import { FlyToGeoJsonExtension } from "../../extensions";

export function useCityCouncilDistrictLayer() {
const { cityCouncilDistrictId } = useParams();
Expand All @@ -17,5 +18,6 @@ export function useCityCouncilDistrictLayer() {
lineWidthUnits: "pixels",
getLineWidth: 3,
getLineColor: [49, 151, 149],
extensions: [new FlyToGeoJsonExtension()],
});
}
2 changes: 2 additions & 0 deletions app/components/layers/useCommunityDistrictLayer.client.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { GeoJsonLayer } from "@deck.gl/layers";
import { useParams } from "@remix-run/react";
import { FlyToGeoJsonExtension } from "../../extensions";

export function useCommunityDistrictLayer() {
const { boroughId, communityDistrictId } = useParams();
Expand All @@ -18,5 +19,6 @@ export function useCommunityDistrictLayer() {
lineWidthUnits: "pixels",
getLineWidth: 3,
getLineColor: [49, 151, 149],
extensions: [new FlyToGeoJsonExtension()],
});
}
45 changes: 45 additions & 0 deletions app/extensions/FlyToGeoJsonExtension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
Layer,
LayerExtension,
UpdateParameters,
FlyToInterpolator,
WebMercatorViewport,
} from "@deck.gl/core";
import { bbox } from "@turf/bbox";
import { Geometry } from "geojson";

export class FlyToGeoJsonExtension extends LayerExtension {
updateState(
this: Layer,
{ props, oldProps, changeFlags }: UpdateParameters<Layer>,
): void {
const { deck: deckInstance } = this.context;
if (deckInstance === undefined) {
throw new Error("Deck instance undefined in FlyToGeoJsonExtension");
}
if (
!Array.isArray(props.data) &&
((Array.isArray(oldProps.data) && oldProps.data.length === 0) ||
changeFlags.dataChanged)
) {
const viewport = this.context.viewport as WebMercatorViewport;
const [minX, minY, maxX, maxY] = bbox(props.data as Geometry);
const { longitude, latitude, zoom } = viewport.fitBounds([
[minX, minY],
[maxX, maxY],
]);
const newViewState = {
longitude,
latitude,
zoom: zoom - 0.25,
transitionDuration: 750,
transitionInterpolator: new FlyToInterpolator(),
};
deckInstance.props.onViewStateChange({
viewState: newViewState,
viewId: viewport.id,
interactionState: {},
});
}
}
}
1 change: 1 addition & 0 deletions app/extensions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { FlyToGeoJsonExtension } from './FlyToGeoJsonExtension';
Loading

0 comments on commit 328101b

Please sign in to comment.