three.js SVG 学习绘制三维地图

54 篇文章 6 订阅
36 篇文章 4 订阅

three.js SVG 学习绘制地图

https://www.js-css.cn/jscode/other/other43/
找到一个不错的资源,不过每个省份的svg数据太小了,不精确。

在这里插入图片描述

主要的是这个js文件:chinaMapConfig.js,有了它我们就可以根据svg路径绘制三维模型了。

在这里插入图片描述

这个网站也有svg的地图。http://mapsvg.com/maps/,相对精确一些,投影方式也不一样。
在这里插入图片描述

先测试一下内蒙古,没有问题。

var neimongol= transformSVGPathExposed(chinaMapConfig.shapes.neimongol);
var extrudeSettings = {
    steps: 2,
    depth: 16,
    bevelEnabled: true,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 1
};
var geometry = new THREE.ExtrudeGeometry( neimongol, extrudeSettings );
var materiala = new THREE.MeshPhongMaterial( {
    color: 0x00ffff ,
    // wireframe:true
} );
var mesha = new THREE.Mesh( geometry, materiala ) ;
scene.add( mesha );

在这里插入图片描述

接着我们开始利用svg绘制完整的三维中国地图:
在这里插入图片描述

三维地图绘制完整,有点单调,添加一个交互事件。点击每个省份可以出发一个事件。
在这里插入图片描述

由于svg的坐标和three.js的坐标不一样,所以需要转换。
我新建了两个group,一个是把所有的省份添加进去,然后进行缩放平移操作。平移的依据是添加的box3,它计算出了group的包围盒。因为地图的本地坐标系不在中心,所以又添加了一个group是用来旋转操作。
最后使用Raycaster来检测点击的省份,并改变颜色,同时绘制了一个长方体。传参数group.children。只检测省份,默认是scene.children。

var group = new THREE.Group();
var chinaMap = new THREE.Group();

window.addEventListener( 'click', onDocumentMouseDown, false );

var extrudeSettings = {
    steps: 2,
    depth: 8,
    bevelEnabled: false,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 1
};

for (let shapesKey in chinaMapConfig.shapes) {
    var materiala = new THREE.MeshPhongMaterial( {
        color: 0xffffff*Math.random()
    } );
    var shapesvgs= $d3g.transformSVGPath(chinaMapConfig.shapes[shapesKey]);
    var geometry = new THREE.ExtrudeGeometry( shapesvgs.toShapes(true), extrudeSettings );
    var mesha = new THREE.Mesh( geometry, materiala ) ;
    group.add( mesha );
}
group.scale.set(0.05,0.05,0.05);
var box = new THREE.Box3().expandByObject(group);
var bx = box.max.x-box.min.x,by = box.max.y-box.min.y,bz = box.max.z-box.min.z;
group.position.set(-bx/2,-by/2,-bz/2);
chinaMap.add(group);
chinaMap.rotation.x = Math.PI/2;
scene.add(chinaMap);

function onDocumentMouseDown(event) {
    var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
    vector = vector.unproject(camera);
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());

    var intersects = raycaster.intersectObjects(group.children); 
    if(intersects.length>0){
        console.log(intersects[0].point);
        intersects[0].object.material.color.set(0xff0000*Math.random());
        cubeDr(4,intersects[0].point.x,intersects[0].point.y+4/2,intersects[0].point.z);
    }
}

哦,上面忘记了介绍svg插件了。https://github.com/asutherland/d3-threeD。
这个插件也是7年没更新了,但是也不影响使用哈。
使用transformSVGPathExposed方法的时候需要引用下面的js插件。
<script src="../threejs/d3-three3D.js"></script>

两种常见的投影方式:

在这里插入图片描述右侧的是叫墨卡托投影,是正轴等角圆柱投影。由荷兰地图学家墨卡托(G.Mercator)于1569年创立。假想一个与地轴方向一致的圆柱切或割于地球,按等角条件,将经纬网投影到圆柱面上,将圆柱面展为平面后,即得本投影。墨卡托投影在切圆柱投影与割圆柱投影中,最早也是最常用的是切圆柱投影。
左侧地图中台湾的左边又一条经度线,是倾斜的。但是在右边的图中,经度线就回成为垂直的。


上面的方法是使用svg的方法,有点局限性,一个是svg的地图难找,而且精确度难以把握,另一个原因是在地理数据可视化中,经纬度用不上。所以我们得改进一下,在我的另外一篇博客中介绍了使用geojson的方法绘制地图,这种方式的可操作行更好,值得学习。

Three.js之GeoJson 3D地图数据可视化飞行线实战

TMD离谱,文章内容违反国家相关法律法规了。 所以图片全部删了 ,换成你们看到的样子。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

X01动力装甲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值