Add a data visualization layer to the Mapbox GL map page (heatmap, markers, clusters, isochrones). Use when building geospatial features like price heat maps or catchment analysis.
Adds a new data layer to the existing map page. Supports heatmaps, clustered markers, polygon overlays, and isochrone areas.
Create the data API endpoint:
router.get("/analytics/geo/{layer-name}", authenticateToken, async (req, res) => {
const data = await prisma.properties.findMany({
where: { latitude: { not: null } },
select: { id: true, latitude: true, longitude: true, price: true, type: true },
});
// Return as GeoJSON FeatureCollection
res.json({
type: "FeatureCollection",
features: data.map(p => ({
type: "Feature",
geometry: { type: "Point", coordinates: [p.longitude, p.latitude] },
properties: { id: p.id, price: Number(p.price), type: p.type },
})),
});
});
Add the layer to the map component at apps/web/src/pages/map/index.tsx:
// After map loads:
map.addSource("price-heatmap", { type: "geojson", data: geojsonData });
map.addLayer({
id: "price-heatmap-layer",
type: "heatmap",
source: "price-heatmap",
paint: {
"heatmap-weight": ["interpolate", ["linear"], ["get", "price"], 0, 0, 5000000, 1],
"heatmap-intensity": 1,
"heatmap-radius": 30,
"heatmap-color": [
"interpolate", ["linear"], ["heatmap-density"],
0, "rgba(0,0,0,0)", 0.2, "#ffffb2", 0.4, "#fd8d3c", 0.6, "#f03b20", 0.8, "#bd0026",
],
},
});
Add layer toggle in the map toolbar:
<Button variant={showHeatmap ? "default" : "outline"} onClick={() => toggleLayer("price-heatmap")}>
خريطة الأسعار
</Button>
Add click interaction — click on area → tooltip with aggregated stats.
Use react-query to fetch GeoJSON data with /add-react-query.
/typecheck passes