抄的b站一个大佬的 添加链接描述 vite建的项目vue3+ts 地图数据需要自己下载 https://overpass-turbo.eu/ 浏览器需要调成英文模式不然下不下来(18年以前貌似没事)
<template>
<div ref="statsDivRef"></div>
<div ref="threeRef"></div>
</template>
<script lang="ts">
import {
reactive,
toRefs,
onBeforeMount,
onMounted,
defineComponent,
ref,
render,
} from "vue";
import {
AmbientLight,
AnimationMixer,
AxesHelper,
BoxGeometry,
BufferAttribute,
BufferGeometry,
Camera,
Clock,
Color,
DirectionalLight,
DoubleSide,
ExtrudeBufferGeometry,
Fog,
FogExp2,
GridHelper,
Group,
HemisphereLight,
Line,
LineBasicMaterial,
LinePieces,
Mesh,
MeshBasicMaterial,
MeshLambertMaterial,
MeshNormalMaterial,
MeshPhongMaterial,
PerspectiveCamera,
PlaneBufferGeometry,
PlaneGeometry,
PointLight,
PointLightShadow,
Scene,
Shape,
SphereGeometry,
SpotLight,
SpotLightHelper,
Vector3,
WebGLRenderer,
} from "three";
import States from "stats.js";
import * as dat from "dat.gui";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { MapControls } from "three/examples/jsm/controls/OrbitControls.js";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
import { getDistance, getRhumbLineBearing } from "geolib";
interface DataProps {}
export default defineComponent({
name: "ExampleB",
setup() {
let camera: any;
let scene: any;
let group: any;
let controls: any;
let light: any;
let center = [-3.1846411, 55.9457427];
let MAT_EUILDING: any;
const threeRef = ref();
const statsDivRef = ref<HTMLDivElement>();
const statsRef = ref<States>();
function initStats() {
statsRef.value = new States();
statsRef.value.showPanel(0);
if (statsDivRef.value) {
statsDivRef.value.appendChild(statsRef.value.dom);
}
}
function groupObj() {
group = new Group();
scene.add(group);
}
function Awake() {
threeRef;
scene = new Scene();
scene.background = new Color(0x222222);
camera = new PerspectiveCamera(
25,
window.innerWidth / window.innerHeight,
1,
100
);
camera.position.set(8, 4, 0);
light = new AmbientLight(0xfafafa, 0.25);
let light1 = new PointLight(0xfafafa, 0, 4);
light1.position.set(100, 90, 40);
let light2 = new PointLight(0xfafafa, 0, 4);
light2.position.set(200, 90, -40);
scene.add(light);
scene.add(light1);
scene.add(light2);
let gh = new GridHelper(
60,
160,
new Color(0x555555),
new Color(0x333333)
);
scene.add(gh);
let renderer = new WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
threeRef.value.appendChild(renderer.domElement);
controls = new MapControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.screenSpacePanning = false;
controls.maxDistance = 800;
controls.update();
Update();
MAT_EUILDING = new MeshNormalMaterial();
GetGeoJson();
function Update() {
window.addEventListener("resize", onWindowResize, false);
requestAnimationFrame(Update);
renderer.render(scene, camera);
controls.update();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function GetGeoJson() {
fetch("./assets/export.geojson").then((res) => {
res.json().then((data) => {
loadBuilding(data);
});
});
}
function loadBuilding(data: any) {
let features = data.features;
for (let i = 0; i < features.length; i++) {
let fel = features[i];
if (!fel["properties"]) return;
if (fel.properties["building"]) {
addBuilding(
fel.geometry.coordinates,
fel.properties,
fel.properties["building:levels"]
);
}
}
}
function addBuilding(data: any, info: any, height = 1) {
for (let i = 0; i < data.length; i++) {
let el = data[i];
let shape = genShape(el, center);
let geometry = genGeometry(shape, {
curveSegments: 1,
depth: 0.05 * height,
bevelEnabled: false,
});
geometry.rotateX(Math.PI /2)
geometry.rotateZ(Math.PI)
let mesh = new Mesh(geometry, MAT_EUILDING);
scene.add(mesh);
}
}
function genShape(points: any, el: any) {
let shape = new Shape();
for (let index = 0; index < points.length; index++) {
let elp = points[index];
elp = GPSPosition(elp, center);
if (index == 0) {
shape.moveTo(elp[0], elp[1]);
} else {
shape.lineTo(elp[0], elp[1]);
}
}
return shape;
}
function GPSPosition(objPosi: any, centerPosi: any) {
let dis = getDistance(objPosi, centerPosi);
let bearing = getRhumbLineBearing(objPosi, centerPosi);
let x = centerPosi[0] + dis * Math.cos((bearing * Math.PI) / 180);
let y = centerPosi[1] + dis * Math.sin((bearing * Math.PI) / 180);
return [-x / 100, y / 100];
}
function genGeometry(shape: any, config: any) {
let genGeometry = new ExtrudeBufferGeometry(shape, config);
genGeometry.computeBoundingBox();
return genGeometry;
}
}
onMounted(() => {
Awake();
});
return {
statsDivRef,
threeRef,
};
},
});
</script>
<style scoped></style>
|