From f4b6d19eb29f05c61401917bc35330c7280fb909 Mon Sep 17 00:00:00 2001 From: vergiLgood1 Date: Wed, 14 May 2025 12:31:31 +0700 Subject: [PATCH] feat: remove fill when district pop up is close --- .../app/_components/map/layers/layers.tsx | 306 +++++++++--------- 1 file changed, 161 insertions(+), 145 deletions(-) diff --git a/sigap-website/app/_components/map/layers/layers.tsx b/sigap-website/app/_components/map/layers/layers.tsx index 578cf08..d811ad2 100644 --- a/sigap-website/app/_components/map/layers/layers.tsx +++ b/sigap-website/app/_components/map/layers/layers.tsx @@ -11,7 +11,7 @@ import TimelineLayer from "./timeline-layer" import type { ICrimes, IIncidentLogs } from "@/app/_utils/types/crimes" import type { IDistrictFeature } from "@/app/_utils/types/map" -import { createFillColorExpression, processCrimeDataByDistrict } from "@/app/_utils/map" +import { createFillColorExpression, getCrimeRateColor, processCrimeDataByDistrict } from "@/app/_utils/map" import UnclusteredPointLayer from "./uncluster-layer" import { toast } from "sonner" @@ -153,17 +153,20 @@ export default function Layers({ easing: (t) => t * (2 - t), }) - if (map.getLayer("clusters")) { - map.getMap().setLayoutProperty("clusters", "visibility", "visible") - } - if (map.getLayer("unclustered-point")) { - map.getMap().setLayoutProperty("unclustered-point", "visibility", "visible") - } + if (map.getLayer("clusters")) { + map.getMap().setLayoutProperty("clusters", "visibility", "visible") + } + + if (map.getLayer("unclustered-point")) { + map.getMap().setLayoutProperty("unclustered-point", "visibility", "visible") + } if (map.getLayer("district-fill")) { const fillColorExpression = createFillColorExpression(null, crimeDataByDistrict) map.getMap().setPaintProperty("district-fill", "fill-color", fillColorExpression as any) } + + } }, [map, crimeDataByDistrict]) @@ -213,6 +216,19 @@ export default function Layers({ 0, ]) + map.getMap().setPaintProperty("district-extrusion", "fill-extrusion-color", [ + "case", + ["has", "kode_kec"], + [ + "match", + ["get", "kode_kec"], + focusedDistrictId || "", + "transparent", + "transparent", + ], + "transparent", + ]) + if (progress < 1) { animationRef.current = requestAnimationFrame(animate) } else { @@ -270,7 +286,7 @@ export default function Layers({ easing: (t) => t * (2 - t), }) - // Hide clusters when focusing on a district + // Hide clusters when focusing on a district if (map.getLayer("clusters")) { map.getMap().setLayoutProperty("clusters", "visibility", "none") } @@ -289,16 +305,16 @@ export default function Layers({ const customEvent = e as CustomEvent if (!map || !customEvent.detail) return - const { longitude, latitude, zoom, bearing, pitch, duration } = customEvent.detail + const { longitude, latitude, zoom, bearing, pitch, duration } = customEvent.detail - map.flyTo({ - center: [longitude, latitude], - zoom: zoom || 15, - bearing: bearing || 0, - pitch: pitch || 45, - duration: duration || 2000, - }) - } + map.flyTo({ + center: [longitude, latitude], + zoom: zoom || 15, + bearing: bearing || 0, + pitch: pitch || 45, + duration: duration || 2000, + }) + } mapboxMap.getCanvas().addEventListener("mapbox_fly_to", handleFlyToEvent as EventListener) @@ -316,93 +332,93 @@ export default function Layers({ const customEvent = e as CustomEvent console.log("Received incident_click event in layers:", customEvent.detail) - if (!customEvent.detail) { - console.error("Empty incident click event data") - return - } + if (!customEvent.detail) { + console.error("Empty incident click event data") + return + } - // Set the marker interaction flag to prevent district selection - isInteractingWithMarker.current = true + // Set the marker interaction flag to prevent district selection + isInteractingWithMarker.current = true - const incidentId = customEvent.detail.id || customEvent.detail.incidentId || customEvent.detail.incident_id + const incidentId = customEvent.detail.id || customEvent.detail.incidentId || customEvent.detail.incident_id - if (!incidentId) { - console.error("No incident ID found in event data:", customEvent.detail) - return - } + if (!incidentId) { + console.error("No incident ID found in event data:", customEvent.detail) + return + } - console.log("Looking for incident with ID:", incidentId) + console.log("Looking for incident with ID:", incidentId) - let foundIncident: ICrimeIncident | undefined + let foundIncident: ICrimeIncident | undefined - if ( - customEvent.detail.latitude !== undefined && - customEvent.detail.longitude !== undefined && - customEvent.detail.category !== undefined - ) { - foundIncident = { - id: incidentId, - district: customEvent.detail.district, - category: customEvent.detail.category, - type_category: customEvent.detail.type, - description: customEvent.detail.description, - status: customEvent.detail.status || "Unknown", - timestamp: customEvent.detail.timestamp ? new Date(customEvent.detail.timestamp) : undefined, - latitude: customEvent.detail.latitude, - longitude: customEvent.detail.longitude, - address: customEvent.detail.address, - } - } else { - for (const crime of crimes) { - for (const incident of crime.crime_incidents) { - if (incident.id === incidentId || incident.id?.toString() === incidentId?.toString()) { - console.log("Found matching incident:", incident) - foundIncident = { - id: incident.id, - district: crime.districts.name, - description: incident.description, - status: incident.status || "unknown", - timestamp: incident.timestamp, - category: incident.crime_categories.name, - type_category: incident.crime_categories.type, - address: incident.locations.address, - latitude: incident.locations.latitude, - longitude: incident.locations.longitude, - } - break - } - } - if (foundIncident) break - } - } + if ( + customEvent.detail.latitude !== undefined && + customEvent.detail.longitude !== undefined && + customEvent.detail.category !== undefined + ) { + foundIncident = { + id: incidentId, + district: customEvent.detail.district, + category: customEvent.detail.category, + type_category: customEvent.detail.type, + description: customEvent.detail.description, + status: customEvent.detail.status || "Unknown", + timestamp: customEvent.detail.timestamp ? new Date(customEvent.detail.timestamp) : undefined, + latitude: customEvent.detail.latitude, + longitude: customEvent.detail.longitude, + address: customEvent.detail.address, + } + } else { + for (const crime of crimes) { + for (const incident of crime.crime_incidents) { + if (incident.id === incidentId || incident.id?.toString() === incidentId?.toString()) { + console.log("Found matching incident:", incident) + foundIncident = { + id: incident.id, + district: crime.districts.name, + description: incident.description, + status: incident.status || "unknown", + timestamp: incident.timestamp, + category: incident.crime_categories.name, + type_category: incident.crime_categories.type, + address: incident.locations.address, + latitude: incident.locations.latitude, + longitude: incident.locations.longitude, + } + break + } + } + if (foundIncident) break + } + } - if (!foundIncident) { - console.error("Could not find incident with ID:", incidentId) - isInteractingWithMarker.current = false - return + if (!foundIncident) { + console.error("Could not find incident with ID:", incidentId) + isInteractingWithMarker.current = false + return + } + + if (!foundIncident.latitude || !foundIncident.longitude) { + console.error("Found incident has invalid coordinates:", foundIncident) + isInteractingWithMarker.current = false + return + } + + console.log("Setting selected incident:", foundIncident) + + // Clear district selection when showing an incident + setSelectedDistrict(null) + selectedDistrictRef.current = null + setFocusedDistrictId(null) + + setSelectedIncident(foundIncident) + + // Reset the marker interaction flag after a delay + setTimeout(() => { + isInteractingWithMarker.current = false + }, 1000) } - if (!foundIncident.latitude || !foundIncident.longitude) { - console.error("Found incident has invalid coordinates:", foundIncident) - isInteractingWithMarker.current = false - return - } - - console.log("Setting selected incident:", foundIncident) - - // Clear district selection when showing an incident - setSelectedDistrict(null) - selectedDistrictRef.current = null - setFocusedDistrictId(null) - - setSelectedIncident(foundIncident) - - // Reset the marker interaction flag after a delay - setTimeout(() => { - isInteractingWithMarker.current = false - }, 1000) - } - mapboxMap.getCanvas().addEventListener("incident_click", handleIncidentClickEvent as EventListener) document.addEventListener("incident_click", handleIncidentClickEvent as EventListener) @@ -450,64 +466,64 @@ export default function Layers({ if (districtCrime) { const selectedYearNum = year ? Number.parseInt(year) : new Date().getFullYear() - let demographics = districtCrime.districts.demographics?.find((d) => d.year === selectedYearNum) + let demographics = districtCrime.districts.demographics?.find((d) => d.year === selectedYearNum) - if (!demographics && districtCrime.districts.demographics?.length) { - demographics = districtCrime.districts.demographics.sort((a, b) => b.year - a.year)[0] - } + if (!demographics && districtCrime.districts.demographics?.length) { + demographics = districtCrime.districts.demographics.sort((a, b) => b.year - a.year)[0] + } - let geographics = districtCrime.districts.geographics?.find((g) => g.year === selectedYearNum) + let geographics = districtCrime.districts.geographics?.find((g) => g.year === selectedYearNum) - if (!geographics && districtCrime.districts.geographics?.length) { - const validGeographics = districtCrime.districts.geographics - .filter((g) => g.year !== null) - .sort((a, b) => (b.year || 0) - (a.year || 0)) + if (!geographics && districtCrime.districts.geographics?.length) { + const validGeographics = districtCrime.districts.geographics + .filter((g) => g.year !== null) + .sort((a, b) => (b.year || 0) - (a.year || 0)) - geographics = validGeographics.length > 0 ? validGeographics[0] : districtCrime.districts.geographics[0] - } + geographics = validGeographics.length > 0 ? validGeographics[0] : districtCrime.districts.geographics[0] + } - if (!demographics || !geographics) { - console.error("Missing district data:", { demographics, geographics }) - return - } + if (!demographics || !geographics) { + console.error("Missing district data:", { demographics, geographics }) + return + } - const crime_incidents = districtCrime.crime_incidents - .filter((incident) => filterCategory === "all" || incident.crime_categories.name === filterCategory) - .map((incident) => ({ - id: incident.id, - timestamp: incident.timestamp, - description: incident.description, - status: incident.status || "", - category: incident.crime_categories.name, - type: incident.crime_categories.type || "", - address: incident.locations.address || "", - latitude: incident.locations.latitude, - longitude: incident.locations.longitude, - })) + const crime_incidents = districtCrime.crime_incidents + .filter((incident) => filterCategory === "all" || incident.crime_categories.name === filterCategory) + .map((incident) => ({ + id: incident.id, + timestamp: incident.timestamp, + description: incident.description, + status: incident.status || "", + category: incident.crime_categories.name, + type: incident.crime_categories.type || "", + address: incident.locations.address || "", + latitude: incident.locations.latitude, + longitude: incident.locations.longitude, + })) - const updatedDistrict: IDistrictFeature = { - ...selectedDistrictRef.current, - number_of_crime: crimeDataByDistrict[districtId]?.number_of_crime || 0, - level: crimeDataByDistrict[districtId]?.level || selectedDistrictRef.current.level, - demographics: { - number_of_unemployed: demographics.number_of_unemployed, - population: demographics.population, - population_density: demographics.population_density, - year: demographics.year, - }, - geographics: { - address: geographics.address || "", - land_area: geographics.land_area || 0, - year: geographics.year || 0, - latitude: geographics.latitude, - longitude: geographics.longitude, - }, - crime_incidents, - selectedYear: year, - selectedMonth: month, - } + const updatedDistrict: IDistrictFeature = { + ...selectedDistrictRef.current, + number_of_crime: crimeDataByDistrict[districtId]?.number_of_crime || 0, + level: crimeDataByDistrict[districtId]?.level || selectedDistrictRef.current.level, + demographics: { + number_of_unemployed: demographics.number_of_unemployed, + population: demographics.population, + population_density: demographics.population_density, + year: demographics.year, + }, + geographics: { + address: geographics.address || "", + land_area: geographics.land_area || 0, + year: geographics.year || 0, + latitude: geographics.latitude, + longitude: geographics.longitude, + }, + crime_incidents, + selectedYear: year, + selectedMonth: month, + } - selectedDistrictRef.current = updatedDistrict + selectedDistrictRef.current = updatedDistrict setSelectedDistrict((prevDistrict) => { if (