Spaces:
Runtime error
Runtime error
| import React, {useState, useEffect} from 'react'; | |
| import {createRoot} from 'react-dom/client'; | |
| import {Map} from 'react-map-gl'; | |
| import maplibregl from 'maplibre-gl'; | |
| import {AmbientLight, PointLight, LightingEffect} from '@deck.gl/core'; | |
| import DeckGL from '@deck.gl/react'; | |
| import {PolygonLayer} from '@deck.gl/layers'; | |
| import {TripsLayer} from '@deck.gl/geo-layers'; | |
| import { Box } from '@mui/system'; | |
| // Source data CSV, Attribution to CARTO, OpenStreetMap contributors to deck.gl trips-layer example | |
| const DATA_URL = { | |
| // BUILDINGS:'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/trips/buildings.json', // eslint-disable-line | |
| BUILDINGS: '/map1.json' | |
| }; | |
| const ambientLight = new AmbientLight({ | |
| color: [255, 255, 255], | |
| intensity: 6.0 | |
| }); | |
| const pointLight = new PointLight({ | |
| color: [255, 255, 255], | |
| intensity: 1.0, | |
| position: [-6.4741164, | |
| 53.4622087, 8000] | |
| }); | |
| // const lightingEffect = new LightingEffect({ambientLight, pointLight}); | |
| const lightingEffect = new LightingEffect({ambientLight, pointLight}); | |
| const material = { | |
| ambient: 0.1, | |
| diffuse: 0.6, | |
| shininess: 32, | |
| specularColor: [60, 64, 70] | |
| }; | |
| const DEFAULT_THEME = { | |
| buildingColor: [51, 204, 255], | |
| trailColor0: [253, 128, 93], | |
| trailColor1: [23, 184, 190], | |
| material, | |
| effects: [lightingEffect] | |
| }; | |
| const INITIAL_VIEW_STATE = { | |
| longitude: -6.269218, | |
| latitude: 53.342505, | |
| zoom: 14.64, | |
| pitch: 59.31, | |
| bearing: 0 | |
| }; | |
| const MAP_STYLE = 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json'; | |
| const landCover = [ | |
| [ | |
| [-74.0, 40.7], | |
| [-74.02, 40.7], | |
| [-74.02, 40.72], | |
| [-74.0, 40.72] | |
| ] | |
| ]; | |
| export default function Map3D({ | |
| buildings = DATA_URL.BUILDINGS, | |
| initialViewState = INITIAL_VIEW_STATE, | |
| mapStyle = MAP_STYLE, | |
| theme = DEFAULT_THEME, | |
| }) { | |
| const [buildingData, setBuildingData] = useState(null); | |
| const [viewState, setViewState] = useState(initialViewState); // Add this line to manage view state | |
| useEffect(() => { | |
| fetch(buildings) | |
| .then((response) => response.json()) | |
| .then((json) => { | |
| const allData = json.datasets[0].data.allData.map(([feature]) => feature); | |
| setBuildingData(allData); | |
| }) | |
| .catch((error) => { | |
| console.error('Error fetching buildings data:', error); | |
| }); | |
| }, [buildings]); | |
| if (!buildingData) { | |
| return <div>Loading...</div>; | |
| } | |
| const layers = [ | |
| new PolygonLayer({ | |
| id: 'ground', | |
| data: landCover, | |
| getPolygon: f => f, | |
| stroked: false, | |
| getFillColor: [0, 0, 0, 0] | |
| }), | |
| new PolygonLayer({ | |
| id: 'buildings', | |
| data: buildingData, | |
| extruded: true, | |
| wireframe: false, | |
| opacity: 0.5, | |
| getPolygon: (f) => f.geometry.coordinates[0][0], | |
| getElevation: (f) => f.properties.Height_Met, | |
| getFillColor: theme.buildingColor, | |
| material: theme.material, | |
| }) | |
| ]; | |
| const onViewStateChange = ({ viewState }) => { | |
| setViewState(viewState); | |
| }; | |
| return ( | |
| <Box sx={{ width: '100%', height: '100%', position: 'relative', borderRadius: '15px', overflow: 'hidden'}}> | |
| <DeckGL | |
| style={{ width: '100%', height: '100%', position: 'absolute'}} | |
| layers={layers} | |
| effects={theme.effects} | |
| initialViewState={initialViewState} | |
| controller={true} | |
| viewState={viewState} | |
| onViewStateChange={onViewStateChange} | |
| > | |
| <Map reuseMaps mapLib={maplibregl} mapStyle={mapStyle} preventStyleDiffing={true} attributionControl={false} /> | |
| </DeckGL> | |
| <div | |
| style={{ | |
| position: 'absolute', | |
| bottom: '10px', | |
| right: '10px', | |
| color: 'white', | |
| background: 'rgba(0, 0, 0, 0.5)', | |
| padding: '5px', | |
| borderRadius: '5px', | |
| }} | |
| > | |
| Longitude: {viewState.longitude.toFixed(6)} | |
| <br /> | |
| Latitude: {viewState.latitude.toFixed(6)} | |
| <br /> | |
| Zoom: {viewState.zoom.toFixed(2)} | |
| <br /> | |
| Pitch: {viewState.pitch.toFixed(2)} | |
| <br /> | |
| Bearing: {viewState.bearing.toFixed(2)} | |
| </div> | |
| </Box> | |
| ); | |
| } | |