Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paint by county #74

Merged
merged 4 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"@sentry/nextjs": "^8.26.0",
"@stitches/react": "^1.2.8",
"@tanstack/react-query": "^5.51.11",
"@turf/boolean-within": "^7.1.0",
"@turf/helpers": "^7.1.0",
"@turf/point-on-feature": "^7.1.0",
"axios": "^1.7.2",
"idb-keyval": "^6.2.1",
"lodash": "^4.17.21",
Expand Down
22 changes: 16 additions & 6 deletions app/src/app/components/sidebar/PaintByCounty.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ import { Box, Text, Checkbox, Flex } from "@radix-ui/themes";
import { useMapStore } from "@/app/store/mapStore";
import { COUNTY_LAYER_IDS } from "../../constants/layers";
import { useState, useEffect } from "react";
import {
getFeaturesInBbox,
getFeaturesIntersectingCounties,
} from "../../utils/helpers";

export default function PaintByCounty() {
const { mapRef, addVisibleLayerIds } = useMapStore((state) => ({
mapRef: state.mapRef,
addVisibleLayerIds: state.addVisibleLayerIds,
}));
const { mapRef, addVisibleLayerIds, setPaintFunction } = useMapStore(
(state) => ({
mapRef: state.mapRef,
addVisibleLayerIds: state.addVisibleLayerIds,
setPaintFunction: state.setPaintFunction,
}),
);
const [checked, setChecked] = useState(false);

useEffect(() => {
Expand All @@ -18,6 +25,9 @@ export default function PaintByCounty() {
mapRef.current?.setLayoutProperty(layerId, "visibility", "visible");
});
addVisibleLayerIds(COUNTY_LAYER_IDS);
setPaintFunction(getFeaturesIntersectingCounties);
} else {
setPaintFunction(getFeaturesInBbox);
}
}, [checked, mapRef, addVisibleLayerIds]);

Expand All @@ -33,8 +43,8 @@ export default function PaintByCounty() {
Paint by County
</Flex>
</Text>
<Text size="1" color="red">
<b>Note:</b> paint-by-county feature not yet implemented.
<Text size="1" color="gray">
Paint-by-county feature is still experimental.
</Text>
</Box>
);
Expand Down
10 changes: 10 additions & 0 deletions app/src/app/constants/basemapLayers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1673,6 +1673,16 @@ export const BASEMAP_LAYERS: LayerSpecification[] = [
"text-halo-width": 1.5,
},
},
{
id: "counties_fill",
type: "fill",
source: "counties",
"source-layer": "tl_2023_us_county",
paint: {
"fill-color": "#fff",
"fill-opacity": 0,
},
Comment on lines +1681 to +1684
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of an ugly hack for queryRenderedFeatures to work but was fine with it.

},
{
id: "counties_boundary",
type: "line",
Expand Down
6 changes: 1 addition & 5 deletions app/src/app/constants/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { LngLatLike } from "maplibre-gl";
import type {
MapOptions,
StyleSpecification,
LayerSpecification,
} from "maplibre-gl";
import type { MapOptions, StyleSpecification } from "maplibre-gl";
import { BASEMAP_LAYERS } from "./basemapLayers";

export const MAP_CENTER: LngLatLike = [-105.358887, 39.113014]; // colorado
Expand Down
10 changes: 9 additions & 1 deletion app/src/app/store/mapStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import {
BLOCK_HOVER_LAYER_ID,
} from "../constants/layers";
import type { UseQueryResult } from "@tanstack/react-query";
import { LayerVisibility } from "../utils/helpers";
import {
LayerVisibility,
PaintEventHandler,
getFeaturesInBbox,
} from "../utils/helpers";

export interface MapStore {
mapRef: MutableRefObject<maplibregl.Map | null> | null;
Expand Down Expand Up @@ -45,6 +49,8 @@ export interface MapStore {
setBrushSize: (size: number) => void;
isPainting: boolean;
setIsPainting: (isPainting: boolean) => void;
paintFunction: PaintEventHandler;
setPaintFunction: (paintFunction: PaintEventHandler) => void;
clearMapEdits: () => void;
freshMap: boolean;
setFreshMap: (resetMap: boolean) => void;
Expand Down Expand Up @@ -121,6 +127,8 @@ export const useMapStore = create(
setBrushSize: (size) => set({ brushSize: size }),
isPainting: false,
setIsPainting: (isPainting) => set({ isPainting }),
paintFunction: getFeaturesInBbox,
setPaintFunction: (paintFunction) => set({ paintFunction }),
Comment on lines +130 to +131
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using this pattern made it really easy to handle different behaviors on hover without messing with map events.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i like it!

clearMapEdits: () =>
set({
zoneAssignments: new Map(),
Expand Down
12 changes: 2 additions & 10 deletions app/src/app/utils/events/mapEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ export const handleMapClick = (
const sourceLayer = mapStore.selectedLayer?.name;

if (activeTool === "brush" || activeTool === "eraser") {
const bbox = boxAroundPoint(e, mapStore.brushSize);

const selectedFeatures = map.current?.queryRenderedFeatures(bbox, {
layers: [BLOCK_LAYER_ID],
});
const selectedFeatures = mapStore.paintFunction(map, e, mapStore.brushSize);

if (activeTool === "brush" && sourceLayer) {
// select on both the map object and the store
Expand Down Expand Up @@ -126,12 +122,8 @@ export const handleMapMouseMove = (
const mapStore = useMapStore.getState();
const activeTool = mapStore.activeTool;
const isPainting = mapStore.isPainting;
const brushSize = mapStore.brushSize;
const bbox = boxAroundPoint(e, brushSize);
const sourceLayer = mapStore.selectedLayer?.name;
const selectedFeatures = map.current?.queryRenderedFeatures(bbox, {
layers: [BLOCK_LAYER_ID],
});
const selectedFeatures = mapStore.paintFunction(map, e, mapStore.brushSize);
if (!isPainting && sourceLayer) {
HighlightFeature(selectedFeatures, map, hoverFeatureIds, sourceLayer);
} else if (activeTool === "brush" && isPainting && sourceLayer) {
Expand Down
Loading