增加一个gis 中国地图的演示

This commit is contained in:
hawk86104 2024-02-24 12:32:44 +08:00
parent c311844701
commit 0d73e5b04b
10 changed files with 304 additions and 1 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ dist
#!/node_modules/@alienkitty/
#!/node_modules/oimophysics/
yarn.lock
yarn-error.log

View File

@ -38,6 +38,7 @@
"cannon-es": "^0.20.0",
"compressing": "^1.10.0",
"core-js": "3.35.1",
"d3-geo": "^3.1.0",
"gl-matrix": "^3.4.3",
"gsap": "3.12.5",
"heatmap.js-fix": "^1.0.0",

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1,3 +1,11 @@
/*
* @Description:
* @Version: 1.668
* @Autor: 地虎降天龙
* @Date: 2024-02-23 12:40:46
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-02-23 16:40:39
*/
export default {
"name": "AMapGIS",

View File

@ -71,7 +71,7 @@ export const loadGeojson = (filepath, dataType) => new Promise((resolve, reject)
resolve(res.features)
})
.catch((err) => {
console.err(err)
console.error(err)
reject(error)
});
})

View File

@ -0,0 +1,113 @@
<!--
* @Description:
* @Version: 1.668
* @Autor: 地虎降天龙
* @Date: 2024-02-24 10:17:12
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-02-24 12:30:12
-->
<template>
<TresGroup ref="tgRef">
<TresMesh v-for="(item, index) in areaList " :key="`${index}`" :properties="item.properties" :renderOrder="index"
@pointer-enter="pEnter" @pointer-leave="pLeave" @pointer-move="pMove">
<TresExtrudeGeometry :args="[item.shape, extrudeSettings]" />
<TresMeshBasicMaterial color="#2defff" :transparent="true" :opacity="0.6" />
<!-- <TresMeshBasicMaterial color="#3480C4" :transparent="true" :opacity="0.5" /> tres暂时不支持多材质 -->
</TresMesh>
</TresGroup>
</template>
<script setup>
import { loadGeojson } from 'PLS/digitalCity/common/utils'
import { watchEffect, ref } from 'vue'
import { useRenderLoop } from '@tresjs/core'
import * as D3 from "d3-geo"
import * as THREE from "three"
import { computeBoundsTree, disposeBoundsTree, acceleratedRaycast } from 'three-mesh-bvh'
const initMeshBvh = () => {
THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
THREE.BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree;
THREE.Mesh.prototype.raycast = acceleratedRaycast;
}
initMeshBvh()
//
const projection = D3
.geoMercator()
.center([104.0, 37.5])
.translate([0, 0])
const areaJson = await loadGeojson('./plugins/simpleGIS/json/china.json', 'features')
const extrudeSettings = {
depth: 10,
bevelEnabled: false,
}
const areaList = []
const makeAreaPrimary = () => {
areaJson.forEach((elem) => {
const coordinates = elem.geometry.coordinates
coordinates.forEach((multiPolygon) => {
multiPolygon.forEach((polygon) => {
const shape = new THREE.Shape()
for (let i = 0; i < polygon.length; i++) {
const [x, y] = projection(polygon[i])
if (i === 0) {
shape.moveTo(x, -y)
}
shape.lineTo(x, -y)
}
areaList.push({ shape, properties: elem.properties })
})
})
})
}
makeAreaPrimary()
const material2 = new THREE.LineBasicMaterial({ color: "#3480C4", linewidth: 1, linecap: 'round' })
const tgRef = ref()
watchEffect(() => {
if (tgRef.value) {
tgRef.value.children.forEach((item) => {
item.geometry.computeBoundsTree()
const arrayMaterial = [item.material, material2]
item.material = arrayMaterial
})
}
})
let tooltip = null
const addElementTips = () => {
const El = document.createElement("div")
El.className = "tooltip"
El.style.border = "1px solid white"
El.style.position = "absolute"
El.style.color = "white"
El.style.padding = "0px 6px"
El.style.whiteSpace = "no-wrap"
El.style.visibility = "hidden"
document.body.appendChild(El)
tooltip = El
}
addElementTips()
const pEnter = (intersection, pointerEvent) => {
intersection.object.material[0].color.set(0xff0000)
tooltip.innerText = intersection.object.properties.name
tooltip.style.visibility = "visible"
}
const pLeave = (intersection, pointerEvent) => {
console.log('pointer-leave', intersection, pointerEvent)
intersection.material[0].color.set(0x2defff)
tooltip.style.visibility = "hidden"
}
const pMove = (intersection, pointerEvent) => {
tooltip.style.left = `${pointerEvent.clientX + 6}px`
tooltip.style.top = `${pointerEvent.clientY + 6}px`
}
const { onLoop } = useRenderLoop()
onLoop(() => {
})
</script>

View File

