我对编码还很陌生,作为一个很好的项目,我想制作一个 gpx 到 stl 转换器。经过一些研究后,我得出的结论是,这一定是可能的。我在这个项目中使用reactJS。
我对应该如何做的发现:
**我目前的问题:**
这是我当前的代码:
import React, { useState } from 'react';
function FileUploader({ onFileUpload }) {
const [selectedFile, setSelectedFile] = useState(null);
const handleFileChange = async (e) => {
const file = e.target.files[0];
// Lees de inhoud van het GPX-bestand
const fileContent = await readFileContent(file);
setSelectedFile(file);
onFileUpload({ file, fileContent });
};
const readFileContent = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
resolve(e.target.result);
};
reader.onerror = (e) => {
reject(new Error('Error reading file.'));
};
reader.readAsText(file);
});
};
return (
<div className="file-uploader">
<label>
Selecteer een GPX-bestand:
<input type="file" accept=".gpx" onChange={handleFileChange} />
</label>
</div>
);
}
export default FileUploader;
**// Converter.js
**
import React, { useEffect, useRef } from 'react';
import * as THREE from 'three';
import { STLExporter } from 'three/addons/exporters/STLExporter.js';
function Converter({ gpxFile }) {
const threeContainerRef = useRef(null);
const sceneRef = useRef(null);
const cameraRef = useRef(null);
const rendererRef = useRef(null);
const downloadSTL = () => {
const STLExporterInstance = new STLExporter();
const stlData = STLExporterInstance.parse(sceneRef.current);
const blob = new Blob([stlData], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
const downloadLink = document.createElement('a');
downloadLink.href = url;
downloadLink.download = 'geconverteerd_model.stl';
downloadLink.click();
// Optioneel: Opruimen van de URL en het element
URL.revokeObjectURL(url);
//renderer.domElement.remove();
};
useEffect(() => {
const convertGPXtoSTL = (gpxData) => {
const validateGPX = (gpxData) => {
try {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(gpxData, 'text/xml');
const trkpts = xmlDoc.querySelectorAll('trkpt');
if (!trkpts.length) {
throw new Error('Geen trackpunten gevonden in het GPX-bestand.');
}
return trkpts;
} catch (error) {
throw new Error(`Ongeldige GPX-gegevens: ${error.message}`);
}
};
const optimizeGPXData = (trkpts) => {
const points = [];
trkpts.forEach((trkpt) => {
const lat = parseFloat(trkpt.getAttribute('lat'));
const lon = parseFloat(trkpt.getAttribute('lon'));
const eleNode = trkpt.querySelector('ele');
if (eleNode) {
const ele = parseFloat(eleNode.textContent);
points.push({ lat, lon, ele });
}
});
return points;
};
const trkpts = validateGPX(gpxData);
const points = optimizeGPXData(trkpts);
console.log('Geoptimaliseerde GPX-punten:', points);
return points;
};
const create3DScene = (points) => {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
threeContainerRef.current.appendChild(renderer.domElement);
const material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
// Maak een geometrie voor de lijnen
const geometry = new THREE.BufferGeometry().setFromPoints(
points.map((point) => new THREE.Vector3(point.lon, point.ele, point.lat))
);
// Maak een lijn met de geometrie en het materiaal
const line = new THREE.Line(geometry, material);
scene.add(line);
camera.position.set(points[0].lon, points[0].ele, points[0].lat);
camera.lookAt(new THREE.Vector3(points[points.length - 1].lon, points[points.length - 1].ele, points[points.length - 1].lat));
// Voeg een grid toe voor visuele referentie
const gridHelper = new THREE.GridHelper(10, 10);
scene.add(gridHelper);
return { scene, camera, renderer };
};
const points = convertGPXtoSTL(gpxFile.fileContent);
const { scene, camera, renderer } = create3DScene(points);
sceneRef.current = scene;
cameraRef.current = camera;
rendererRef.current = renderer;
// Animeren van de scene
const animate = () => {
requestAnimationFrame(animate);
// Voeg hier eventuele animaties of updates toe
renderer.render(scene, camera);
};
animate();
// Voeg cleanup-functie toe
return () => {
renderer.domElement.remove();
};
}, [gpxFile.fileContent]);
return (
<div className="converter">
<h2>GPX-bestand geüpload:</h2>
<p>Bestandsnaam: {gpxFile.file.name}</p>
<p>Bestandsinhoud: {gpxFile.fileContent}</p>
<h2>3D-weergave van GPX-data:</h2>
<div ref={threeContainerRef}></div>
<button onClick={downloadSTL}>Download STL</button>
</div>
);
}
export default Converter;
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
这个问题似乎与您在 Three.js 中为路线创建几何图形并将其导出到 STL 的方式有关
2)在downloadSTL()中,在导出到STL之前确保场景具有有效的几何体。另外,考虑使用三个/examples/jsm/exporters/STLExporter.js中的STLExporter