<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>自定义三维图层</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
<style>
html, body, #container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
window._AMapSecurityConfig = {
securityJsCode: '***',
}
</script>
<script src="//webapi.amap.com/maps?v=2.0&key=***"></script>
<script src="https://rawgit.com/mrdoob/three.js/r149/build/three.js"></script>
<script>javascript: (function () { var script = document.createElement('script'); script.onload = function () { var stats = new Stats(); document.body.appendChild(stats.dom); requestAnimationFrame(function loop() { stats.update(); requestAnimationFrame(loop) }); }; script.src = 'https://mrdoob.github.io/stats.js/build/stats.min.js'; document.head.appendChild(script); })()</script>
<script type="text/javascript">
var map = new AMap.Map('container', {
center: [**, **],
zooms: [2, 22],
expandZoomRange: true,
mapStyle: "***",
zoom: 19,
viewMode: '3D',
pitch: 50,
showBuildingBlock: false,
});
var camera;
var renderer;
var scene;
var meshMat;
var selectMeshMat;
var lineMaterial;
var meshes = [];
const mouse = new THREE.Vector2()
let rayCaster = new THREE.Raycaster()
// 数据转换工具
var customCoords = map.customCoords;
fetch(
'./ydqhy_gcj02.json'
).then(res => res.json())
.then(data => {
//获取数据,组织数据
var coordtransArr = [];
var s_heigthArr = [];
var addrArr = [];
for (var m = 0; m < data.features.length; m++) {
var coods = data.features[m].geometry.coordinates;
var s_heigth = data.features[m].properties.s_heigth;
var addr = data.features[m].properties.SJLY + data.features[m].properties.adminname + data.features[m].properties.name + data.features[m].properties.room;
var coordtrans = customCoords.lngLatsToCoords(coods[0][0]);
coordtransArr.push(coordtrans);
s_heigthArr.push(s_heigth);
addrArr.push(addr);
}
// 创建 GL 图层
var gllayer = new AMap.GLCustomLayer({
// 图层的层级
zIndex: 10,
// 初始化的操作,创建图层过程中执行一次。
init: (gl) => {
// 这里我们的地图模式是 3D,所以创建一个透视相机,相机的参数初始化可以随意设置,因为在 render 函数中,每一帧都需要同步相机参数,因此这里变得不那么重要。
// 如果你需要 2D 地图(viewMode: '2D'),那么你需要创建一个正交相机
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 1 << 30);
renderer = new THREE.WebGLRenderer({
context: gl, // 地图的 gl 上下文
//alpha: true,
antialias: true,
// canvas: gl.canvas,
});
// 自动清空画布这里必须设置为 false,否则地图底图将无法显示
renderer.autoClear = false;
scene = new THREE.Scene();
// 环境光照和平行光
var aLight = new THREE.AmbientLight(0xffffff, 0.3);
var dLight = new THREE.DirectionalLight(0xffffff, 1);
dLight.position.set(1000, -100, 900);
scene.add(dLight);
scene.add(aLight);
//线材质
lineMaterial = new THREE.LineBasicMaterial({
color: "rgba(0,0,0,1)",
linewidth: 1,
linecap: 'square',
linejoin: 'square'
});
//初始化时材质
meshMat = new THREE.MeshStandardMaterial({
color: "#69b1ff",
transparent: true,
opacity: 1,
// depthWrite: false, //設置false遮擋後面
side: THREE.DoubleSide
});
//选中时材质
selectMat = new THREE.MeshStandardMaterial({
color: "#FF0000",
transparent: true,
opacity: 1,
// depthWrite: false, //設置false遮擋後面
side: THREE.DoubleSide
});
//遍历多边形数据并生成多个mesh
for (var i = 0; i < coordtransArr.length; i++) {
var ss = coordtransArr[i];
const pointsArr = [];
for (var j = 0; j < ss.length; j++) {
var vec2 = new THREE.Vector2(ss[j][0], ss[j][1]);
pointsArr.push(vec2);
}
//构造二维面
const shape = new THREE.Shape(pointsArr);
//拉伸造型
const geometry = new THREE.ExtrudeGeometry(
shape, //二维轮廓
{
depth: 15, //拉伸长度
}
);
var mesh = new THREE.Mesh(geometry, meshMat);
//设置mesh的其他属性
mesh.morphTargetDictionary = { "地址": addrArr[i] };
//设置起始位置
mesh.position.z = Number(s_heigthArr[i] * 5);
//将多边形几何转为线
const lineGeom = new THREE.EdgesGeometry(geometry);
//添加边框线
const line = new THREE.LineSegments(lineGeom, lineMaterial)
line.scale.copy(mesh.scale);
line.rotation.copy(mesh.rotation);
line.position.copy(mesh.position);
//添加mesh和line
scene.add(mesh);
scene.add(line);
}
},
render: () => {
// 这里必须执行!!重新设置 three 的 gl 上下文状态。
renderer.resetState();
// 重新设置图层的渲染中心点,将模型等物体的渲染中心点重置
// 否则和 LOCA 可视化等多个图层能力使用的时候会出现物体位置偏移的问题
//customCoords.setCenter([117.058737302200598, 36.636412736588625]);
var { near, far, fov, up, lookAt, position } = customCoords.getCameraParams();
camera.near = near;
camera.far = far;
camera.fov = fov;
camera.position.set(...position);
camera.up.set(...up);
camera.lookAt(...lookAt);
camera.updateProjectionMatrix();
renderer.render(scene, camera);
// 这里必须执行!!重新设置 three 的 gl 上下文状态。
renderer.resetState();
},
alwaysRender: true
});
map.add(gllayer);
window.addEventListener('resize', onWindowResize);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
//点击变色
var uuids = [];
window.addEventListener("click", handlerClick);
function handlerClick(e) {
mouse.x = (e.clientX / window.innerWidth) * 2 - 1 //通过web中鼠标坐标得到标准屏幕坐标
mouse.y = -(e.clientY / window.innerHeight) * 2 + 1
rayCaster.setFromCamera(mouse, camera) //通过摄像机和鼠标位置更新射线
let intersects = rayCaster.intersectObjects(scene.children) //获取场景中所有与射线相交的物体,结果是一个数组
if (intersects.length > 0) {
var uuid = intersects[0].object.uuid;
var interstMesh = intersects[0].object;
var index = uuids.indexOf(uuid)
if (interstMesh instanceof THREE.Mesh) {
if (index == -1) {
uuids.push(uuid);
interstMesh.material = selectMat;
console.log(interstMesh.morphTargetDictionary);
}
else {
uuids.splice(index, 1);
interstMesh.material = meshMat;
}
//重要代码,地图重新渲染
map.render();
}
}
}
});
</script>
</body>
</html>
高德地图js结合threejs生成户室白膜效果
最新推荐文章于 2024-08-10 23:17:41 发布