@ -0,0 +1,22 @@
/*
* @Description:
* @Version: 1.668
* @Autor: 地虎降天龙
* @Date: 2024-02-23 16:40:14
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-02-24 12:31:43
*/
export default {
"name": "simpleGIS",
"title": "简单的GIS例子",
"intro": "都是些GIS行业的应用简单例子",
"version": "0.0.1",
"author": "地虎降天龙",
"website": "https://gitee.com/hawk86104",
"state": "active",
"require": [],
"preview": [
{ "src": "plugins/simpleGIS/preview/chinaMap.png", "type": "img", "name": "chinaMap", "title": "中国地图展示" },
]
}

View File

@ -0,0 +1,48 @@
<!--
* @Description:
* @Version: 1.668
* @Autor: 地虎降天龙
* @Date: 2024-02-24 10:03:05
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-02-24 11:23:18
-->
<template>
<TresCanvas v-bind="state" window-size>
<TresPerspectiveCamera :position="[0, 0, 166]" :fov="75" :near="0.1" :far="1000" :look-at="[0, 0, 0]" />
<OrbitControls v-bind="controlsState" />
<!-- <TresGridHelper /> -->
<Suspense>
<chinaMapMesh />
</Suspense>
</TresCanvas>
</template>
<script setup lang="ts">
import { reactive, watchEffect } from 'vue'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { OrbitControls } from '@tresjs/cientos'
import chinaMapMesh from '../components/chinaMapMesh.vue'
const state = reactive({
clearColor: '#201919',
// alpha: false,
})
const controlsState = reactive({
enableDamping: true,
dampingFactor: 0.05,
})
const { onLoop } = useRenderLoop()
onLoop(() => {
})
watchEffect(() => {
})
</script>

View File

@ -0,0 +1,109 @@
<template>
<TresCanvas v-bind="state" window-size>
<TresPerspectiveCamera :position="[15, 15, 15]" :fov="45" :near="0.1" :far="1000" :look-at="[0, 0, 0]" />
<OrbitControls v-bind="controlsState" />
<TresAmbientLight :intensity="0.5" />
<TresMesh ref="sphereRef" :position="[0, 4, 0]" cast-shadow @pointer-enter="onPointerEnter"
@pointer-leave="onPointerLeave">
<TresSphereGeometry :args="[2, 32, 32]" />
<TresMeshToonMaterial color="#006060" />
</TresMesh>
<TresMesh ref="sphereRef2" :position="[4, 4, 0]" cast-shadow @pointer-enter="onPointerEnter"
@pointer-leave="onPointerLeave">
<TresSphereGeometry :args="[2, 32, 32]" />
<TresMeshToonMaterial color="#006060" />
</TresMesh>
<TresMesh :rotation="[-Math.PI / 2, 0, 0]" receive-shadow>
<TresPlaneGeometry :args="[20, 20, 20, 20]" />
<TresMeshToonMaterial />
</TresMesh>
<TresDirectionalLight ref="TDirectionalLight" :position="[10, 8, 4]" :intensity="1" cast-shadow />
<TresDirectionalLight :position="[10, 2, 4]" :intensity="1" cast-shadow />
<TresGridHelper />
</TresCanvas>
</template>
<script setup lang="ts">
import { SRGBColorSpace, BasicShadowMap, NoToneMapping } from 'three'
import { reactive, ref, onMounted, shallowRef, watchEffect } from 'vue'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { OrbitControls } from '@tresjs/cientos'
const state = reactive({
clearColor: '#201919',
shadows: true,
alpha: false,
shadowMapType: BasicShadowMap,
outputColorSpace: SRGBColorSpace,
toneMapping: NoToneMapping,
})
const controlsState = reactive({
enableDamping: true,
dampingFactor: 0.05,
enableZoom: true,
autoRotate: false,
autoRotateSpeed: 2,
maxPolarAngle: Math.PI,
minPolarAngle: 0,
maxAzimuthAngle: Math.PI,
minAzimuthAngle: -Math.PI,
enablePan: true,
keyPanSpeed: 7,
maxDistance: 100,
minDistance: 0,
minZoom: 0,
maxZoom: 100,
zoomSpeed: 1,
enableRotate: true,
rotateSpeed: 1,
})
const sphereRef = ref()
const sphereRef2 = ref()
const TDirectionalLight = shallowRef()
// const { onLoop, pause, resume } = useRenderLoop()
const { onLoop } = useRenderLoop()
onLoop(({ elapsed }) => {
if (!sphereRef.value) return
sphereRef.value.position.y += Math.sin(elapsed) * 0.01
sphereRef2.value.position.y += Math.sin(elapsed) * 0.01
})
function onPointerEnter(ev: any) {
if (ev) {
ev.object.material.color.set('#DFFF45')
// pause()
}
}
function onPointerLeave(ev: any) {
if (ev) {
ev.material.color.set('#006060')
}
}
watchEffect(() => {
if (TDirectionalLight.value) {
TDirectionalLight.value.shadow.mapSize.set(1000, 1000)
TDirectionalLight.value.shadow.camera.near = 0.5; // default
TDirectionalLight.value.shadow.camera.far = 50000; // default
TDirectionalLight.value.shadow.camera.top = 20
TDirectionalLight.value.shadow.camera.right = 20
TDirectionalLight.value.shadow.camera.left = -20
TDirectionalLight.value.shadow.camera.bottom = -20
}
})
onMounted(() => {
})
</script>