1. 程式人生 > 實用技巧 >python 靜態方法、類方法、屬性方法詳解

python 靜態方法、類方法、屬性方法詳解

通過地圖資料配合three可以做出非常酷炫的地圖,在大資料展示中十分常見。

這篇郭先生就來說說使用three.js幾何體製作3D地圖。線上案例點選原文地址

地圖的資料是各個地圖塊的點陣列,通過THREE.ExtrudeGeometry方法擠壓出地圖的版塊,然後通過THREE.Line方法畫出地圖的分割線。地圖的資料參見DATAV.GeoAtlas,滑鼠懸浮到地圖版塊高亮,效果如圖

1. 得到資料,遍歷資料,處理資料

rawMap() {
    this.worldGeometry = mapJson; //mapJson就是地圖的json資料
    this.worldGeometry.features.forEach((worldItem, worldItemIndex) => {
        worldItem.geometry.coordinates.forEach(worldChildItem 
=> { worldChildItem.forEach(countryItem => { //每個版塊的點陣列 this.drawExtrude(this.drawShape(countryItem)) //傳遞資料畫出地圖的shape,返回結果再傳到drawExtrude方法得到ExtrudeGeometry網格 this.drawLine(countryItem); //傳遞資料畫出地圖邊線 }); }); }); group.scale.y
= 1.2; //group裡面包含所有版塊網格 scene.add(group); lineGroup.scale.y = 1.2; //lineGruop裡面包含所有線的網格 scene.add(lineGroup); this.render(); }

2. 傳遞資料畫出地圖的shape,返回結果再傳到drawExtrude方法得到ExtrudeGeometry網格。

drawShape(posArr) {
    var shape = new THREE.Shape();
    shape.moveTo(posArr[0][0] - this.offsetX, posArr[0][1] - this
.offsetY); posArr.forEach(item => { shape.lineTo(item[0] - this.offsetX, item[1] - this.offsetY); }); return shape; } drawExtrude(shapeObj) { var geometry = new THREE.ExtrudeGeometry(shapeObj, this.options); var material1 = new THREE.MeshPhongMaterial({ color: this.bgColor, specular: this.bgColor }); var material2 = new THREE.MeshBasicMaterial({ color: 0x008bfb }); let shapeGeometryObj = new THREE.Mesh(geometry, [material1, material2]); shapeGeometryObj.name = 'board'; group.add(shapeGeometryObj); }

3. 傳遞資料畫出地圖邊線

drawLine(posArr) {
    let geometry1 = new THREE.Geometry();
    let geometry2 = new THREE.Geometry();
        posArr.forEach(item => {
        geometry1.vertices.push(
            new THREE.Vector3(
                item[0] - this.offsetX,
                item[1] - this.offsetY,
                1.01
            )
        );
        geometry2.vertices.push(
            new THREE.Vector3(
                item[0] - this.offsetX,
                item[1] - this.offsetY,
                -0.01
            )
        );
    });
    let lineMaterial = new THREE.LineBasicMaterial({ color: 0x008bfb });
    let line1 = new THREE.Line(geometry1, lineMaterial);
    let line2 = new THREE.Line(geometry2, lineMaterial);
    lineGroup.add(line1);
    lineGroup.add(line2);
}

4. 滑鼠懸浮後高亮版塊

handleMousemove(event) {
    event.preventDefault();
    let mouse = new THREE.Vector2(0, 0);
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
    this.raycaster.setFromCamera(mouse, camera);
    let intersects = this.raycaster.intersectObjects(group.children);
    this.previousObj.material[0].color = new THREE.Color(this.bgColor);
    if(intersects[0] && intersects[0].object) {
        intersects[0].object.material[0].color = new THREE.Color(0xffaa00);
        this.previousObj = intersects[0].object; //previousObj儲存懸浮的物件,滑鼠移開後恢復顏色。
    }
}

主要程式碼部分就是這樣,我們也可以在顏色改變時加入一些漸變動畫,three.js可以寫出各種各樣的地圖,這是入門級的版本,希望給萌新一些啟發。

轉載請註明地址:郭先生的部落格