单张图像上的自定义坐标 [英] Leaflet custom coordinates on image

查看:132
本文介绍了单张图像上的自定义坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大小为8576x8576px的图像,我想让坐标匹配1:1。另外我想要坐标0,0在图像的中心(现在的中心是-128,128)。而且我也想显示坐标。我想放置一个用于插入坐标的定位按钮,然后在地图上找到它们。
这样的事情: http://xero-hurtworld.com/map_steam.php
(我使用相同的图像但更大)。我的代码到目前为止:



https://jsfiddle.net/ze62dte0/

 <!DOCTYPE html> 
< html>
< head>
< title> Map< / title>
< meta charset =utf-8/>
< meta name =viewportcontent =initial-scale = 1.0,user-scalable = no/>
< link rel =stylesheethref =http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css/>
<! - [if lte IE 8]>
< link rel =stylesheethref =http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.ie.css/>
<![endif] - >
< script src =http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.jscharset =utf-8>< / script>
< script>
函数init(){
var mapMinZoom = 0;
var mapMaxZoom = 3;
var map = L.map('map',{
maxZoom:mapMaxZoom,
minZoom:mapMinZoom,
crs:L.CRS.Simple
})。 setView([0,0],mapMaxZoom);



window.latLngToPixels = function(latlng){
return window.map.project([latlng.lat,latlng.lng],window.map) getMaxZoom());
};
window.pixelsToLatLng = function(x,y){
return window.map.unproject([x,y],window.map.getMaxZoom());
};

var mapBounds = new L.LatLngBounds(
map.unproject([0,8576],mapMaxZoom),
map.unproject([8576,0],mapMaxZoom)) ;

map.fitBounds(mapBounds);
L.tileLayer('{z} / {x} / {y} .jpg',{
minZoom:mapMinZoom,maxZoom:mapMaxZoom,
bounds:mapBounds,
noWrap :true,
tms:false
})。addTo(map);

L.marker([0,0])。addTo(map).bindPopup(Zero);

L.marker([ - 128,128])。addTo(map).bindPopup(center);

var popup = L.popup();

<! - 点击弹出>
var popup = L.popup();

function onMapClick(e){
popup
.setLatLng(e.latlng)
.setContent(你点击了+ e.latlng.toString() )
.openOn(map);
}

map.on('点击',onMapClick);

}
< / script>
< style>
html,body,#map {width:100%;高度:100%;余量:0;填充:0; }
< / style>
< / head>
< body onload =init()>
< div id =map>< / div>
< / body>
< / html>


解决方案

如果我理解正确, L.CRS.Simple 将tile 0/0/0(tile size 268px,即8576 / 2,5)放在一起,以便:




  • 位置 [0,0] 位于该图块的中心。

  • 整个世界(即整个瓷砖0/0/0)从位置 [ - 8576/2,-8576/2] [8576 / 2,8576/2]



您只需要调整 L.CRS.Simple 与适当的转换,以计算1/2 5 = 1/32(而不只是1)的标度,偏移量为8576 * 1/32 / 2 = 268/2 = 134(而不是0.5)。

  L.CRS.MySimple = L.extend },L.CRS.Simple,{
transformation:new L.Transformation(1/32,134,-1 / 32,134)
});

var map = L.map('map',{
maxZoom:mapMaxZoom,
minZoom:mapMinZoom,
crs:L.CRS.MySimple
})。setView([0,0],mapMaxZoom);

演示: http://plnkr.co/edit/5SQqp7SP4nf8muPM5iso?p=preview (我使用Plunker而不是jsfiddle,因为你提供了一个HTML的完整的页面代码,而jsfiddle希望你拆分您的HTML,CSS和JavaScript代码分为单独的块)。



为了显示坐标和定位按钮,这将是非常容易实现的,因此它是类似于你提到的例子。如果需要帮助,请随时开启新的问题。



在上述演示中,我使用了 Leaflet.Coordinates插件快速实现这两个功能(请参阅地图左下角的控件;您必须在地图上开始移动鼠标以使坐标出现;单击在此控制下打开版本模式)。






编辑:



对于Leaflet.Coordinates插件,它将显示坐标经度包含在[-180;



在你的情况下,坐标不是度数,没有点包围经度。



我认为这是点击弹出窗口和控件之间坐标差异的原因。



只需修补插件代码即可防止包装:

  //首先修补以避免经度包装。 
L.Control.Coordinates.include({
_update:function(evt)){
var pos = evt.latlng,
opts = this.options;
if (pos){
// pos = pos.wrap(); //删除该指令
this._currentPos = pos;
this._inputY.value = L.NumberFormatter.round( pos.lat,opts.decimals,opts.decimalSeperator);
this._inputX.value = L.NumberFormatter.round(pos.lng,opts.decimals,opts.decimalSeperator);
this._label。 innerHTML = this._createCoordinateLabel(pos);
}
}
});

更新演示: http://plnkr.co/edit/M3Ru0xqn6AxAaSb4kIJU?p=preview


