Reputation: 2880
I have a Map where I draw polygons for the coordinates that define the roofs:
However, I struggle to disable specific areas on the roofs by making them transparent ( the gray area ) where these should not colored.
Example:
I tried to use the Turf Mask but it does not have supported types in TypeScript.
"use client";
import mapboxGL from "mapbox-gl";
import { useEffect } from "react";
import * as turf from "@turf/turf";
mapboxGL.accessToken =
"pk.eyJ1IjoibWVuYWktYWxhLWVkZGluZSIsImEiOiJjbHVicnFzc2swZWVvMm1wOTMxeDIzODEwIn0.Eyhkr7IB2xn7t7qu81lZdQ";
const roofs = [
{
id: 1,
coords: [
[
[13.39064959480109, 52.502411506536646],
[13.390677477503317, 52.502266943310815],
[13.391043798518297, 52.50229152494538],
[13.391029771613262, 52.502425707597695],
[13.390945162035308, 52.502404052414676],
[13.39064959480109, 52.502411506536646],
],
],
panelsCoords: [
[
[13.391003158801936, 52.5023203928001],
[13.391003158801936, 52.50230342787046],
[13.391031554050215, 52.50230342787046],
[13.391031554050215, 52.5023203928001],
[13.391003158801936, 52.5023203928001],
],
[
[13.390966384830506, 52.502318394483325],
[13.390966384830506, 52.502301339310236],
[13.390994831868682, 52.502301339310236],
[13.390994831868682, 52.502318394483325],
[13.390966384830506, 52.502318394483325],
],
[
[13.390919224917724, 52.5023165822366],
[13.390919224917724, 52.502298657033435],
[13.390949197666572, 52.502298657033435],
[13.390949197666572, 52.5023165822366],
[13.390919224917724, 52.5023165822366],
],
],
floorplanCoords: [
[
[13.390796619117907, 52.50227312401066],
[13.390811606839435, 52.50216060100934],
[13.390931508610208, 52.50216820392353],
[13.390912773958291, 52.502280726905866],
[13.390796619117907, 52.50227312401066], // Closed loop
],
],
},
{
id: 2,
coords: [
[
[13.391047919266668, 52.502284415735176],
[13.390678637916295, 52.502259059516746],
[13.390709077593073, 52.502108872386145],
[13.391069547458784, 52.50213276582787],
[13.391047919266668, 52.502284415735176],
],
],
panelsCoords: [
[
[13.390988642150461, 52.50227125005367],
[13.390988642150461, 52.50225320812541],
[13.39102709226978, 52.50225320812541],
[13.39102709226978, 52.50227125005367],
[13.390988642150461, 52.50227125005367],
],
],
},
];
const BuildingMap = () => {
useEffect(() => {
const map = new mapboxGL.Map({
container: "map-container",
style: "mapbox://styles/mapbox/satellite-v9",
zoom: 20,
center: [13.390853194154147, 52.50235398440585], // Adjust as needed
antialias: true,
});
map.on("load", function () {
roofs.forEach((roof) => {
// Process the main roof polygon (if needed)
// For each roof, add its main polygon
if (roof.coords) {
const polygon = turf.polygon(roof.coords, { name: "roof" });
map.addSource(`roof-${roof.id}`, {
type: "geojson",
data: polygon,
});
map.addLayer({
id: `roof-${roof.id}`,
type: "fill",
source: `roof-${roof.id}`,
paint: {
"fill-color": "green", // Example roof color
"fill-opacity": 0.6,
},
});
map.addSource(`floorplan-${roof.id}`, {
type: "geojson",
data: {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {},
geometry: {
coordinates: [
[
[13.390796619117907, 52.50227312401066],
[13.390811606839435, 52.50216060100934],
[13.390931508610208, 52.50216820392353],
[13.390912773958291, 52.502280726905866],
[13.390796619117907, 52.50227312401066],
],
],
type: "Polygon",
},
},
],
},
});
map.addLayer({
id: `floorplan-${roof.id}`,
type: "fill",
source: `floorplan-${roof.id}`,
paint: {
"fill-color": "gray", // Example panel color, adjust as needed
"fill-opacity": 0.8,
},
});
}
// Process panels if they exist
if (roof.panelsCoords) {
const panelFeatures: GeoJSON.Feature<GeoJSON.Geometry>[] =
roof.panelsCoords.map((panelCoords, index) => {
// Create a Turf.js polygon for the current panel
const panelPolygon = turf.polygon([panelCoords]);
// Calculate the area of the panel using Turf.js
const area = turf.area(panelPolygon);
// Return a feature with the area included in properties
return {
type: "Feature",
properties: {
panelId: index,
area: area, // Add the calculated area to the feature properties
},
geometry: {
type: "Polygon",
coordinates: [panelCoords],
},
};
});
if (panelFeatures) {
map.addSource(`panels-${roof.id}`, {
type: "geojson",
data: {
type: "FeatureCollection",
features: panelFeatures,
},
});
map.addLayer({
id: `panels-${roof.id}`,
type: "fill",
source: `panels-${roof.id}`,
paint: {
"fill-color": "red", // Example panel color, adjust as needed
"fill-opacity": 0.8,
},
});
}
}
});
});
return () => {
map.remove();
};
// map.on("click", "polygon", function (e) {
// const polygon = map.getPaintProperty("polygon", "fill-color");
// // e.target.setPadding({left:4,top:4})
// if (polygon === "green") {
// map.setPaintProperty("polygon", "fill-color", "transparent");
// map.setPaintProperty("polygon", "fill-outline-color", "green");
// // Change the fill color to red
// // Change the fill color to red
// return;
// } else {
// map.setPaintProperty("polygon", "fill-color", "green"); // Change the fill color to red
// }
// // You can add your custom logic here for when the polygon is clicked
// // For example, display an alert or a custom popup
// });
// // Change the cursor to a pointer when the mouse is over the polygon
// map.on("mouseenter", "polygon", function () {
// map.getCanvas().style.cursor = "pointer";
// });
// // Change it back to the default when it leaves.
// map.on("mouseleave", "polygon", function () {
// map.getCanvas().style.cursor = "";
// });
}, []);
return (
<div id="map-container" style={{ width: "100vw", height: "100vh" }}></div>
);
};
export default BuildingMap;
My question is how to apply the example of Mask by Turf using MapboxGL?
Upvotes: 0
Views: 88