一、代码效果展示
只要换个密钥即可使用,代码已经添加了控件直接控制不同类型地图(以及注记)。如果需要了解如何单独展示某类型的地图,具体的讲解教程请看OpenLayers集成天地图服务开发指南。
下方代码中找到这个,引号内部填入您的密钥。 密钥申请教程天地图账号注册&密钥key申请。
var tdtKey = "您的密钥";
二、完整代码。
<!DOCTYPE html>
<html lang="zh">
<head>
<!-- 引入在线 OpenLayers 样式和脚本 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css">
<script src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script>
<style>
.map {
height: 95vh;
width: 95vw;
position: relative;
}
/* 图层控制面板样式 */
.layer-control {
position: absolute;
top: 10px;
right: 10px;
background-color: white;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.2);
z-index: 1000;
max-width: 250px;
}
.layer-control h3 {
margin-top: 0;
margin-bottom: 10px;
font-size: 16px;
color: #333;
}
.layer-group {
margin-bottom: 10px;
}
.layer-group-title {
font-weight: bold;
margin-bottom: 5px;
color: #555;
}
.layer-item {
margin-left: 10px;
margin-bottom: 5px;
}
.layer-item label {
display: flex;
align-items: center;
cursor: pointer;
}
.layer-item input {
margin-right: 5px;
}
/* 底部信息栏 */
.info-bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(255,255,255,0.8);
padding: 5px 10px;
font-size: 12px;
display: flex;
justify-content: space-between;
}
/* 响应式设计 */
@media (max-width: 768px) {
.layer-control {
max-width: 200px;
font-size: 14px;
}
}
</style>
<title>天地图多图层浏览器</title>
</head>
<body>
<div id="map" class="map">
<!-- 图层控制面板 -->
<div class="layer-control">
<h3>图层控制</h3>
<div class="layer-group">
<div class="layer-group-title">底图选择</div>
<div class="layer-item">
<label><input type="radio" name="baseLayer" value="vec" checked> 矢量图</label>
</div>
<div class="layer-item">
<label><input type="radio" name="baseLayer" value="img"> 影像图</label>
</div>
<div class="layer-item">
<label><input type="radio" name="baseLayer" value="ter"> 地形图</label>
</div>
</div>
<div class="layer-group">
<div class="layer-group-title">注记图层</div>
<div class="layer-item">
<label><input type="checkbox" id="labelLayer" checked> 显示注记</label>
</div>
</div>
</div>
<!-- 底部信息栏 -->
<div class="info-bar">
<div id="scale-info">比例尺: </div>
<div id="coordinate-info">坐标: </div>
</div>
</div>
<script type="text/javascript">
// 天地图密钥
var tdtKey = "您的密钥";
// 定义图层组
var vecLayer = new ol.layer.Tile({
title: "天地图矢量图层",
source: new ol.source.XYZ({
url: "http://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=" + tdtKey,
wrapX: true
}),
visible: true
});
var cvaLayer = new ol.layer.Tile({
title: "天地图矢量图层注记",
source: new ol.source.XYZ({
url: "http://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=" + tdtKey,
wrapX: true
}),
visible: true
});
var imgLayer = new ol.layer.Tile({
title: "天地图影像图层",
source: new ol.source.XYZ({
url: "http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=" + tdtKey,
wrapX: true
}),
visible: false
});
var ciaLayer = new ol.layer.Tile({
title: "天地图影像图层注记",
source: new ol.source.XYZ({
url: "http://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=" + tdtKey,
wrapX: true
}),
visible: false
});
var terLayer = new ol.layer.Tile({
title: "天地图地形图层",
source: new ol.source.XYZ({
url: "http://t0.tianditu.gov.cn/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=" + tdtKey,
wrapX: true
}),
visible: false
});
var ctaLayer = new ol.layer.Tile({
title: "天地图地形图层注记",
source: new ol.source.XYZ({
url: "http://t0.tianditu.gov.cn/DataServer?T=cta_w&x={x}&y={y}&l={z}&tk=" + tdtKey,
wrapX: true
}),
visible: false
});
// 创建地图
var map = new ol.Map({
target: 'map',
layers: [vecLayer, imgLayer, terLayer, cvaLayer, ciaLayer, ctaLayer],
view: new ol.View({
center: ol.proj.fromLonLat([120.62, 31.32]), // 设置初始中心点(苏州)
zoom: 8,
maxZoom: 18,
minZoom: 2,
projection: "EPSG:3857" // 使用Web墨卡托投影以适配 OpenLayers
}),
controls: [
new ol.control.Zoom(),
new ol.control.Attribution(),
new ol.control.ScaleLine(),
new ol.control.Rotate(),
new ol.control.ZoomSlider(),
new ol.control.FullScreen()
]
});
// 图层控制逻辑
var baseLayers = {
'vec': [vecLayer, cvaLayer],
'img': [imgLayer, ciaLayer],
'ter': [terLayer, ctaLayer]
};
var labelLayers = {
'vec': cvaLayer,
'img': ciaLayer,
'ter': ctaLayer
};
// 底图切换
var baseLayerRadios = document.getElementsByName('baseLayer');
var currentBaseLayer = 'vec';
for (var i = 0; i < baseLayerRadios.length; i++) {
baseLayerRadios[i].addEventListener('change', function() {
// 隐藏当前底图
baseLayers[currentBaseLayer].forEach(function(layer) {
layer.setVisible(false);
});
// 显示新选择的底图
currentBaseLayer = this.value;
baseLayers[currentBaseLayer][0].setVisible(true); // 底图
// 根据注记复选框状态决定是否显示注记
var labelCheckbox = document.getElementById('labelLayer');
baseLayers[currentBaseLayer][1].setVisible(labelCheckbox.checked);
});
}
// 注记图层控制
var labelCheckbox = document.getElementById('labelLayer');
labelCheckbox.addEventListener('change', function() {
// 获取当前选中的底图对应的注记图层
var currentLabelLayer = labelLayers[currentBaseLayer];
currentLabelLayer.setVisible(this.checked);
});
// 显示坐标信息
var coordinateInfo = document.getElementById('coordinate-info');
map.on('pointermove', function(evt) {
var coords = ol.proj.toLonLat(evt.coordinate);
coordinateInfo.innerHTML = '坐标: ' + coords[0].toFixed(6) + ', ' + coords[1].toFixed(6);
});
// 显示比例尺信息
var scaleInfo = document.getElementById('scale-info');
map.getView().on('change:resolution', function() {
var resolution = map.getView().getResolution();
var units = map.getView().getProjection().getUnits();
var dpi = 25.4 / 0.28;
var mpu = ol.proj.METERS_PER_UNIT[units];
var scale = resolution * mpu * 39.37 * dpi;
scale = Math.round(scale);
scaleInfo.innerHTML = '比例尺: 1:' + scale;
});
</script>
</body>
</html>