高德地图 JS API示例-Object3D 图形- ›通用接口- ›Object3D 的拾取

高德地图 JS API示例-Object3D 图形- ›通用接口- ›Object3D 的拾取

<!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>Object3D 的拾取</title>
    <meta name="description" content="使用 getObject3DByContainerPos 方法,对 Object3D 对象进行拾取。">
    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
    <style>
        html, body, #container { margin: 0; width: 100%; height: 100%; }
        .info span { color: #0288d1; }
    </style>
</head>
<body>
<div id="container"></div>
<div class="info" style="min-width: 350px;">
    <h4>Object3D 拾取信息</h4>
    <p>选中的 Mesh ID:<span id="mesh-id">--</span></p>
    <p>选中的 face 所在的索引:<span id="face-index">--</span></p>
    <p>交叉点距透视原点的距离:<span id="distance">--</span></p>
    <p>与拾取对象的交叉点:
        <span id="cross-point">--</span>
    </p>
</div>
<script src="//cache.amap.com/lbs/static/es5.min.js"></script>
<script src="//webapi.amap.com/maps?v=1.4.15&key=您申请的key值&plugin=Map3D"></script>
<script>
    // 创建 3D 底图
    var map = new AMap.Map('container', {
        viewMode: '3D', // 开启 3D 模式
        pitch: 55,
        rotation: 35,
        center: [116.39756, 39.910215],
        features: ['bg', 'road'],
        zoom: 15
    });

    map.AmbientLight = new AMap.Lights.AmbientLight([1, 1, 1], 0.5);
    map.DirectionLight = new AMap.Lights.DirectionLight([1, -1, 2], [1, 1, 1], 0.8);

    // 添加 Object3DLayer 图层,用于添加 3DObject 对象
    var object3Dlayer = new AMap.Object3DLayer();
    map.add(object3Dlayer);

    var meshes = [];

    // 以不规则棱柱体 Prism 为例,添加至 3DObjectLayer 图层中
    var paths = [
        [
            [116.395951, 39.907129],
            [116.399127, 39.907178],
            [116.399534, 39.900413],
            [116.396316, 39.900331]
        ],
        [
            [116.391531, 39.922912],
            [116.401938, 39.923241],
            [116.402431, 39.913334],
            [116.398354, 39.913103],
            [116.398311, 39.912659],
            [116.396273, 39.912643],
            [116.396101, 39.913108],
            [116.392067, 39.912959]
        ]
    ];

    // Object3D.Mesh 的 color 分别是[r, g, b, a],每个分量只支持 [0 - 1] 区间,
    var color = [100 / 255, 150 / 255, 230 / 255, 0.9];
    var selectColor = [255 / 255, 245 / 255, 47 / 255, 0.9];

    function initMesh() {

        paths.forEach(function (path) {
            var bounds = path.map(function (p) {
                return new AMap.LngLat(p[0], p[1]);
            });

            // 创建 Object3D.Mesh 对象
            var mesh = new AMap.Object3D.Mesh();
            meshes.push(mesh);
            var geometry = mesh.geometry;
            var vertices = geometry.vertices;
            var vertexColors = geometry.vertexColors;
            var faces = geometry.faces;
            var vertexLength = bounds.length * 2;

            var verArr = [];

            // 设置侧面
            bounds.forEach(function (lngLat, index) {
                var g20 = map.lngLatToGeodeticCoord(lngLat);
                verArr.push([g20.x, g20.y]);
                // 构建顶点-底面顶点
                vertices.push(g20.x, g20.y, 0);
                // 构建顶点-顶面顶点
                vertices.push(g20.x, g20.y, -1000);

                // 设置底面顶点颜色
                vertexColors.push.apply(vertexColors, color);
                // 设置顶面顶点颜色
                vertexColors.push.apply(vertexColors, color);

                // 设置三角形面
                var bottomIndex = index * 2;
                var topIndex = bottomIndex + 1;
                var nextBottomIndex = (bottomIndex + 2) % vertexLength;
                var nextTopIndex = (bottomIndex + 3) % vertexLength;

                //侧面三角形1
                faces.push(bottomIndex, topIndex, nextTopIndex);
                //侧面三角形2
                faces.push(bottomIndex, nextTopIndex, nextBottomIndex);
            });

            // 设置顶面,根据顶点拆分三角形
            var triangles = AMap.GeometryUtil.triangulateShape(verArr);
            for (var v = 0; v < triangles.length; v += 3) {
                var a = triangles[v];
                var b = triangles[v + 2];
                var c = triangles[v + 1];
                faces.push(a * 2 + 1, b * 2 + 1, c * 2 + 1);
            }

            // 开启透明度支持
            mesh.transparent = true;

            // 添加至 3D 图层
            object3Dlayer.add(mesh);
        });

    }

    function updateMesh(obj) {
        var mesh = meshes.find(function (mesh) {
            return mesh == obj;
        });

        // 重置 Mesh 颜色
        meshes.forEach(function (mesh) {
            updateMeshColor(mesh, color);
        });

        // 更新选中 Mesh 的 vertexColors
        if (mesh) {
            updateMeshColor(mesh, selectColor);
        }

    }

    function updateMeshColor(mesh, color) {
        var vertexColors = mesh.geometry.vertexColors;
        var len = vertexColors.length;
        for (var i = 0; i < len / 4; i++) {
            var r = color[0];
            var g = color[1];
            var b = color[2];
            var a = color[3];
            // 不能重新赋值,只允许修改内容
            vertexColors.splice(i * 4, 4, r, g, b, a);
        }

        mesh.needUpdate = true;
        mesh.reDraw();
    }

    // prism 拾取
    map.on('mousemove', function (ev) {
        var pixel = ev.pixel;
        var px = new AMap.Pixel(pixel.x, pixel.y);
        var obj = map.getObject3DByContainerPos(px, [object3Dlayer], false) || {};

        // 选中的 face 所在的索引
        var index = obj.index;
        // 选中的 object3D 对象,这里为当前 Mesh
        var object = obj.object;
        // 被拾取到的对象和拾取射线的交叉点的3D坐标
        var point = obj.point;
        // 交叉点距透视原点的距离
        var distance = obj.distance;

        updateInfo(obj);
        updateMesh(object);
    });

    function updateInfo(obj) {
        var $meshId = document.getElementById('mesh-id');
        var $faceIndex = document.getElementById('face-index');
        var $crossPoint = document.getElementById('cross-point');
        var $distance = document.getElementById('distance');

        $meshId.innerHTML = (!isNil(obj.object) && !isNil(obj.object.id)) ? obj.object.id : '--';
        $faceIndex.innerHTML = !isNil(obj.index) ? obj.index : '--';
        $distance.innerHTML = !isNil(obj.distance) ? obj.distance : '--';
        var p = '--';
        if (obj.point) {
            p = [
                '',
                'X: ' + obj.point[0],
                'Y: ' + obj.point[1],
                'Z: ' + obj.point[2]
            ].join('<br>');
        }

        $crossPoint.innerHTML = p;
    }

    function isNil(obj) {
        return obj == undefined;
    }

    initMesh();
//    updateMeshColor(meshes[0], selectColor);


</script>
</body>
</html>
5 1 投票
文章评分
订阅评论
提醒
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x