No artigo anterior Guia de primeiros passos do folheto: Criando mapas interativos do zero , implementamos um aplicativo de mapa básico. Neste artigo, adicionaremos Amap (sistema de coordenadas de amostragem GCJ-02) e mapearemos Várias maneiras de lidar com deslocamentos.
Adicionar Amap e correção do sistema de coordenadas
Adicione um mapa de satélite Gaode e um mapa transparente de informações de ruas de Gaode.
<script>
// osm
let openstreetmap = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'})
// 高德
let amap = L.layerGroup([L.tileLayer('http://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
minZoom:6,
maxZoom: 18,
attribution: '© AMap'
}), L.tileLayer('http://webst03.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}', {
minZoom:6,
maxZoom: 18,
attribution: '© AMap'
})]);
let baseLayers = {
'OpenStreetMap': openstreetmap,
'Streets': amap
};
// 创建地图对象,并设置 OSM 作为默认底图
let map = L.map('map', {
center: [22.5247, 113.8578],
zoom: 13,
layers: [openstreetmap], // 设置 OSM 为默认底图
});
L.control.layers(baseLayers).addTo(map);
</script>
Correção do mapa
Conforme mostrado na imagem acima, você pode ver que há um desvio entre a posição real de calibração de longitude e latitude do marcador [22.5247, 113.8578] e a posição exibida. O Amap usa o sistema de coordenadas GCJ-02 e nosso marcador usa o sistema de coordenadas WGS-84, portanto, precisamos realizar uma conversão do sistema de coordenadas WGS-84 para o sistema de coordenadas GCJ-02.
https://github.com/googollee/eviltransform
Faça download dos arquivos eviltransform/javascript/
no diretório do warehouse transform.js
e coloque-os transform.js
no index.html
mesmo diretório de nível.
Adicione o seguinte conteúdo em html
<script type="text/javascript" src='./transform.js' crossorigin=""></script>
transform.min.js
Ou use arquivos acelerados por CDN
<script src="https://cdn.jsdelivr.net/npm/[email protected]/transform.min.js" crossorigin=""></script>
A conversão de WGS-84 para GCJ-02 pode ser obtida usando eviltransform.wgs2gcj
o método. Precisamos apenas 22.5247, 113.8578
inserir a longitude e a latitude que inserimos na função a seguir.
let geo = eviltransform.wgs2gcj(22.5247, 113.8578)
let marker = L.marker(geo).addTo(map);
marker.bindPopup("这是一个标记的弹出窗口。").openPopup();
Acima, usamos o método de conversão direta das coordenadas de entrada no mesmo sistema de coordenadas dos blocos.
Claro, também podemos usar outros métodos:
- Personalize o plug-in CRS e use-o para processar deslocamentos no método latLngToPoint.
L.CRS.CustomCRS = L.extend({
}, L.CRS.EPSG3857, {
// 实现 latLngToPoint 和 pointToLatLng 方法
latLngToPoint: function (latlng, zoom) {
// 判断经纬度的来源,瓦片请求不做处理,其他请求来源做偏移处理。
// if(latlng.lat === 22.5247 && latlng.lng === 113.8578){
// let a = eviltransform.wgs2gcj(latlng.lat, latlng.lng)
// latlng.lat = a.lat
// latlng.lng = a.lng
// }else
// {
// console.log("other")
// }
// 自定义实现 latLngToPoint 方法
var projectedPoint = this.projection.project(latlng);
var scale = this.scale(zoom);
var point = this.transformation.transform(projectedPoint, scale);
console.log("latLngToPoint:",point.x,point.y)
return point;
},
pointToLatLng: function (point, zoom) {
// 自定义实现 pointToLatLng 方法
var scale = this.scale(zoom);
var untransformedPoint = this.transformation.untransform(point, scale);
var latlng = this.projection.unproject(untransformedPoint);
console.log("pointToLatLng:",point.x,point.y)
return latlng;
}
})
Ao instanciar o mapa, use o L.CRS.CustomCRS customizado.
let map = L.map('map', {
crs: window.L.CRS.CustomCRS}).setView([22.5247, 113.8578], 13);
- Personalize o plug-in Marker, use este plug-in para realizar o processamento de deslocamento no método de atualização.
// 定义 CustomMarker 插件
L.CustomMarker = L.Marker.extend({
options: {
// 这里可以添加自定义的选项
},
// 初始化方法
initialize: function (latlng, options) {
L.Marker.prototype.initialize.call(this, latlng, options);
},
update: function () {
if (this._icon && this._map) {
// 偏移处理
if(isSelectedAMap){
let geo = eviltransform.wgs2gcj(this._latlng.lat, this._latlng.lng)
let pos = this._map.latLngToLayerPoint(geo).round();
this._setPos(pos);
}else{
let pos = this._map.latLngToLayerPoint(this._latlng).round();
this._setPos(pos);
}
}
return this;
},
});
// 工厂方法
L.customMarker = function (latlng, options) {
return new L.CustomMarker(latlng, options);
};
Instruções:
let marker = L.customMarker([22.5247, 113.8578]).addTo(map);
Código completo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Leaflet@cheungxiongwei</title>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""/>
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/transform.min.js" crossorigin=""></script>
<style>
html, body {
overflow: hidden;
background: #fff;
width: 100%;
height: 100%;
margin: 0;
position: absolute;
top: 0;
}
#map {
height: 100%;
width: 100%;
margin: 0 auto;
background-color: #01172a;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
<script>
// 定义 CustomMarker 插件
L.CustomMarker = L.Marker.extend({
options: {
// 这里可以添加自定义的选项
},
// 初始化方法
initialize: function (latlng, options) {
L.Marker.prototype.initialize.call(this, latlng, options);
},
update: function () {
if (this._icon && this._map) {
// 偏移处理
if(isSelectedAMap){
let geo = eviltransform.wgs2gcj(this._latlng.lat, this._latlng.lng)
let pos = this._map.latLngToLayerPoint(geo).round();
this._setPos(pos);
}else{
let pos = this._map.latLngToLayerPoint(this._latlng).round();
this._setPos(pos);
}
}
return this;
},
});
// 工厂方法
L.customMarker = function (latlng, options) {
return new L.CustomMarker(latlng, options);
};
// osm
let openstreetmap = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'})
// 高德
let amap = L.layerGroup([L.tileLayer('http://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
minZoom:6,
maxZoom: 18,
attribution: '© AMap'
}), L.tileLayer('http://webst03.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}', {
minZoom:6,
maxZoom: 18,
attribution: '© AMap'
})]);
let baseLayers = {
'OpenStreetMap': openstreetmap,
'Streets': amap
};
// 创建地图对象,并设置 OSM 作为默认底图
let map = L.map('map', {
center: [22.5247, 113.8578],
zoom: 13,
layers: [amap], // 设置 OSM 为默认底图
});
L.control.layers(baseLayers).addTo(map);
let isSelectedAMap = true
// 监听底图切换事件
map.on('baselayerchange', function (event) {
// 获取当前选择的地图图层
let selectedLayer = event.layer;
// 判断当前选择的地图
if (selectedLayer === openstreetmap) {
console.log('当前选择的地图是 OpenStreetMap');
// 在这里执行其他逻辑
isSelectedAMap = false
} else if (selectedLayer === amap) {
console.log('当前选择的地图是 Streets');
// 在这里执行其他逻辑
isSelectedAMap = true
}
});
let marker = L.customMarker([22.5247, 113.8578]).addTo(map);
</script>
</html>