maptalks 开发GIS地图(14)maptalks.three.07 - bloom

1. 这个demo有着比较惊艳的效果,很多实际在用的项目上都采用了这种效果。

 

2.  添加地图并初始化建筑。

 1 var baseLayer = new maptalks.TileLayer('tile', {
 2             urlTemplate: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
 3             subdomains: ['a', 'b', 'c', 'd'],
 4             attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
 5         });
 6 
 7         var map = new maptalks.Map("map", {
 8             center: [13.412830873144912, 52.53720286413957],
 9             zoom: 16,
10             pitch: 70,
11             bearing: 180,
12             centerCross: true,
13             doubleClickZoom: false
14         });
15         // features to draw
16         var features = [];
17         buildings.forEach(function (b) {
18             features = features.concat(b.features);
19         });
20         // the ThreeLayer to draw buildings
21         var threeLayer = new maptalks.ThreeLayer('t', {
22             forceRenderOnMoving: true,
23             forceRenderOnRotating: true,
24             // animation: true
25         });
26         var stats;
27         var buildingMaterial = new THREE.MeshBasicMaterial({ color: 'rgb(19,19,38)' });
28         var buildingMeshes = [];
29 
30         threeLayer.prepareToDraw = function (gl, scene, camera) {
31             stats = new Stats();
32             stats.domElement.style.zIndex = 100;
33             document.getElementById('map').appendChild(stats.domElement);
34 
35             var light = new THREE.DirectionalLight(0xffffff);
36             light.position.set(0, -10, 10).normalize();
37             scene.add(light);
38 
39             this.initBloom();
40             this.setRendererRenderScene();
41 
42             features.forEach(function (g) {
43                 var heightPerLevel = 10;
44                 var levels = g.properties.levels || 1;
45                 var mesh = threeLayer.toExtrudePolygon(maptalks.GeoJSON.toGeometry(g), {
46                     height: heightPerLevel * levels,
47                     topColor: '#fff',
48                     // interactive: false
49                 }, buildingMaterial);
50                 buildingMeshes.push(mesh);
51             });
52             threeLayer.addMesh(buildingMeshes);
53             addLines();
54 
55         };
56         threeLayer.addTo(map);

 

3. 初始化 bloom 效果。

 1       /**
 2          * initBloom
 3          * */
 4         maptalks.ThreeLayer.prototype.initBloom = function () {
 5             const params = {
 6                 exposure: 1,
 7                 bloomStrength: 4.5,
 8                 bloomThreshold: 0,
 9                 bloomRadius: 0,
10                 debug: false
11             };
12             const renderer = this.getThreeRenderer();
13             const size = this.getMap().getSize();
14             this.composer = new THREE.EffectComposer(renderer);
15             this.composer.setSize(size.width, size.height);
16 
17             const scene = this.getScene(), camera = this.getCamera();
18             this.renderPass = new THREE.RenderPass(scene, camera);
19 
20             this.composer.addPass(this.renderPass);
21 
22             const bloomPass = this.bloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(size.width, size.height));
23             bloomPass.renderToScreen = true;
24             bloomPass.threshold = params.bloomThreshold;
25             bloomPass.strength = params.bloomStrength;
26             bloomPass.radius = params.bloomRadius;
27 
28             // composer.setSize(size.width, size.height);
29             // composer.addPass(renderPass);
30             this.composer.addPass(bloomPass);
31             this.bloomEnable = true;
32         }

 

4.  添加道路线。

道路线分两种,一种是角色不发光,没有白色移动物在上面跑,另外一种是橘色发光,有白色物体在沿线移动。

 1   function addLines() {
 2             fetch('./data/berlin-roads.txt').then(function (res) {
 3                 return res.text();
 4             }).then(function (geojson) {
 5                 geojson = LZString.decompressFromBase64(geojson);
 6                 geojson = JSON.parse(geojson);
 7                 var lineStrings = maptalks.GeoJSON.toGeometry(geojson);
 8                 var data = [], data1 = [];
 9                 var classMap = {};
10                 lineStrings.forEach(lineString => {
11                     const fclass = lineString.getProperties().fclass;
12                     classMap[fclass] = fclass;
13                     //main road
14                     if (fclass && (fclass.includes('primary') || fclass.includes('secondary') || fclass.includes('tertiary'))) {
15                         data1.push(lineString);
16                     } else {
17                         data.push(lineString);
18                     }
19                 });
20                 const list = [];
21                 data.forEach(lineString => {
22                     list.push({
23                         lineString,
24                         len: lineLength(lineString)
25                     });
26                 });
27                 data = list.sort(function (a, b) {
28                     return b.len - a.len
29                 });
30 
31                 baseLines = data.slice(0, 200).map(function (d) {
32                     var line = threeLayer.toLine(d.lineString, {}, baseLineMaterial);
33                     line.getObject3d().layers.enable(1);
34                     return line;
35                 });
36                 threeLayer.addMesh(baseLines);
37 
38                 addExtrudeLine(data1);
39 
40             });
41         }
42 
43         var material = new THREE.MeshBasicMaterial({
44             color: 'rgb(255,45,0)', transparent: true, blending: THREE.AdditiveBlending
45         });
46         var highlightmaterial = new THREE.MeshBasicMaterial({ color: '#ffffff', transparent: true });
47         var lines, lineTrails;
48 
49         function addExtrudeLine(lineStrings) {
50             var timer = 'generate line time';
51             console.time(timer);
52             const list = [];
53             lineStrings.forEach(lineString => {
54                 list.push({
55                     lineString,
56                     len: lineLength(lineString)
57                 });
58             });
59             lineStrings = list.sort(function (a, b) {
60                 return b.len - a.len
61             });
62 
63             lines = lineStrings.slice(0, 1000).map(d => {
64                 var line = threeLayer.toExtrudeLine(d.lineString, { altitude: 0, width: 4, height: 1 }, material);
65                 line.getObject3d().layers.enable(1);
66                 return line;
67             });
68             lineTrails = lineStrings.slice(0, 300).map(function (d) {
69                 var line = threeLayer.toExtrudeLineTrail(d.lineString, { altitude: 0, width: 5, height: 2, chunkLength: d.len / 40, speed: 1, trail: 6 }, highlightmaterial);
70                 line.getObject3d().layers.enable(1);
71                 return line;
72             });
73 
74             console.log('lines.length:', lines.length);
75             console.timeEnd(timer);
76             threeLayer.addMesh(lines);
77             threeLayer.addMesh(lineTrails);
78             initGui();
79             // threeLayer.config('animation', true);
80             animation();
81         }

 

5. 建筑的数据使用的是 building.js

类似geojson 的json数据。没有geojson前面的头,直接就是对象数据。

 

 

6.道路的数据使用的是  ./data/berlin-roads.txt

可以看出,这是一份加密数据,使用 LZString.decompressFromBase64 进行解密。解析后的数据就比较正常了。应该是geojson格式的数据了。

然后对数据截取一部分作为白光bloom效果的路线。

并且为了保证移动物的平滑性,把每个数据平均分为了1000份,这样移动物移动的时候,就比较光滑了。

 

 

7. 页面显示

 

 

8. 源码地址

https://github.com/WhatGIS/maptalkMap

 
posted @ 2021-04-30 16:25  googlegis  阅读(745)  评论(0编辑  收藏  举报

坐标合肥,非典型GIS开发人员 GitHub