整地图

This commit is contained in:
aixianling
2024-07-01 18:22:37 +08:00
parent 0e970099a0
commit 8320225e95
4 changed files with 493 additions and 2077 deletions

BIN
public/bgf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ const libs = [
`${KENGEE_CDN_BASE}/js/dayjs.min.js`, `${KENGEE_CDN_BASE}/js/dayjs.min.js`,
`${KENGEE_CDN_BASE}/js/Tween.js`, `${KENGEE_CDN_BASE}/js/Tween.js`,
`${KENGEE_CDN_BASE}/js/three/three.js`, `${KENGEE_CDN_BASE}/js/three/three.js`,
`${KENGEE_CDN_BASE}/js/three/js/controls/OrbitControls.js`, `${KENGEE_CDN_BASE}/js/d3-array.min.js`,
`${KENGEE_CDN_BASE}/js/d3-geo.min.js`, `${KENGEE_CDN_BASE}/js/d3-geo.min.js`,
] ]
window.$loadScript = (type = 'js', url, dom = "body") => { window.$loadScript = (type = 'js', url, dom = "body") => {

View File

@@ -1,8 +1,24 @@
<script> <script>
const {TWEEN, THREE, d3, axios, OrbitControls} = window export default {
name: "AppThreeMap",
label: "3D地图",
data() {
return {
geoMap: null
}
},
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`))
},
initMap() {
const {THREE, d3, axios, TWEEN} = window
const rootEl = this.$el
class GeoMap { class GeoMap {
constructor() { constructor() {
this.cameraPosition = {x: 100, y: 0, z: 100}; // 相机位置 this.cameraPosition = {x: 15, y: 5, z: 15}; // 相机位置
this.scene = null; // 场景 this.scene = null; // 场景
this.camera = null; // 相机 this.camera = null; // 相机
this.renderer = null; // 渲染器 this.renderer = null; // 渲染器
@@ -21,12 +37,12 @@ class GeoMap {
init() { init() {
this.setScene(); this.setScene();
this.setCamera(); this.setCamera();
this.setLight(); // this.setLight();
// this.setAxes();
this.setRenderer(); this.setRenderer();
this.setControl(); this.setControl();
this.setAxes();
this.makeGround(); this.makeGround();
this.getMap('https://geo.datav.aliyun.com/areas_v3/bound/330000_full.json', '开封'); this.getMap('http://10.0.97.209/blade-visual/map/data?id=1456');
this.animat(); this.animat();
this.bindMouseEvent(); this.bindMouseEvent();
} }
@@ -48,12 +64,12 @@ class GeoMap {
* @desc 获取地图 * @desc 获取地图
* */ * */
getMap(url, type) { getMap(url) {
const that = this; const that = this;
axios.get(url).then(function (res) { axios.get(url).then(function (res) {
if (res.status === 200) { if (res.status === 200) {
const data = res.data; const data = res.data;
that.setMapData(data, type) that.setMapData(data)
} }
}) })
} }
@@ -76,13 +92,12 @@ class GeoMap {
* @desc 绘制地图 * @desc 绘制地图
* @params geojson * @params geojson
* */ * */
setMapData(data) {
setMapData(data, type) {
const that = this; const that = this;
let vector3json = []; let vector3json = [];
data.features.forEach(function (features, featuresIndex) { data.features.forEach(function (features, featuresIndex) {
const areaItems = features.geometry.coordinates; const areaItems = features.geometry.coordinates;
features.properties.cp = that.lnglatToVector3(features.properties.cp); features.properties.cp = that.lnglatToVector3(features.properties.centroid);
vector3json[featuresIndex] = { vector3json[featuresIndex] = {
data: features.properties, data: features.properties,
mercator: [] mercator: []
@@ -96,11 +111,8 @@ class GeoMap {
}) })
}) })
}); });
if (type === 'sichuan') { console.log(data)
this.drawMap(vector3json) this.drawMap(vector3json)
} else if (type === 'china') {
this.drawChinaMap(vector3json)
}
} }
/** /**
@@ -134,6 +146,7 @@ class GeoMap {
const lineMaterial = new THREE.LineBasicMaterial({ const lineMaterial = new THREE.LineBasicMaterial({
color: '#9800ff' color: '#9800ff'
}); });
console.log(data)
data.forEach(function (areaData) { data.forEach(function (areaData) {
let areaGroup = new THREE.Group(); let areaGroup = new THREE.Group();
areaGroup.name = 'area'; areaGroup.name = 'area';
@@ -162,73 +175,6 @@ class GeoMap {
that.scene.add(that.mapGroup); that.scene.add(that.mapGroup);
} }
/**
* @desc 绘制图形作为背景
* @param data
* */
drawChinaMap(data) {
let that = this;
let mapGroup = new THREE.Group();
mapGroup.position.y = 0;
this.scene.add(mapGroup);
const lineMaterial = new THREE.LineDashedMaterial({
color: '#656565',
dashSize: 0.1,
gapSize: 0.2
});
let fakeLightMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff,
flatShading: true,
vertexColors: THREE.VertexColors,
side: THREE.DoubleSide,
transparent: true,
opacity: 0.5,
depthTest: false,
wireframe: false,
});
data.forEach(function (areaData) {
if (areaData.data.id === '51') {
areaData.mercator.forEach(function (areaItem) {
let geometry = new THREE.BufferGeometry();
let verticesArr = [];
for (let i = 0; i < areaItem.length - 1; i++) {
verticesArr.push(areaItem[i].x, areaItem[i].y, areaItem[i].z);
verticesArr.push(areaItem[i + 1].x, areaItem[i + 1].y, areaItem[i + 1].z + 5);
verticesArr.push(areaItem[i].x, areaItem[i].y, areaItem[i].z + 5);
verticesArr.push(areaItem[i].x, areaItem[i].y, areaItem[i].z);
verticesArr.push(areaItem[i + 1].x, areaItem[i + 1].y, areaItem[i + 1].z);
verticesArr.push(areaItem[i + 1].x, areaItem[i + 1].y, areaItem[i + 1].z + 5);
}
geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(verticesArr), 3));
let count = geometry.attributes.position.count;
geometry.addAttribute('color', new THREE.BufferAttribute(new Float32Array(count * 3), 3));
let color = new THREE.Color();
let positions = geometry.attributes.position;
let colors = geometry.attributes.color;
for (let i = 0; i < count; i++) {
let a = positions.getZ(i) ? 0 : 1;
color.setHSL((268 * a) / 360, 1.0 * a, a ? 0.5 : 0.13);
colors.setXYZ(i, color.r, color.g, color.b);
}
let mesh = new THREE.Mesh(geometry, fakeLightMaterial);
mapGroup.add(mesh);
});
} else {
areaData.mercator.forEach(function (areaItem) {
// Draw Line
let lineGeometry = new THREE.Geometry();
lineGeometry.vertices = areaItem;
let lineMesh = new THREE.Line(lineGeometry, lineMaterial);
lineMesh.computeLineDistances();
mapGroup.add(lineMesh);
});
}
});
that.scene.add(mapGroup);
}
/** /**
* @desc 移动相机 * @desc 移动相机
* */ * */
@@ -259,9 +205,9 @@ class GeoMap {
* @desc 坐标转换 * @desc 坐标转换
* @param lnglat [x,y] * @param lnglat [x,y]
* */ * */
lnglatToVector3(lnglat) { lnglatToVector3(lnglat = []) {
if (!this.projection) { if (!this.projection) {
this.projection = d3.geoMercator().center([104.072259, 30.663403]).scale(100).translate([0, 0]); this.projection = d3.geoMercator().center([114.31, 34.80]).scale(100).translate([0, 0]);
} }
const [x, y] = this.projection([lnglat[0], lnglat[1]]) const [x, y] = this.projection([lnglat[0], lnglat[1]])
const z = 0; const z = 0;
@@ -296,7 +242,7 @@ class GeoMap {
this.renderer.sortObjects = true; // 渲染顺序 this.renderer.sortObjects = true; // 渲染顺序
this.renderer.setClearColor('#212121'); this.renderer.setClearColor('#212121');
this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setSize(window.innerWidth, window.innerHeight);
this.$el.appendChild(this.renderer.domElement); rootEl.appendChild(this.renderer.domElement);
function onWindowResize() { function onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.aspect = window.innerWidth / window.innerHeight;
@@ -383,7 +329,7 @@ class GeoMap {
* @desc 创建地面函数 * @desc 创建地面函数
* */ * */
makeGround() { makeGround() {
const maps = new THREE.TextureLoader().load('/images/bgf.png'); const maps = new THREE.TextureLoader().load('/bgf.png');
maps.wrapS = maps.wrapT = THREE.RepeatWrapping; maps.wrapS = maps.wrapT = THREE.RepeatWrapping;
maps.repeat.set(14, 14); // 纹理 y,x方向重铺 maps.repeat.set(14, 14); // 纹理 y,x方向重铺
maps.needsUpdate = false; // 纹理更新 maps.needsUpdate = false; // 纹理更新
@@ -409,7 +355,7 @@ class GeoMap {
lightGroup(areaData) { lightGroup(areaData) {
/*光柱*/ /*光柱*/
const lightMapTexture = new THREE.TextureLoader().load('/images/light.png'); const lightMapTexture = new THREE.TextureLoader().load('/light.png');
lightMapTexture.repeat.set(1, 1); // 纹理 y,x方向重铺 lightMapTexture.repeat.set(1, 1); // 纹理 y,x方向重铺
lightMapTexture.needsUpdate = false; // 纹理更新 lightMapTexture.needsUpdate = false; // 纹理更新
let lightTipGroup = new THREE.Group(); let lightTipGroup = new THREE.Group();
@@ -540,13 +486,14 @@ class GeoMap {
} }
} }
export default { return new GeoMap()
name: "AppThreeMap", }
label: "3D地图", },
mounted() { mounted() {
THREE.OrbitControls = OrbitControls this.loadLib().then(() => {
this.geoMap = new GeoMap(); this.geoMap = this.initMap();
this.geoMap.init(); this.geoMap.init();
})
} }
} }
</script> </script>
@@ -555,7 +502,7 @@ export default {
<section class="AppThreeMap"/> <section class="AppThreeMap"/>
</template> </template>
<style scoped> <style>
.AppThreeMap { .AppThreeMap {
} }
</style> </style>