diff --git a/src/views/AppThreeMap.vue b/src/views/AppThreeMap.vue index 1619b13..3d29764 100644 --- a/src/views/AppThreeMap.vue +++ b/src/views/AppThreeMap.vue @@ -5,7 +5,7 @@ export default { data() { return { geoMap: null, - layers: [{longitude: 113.631676, latitude: 34.766458}] + layers: [] } }, computed: { @@ -14,17 +14,22 @@ export default { methods: { loadLib() { const {$waitFor, THREE, $loadScript} = window - return $waitFor(THREE).then(() => $loadScript('js', `http://10.0.97.209/presource/datascreen/js/three/js/controls/OrbitControls.js`)) + return $waitFor(THREE).then(() => Promise.all([ + `http://10.0.97.209/presource/datascreen/js/three/js/controls/OrbitControls.js`, + // `http://10.0.97.209/presource/datascreen/js/three/js/utils/BufferGeometryUtils.js`, + `http://10.0.97.209/presource/datascreen/js/three/js/QuickHull.js`, + `http://10.0.97.209/presource/datascreen/js/three/js/geometries/ConvexGeometry.js`, + ].map(e => $loadScript('js', e)))) }, initMap() { const {THREE, d3, axios, TWEEN} = window const rootEl = this.$el const root = this - const scale = 7 + const scale = 4 class GeoMap { constructor() { - this.cameraPosition = {x: 10, y: 0, z: 100}; // 相机位置 + this.cameraPosition = {x: 16, y: 0, z: 80}; // 相机位置 this.scene = null; // 场景 this.camera = null; // 相机 this.renderer = null; // 渲染器 @@ -75,6 +80,7 @@ export default { axios.get(url).then(function (res) { if (res.status === 200) { const data = res.data; + that.geoJson = data that.setMapData(data) } }) @@ -100,7 +106,22 @@ export default { * */ setMapData(data) { const that = this; - let vector3json = []; + const getLnglat = (arr, cb) => { + arr?.map(e => { + if (e.length === 2 && typeof e[0] === 'number' && typeof e[1] === 'number') { + cb(e) + } else { + getLnglat(e, cb) + } + }) + } + let vector3json = [], + vector3border = [] + getLnglat([[[[114.22071, 34.919066], [114.208505, 34.926602], [114.200704, 34.939504], [114.172834, 34.931871], [114.160566, 34.933496], [114.120491, 34.956638], [114.101869, 34.954768], [114.080542, 34.944527], [114.051225, 34.944527], [114.028451, 34.959346], [114.018385, 34.958608], [113.985293, 34.928276], [113.973654, 34.910447], [113.953585, 34.898082], [113.905331, 34.901333], [113.870163, 34.885666], [113.826062, 34.877683], [113.800456, 34.87995], [113.78649, 34.890445], [113.777116, 34.905028], [113.766106, 34.91488], [113.749057, 34.919017], [113.725528, 34.917392], [113.716846, 34.913402], [113.684824, 34.906358], [113.670731, 34.910299], [113.665069, 34.918525], [113.650348, 34.928769], [113.631348, 34.929311], [113.592091, 34.933743], [113.57479, 34.950583], [113.552582, 34.965155], [113.543271, 34.96801], [113.515086, 34.965992], [113.495835, 34.959937], [113.477339, 34.957278], [113.449658, 34.960232], [113.429463, 34.964761], [113.427198, 34.983563], [113.407821, 34.989518], [113.37561, 34.98002], [113.362587, 34.970323], [113.343462, 34.950533], [113.333018, 34.944871], [113.315277, 34.942212], [113.28986, 34.952601], [113.260543, 34.953586], [113.243934, 34.946201], [113.239342, 34.939504], [113.236951, 34.925174], [113.227703, 34.908427], [113.197631, 34.900299], [113.179512, 34.893697], [113.139815, 34.884631], [113.14793, 34.856096], [113.119431, 34.853977], [113.107666, 34.844709], [113.06023, 34.83756], [113.039595, 34.841948], [113.025063, 34.854913], [113.004364, 34.864081], [112.992851, 34.863539], [112.989077, 34.856343], [112.976117, 34.847765], [112.943025, 34.831102], [112.938181, 34.831595], [112.914148, 34.84747], [112.902321, 34.852301], [112.884516, 34.853089], [112.879106, 34.849688], [112.873192, 34.832827], [112.866461, 34.829524], [112.853501, 34.810736], [112.838653, 34.812116], [112.827266, 34.819218], [112.814118, 34.811475], [112.80984, 34.7951], [112.810595, 34.784938], [112.817263, 34.778278], [112.837144, 34.782915], [112.846329, 34.780054], [112.875017, 34.779659], [112.887914, 34.782718], [112.89993, 34.780596], [112.909367, 34.771123], [112.908486, 34.757405], [112.902258, 34.753161], [112.909933, 34.737465], [112.939502, 34.72384], [112.931764, 34.711694], [112.91635, 34.710953], [112.901692, 34.693521], [112.893827, 34.694953], [112.879735, 34.705077], [112.867782, 34.708089], [112.8496, 34.699694], [112.830223, 34.694163], [112.829217, 34.683346], [112.835885, 34.667785], [112.831041, 34.656669], [112.847147, 34.640362], [112.841799, 34.628648], [112.825001, 34.628698], [112.82475, 34.625188], [112.840226, 34.623161], [112.845574, 34.609913], [112.839408, 34.596514], [112.846329, 34.58885], [112.862183, 34.590284], [112.864133, 34.580146], [112.877722, 34.567731], [112.87898, 34.560015], [112.890682, 34.547102], [112.910751, 34.545173], [112.929562, 34.547548], [112.952273, 34.547647], [112.967749, 34.541264], [112.984736, 34.539038], [112.976683, 34.53117], [112.947995, 34.531467], [112.929813, 34.526023], [112.925598, 34.509789], [112.927297, 34.499691], [112.920125, 34.482016], [112.922956, 34.47657], [112.905215, 34.468201], [112.896155, 34.475827], [112.862371, 34.473648], [112.856017, 34.478402], [112.838024, 34.477164], [112.806002, 34.479243], [112.798012, 34.487166], [112.774609, 34.500137], [112.767374, 34.49479], [112.740384, 34.491077], [112.744285, 34.4683], [112.741894, 34.433973], [112.736673, 34.422578], [112.729626, 34.416978], [112.735918, 34.404242], [112.733653, 34.39309], [112.72409, 34.388877], [112.721825, 34.380152], [112.730318, 34.377426], [112.728117, 34.361163], [112.732898, 34.350898], [112.756805, 34.357394], [112.760076, 34.346584], [112.776622, 34.345046], [112.787002, 34.343261], [112.788953, 34.331158], [112.81223, 34.340037], [112.824184, 34.33344], [112.83318, 34.333638], [112.854633, 34.316325], [112.842114, 34.311612], [112.84117, 34.297818], [112.856458, 34.302185], [112.87357, 34.298016], [112.884516, 34.30144], [112.91245, 34.293749], [112.936293, 34.295535], [112.954097, 34.302135], [112.960829, 34.297867], [112.992977, 34.296478], [113.013235, 34.300398], [113.020847, 34.290424], [113.027642, 34.289282], [113.037142, 34.280299], [113.059476, 34.280944], [113.075518, 34.276527], [113.082439, 34.26645], [113.097726, 34.26223], [113.109365, 34.263471], [113.142583, 34.272804], [113.15202, 34.266351], [113.175297, 34.281639], [113.184356, 34.290225], [113.18379, 34.295634], [113.196436, 34.312257], [113.210276, 34.312009], [113.223362, 34.325057], [113.224557, 34.33473], [113.235567, 34.339045], [113.267904, 34.337805], [113.276334, 34.342814], [113.276586, 34.351444], [113.314648, 34.352287], [113.314019, 34.373856], [113.320436, 34.383375], [113.315969, 34.391157], [113.32528, 34.404986], [113.348809, 34.404738], [113.353968, 34.396411], [113.370388, 34.389918], [113.366991, 34.379805], [113.389828, 34.375988], [113.401655, 34.377525], [113.414867, 34.374947], [113.406751, 34.355213], [113.414175, 34.349361], [113.429085, 34.350303], [113.459409, 34.334432], [113.471425, 34.330811], [113.482875, 34.342864], [113.498729, 34.338598], [113.510871, 34.342715], [113.518169, 34.335771], [113.516848, 34.328579], [113.529619, 34.317913], [113.556608, 34.311513], [113.566737, 34.318359], [113.579697, 34.319897], [113.600836, 34.313299], [113.608951, 34.3132], [113.624805, 34.303375], [113.634494, 34.290026], [113.643994, 34.288488], [113.658589, 34.275037], [113.669851, 34.275385], [113.679728, 34.282532], [113.70332, 34.276725], [113.7003, 34.289381], [113.71326, 34.29092], [113.713386, 34.301391], [113.727227, 34.305757], [113.736852, 34.317863], [113.756732, 34.313795], [113.777242, 34.314589], [113.793159, 34.328083], [113.791208, 34.331803], [113.803791, 34.33721], [113.832353, 34.32342], [113.848584, 34.322725], [113.85022, 34.32719], [113.880481, 34.32972], [113.885451, 34.327785], [113.888093, 34.348369], [113.879978, 34.356056], [113.885199, 34.370485], [113.878531, 34.394577], [113.878153, 34.411478], [113.891616, 34.437342], [113.903507, 34.454185], [113.912126, 34.452352], [113.915586, 34.444922], [113.929993, 34.443485], [113.938108, 34.454729], [113.948929, 34.452699], [113.948615, 34.435063], [113.968495, 34.439324], [113.990326, 34.435707], [114.006557, 34.439225], [114.019894, 34.445368], [114.021719, 34.458989], [114.01851, 34.46721], [114.008256, 34.470082], [114.009577, 34.480135], [114.0226, 34.488552], [114.035119, 34.503998], [114.062486, 34.490532], [114.07035, 34.481472], [114.083373, 34.480927], [114.094383, 34.492265], [114.093942, 34.50182], [114.100296, 34.535178], [114.107217, 34.557887], [114.118478, 34.570155], [114.129802, 34.575348], [114.127852, 34.584943], [114.133451, 34.591025], [114.136848, 34.605711], [114.125461, 34.607886], [114.127726, 34.61718], [114.14553, 34.61456], [114.145153, 34.604277], [114.15459, 34.60576], [114.15157, 34.618268], [114.157547, 34.625979], [114.150375, 34.656669], [114.160441, 34.665611], [114.157547, 34.686507], [114.158113, 34.704336], [114.141189, 34.7191], [114.138484, 34.73475], [114.158364, 34.759379], [114.172331, 34.768311], [114.161762, 34.781238], [114.134143, 34.802154], [114.122504, 34.81833], [114.133703, 34.825628], [114.162517, 34.828883], [114.185354, 34.825628], [114.199824, 34.832729], [114.211085, 34.860877], [114.220522, 34.906801], [114.22071, 34.919066]]]], p => { + const lnglat = that.lnglatToVector3(p); + const vector3 = new THREE.Vector3(lnglat[0], lnglat[1], lnglat[2]).multiplyScalar(1.2); + vector3border.push(vector3) + }) data.features.forEach(function (features, featuresIndex) { const areaItems = features.geometry.coordinates; features.properties.cp = that.lnglatToVector3(features.properties.centroid); @@ -108,15 +129,6 @@ export default { data: features.properties, mercator: [] }; - const getLnglat = (arr, cb) => { - arr?.map(e => { - if (e.length > 2) { - getLnglat(e, cb) - } else if (e.length === 2) { - cb(e) - } - }) - } areaItems.forEach(function (item, areaIndex) { vector3json[featuresIndex].mercator[areaIndex] = []; getLnglat(item, cp => { @@ -126,20 +138,20 @@ export default { }) }) }); - this.drawMap(vector3json) + this.drawMap(vector3json, vector3border) } /** * @desc 绘制图形 * @param data * */ - drawMap(data) { + drawMap(data, border) { let that = this; this.mapGroup = new THREE.Group(); this.mapGroup.position.y = 0; this.scene.add(that.mapGroup); const extrudeSettings = { - depth: 0.8, + depth: 0.2, steps: 1, bevelSegments: 0, curveSegments: 1, @@ -151,52 +163,74 @@ export default { const ctx = canvas.getContext('2d'); const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0); - gradient.addColorStop(1, '#09E2F8'); // 起始颜色 - gradient.addColorStop(0, 'rgba(61,127,255,0.35)'); // 结束颜色 + gradient.addColorStop(0, 'rgba(61,127,255,0.35)'); + gradient.addColorStop(1, '#09E2F8'); + // gradient.addColorStop(0, 'rgba(61,127,255,0.01)'); // 结束颜色 ctx.fillStyle = gradient; ctx.fillRect(0, 0, canvas.width, canvas.height); const blockMaterial = new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(canvas), - side: THREE.DoubleSide + // side: THREE.DoubleSide, + transparent: true, wireframe: false }); const blockSideMaterial = new THREE.MeshBasicMaterial({ color: '#002240', - opacity: 0.7, - transparent: true, wireframe: false }); const lineMaterial = new THREE.LineBasicMaterial({ color: '#97CAE6' }); + const areas = [] data.forEach(function (areaData) { let areaGroup = new THREE.Group(); areaGroup.name = 'area'; areaGroup._groupType = 'areaBlock'; areaData.mercator.forEach(function (areaItem) { - // Draw area block - let shape = new THREE.Shape(areaItem); - let geometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings); - let mesh = new THREE.Mesh(geometry, [blockMaterial, blockSideMaterial]); - areaGroup.add(mesh); + // let mesh = new THREE.Mesh(geometry, [blockMaterial, blockSideMaterial]); + // areaGroup.add(mesh); // Draw Line let lineGeometry = new THREE.Geometry(); lineGeometry.vertices = areaItem; let lineMesh = new THREE.Line(lineGeometry, lineMaterial); - let lineMeshCp = lineMesh.clone(); - lineMeshCp.position.z = 0.8; + lineMesh.position.z = 0.201; areaGroup.add(lineMesh); - areaGroup.add(lineMeshCp); - // add mesh to meshList for mouseEvent - that.meshList.push(mesh); }); // areaGroup.add(that.transLayer(areaData)); // areaGroup.add(that.tipsSprite(areaData)); - areaGroup.scale.set(scale, scale, scale) that.mapGroup.add(areaGroup); }); + const shape = new THREE.Shape(border); + const areaGeometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings); + // const mesh = new THREE.Mesh(areaGeometry, [blockMaterial, blockSideMaterial]); + const mesh = new THREE.Mesh(areaGeometry, blockMaterial); + that.mapGroup.add(mesh) + that.mapGroup.scale.set(scale, scale, scale) that.scene.add(that.mapGroup); } + transLayer({bakeStockAmt, longitude, latitude} = {}) { + longitude = Number(longitude || 0).toFixed(6); + latitude = Number(latitude || 0).toFixed(6); + const markerGeometry = new THREE.CircleBufferGeometry(0.1, 32); + const markerMaterial = new THREE.MeshBasicMaterial({ + side: THREE.DoubleSide, + blending: THREE.AdditiveBlending, + color: bakeStockAmt > 0 ? "#66FFFF" : "#FFD15C", + // color: "#66FFFF", + depthTest: false, + transparent: true, + opacity: 1 + }); + const marker = new THREE.Mesh(markerGeometry, markerMaterial); + // const [x, y, z] = this.lnglatToVector3([longitude, latitude]) + + const lnglat = this.lnglatToVector3([longitude, latitude]); + const v3 = new THREE.Vector3(lnglat[0], lnglat[1], lnglat[2]).multiplyScalar(1.2); + // marker.scale.set(scale, scale, 1) + marker.position.set(v3.x * scale, v3.y * scale, 0.201 * scale) + return marker + } + addMarkers() { root.layers.map(layer => this.scene.add(this.transLayer(layer))) } @@ -233,7 +267,7 @@ export default { * */ lnglatToVector3(lnglat = []) { if (!this.projection) { - this.projection = d3.geoMercator().center([113.665412, 34.757975]).scale(100).translate([0, 0]); + this.projection = d3.geoMercator().center([113.665412, 34.757975]).scale(100).translate([0.3, 0]); } const [x, y] = this.projection([lnglat[0], lnglat[1]]) const z = 0; @@ -263,7 +297,6 @@ export default { * @desc 创建渲染器 * */ setRenderer() { - console.log(rootEl.offsetWidth, rootEl.offsetHeight) this.renderer = new THREE.WebGLRenderer({antialias: true}); this.renderer.setPixelRatio(window.devicePixelRatio * 1); this.renderer.sortObjects = true; // 渲染顺序 @@ -367,30 +400,6 @@ export default { ground.castShadow = true; } - /** - * @desc 光柱 - * */ - - transLayer({bakeStockAmt, longitude, latitude} = {}) { - const markerGeometry = new THREE.CircleBufferGeometry(0.1, 32); - const markerMaterial = new THREE.MeshBasicMaterial({ - side: THREE.DoubleSide, - blending: THREE.AdditiveBlending, - color: bakeStockAmt > 0 ? "#66FFFF" : "#FFD15C", - // color: "#66FFFF", - depthTest: false, - transparent: true, - opacity: 1 - }); - const marker = new THREE.Mesh(markerGeometry, markerMaterial); - const [x, y, z] = this.lnglatToVector3([longitude, latitude]) - const v3 = new THREE.Vector3(x, y, z).multiplyScalar(1.2) - // marker.scale.set(scale, scale, 1) - marker.position.set(x * 30, y * 30, -1) - console.log( marker.position) - return marker - } - /** * @desc 地区名称 采用sprite * */