diff --git a/src/three/Space.tsx b/src/three/Space.tsx index 9e0d311..9799724 100644 --- a/src/three/Space.tsx +++ b/src/three/Space.tsx @@ -1,10 +1,8 @@ import React, { useEffect, useState } from "react"; -import { Canvas, useThree } from "@react-three/fiber"; +import { Canvas, useThree, useLoader } from "@react-three/fiber"; import { useAreaStore } from "@/state/areaStore"; import { OrbitControls, Html } from "@react-three/drei"; import * as THREE from "three"; -import { NextButton } from "@/components/button/BottomButton"; -import { ChevronRight } from "lucide-react"; import { css } from "@emotion/react"; import { useActionStore } from "@/state/exportStore"; import { GLTFExporter } from "three/examples/jsm/Addons.js"; @@ -21,7 +19,6 @@ function Building({ const [hovered, setHovered] = useState(false); const [clicked, setClicked] = useState(false); const [hoverPos, setHoverPos] = useState(null); - return ( { @@ -76,20 +73,114 @@ function Building({ ); } -export function Space() { - const areas = useAreaStore((state) => state.areas); +function Roads({ area }: { area: any }) { + const [roads, setRoads] = useState([]); const center = useAreaStore((state) => state.center); - const refLat = (center[1].lat + center[0].lat) / 2; const refLng = (center[1].lng + center[0].lng) / 2; - const scale = 111000; - + const scale = 51000; function project(lat: number, lng: number) { const x = (lng - refLng) * scale; const y = (lat - refLat) * scale; return new THREE.Vector2(x, y); } + useEffect(() => { + const south = area[1].lat; + const west = area[1].lng; + const north = area[0].lat; + const east = area[0].lng; + const query = `[out:json][timeout:25];(way["highway"](${south},${west},${north},${east}););out body geom;`; + fetch("https://overpass-api.de/api/interpreter", { + method: "POST", + body: query, + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + }) + .then((response) => response.json()) + .then((data) => { + setRoads(data.elements); + }) + .catch((err) => console.error(err)); + }, [area]); + return ( + <> + {roads.map((road, index) => { + if (!road.geometry || road.geometry.length < 2) return null; + const points = road.geometry.map((pt: any) => { + const v = project(pt.lat, pt.lon); + return new THREE.Vector3(v.x, 0.1, -v.y); + }); + const lineGeometry = new THREE.BufferGeometry().setFromPoints(points); + return ( + + + + ); + })} + + ); +} +export function Export() { + const { scene } = useThree(); + const action = useActionStore((state) => state.action); + const setAction = useActionStore((state) => state.setAction); + useEffect(() => { + if (action === true) { + setAction(false); + exportGLB(); + } + }, [action, setAction, scene]); + const exportGLB = () => { + const sceneClone = scene.clone(true); + sceneClone.traverse((child) => { + if (child.userData && child.userData.skipExport === true) { + child.parent?.remove(child); + } + if ((child as any).isHtml === true) { + child.parent?.remove(child); + } + }); + const exporter = new GLTFExporter(); + const options = { binary: true, embedImages: true }; + exporter.parse( + sceneClone, + (result) => { + if (result instanceof ArrayBuffer) { + const blob = new Blob([result], { type: "model/gltf-binary" }); + const link = document.createElement("a"); + link.style.display = "none"; + document.body.appendChild(link); + link.href = URL.createObjectURL(blob); + link.download = "scene.glb"; + link.click(); + document.body.removeChild(link); + } else { + console.error("GLB export failed: unexpected result", result); + } + }, + (error) => { + console.error("An error occurred during export", error); + }, + options + ); + }; + return null; +} +export function Space() { + const areas = useAreaStore((state) => state.areas); + const center = useAreaStore((state) => state.center); + const refLat = (center[1].lat + center[0].lat) / 2; + const refLng = (center[1].lng + center[0].lng) / 2; + const scale = 51000; + function project(lat: number, lng: number) { + const x = (lng - refLng) * scale; + const y = (lat - refLat) * scale; + return new THREE.Vector2(x, y); + } const areaData = () => { const result: Array<{ shape: THREE.Shape; @@ -122,9 +213,7 @@ export function Space() { }); return result; }; - const buildingsData = areaData(); - return ( @@ -143,71 +232,10 @@ export function Space() { tags={item.tags} /> ))} + ); } - -// function Floor() { -// return ( -// -// -// -// -// ); -// } - -export function Export() { - const { scene } = useThree(); - - const action = useActionStore((state) => state.action); - const setAction = useActionStore((state) => state.setAction); - - useEffect(() => { - if (action == true) { - setAction(false); - console.log(action); - exportGLB(); - } - }, [action]); - - const exportGLB = () => { - const sceneClone = scene.clone(true); - sceneClone.traverse((child) => { - if (child.userData && child.userData.skipExport === true) { - if (child.parent) child.parent.remove(child); - } - }); - - const exporter = new GLTFExporter(); - const options = { - binary: true, - embedImages: true, - }; - exporter.parse( - sceneClone, - (result) => { - if (result instanceof ArrayBuffer) { - const blob = new Blob([result], { type: "model/gltf-binary" }); - const link = document.createElement("a"); - link.style.display = "none"; - document.body.appendChild(link); - link.href = URL.createObjectURL(blob); - link.download = "scene.glb"; - link.click(); - document.body.removeChild(link); - } else { - console.error("GLB export failed: unexpected result", result); - } - }, - function () { - console.log("An error happened"); - }, - options - ); - }; - - return <>; -}