首页 > 解决方案 > 如何在点击时获取传单 ImageOverlay 的像素坐标

问题描述

我有一张传单地图,它由一个平铺层和一个 imageOverlay 上方组成,它半透明地将温度分布显示为彩色区域。叠加层放置在瓦片层内的某些边界处。当我单击叠加层上的某个位置时,我想弄清楚该点的像素具有什么颜色。

我的问题是将单击的位置投影到 imageOverlay 上,考虑到 imageOverlay 到可见地图的偏移量和缩放级别。最终我想获得图像的像素坐标(以它的自然分辨率)

代码大致如下所示:

var imgUrl = 'https://somewhere.somewhere/myImage.png';
var tilesUrl = 'https://somewhere.somewhere/{z}/{x}/{y}.png';
var tilesBounds = [...];
var imgBounds = [...];
var latlng = [...];

var mymap = L.map('mapid').setView(latlng, 9);
L.tileLayer(tilesUrl, {
    attribution: 'TILES',
    maxZoom: 12,
    minZoom: 7,
    id: 'tiles',
    tms: true,
    maxBounds: tilesBounds
}).addTo(mymap);

var imgOverlay = L.imageOverlay(imgUrl, imgBounds {
    attribution: 'dataimg',
    opacity: '0.4',
    id: 'dataImg',
    interactive: true
}).addTo(mymap);

imgOverlay.on('click',
  (e) => {

    var x = ???;
    var y = ???;

    var color = getColorAt(x, y);

  }
)

标签: javascriptleafletoverlay

解决方案


一种可能的解决方案是

  • 获取鼠标相对于当前尺寸图像的坐标
  • 然后交叉相乘确定相对于图像原始大小的坐标

例如,imgWidth作为imgHeight图像的原始尺寸:

imgOverlay.on('click', (leafletEvent) => {
    // see https://stackoverflow.com/a/42111623/1071630
    var e = leafletEvent.originalEvent;
    var rect = e.target.getBoundingClientRect();
    var zoomedX = e.clientX - rect.left; //x position within the element.
    var zoomedY = e.clientY - rect.top;  //y position within the element

    const x = Math.round(zoomedX * imgWidth / rect.width);
    const y = Math.round(zoomedY * imgHeight / rect.height);
    console.log(x, y);
});

var map = L.map('map').setView([48.854, 2.2922926], 14);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

const bounds = [[48.85, 2.28], [48.86, 2.29]]
const imgOverlay = L.imageOverlay('https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Tour_Eiffel_en_mai_2014.JPG/450px-Tour_Eiffel_en_mai_2014.JPG', bounds, {
    attribution: 'Nicolas Halftermeyer / CC BY-SA (https://creativecommons.org/licenses/by-sa/3.0)',
    id: 'dataImg',
    interactive: true
}).addTo(map);

const imgWidth = 450, imgHeight = 600;
imgOverlay.on('click', (leafletEvent) => {
    // see https://stackoverflow.com/a/42111623/1071630
    var e = leafletEvent.originalEvent;
    var rect = e.target.getBoundingClientRect();
    var zoomedX = e.clientX - rect.left; //x position within the element.
    var zoomedY = e.clientY - rect.top;  //y position within the element

    const x = Math.round(zoomedX * imgWidth / rect.width);
    const y = Math.round(zoomedY * imgHeight / rect.height);
    document.getElementById('log').innerHTML+= x+","+y+"<br>";
});
#map {width: 400px; height: 200px;}
#log {position: absolute; top: 0; right:10px; width: 100px;}
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet"/>
<div style='position: relative'>
  <div id="map"></div>
  <div id='log'></div>
 </div>


推荐阅读