使用Leaflet地图库在单击(右键单击)时获取图像叠加的像素坐标

14

我正在尝试使用leaflet地图库,在单击图像叠加时(右键单击/上下文菜单),获取像素坐标。基本上,当用户点击图像时,我需要找到用户点击图像的x、y或宽度、高度。

目前这是我所拥有的。

// Using leaflet.js to pan and zoom a big image.
// See also: http://kempe.net/blog/2014/06/14/leaflet-pan-zoom-image.html

// create the slippy map
var map = L.map('image-map', {
    minZoom: 1,
    maxZoom: 4,
    center: [0, 0],
    zoom: 1,
    crs: L.CRS.Simple,
});

// dimensions of the image
var w = 2000,
    h = 1500,
    url = 'http://kempe.net/images/newspaper-big.jpg';

// calculate the edges of the image, in coordinate space
var southWest = map.unproject([0, h], map.getMaxZoom() - 1);
var northEast = map.unproject([w, 0], map.getMaxZoom() - 1);
var bounds = new L.LatLngBounds(southWest, northEast);

// add the image overlay, 
// so that it covers the entire map
L.imageOverlay(url, bounds).addTo(map);

// tell leaflet that the map is exactly as big as the image
map.setMaxBounds(bounds);

function onMapClick(e) {

 //returns on right click events   
 console.log(e);


}

//Hadnel on right click functions TODO: MOVE THIS LATER
map.on('contextmenu', onMapClick);

当前在 onMapClick(e) 中,当我点击时检查返回的事件,看不到所有返回的坐标与我点击位置的 x、y 坐标以及图片宽度和高度有任何接近的证据。

实际上,我希望能够看到我点击的图片位置的 x、y 坐标或宽度、高度,假设该图片的尺寸为 20000x15000 像素。

这是 jsfiddle http://jsfiddle.net/rayshinn/yvfwzfw4/1/

不确定原因,但当你缩放到最小时,它似乎有点错误。只需放大到最大即可停止 jsfiddle 上的 bug。这个 bug 不是重点,因为它不会在我的本地环境中发生!好像与 fiddle 有关。


1
你能发布一个 JSFiddle 吗? - pk.
4个回答

12

这张传单给出了“image-map” div上的x,y坐标,该div会随着缩放而改变大小。但是事件坐标不会根据您的图像大小进行缩放。

为了获得相对于实际图片大小的x,y坐标,您需要将坐标乘以当前div尺寸和全尺寸图片尺寸的比率。

查看我的Fiddle

我通过将事件坐标乘以您的var wvar h,并将它们除以地图的高度和宽度来计算您的x,y:

function onMapClick(e) {

    var mapWidth=map._container.offsetWidth;
    var mapHeight=map._container.offsetHeight;
    console.log(e.containerPoint.x * w / mapWidth);
    console.log(e.containerPoint.y * h / mapHeight);
    console.log(e);


}

这个解决方案即使地图被调整大小也能正常工作。当地图缩小并且不是JSFiddle容器的100%宽度和高度时,它似乎在JSFiddle上无法工作,但我相信这是JSFiddle的一个副作用。我很好奇并将其与我的解决方案进行了比较,并验证了此解决方案即使地图被调整大小也能正常工作。 - muglio
我同意你的答案。它很好,我已经点赞了。在我的不同的答案中,我表明你值得获得悬赏。 - muglio
我想澄清一下,我刚才是在指出JSFiddle的问题。我在JSFiddle之外测试了您的解决方案,它可行。 - muglio
如果您将JSFiddle全屏,您可以在地图上放大到最大。然后将其缩小到最小...地图开始弹跳(jsfiddle问题),然后调整窗口大小直到地图停止弹跳。再放大几次,然后全部缩小。这会导致X坐标在地图的最左侧变为负数。看起来fiddle在地图中引入了负边距问题。 - muglio
@muglio 啊,我现在明白了。是的,这个Fiddle有点奇怪。 - Dave Alperovich
显示剩余6条评论

9
为了解决这个问题,您需要利用地图项目将纬度和经度转换为图像中的坐标。
地图上的“Project”方法是关键。

http://leafletjs.com/reference.html#map-conversion-methods

投影将提供图像中的X,Y坐标。这些值将根据图像的缩放比例(即地图缩放级别)进行缩放。
计算单击事件的自然(X,Y)坐标只需要计算地图边界或叠加层大小的比例尺,并将其除以投影点击坐标。
  1. 创建imageOverlay时,请将其存储在变量中。需要引用该变量以确定图像图层的比例因子。
  2. 单击时,将点击处的经纬度投影到(x,y)坐标中
  3. 将当前图像的宽度和高度与自然宽度和高度进行除法运算(您需要执行此操作以处理地图缩放导致的大小更改)
  4. 将投影点击坐标除以比例因子。这将为您提供原始图像中实际的X,Y坐标,我认为这就是您想要的。下面是代码,可以查看fiddle以获取工作示例。http://jsfiddle.net/muglio/h5st7bpt/

.

// so that it covers the entire map
var overlay = L.imageOverlay(url, bounds)
overlay.addTo(map);

// tell leaflet that the map is exactly as big as the image
map.setMaxBounds(bounds);

function onMapClick(e) {
    //Project the map click to x,y coordinates
    //This projection is the actual XY coordinates of the image layer
    //This coordinate is scaled by the amount the image is zoomed.
    var clientClick = map.project(e.latlng);

    //Grab the original overlay
    var overlayImage = overlay._image;

    //Calculate the current image ratio from the original (deals with zoom)
    var yR = overlayImage.clientHeight / overlayImage.naturalHeight;
    var xR = overlayImage.clientWidth / overlayImage.naturalWidth;

    //scale the click coordinates to the original dimensions
    //basically compensating for the scaling calculated by the map projection
    var x = clientClick.x / xR;
    var y = clientClick.y / yR;
    console.log(x,y);
}

希望这可以帮到你!

谢谢。让我们看看哪种解决方案最适合 OP。 - Dave Alperovich
嗨muglio,非常感谢您花费时间和精力帮助我!非常感激。 - BaconJuice
@BaconJuice 没问题。 - muglio

0

我不了解leaflet,但你不需要它来实现这个。使用JavaScript,您可以实现一个监听器并在标记中使用event.latLng来操作信息。

google.maps.event.addListener(map, 'click', function(event) {
    marker.setPosition(event.latLng);   
});

检查这个有效的fiddle


嗨@Jordi,我不是在尋找地圖的緯度和經度。我正在尋找圖像的x和y座標。 - BaconJuice
我明白...你能否发布一个fiddle或一些示例,以便我们可以看到问题? - Jordi Castilla

0

当您触发上下文菜单事件时,您将收到containerPoint,其中包含x和y坐标放置(容器级别)。由于您知道/可以检索地图容器的尺寸,并且您知道图像的本机尺寸...这不应该足以进行计算吗?

例如,如果您知道地图容器宽度为1000px...并且您接收到一个上下文菜单事件,其中x坐标为500...那么您就知道有人直接点击了中心,因为500 / 1000(地图容器宽度)= 0.5,这意味着图像上的实际位置将是本机宽度(根据您的变量w为2000)* 0.5 = 1000。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接