Leaflet JS地图:Angular4中实现相对浏览器窗口定位适配打印
解决Leaflet地图打印时固定目标点位置的问题
我明白你的痛点:直接设置地图中心经纬度的话,不同浏览器窗口尺寸下,英国区域的显示效果差异很大,小窗口甚至会裁切内容,而且你还需要打印页面上的其他元素,单纯用Leaflet打印插件满足不了需求。
其实完全可以实现让目标经纬度(英国区域的点)固定在距离地图容器左上角的指定像素位置,核心思路是利用Leaflet提供的坐标转换方法,把经纬度和容器像素坐标互相转换,从而计算出合适的地图中心。
具体实现步骤
- 确定你要固定的目标经纬度(比如你之前用的
[54, -5]) - 设定一个固定的像素偏移量(比如距离容器左上角
200px横向,150px纵向,你可以根据自己的需求调整) - 在打印触发时,通过坐标转换计算出需要调整的地图中心,确保目标点落在指定的像素位置
修改你的Angular组件代码
我帮你调整了现有代码,添加了printMap方法来实现这个逻辑:
import {Component, HostListener, OnInit} from "@angular/core"; declare let L: any; @Component({ selector: 'map', templateUrl: './src/map.html' }) export class MapComponent implements OnInit { smallScreen: number = 600; center: any = [54, -5]; zoom: number = 6; centerSmall: any = [50, 10]; zoomSmall: number = 5; private atMap: any; constructor() { } ngOnInit() { setTimeout(() => { this.initialiseMap(this.center, this.zoom); }, 1000) } private initialiseMap(center:any, zoom:number) { if(this.atMap != undefined || this.atMap != null){ this.atMap.off(); this.atMap.remove(); } this.atMap = L.map('mapid',{ center: center, zoomControl: false, zoom: zoom }); this.atMap.options.maxZoom = 15; this.atMap.options.minZoom = 5; L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>', id: 'mapbox.streets', accessToken: 'pk.eyJ1IjoidHRtdCIsImEiOiJjajhqeWhjOW8wN2JvMndwbTlqaTV0YjhhIn0.rlysm052tK3vDdZSSg-wQg' }).addTo(this.atMap); } // 新增打印方法 printMap() { // 你要固定位置的目标经纬度(英国区域中心点) const targetLatLng = L.latLng(this.center[0], this.center[1]); // 自定义固定偏移:距离地图容器左上角的像素距离(可根据需求调整) const fixedOffset = L.point(200, 150); // 计算目标点当前在容器中的像素坐标 const currentContainerPoint = this.atMap.latLngToContainerPoint(targetLatLng); // 计算需要偏移的量:让目标点移动到固定偏移位置 const offsetDiff = fixedOffset.subtract(currentContainerPoint); // 反算出新的地图中心 const newCenter = this.atMap.containerPointToLatLng( this.atMap.latLngToContainerPoint(this.atMap.getCenter()).add(offsetDiff) ); // 设置新的地图中心,同时固定缩放级别(避免窗口大小影响缩放) this.atMap.setView(newCenter, this.zoom); // 触发浏览器打印 window.print(); // 打印完成后自动重置地图(可选) setTimeout(() => { this.resetMap(); }, 500); } // 重置地图到初始状态 resetMap() { this.atMap.setView(this.center, this.zoom); } }
模板修改(map.html)
给你的打印按钮绑定新增的方法:
<button (click)="printMap()">打印地图</button> <button (click)="resetMap()">重置地图</button> <div id="mapid" style="width: 100%; height: 600px;"></div>
原理说明
latLngToContainerPoint: 把经纬度坐标转换成地图容器内的像素坐标(相对容器左上角)containerPointToLatLng: 把容器内的像素坐标转换成对应的经纬度- 通过计算目标点当前像素位置和期望固定位置的差值,反推出需要调整的地图中心,这样不管窗口多大,目标点都会精准落在你设定的像素位置上,不会出现裁切问题
另外,如果你希望打印时的缩放级别也完全固定,可以在setView里直接写死一个zoom值(比如6),这样所有窗口尺寸下打印的缩放比例都是一致的。
内容的提问来源于stack exchange,提问作者ttmt
相关产品推荐
相关产品推荐