I have an image which size is 8576x8576px, and I want to make the coordinates match 1:1. Also I want the coordinates 0,0 in the center of the image (now the center is -128,128). And I want to show the coordinates too. I want to put a locate button for the user insert coordinates and then find them on the map. Something like this: http://xero-hurtworld.com/map_steam.php (I am using the same image but bigger). The tile size I made its 268px.

My code so far:

https://jsfiddle.net/ze62dte0/

<!DOCTYPE html>
<html>
  <head>
    <title>Map</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css" />
    <!--[if lte IE 8]>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.ie.css" />
    <![endif]-->
    <script src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js" charset="utf-8"></script>
    <script>
      function init() {
        var mapMinZoom = 0;
        var mapMaxZoom = 3;
        var map = L.map('map', {
          maxZoom: mapMaxZoom,
          minZoom: mapMinZoom,
          crs: L.CRS.Simple
        }).setView([0, 0], mapMaxZoom);



    window.latLngToPixels = function(latlng){
    return window.map.project([latlng.lat,latlng.lng], window.map.getMaxZoom());
    };
    window.pixelsToLatLng = function(x,y){
    return window.map.unproject([x,y], window.map.getMaxZoom());
    };

        var mapBounds = new L.LatLngBounds(
            map.unproject([0, 8576], mapMaxZoom),
            map.unproject([8576, 0], mapMaxZoom));

        map.fitBounds(mapBounds);
        L.tileLayer('{z}/{x}/{y}.jpg', {
          minZoom: mapMinZoom, maxZoom: mapMaxZoom,
          bounds: mapBounds,
          noWrap: true,
          tms: false
        }).addTo(map);

        L.marker([0, 0]).addTo(map).bindPopup("Zero");

        L.marker([-128, 128]).addTo(map).bindPopup("center");

        var popup = L.popup();

        <!-- Click pop-up>
        var popup = L.popup();

        function onMapClick(e) {
            popup
            .setLatLng(e.latlng)
            .setContent("You clicked in " + e.latlng.toString ())
            .openOn(map);
        }

        map.on('click', onMapClick);

      }
    </script>
    <style>
      html, body, #map { width:100%; height:100%; margin:0; padding:0; }
    </style>
  </head>
  <body onload="init()">
    <div id="map"></div>
  </body>
</html>

解决方案

If I understand correctly, you want a CRS similar to L.CRS.Simple that places tile 0/0/0 (tile size 268px, which is 8576 / 2⁵) so that:

  • Position [0, 0] is at the center of that tile.
  • The entire world (i.e. entire tile 0/0/0) goes from position [-8576/2, -8576/2] to [8576/2, 8576/2].

You would just need to adjust the L.CRS.Simple with the appropriate transformation, to account for this scale of 1/2⁵ = 1/32 (instead of just 1) and offset of 8576 * 1/32 / 2 = 268 / 2 = 134 (instead of 0.5).

L.CRS.MySimple = L.extend({}, L.CRS.Simple, {
  transformation: new L.Transformation(1 / 32, 134, -1 / 32, 134)
});

var map = L.map('map', {
  maxZoom: mapMaxZoom,
  minZoom: mapMinZoom,
  crs: L.CRS.MySimple
}).setView([0, 0], mapMaxZoom);

Demo: http://plnkr.co/edit/5SQqp7SP4nf8muPM5iso?p=preview (I used Plunker instead of jsfiddle because you provided a full page code with HTML, whereas jsfiddle expects you to split your HTML, CSS and JavaScript codes into separate blocks).

As for showing the coordinates and a "locate" button, it would be quite easy to implement so that it is similar to the example you mention. Feel free to open new questions if you need help.

In the above demo, I used Leaflet.Coordinates plugin to implement quickly both functionalities (see the control on bottom left corner of the map; you have to start moving your mouse on the map for the coordinates to appear; click on that control to open the edition mode).


EDIT:

As for the Leaflet.Coordinates plugin, it wraps displayed coordinates longitude to stay within [-180; 180] degrees.

In your case where coordinates are not degrees, there is no point wrapping the longitude.

I think this is the cause for the discrepancy of coordinates between the click popup and the control.

Simply patch the plugin code to prevent wrapping:

// Patch first to avoid longitude wrapping.
L.Control.Coordinates.include({
  _update: function(evt) {
    var pos = evt.latlng,
      opts = this.options;
    if (pos) {
      //pos = pos.wrap(); // Remove that instruction.
      this._currentPos = pos;
      this._inputY.value = L.NumberFormatter.round(pos.lat, opts.decimals, opts.decimalSeperator);
      this._inputX.value = L.NumberFormatter.round(pos.lng, opts.decimals, opts.decimalSeperator);
      this._label.innerHTML = this._createCoordinateLabel(pos);
    }
  }
});

Updated demo: http://plnkr.co/edit/M3Ru0xqn6AxAaSb4kIJU?p=preview

这篇关于单张图像上的自定义坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