2024-06-27 18:01:47 +08:00
|
|
|
<script>
|
2024-07-01 18:22:37 +08:00
|
|
|
export default {
|
|
|
|
|
name: "AppThreeMap",
|
|
|
|
|
label: "3D地图",
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
2024-07-02 18:25:08 +08:00
|
|
|
geoMap: null,
|
2024-07-04 01:35:08 +08:00
|
|
|
layers: []
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
|
|
|
|
},
|
2024-07-02 18:25:08 +08:00
|
|
|
computed: {
|
|
|
|
|
search: v => v.$marketBoard.search
|
|
|
|
|
},
|
2024-07-01 18:22:37 +08:00
|
|
|
methods: {
|
|
|
|
|
loadLib() {
|
|
|
|
|
const {$waitFor, THREE, $loadScript} = window
|
2024-07-04 01:35:08 +08:00
|
|
|
return $waitFor(THREE).then(() => Promise.all([
|
|
|
|
|
`http://10.0.97.209/presource/datascreen/js/three/js/controls/OrbitControls.js`,
|
2024-07-09 02:02:18 +08:00
|
|
|
`http://10.0.97.209/presource/datascreen/js/three/js/renderers/CSS3DRenderer.js`,
|
2024-07-10 01:58:51 +08:00
|
|
|
`http://10.0.97.209/presource/datascreen/js/three/js/loaders/FontLoader.js`,
|
|
|
|
|
`http://10.0.97.209/presource/datascreen/js/three/js/geometries/TextGeometry.js`,
|
2024-07-04 01:35:08 +08:00
|
|
|
].map(e => $loadScript('js', e))))
|
2024-07-01 18:22:37 +08:00
|
|
|
},
|
|
|
|
|
initMap() {
|
|
|
|
|
const {THREE, d3, axios, TWEEN} = window
|
|
|
|
|
const rootEl = this.$el
|
2024-07-02 18:25:08 +08:00
|
|
|
const root = this
|
2024-07-04 01:35:08 +08:00
|
|
|
const scale = 4
|
2024-07-04 17:58:23 +08:00
|
|
|
const transform = (o, n, t) => new TWEEN.Tween(o).to(n, t).start();
|
2024-07-01 18:22:37 +08:00
|
|
|
|
|
|
|
|
class GeoMap {
|
|
|
|
|
constructor() {
|
2024-07-04 01:49:01 +08:00
|
|
|
this.cameraPosition = {x: 40, y: 0, z: 40}; // 相机位置
|
2024-07-01 18:22:37 +08:00
|
|
|
this.scene = null; // 场景
|
|
|
|
|
this.camera = null; // 相机
|
|
|
|
|
this.renderer = null; // 渲染器
|
|
|
|
|
this.controls = null; // 控制器
|
|
|
|
|
this.mapGroup = []; // 组
|
2024-07-04 17:58:23 +08:00
|
|
|
this.selectedObject = null; // 当前选中对象
|
2024-07-01 18:22:37 +08:00
|
|
|
this.loopIndex = 0; // 循环标记
|
2024-07-04 17:58:23 +08:00
|
|
|
this.mouse = new THREE.Vector2();
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
2024-06-27 18:01:47 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 初始化
|
|
|
|
|
* */
|
|
|
|
|
init() {
|
|
|
|
|
this.setScene();
|
|
|
|
|
this.setCamera();
|
2024-07-10 01:58:51 +08:00
|
|
|
this.setAxes();
|
2024-07-01 18:22:37 +08:00
|
|
|
this.setRenderer();
|
|
|
|
|
this.setControl();
|
|
|
|
|
this.makeGround();
|
|
|
|
|
this.getMap('http://10.0.97.209/blade-visual/map/data?id=1456');
|
2024-07-02 18:25:08 +08:00
|
|
|
this.addMarkers()
|
2024-07-01 18:22:37 +08:00
|
|
|
this.animat();
|
2024-07-02 18:25:08 +08:00
|
|
|
this.bindMouseEvent()
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 动画循环
|
|
|
|
|
* */
|
|
|
|
|
animat() {
|
|
|
|
|
requestAnimationFrame(this.animat.bind(this));
|
|
|
|
|
TWEEN.update();
|
|
|
|
|
this.controls.update();
|
|
|
|
|
this.renderer.render(this.scene, this.camera);
|
|
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 获取地图
|
|
|
|
|
* */
|
|
|
|
|
getMap(url) {
|
|
|
|
|
const that = this;
|
|
|
|
|
axios.get(url).then(function (res) {
|
|
|
|
|
if (res.status === 200) {
|
|
|
|
|
const data = res.data;
|
2024-07-04 01:35:08 +08:00
|
|
|
that.geoJson = data
|
2024-07-01 18:22:37 +08:00
|
|
|
that.setMapData(data)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 绘制地图
|
|
|
|
|
* @params geojson
|
|
|
|
|
* */
|
|
|
|
|
setMapData(data) {
|
|
|
|
|
const that = this;
|
2024-07-04 01:35:08 +08:00
|
|
|
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.99297
|
|
|
|
|
const lnglat = that.lnglatToVector3(p);
|
|
|
|
|
const vector3 = new THREE.Vector3(lnglat[0], lnglat[1], lnglat[2]).multiplyScalar(1.2);
|
|
|
|
|
vector3border.push(vector3)
|
|
|
|
|
})
|
2024-07-01 18:22:37 +08:00
|
|
|
data.features.forEach(function (features, featuresIndex) {
|
|
|
|
|
const areaItems = features.geometry.coordinates;
|
|
|
|
|
features.properties.cp = that.lnglatToVector3(features.properties.centroid);
|
|
|
|
|
vector3json[featuresIndex] = {
|
|
|
|
|
data: features.properties,
|
|
|
|
|
mercator: []
|
|
|
|
|
};
|
|
|
|
|
areaItems.forEach(function (item, areaIndex) {
|
|
|
|
|
vector3json[featuresIndex].mercator[areaIndex] = [];
|
2024-07-02 18:25:08 +08:00
|
|
|
getLnglat(item, cp => {
|
2024-07-01 18:22:37 +08:00
|
|
|
const lnglat = that.lnglatToVector3(cp);
|
|
|
|
|
const vector3 = new THREE.Vector3(lnglat[0], lnglat[1], lnglat[2]).multiplyScalar(1.2);
|
|
|
|
|
vector3json[featuresIndex].mercator[areaIndex].push(vector3)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
});
|
2024-07-04 01:35:08 +08:00
|
|
|
this.drawMap(vector3json, vector3border)
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 绘制图形
|
|
|
|
|
* @param data
|
|
|
|
|
* */
|
2024-07-04 01:35:08 +08:00
|
|
|
drawMap(data, border) {
|
2024-07-01 18:22:37 +08:00
|
|
|
let that = this;
|
|
|
|
|
this.mapGroup = new THREE.Group();
|
|
|
|
|
this.mapGroup.position.y = 0;
|
|
|
|
|
this.scene.add(that.mapGroup);
|
|
|
|
|
const extrudeSettings = {
|
2024-07-04 01:35:08 +08:00
|
|
|
depth: 0.2,
|
2024-07-01 18:22:37 +08:00
|
|
|
steps: 1,
|
|
|
|
|
bevelSegments: 0,
|
|
|
|
|
curveSegments: 1,
|
|
|
|
|
bevelEnabled: false,
|
|
|
|
|
};
|
2024-07-02 18:25:08 +08:00
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
|
canvas.width = 256;
|
|
|
|
|
canvas.height = 256;
|
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
|
|
|
|
|
|
const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
|
2024-07-04 01:35:08 +08:00
|
|
|
gradient.addColorStop(0, 'rgba(61,127,255,0.35)');
|
|
|
|
|
gradient.addColorStop(1, '#09E2F8');
|
|
|
|
|
// gradient.addColorStop(0, 'rgba(61,127,255,0.01)'); // 结束颜色
|
2024-07-02 18:25:08 +08:00
|
|
|
ctx.fillStyle = gradient;
|
|
|
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
2024-07-01 18:22:37 +08:00
|
|
|
const blockMaterial = new THREE.MeshBasicMaterial({
|
2024-07-02 18:25:08 +08:00
|
|
|
map: new THREE.CanvasTexture(canvas),
|
2024-07-04 01:35:08 +08:00
|
|
|
// side: THREE.DoubleSide,
|
|
|
|
|
transparent: true, wireframe: false
|
2024-07-01 18:22:37 +08:00
|
|
|
});
|
|
|
|
|
const blockSideMaterial = new THREE.MeshBasicMaterial({
|
2024-07-02 18:25:08 +08:00
|
|
|
color: '#002240',
|
2024-07-01 18:22:37 +08:00
|
|
|
wireframe: false
|
|
|
|
|
});
|
2024-07-10 01:58:51 +08:00
|
|
|
const lineMaterial = new THREE.LineBasicMaterial({color: '#97CAE6'});
|
2024-07-04 01:35:08 +08:00
|
|
|
const areas = []
|
2024-07-01 18:22:37 +08:00
|
|
|
data.forEach(function (areaData) {
|
|
|
|
|
let areaGroup = new THREE.Group();
|
|
|
|
|
areaGroup.name = 'area';
|
|
|
|
|
areaGroup._groupType = 'areaBlock';
|
|
|
|
|
areaData.mercator.forEach(function (areaItem) {
|
2024-07-04 01:35:08 +08:00
|
|
|
// let mesh = new THREE.Mesh(geometry, [blockMaterial, blockSideMaterial]);
|
|
|
|
|
// areaGroup.add(mesh);
|
2024-07-01 18:22:37 +08:00
|
|
|
// Draw Line
|
2024-07-10 01:58:51 +08:00
|
|
|
let lineGeometry = new THREE.BufferGeometry().setFromPoints(areaItem);
|
2024-07-01 18:22:37 +08:00
|
|
|
let lineMesh = new THREE.Line(lineGeometry, lineMaterial);
|
2024-07-04 01:35:08 +08:00
|
|
|
lineMesh.position.z = 0.201;
|
2024-07-01 18:22:37 +08:00
|
|
|
areaGroup.add(lineMesh);
|
|
|
|
|
});
|
2024-07-02 18:25:08 +08:00
|
|
|
// areaGroup.add(that.transLayer(areaData));
|
|
|
|
|
// areaGroup.add(that.tipsSprite(areaData));
|
2024-07-01 18:22:37 +08:00
|
|
|
that.mapGroup.add(areaGroup);
|
|
|
|
|
});
|
2024-07-04 01:35:08 +08:00
|
|
|
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)
|
2024-07-10 02:04:54 +08:00
|
|
|
that.mapGroup.position.set(-3, 0, 0)
|
2024-07-01 18:22:37 +08:00
|
|
|
that.scene.add(that.mapGroup);
|
|
|
|
|
}
|
2024-06-27 18:01:47 +08:00
|
|
|
|
2024-07-04 02:11:29 +08:00
|
|
|
transLayer(item = {}) {
|
|
|
|
|
let {bakeStockAmt, longitude, latitude} = item
|
2024-07-04 01:35:08 +08:00
|
|
|
longitude = Number(longitude || 0).toFixed(6);
|
|
|
|
|
latitude = Number(latitude || 0).toFixed(6);
|
2024-07-10 02:11:22 +08:00
|
|
|
const markerGeometry = new THREE.CircleBufferGeometry(0.015, 32);
|
2024-07-04 01:35:08 +08:00
|
|
|
const markerMaterial = new THREE.MeshBasicMaterial({
|
|
|
|
|
side: THREE.DoubleSide,
|
|
|
|
|
blending: THREE.AdditiveBlending,
|
|
|
|
|
color: bakeStockAmt > 0 ? "#66FFFF" : "#FFD15C",
|
|
|
|
|
depthTest: false,
|
|
|
|
|
transparent: true,
|
|
|
|
|
opacity: 1
|
|
|
|
|
});
|
|
|
|
|
const marker = new THREE.Mesh(markerGeometry, markerMaterial);
|
|
|
|
|
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)
|
2024-07-04 02:11:29 +08:00
|
|
|
marker.data = item
|
2024-07-10 02:11:22 +08:00
|
|
|
marker.position.set(v3.x, v3.y, 0.201)
|
2024-07-04 01:35:08 +08:00
|
|
|
return marker
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-02 18:25:08 +08:00
|
|
|
addMarkers() {
|
2024-07-04 02:11:29 +08:00
|
|
|
this.markers = [];
|
|
|
|
|
root.layers.map(layer => {
|
|
|
|
|
const marker = this.transLayer(layer)
|
|
|
|
|
this.markers.push(marker)
|
2024-07-10 02:11:22 +08:00
|
|
|
this.mapGroup.add(marker)
|
2024-07-04 02:11:29 +08:00
|
|
|
})
|
2024-07-02 18:25:08 +08:00
|
|
|
}
|
|
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 坐标转换
|
|
|
|
|
* @param lnglat [x,y]
|
|
|
|
|
* */
|
|
|
|
|
lnglatToVector3(lnglat = []) {
|
|
|
|
|
if (!this.projection) {
|
2024-07-04 01:35:08 +08:00
|
|
|
this.projection = d3.geoMercator().center([113.665412, 34.757975]).scale(100).translate([0.3, 0]);
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
|
|
|
|
const [x, y] = this.projection([lnglat[0], lnglat[1]])
|
|
|
|
|
const z = 0;
|
|
|
|
|
return [y, x, z]
|
|
|
|
|
}
|
2024-06-27 18:01:47 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 创建场景
|
|
|
|
|
* */
|
|
|
|
|
setScene() {
|
|
|
|
|
this.scene = new THREE.Scene();
|
|
|
|
|
}
|
2024-06-27 18:01:47 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 创建相机
|
|
|
|
|
* */
|
|
|
|
|
setCamera() {
|
2024-07-02 19:01:27 +08:00
|
|
|
this.camera = new THREE.PerspectiveCamera(10, rootEl.offsetWidth / rootEl.offsetHeight, 1, 2000);
|
2024-07-01 18:22:37 +08:00
|
|
|
this.camera.up.x = 0;
|
|
|
|
|
this.camera.up.y = 0;
|
|
|
|
|
this.camera.up.z = 1;
|
|
|
|
|
this.camera.lookAt(0, 0, 0);
|
|
|
|
|
this.scene.add(this.camera);
|
|
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 创建渲染器
|
|
|
|
|
* */
|
|
|
|
|
setRenderer() {
|
|
|
|
|
this.renderer = new THREE.WebGLRenderer({antialias: true});
|
|
|
|
|
this.renderer.setPixelRatio(window.devicePixelRatio * 1);
|
|
|
|
|
this.renderer.sortObjects = true; // 渲染顺序
|
2024-07-04 17:58:23 +08:00
|
|
|
this.renderer.setClearColor(0xffffff, 0);
|
2024-07-02 19:01:27 +08:00
|
|
|
this.renderer.setSize(rootEl.offsetWidth, rootEl.offsetHeight);
|
2024-07-01 18:22:37 +08:00
|
|
|
rootEl.appendChild(this.renderer.domElement);
|
|
|
|
|
|
|
|
|
|
function onWindowResize() {
|
2024-07-02 19:01:27 +08:00
|
|
|
this.camera.aspect = rootEl.offsetWidth / rootEl.offsetHeight;
|
2024-07-01 18:22:37 +08:00
|
|
|
this.camera.updateProjectionMatrix();
|
2024-07-02 19:01:27 +08:00
|
|
|
this.renderer.setSize(rootEl.offsetWidth, rootEl.offsetHeight);
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-02 18:50:20 +08:00
|
|
|
rootEl.addEventListener('resize', onWindowResize.bind(this), false);
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 创建控制器
|
|
|
|
|
* */
|
|
|
|
|
setControl() {
|
2024-07-09 02:02:18 +08:00
|
|
|
this.controls = new THREE.OrbitControls(this.camera, rootEl);
|
|
|
|
|
// this.controls.enableRotate = false
|
2024-07-01 18:22:37 +08:00
|
|
|
this.camera.position.set(this.cameraPosition.x, this.cameraPosition.y, this.cameraPosition.z);
|
|
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 创建一个xyz坐标轴
|
|
|
|
|
* */
|
|
|
|
|
setAxes() {
|
|
|
|
|
const axes = new THREE.AxesHelper(100);
|
|
|
|
|
this.scene.add(axes);
|
|
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
/**
|
|
|
|
|
* @desc 鼠标 hover 事件
|
|
|
|
|
* */
|
|
|
|
|
bindMouseEvent() {
|
2024-07-04 17:58:23 +08:00
|
|
|
const that = this, _this = this;
|
|
|
|
|
const raycaster = new THREE.Raycaster();
|
2024-07-01 18:22:37 +08:00
|
|
|
|
|
|
|
|
function onMouseMove(event) {
|
2024-07-04 17:58:23 +08:00
|
|
|
const {top, left, width, height} = rootEl.getBoundingClientRect();
|
|
|
|
|
// const clientX = event.clientX - left
|
|
|
|
|
// const clientY = event.clientY - top
|
|
|
|
|
|
|
|
|
|
that.mouse.x = (event.clientX / width) * 2 - 1; //标准设备横坐标
|
|
|
|
|
that.mouse.y = -(event.clientY / height) * 2 + 1; //标准设备纵坐标
|
|
|
|
|
// const standardVector = new THREE.Vector3(x, y, 0.5); //标准设备坐标
|
|
|
|
|
// //标准设备坐标转世界坐标
|
|
|
|
|
// const worldVector = standardVector.unproject(that.camera);
|
|
|
|
|
// //射线投射方向单位向量(worldVector坐标减相机位置坐标)
|
|
|
|
|
// const ray = worldVector.sub(that.camera.position).normalize();
|
|
|
|
|
// //创建射线投射器对象
|
|
|
|
|
// let raycaster = new THREE.Raycaster(that.camera.position, ray);
|
|
|
|
|
// //返回射线选中的对象
|
|
|
|
|
// let intersects = raycaster.intersectObjects(that.meshList);
|
|
|
|
|
// if (intersects.length) {
|
|
|
|
|
// if (intersects[0].object.parent && intersects[0].object.parent._groupType === 'areaBlock') {
|
|
|
|
|
// if (that.selectObject !== intersects[0].object.parent) {
|
|
|
|
|
// if (that.selectObject) {
|
|
|
|
|
// transiform(that.selectObject.position, {
|
|
|
|
|
// x: that.selectObject.position.x,
|
|
|
|
|
// y: that.selectObject.position.y,
|
|
|
|
|
// z: 0
|
|
|
|
|
// }, 100);
|
|
|
|
|
// transiform(intersects[0].object.parent.position, {
|
|
|
|
|
// x: intersects[0].object.parent.position.x,
|
|
|
|
|
// y: intersects[0].object.parent.position.y,
|
|
|
|
|
// z: 0.8
|
|
|
|
|
// }, 100);
|
|
|
|
|
// that.selectObject = intersects[0].object.parent;
|
|
|
|
|
// } else {
|
|
|
|
|
// transiform(intersects[0].object.parent.position, {
|
|
|
|
|
// x: intersects[0].object.parent.position.x,
|
|
|
|
|
// y: intersects[0].object.parent.position.y,
|
|
|
|
|
// z: 0.8
|
|
|
|
|
// }, 100);
|
|
|
|
|
// that.selectObject = intersects[0].object.parent;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onPointerMove() {
|
|
|
|
|
if (_this.selectedObject) {
|
|
|
|
|
_this.selectedObject.material.color.set(0xffffff);
|
|
|
|
|
_this.selectedObject = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (raycaster) {
|
2024-07-05 17:36:16 +08:00
|
|
|
const intersects = raycaster.intersectObjects(_this.markers);
|
|
|
|
|
console.log(intersects)
|
2024-07-04 17:58:23 +08:00
|
|
|
if (intersects.length > 0) {
|
|
|
|
|
const res = intersects.filter(function (res) {
|
|
|
|
|
return res && res.object;
|
|
|
|
|
})[intersects.length - 1];
|
|
|
|
|
if (res && res.object) {
|
|
|
|
|
_this.selectedObject = res.object;
|
|
|
|
|
_this.selectedObject.material.color.set('#f00');
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-04 02:11:29 +08:00
|
|
|
const onClick = evt => {
|
|
|
|
|
// 创建一个射线投射器
|
2024-07-04 17:58:23 +08:00
|
|
|
raycaster.setFromCamera(this.mouse, this.camera);
|
2024-07-05 17:36:16 +08:00
|
|
|
console.log(raycaster.intersectObjects(this.markers))
|
2024-07-04 17:58:23 +08:00
|
|
|
const marker = this.markers.find(e => raycaster.intersectObject(e, true).length > 0)
|
|
|
|
|
if (marker) {
|
|
|
|
|
console.log("选取的点:", marker)
|
|
|
|
|
const {$glob} = window
|
|
|
|
|
root.$storeBoard.search.storeCode = marker.data?.storeCode
|
|
|
|
|
$glob.group = '9f299712-5549-413b-a93b-7c3e3b5bfadb'
|
|
|
|
|
}
|
2024-07-04 02:11:29 +08:00
|
|
|
}
|
|
|
|
|
window.addEventListener('mousemove', onMouseMove, false);
|
2024-07-04 17:58:23 +08:00
|
|
|
// rootEl.addEventListener('pointermove', onPointerMove);
|
|
|
|
|
rootEl.addEventListener('click', onClick);
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
makeGround() {
|
2024-07-10 01:58:51 +08:00
|
|
|
const material = new THREE.MeshBasicMaterial({opacity: 0.5, transparent: true, color: '#07193D'});
|
2024-07-01 18:22:37 +08:00
|
|
|
const geometry = new THREE.PlaneGeometry(100, 100, 1, 1);
|
|
|
|
|
let ground = new THREE.Mesh(geometry, material);
|
|
|
|
|
ground.position.x = 0;
|
|
|
|
|
ground.position.y = 0;
|
|
|
|
|
ground.position.z = -1;
|
|
|
|
|
this.scene.add(ground);
|
|
|
|
|
ground.receiveShadow = true;
|
|
|
|
|
ground.castShadow = true;
|
2024-07-10 01:58:51 +08:00
|
|
|
const loader = new THREE.FontLoader();
|
|
|
|
|
loader.load('/presource/datascreen/js/three/fonts/PingFang SC_Regular.json', (font) => {
|
|
|
|
|
const textGeometry = new THREE.TextGeometry('郑州市', {
|
|
|
|
|
font: font,
|
|
|
|
|
size: 1,
|
|
|
|
|
height: 0.2,
|
|
|
|
|
curveSegments: 12,
|
|
|
|
|
bevelEnabled: true,
|
|
|
|
|
bevelThickness: 0.01,
|
|
|
|
|
bevelSize: 0.02,
|
|
|
|
|
bevelOffset: 0,
|
|
|
|
|
bevelSegments: 5
|
|
|
|
|
});
|
2024-07-10 02:04:54 +08:00
|
|
|
textGeometry.translate(1, 0, 3.2)
|
|
|
|
|
textGeometry.rotateX(Math.PI / 2)
|
2024-07-10 01:58:51 +08:00
|
|
|
textGeometry.rotateZ(Math.PI / 2)
|
2024-07-10 02:11:22 +08:00
|
|
|
const textMaterial = new THREE.MeshPhongMaterial({color: 0xffffff});
|
2024-07-10 01:58:51 +08:00
|
|
|
const text = new THREE.Mesh(textGeometry, textMaterial);
|
|
|
|
|
this.scene.add(text);
|
2024-07-10 02:04:54 +08:00
|
|
|
// const planeGeometry = new THREE.PlaneGeometry(textGeometry.boundingBox.max.x, textGeometry.boundingBox.max.y);
|
|
|
|
|
// const planeMaterial = new THREE.MeshBasicMaterial({color: '#07193D', side: THREE.DoubleSide});
|
|
|
|
|
// const plane = new THREE.Mesh(planeGeometry, planeMaterial);
|
|
|
|
|
// plane.position.copy(text.position).add(new THREE.Vector3(0, -textGeometry.boundingBox.max.y, 0));
|
|
|
|
|
// plane.position.set(0, 0, 0);
|
|
|
|
|
// this.scene.add(plane);
|
2024-07-10 01:58:51 +08:00
|
|
|
})
|
|
|
|
|
// const div = document.createElement("div");
|
|
|
|
|
// div.style.color = "#fff";
|
|
|
|
|
// div.style.width = "40px";
|
|
|
|
|
// div.style.height = "25px";
|
|
|
|
|
// div.style.borderWidth = "1px";
|
|
|
|
|
// div.style.borderStyle = "solid";
|
|
|
|
|
// div.style.borderColor = "#00ffc4";
|
|
|
|
|
// div.style.borderRadius = "5px";
|
|
|
|
|
// div.style.fontSize = "14px";
|
|
|
|
|
// div.style.fontWeight = 600;
|
|
|
|
|
// div.style.textShadow = "1px 1px 6px #fff";
|
|
|
|
|
// div.style.textAlign = "center";
|
|
|
|
|
// div.style.lineHeight = "25px";
|
|
|
|
|
// div.textContent = `我操你大爷`;
|
|
|
|
|
// const tip = new THREE.CSS3DObject(div);
|
|
|
|
|
// tip.scale.set(0.01, 0.01, 0.01);
|
|
|
|
|
// tip.position.set(0, 0, 1);
|
|
|
|
|
// this.scene.add(tip);
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
tipsSprite(areaData) {
|
|
|
|
|
let canvas = document.createElement("canvas");
|
|
|
|
|
canvas.width = 500;
|
|
|
|
|
canvas.height = 60;
|
|
|
|
|
document.body.appendChild(canvas);
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
let ctx = canvas.getContext("2d");
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
ctx.fillStyle = "#ffffff";
|
2024-07-02 18:25:08 +08:00
|
|
|
ctx.font = "20px Arial";
|
2024-07-01 18:22:37 +08:00
|
|
|
ctx.textAlign = "center";
|
|
|
|
|
ctx.fillText(areaData.data.name, 250, 40);
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
let texture = new THREE.CanvasTexture(canvas);
|
|
|
|
|
texture.needsUpdate = true;
|
|
|
|
|
let SpriteMaterial = new THREE.SpriteMaterial({
|
|
|
|
|
map: texture,
|
|
|
|
|
depthTest: false,
|
|
|
|
|
});
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
let textSprite = new THREE.Sprite(SpriteMaterial);
|
|
|
|
|
textSprite.position.set(areaData.data.cp[0], areaData.data.cp[1], 1);
|
|
|
|
|
textSprite.scale.set(4, 0.5, 1);
|
|
|
|
|
textSprite.renderOrder = 3;
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
return textSprite
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-07-01 02:32:42 +08:00
|
|
|
|
2024-07-01 18:22:37 +08:00
|
|
|
return new GeoMap()
|
2024-07-02 18:25:08 +08:00
|
|
|
},
|
|
|
|
|
getData() {
|
|
|
|
|
const {$http, $waitFor} = window
|
|
|
|
|
const {groupCodeList, currentDate} = this.search
|
|
|
|
|
return $waitFor($http).then(() => $http.post("/data-boot/la/screen/marketBoard/storeReport", {
|
|
|
|
|
groupCodeList, currentDate
|
|
|
|
|
})).then(res => {
|
|
|
|
|
if (res?.data) {
|
|
|
|
|
return this.layers = res.data || []
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-07-01 18:22:37 +08:00
|
|
|
}
|
|
|
|
|
},
|
2024-07-02 18:50:20 +08:00
|
|
|
watch: {
|
|
|
|
|
search: {
|
|
|
|
|
immediate: true, deep: true, handler() {
|
|
|
|
|
const {$waitFor} = window
|
|
|
|
|
this.getData().then(() => $waitFor(this.geoMap)).then(() => this.geoMap.addMarkers())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
2024-07-01 02:32:42 +08:00
|
|
|
mounted() {
|
2024-07-02 18:50:20 +08:00
|
|
|
this.loadLib().then(() => {
|
2024-07-01 18:22:37 +08:00
|
|
|
this.geoMap = this.initMap();
|
|
|
|
|
this.geoMap.init();
|
|
|
|
|
})
|
2024-06-27 18:01:47 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<section class="AppThreeMap"/>
|
|
|
|
|
</template>
|
2024-07-09 02:02:18 +08:00
|
|
|
<style>
|
|
|
|
|
.AppThreeMap {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
</style>
|