安装依赖
(一般是pnpm或yarn或者是ui界面,这样快一点)
bash
npm install @geoscene/core
创建第一个地图
概览 | GeoScene Maps SDK for JavaScript
设置布局
我的布局基本为下面的这样,所以要设置一下排版(以ant-design为例)

app.vue里的布局
ini
<template>
<a-layout id="components-layout-demo-fixed" :style="{
position: 'relative',
minHeight: '100vh'
}">
<a-layout-header :style="{
position: 'fixed',
zIndex: 1000,
width: '100%',
height: '40px',
top: 0,
left: 0
}">
<a-menu
theme="dark"
mode="horizontal"
:default-selected-keys="[currentRoute]"
:style="{ lineHeight: '40px' }"
@select="handleMenuSelect"
>
<a-menu-item key="map">
<router-link to="/">可视化地图</router-link>
</a-menu-item>
<a-menu-item key="nav2">
<router-link to="/nav2">nav 2</router-link>
</a-menu-item>
<a-menu-item key="nav3">
<router-link to="/nav3">nav 3</router-link>
</a-menu-item>
</a-menu>
</a-layout-header>
<a-layout-content :style="{
position: 'absolute', // 确保地图可以独占余下的页面空间
top: '40px',
bottom: '0',
left: '0',
right: '0',
overflow: 'auto' // 确保内容可滚动
}">
<router-view />
</a-layout-content>
</a-layout>
</template>
加载地图
在全局的那个index.html文件里添加全局的css样式
ini
<link rel="stylesheet" href="\node_modules@geoscene\core\assets\geoscene\themes\light\main.css">
当然也可以将light改为dark,这样就是夜间模式了
如果要去除地图外边框的蓝色线条,可以在light\main.css文件里geoscene-view-outline将其改为0。
具体导入什么文件看视频或者官方文档,或者去文件夹里找
xml
<template>
<div id="viewDiv"></div>
</template>
<script setup>
import { onMounted } from 'vue' // 导入钩子函数
// 具体导入什么文件看视频或者官方文档,或者去文件夹里找
import Map from '@geoscene/core/Map' // 导入Map类
import MapView from '@geoscene/core/views/MapView'
onMounted(() => { // 生命周期函数
const map = new Map({ // 创建Map实例
basemap: 'tianditu-vector' // 设置底图为混合
})
const view = new MapView({ // 创建MapView实例
container: 'viewDiv', // 绑定dom节点
map: map, // 指定地图
center: [115.9, 28.5], // 设置中心点坐标
zoom: 10 // 缩放等级
})
view.ui.remove("attribution") // 移除相关控件
})
</script>
<style scoped>
#viewDiv {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
/* filter: brightness(0.88) contrast(0.95) grayscale(0) hue-rotate(180deg) opacity(1) saturate(2.5) sepia(0.5) invert(1); */
}
</style>
如果要求是3D视图,那么
xml
<script setup>
import { onMounted } from 'vue'
import Map from '@geoscene/core/Map'
import SceneView from '@geoscene/core/views/SceneView' // 导入SceneView类
onMounted(() => {
const map = new Map({
basemap: 'tianditu-vector',
ground: 'world-elevation' // 3D场景通常需要设置地面
})
const view = new SceneView({
container: 'viewDiv',
map: map,
camera: { // 3D场景使用camera而不是center/zoom
position: {
x: 115.9, // 经度
y: 28.65, // 纬度
z: 90000 // 高度,单位米
},
tilt: 0, // 倾斜角度(0-90)
heading: 0 // 方向角(0-360)
}
})
view.ui.remove("attribution")
})
</script>
以上代码确保浏览器开启硬件加速。
添加控件
csharp
import Fullscreen from '@geoscene/core/widgets/Fullscreen'
const fullscreen = new Fullscreen({
view: view
})
view.ui.add(fullscreen, "top-right") // 将控件添加到地图右上角
地图点击事件
arduino
/* 点击地图事件 */
view.on("click", function (event) {
// 获取点击位置的坐标
const point = event.mapPoint;
console.log("经度:", point.longitude.toFixed(6)); // 注意不是x
console.log("纬度:", point.latitude.toFixed(6));
console.log("高程:", point.z.toFixed(2));
console.log("空间参考:", point.spatialReference.wkid);
// 也可以直接打印整个点对象
console.log("完整的点对象:", point);
});
一个完整的底图设计(底图切换+pinia存储相机位置+防抖函数读取相机位置)
xml
<template>
<div id="viewDivContainer" :class="{ 'dark-mode': MapLayerStore.isDarkMode }">
<div id="viewDiv"></div> <!-- 用于控制底图颜色,所以viewDiv放在viewDivContainer容器内 -->
</div>
</template>
<script setup>
import {onMounted, onUnmounted, ref, watch} from 'vue'
import Map from '@geoscene/core/Map'
import SceneView from '@geoscene/core/views/SceneView'
import Fullscreen from '@geoscene/core/widgets/Fullscreen'
// MapStore 用于获取底图信息
import {useMapLayerStore} from '@/store/MapLayers.js'
const MapLayerStore = useMapLayerStore()
let map = null // 用于存储地图对象
let view = null // 用于存储视图对象
const cameraWatchHandle = ref(null) // 用于存储相机变化的值
// 防抖函数
function debounce(func, delay) {
let timer = null;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// 防抖后的回调函数
const debouncedCallback = debounce((camera) => {
console.log('Camera changed:', camera);
cameraWatchHandle.value = {
x: camera.position.longitude,
y: camera.position.latitude,
z: camera.position.z,
tilt: camera.tilt,
heading: camera.heading
};
}, 300); // 设置延迟时间为 200 毫秒
// 监听底图的变化
watch(() => MapLayerStore.isImageBasemap, (newValue) => {
if (map) {
map.basemap = newValue ? "tianditu-image" : "tianditu-vector";
}
});
onMounted(() => {
map = new Map({
basemap: MapLayerStore.isImageBasemap ? "tianditu-image" : "tianditu-vector",
})
view = new SceneView({
container: 'viewDiv',
map: map,
camera: {
position: {
x: MapLayerStore.mapX,
y: MapLayerStore.mapY,
z: MapLayerStore.mapZ
},
tilt: MapLayerStore.mapTilt,
heading: MapLayerStore.mapHeading
}
});
// 监听 camera 变化,添加防抖
view.watch('camera', debouncedCallback);
// 控件管理
view.ui.remove(["attribution", "navigation-toggle"])
const fullscreen = new Fullscreen({
view: view
})
view.ui.add(fullscreen, "top-right")
})
onUnmounted(() => {
// 最后切换页面的时候将相机位置更新到store中
MapLayerStore.updateCameraPosition(cameraWatchHandle.value)
// 清理view和map
if (view) {
view.destroy()
view = null
}
if (map) {
map.destroy()
map = null
}
})
</script>
<style scoped>
#viewDivContainer {
height: 100%;
width: 100%;
position: relative;
}
#viewDivContainer.dark-mode #viewDiv {
filter: brightness(0.7) contrast(1.4) hue-rotate(180deg) opacity(1) saturate(3) sepia(0.5) invert(1);
}
#viewDiv {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
.geoscene-view {
--geoscene-view-outline: none !important;
}
</style>
切换底图和底图颜色的开关
ini
<div class="switch-container">
<label>底图颜色:</label>
<a-switch :disabled="MapLayerStore.isImageBasemap" v-model:checked="MapLayerStore.isDarkMode" checked-children="暗色" un-checked-children="亮色"/>
<label>底图类型:</label>
<a-switch
v-model:checked="MapLayerStore.isImageBasemap"
:disabled="MapLayerStore.isDarkMode"
checked-children="影像底图"
un-checked-children="矢量底图"
/>
</div>
底图全局的状态管理
ini
export const useMapLayerStore = defineStore('MapLayers', () => {
const isDarkMode = ref(false);
const isImageBasemap = ref(false);
const mapX = ref(115.9);
const mapY = ref(28.65);
const mapZ = ref(90000);
const mapTilt = ref(0);
const mapHeading = ref(0);
// Action to update all camera properties at once
function updateCameraPosition(position) {
console.log("updateCameraPosition", position)
mapX.value = position.x;
mapY.value = position.y;
mapZ.value = position.z;
mapTilt.value = position.tilt;
mapHeading.value = position.heading;
}
return {
isDarkMode,
isImageBasemap,
mapX,
mapY,
mapZ,
mapTilt,
mapHeading,
updateCameraPosition
}
});