【问题标题】:How to call fromLatLngToDivPixel in Google Maps API V3?如何在 Google Maps API V3 中调用 fromLatLngToDivPixel?
【发布时间】:2010-12-05 01:14:41
【问题描述】:

我知道该方法存在并且已记录在案,但我不知道如何获取 MapCanvasProjection 对象。

【问题讨论】:

    标签: javascript google-maps google-maps-api-3 projection


    【解决方案1】:

    http://qfox.nl/notes/116

    var overlay = new google.maps.OverlayView();
    overlay.draw = function() {};
    overlay.setMap(map);
    var point = overlay.getProjection().fromLatLngToDivPixel(latLng); 
    

    确实很丑。 v2 更容易 - google api v3 的另一个缺陷!

    【讨论】:

    【解决方案2】:

    我认为最简单的方法是忽略 Google 希望通过删除和隐藏有用的功能而不是添加新功能来让我们的生活更艰难,而只是编写自己的方法来做同样的事情。

    这是某人在其他地方发布的函数的一个版本(我现在找不到),它对我有用:

    fromLatLngToPixel: function (position) {
      var scale = Math.pow(2, Map.getZoom());
      var proj = Map.getProjection();
      var bounds = Map.getBounds();
    
      var nw = proj.fromLatLngToPoint(
        new google.maps.LatLng(
          bounds.getNorthEast().lat(),
          bounds.getSouthWest().lng()
        ));
      var point = proj.fromLatLngToPoint(position);
    
      return new google.maps.Point(
        Math.floor((point.x - nw.x) * scale),
        Math.floor((point.y - nw.y) * scale));
    },
    

    现在您可以随时随地调用它。我特别需要它用于自定义上下文菜单,它完美地完成了工作。

    EDIT:我还写了一个反向函数,fromPixelToLatLng,它的作用正好相反。它只是基于第一个,应用了一些数学:

    fromPixelToLatLng: function (pixel) {
      var scale = Math.pow(2, Map.getZoom());
      var proj = Map.getProjection();
      var bounds = Map.getBounds();
    
      var nw = proj.fromLatLngToPoint(
        new google.maps.LatLng(
          bounds.getNorthEast().lat(),
          bounds.getSouthWest().lng()
        ));
      var point = new google.maps.Point();
    
      point.x = pixel.x / scale + nw.x;
      point.y = pixel.y / scale + nw.y;
    
      return proj.fromPointToLatLng(point);
    }
    

    【讨论】:

    【解决方案3】:

    我对这里的答案不满意。所以我做了一些实验,找到了“最简单”的工作解决方案,它接近拉尔夫的答案,但希望更容易理解。 (我希望 Google 让这个功能更易于使用!)

    首先你声明一个OverlayView 的子类,像这样:

    function CanvasProjectionOverlay() {}
    CanvasProjectionOverlay.prototype = new google.maps.OverlayView();
    CanvasProjectionOverlay.prototype.constructor = CanvasProjectionOverlay;
    CanvasProjectionOverlay.prototype.onAdd = function(){};
    CanvasProjectionOverlay.prototype.draw = function(){};
    CanvasProjectionOverlay.prototype.onRemove = function(){};
    

    然后在其他地方在你的代码中实例化地图,你也实例化这个 OverlayView 并设置它的地图,像这样:

    var map = new google.maps.Map(document.getElementById('google-map'), mapOptions);
    
    // Add canvas projection overlay so we can use the LatLng to pixel converter
    var canvasProjectionOverlay = new CanvasProjectionOverlay();
    canvasProjectionOverlay.setMap(map);
    

    然后,当您需要使用fromLatLngToContainerPixel 时,您只需这样做:

    canvasProjectionOverlay.getProjection().fromLatLngToContainerPixel(myLatLng);
    

    请注意,因为 MapCanvasProjection 对象只有在调用 draw() 时才可用,这在地图的 idle 之前的某个时间,我建议创建一个布尔“mapInitialized”标志,在第一个地图 @987654328 上将其设置为 true @ 打回来。然后再做你需要做的事情。

    【讨论】:

    • 这应该是该问题的公认答案。非常清楚 - 谢谢!
    【解决方案4】:
    var map;
    // Create your map
    MyOverlay.prototype = new google.maps.OverlayView();
    MyOverlay.prototype.onAdd = function() { }
    MyOverlay.prototype.onRemove = function() { }
    MyOverlay.prototype.draw = function() { }
    function MyOverlay(map) { this.setMap(map); }
    var overlay = new MyOverlay(map);
    var projection = overlay.getProjection();
    

    【讨论】:

    • 我试过这段代码,变量投影似乎是“未定义”。知道为什么吗?谢谢!
    • 注意:(这让我难过了半个小时)- 确保在创建地图时创建叠加层,而不是在需要坐标时(通过 fromLatLngToDivPixel)。如果你这样做,你会得到 Uncaught TypeError: Cannot call method 'fromLatLngToDivPixel' of undefined。看起来 Google 会异步执行其中一些操作。
    • @AlexeyMK 这也吸引了我!直到我找到你的评论。
    【解决方案5】:

    要获得 MapCanvasProjection,您可以从 OverlayView 派生一个类并调用返回 MapCanvasProjection 类型的 getProjection() 方法

    必须实现 onAdd()、draw() 和 onRemove() 才能从 OverlayView 派生。

    function MyOverlay(options) {
        this.setValues(options);
    
        var div = this.div_= document.createElement('div');
    
        div.className = "overlay";
    };
    
    // MyOverlay is derived from google.maps.OverlayView
    MyOverlay.prototype = new google.maps.OverlayView;
    
    MyOverlay.prototype.onAdd = function() {
    
        var pane = this.getPanes().overlayLayer;
        pane.appendChild(this.div_);
    
    }
    
    MyOverlay.prototype.onRemove = function() {
        this.div_.parentNode.removeChild(this.div_);
    }
    
    MyOverlay.prototype.draw = function() {
        var projection = this.getProjection();
        var position = projection.fromLatLngToDivPixel(this.getMap().getCenter());
    
        var div = this.div_;
        div.style.left = position.x + 'px';
        div.style.top = position.y + 'px';
        div.style.display = 'block';
    };
    

    然后当您创建地图时

    var OverLayMap = new MyOverlay( { map: map } );
    

    对于 V2 你应该可以从你的 GMap2 实例调用 fromLatLngToDivPixel

    var centerPoint = map.fromLatLngToDivPixel(map.getCenter());
    

    【讨论】:

    • 你不是将 API v2 与 v3 混合在一起吗?
    • 我认为这是新 API 的一个大问题。它应该有一个更简单的方法来做到这一点
    猜你喜欢
    • 2012-02-26
    • 2023-04-01
    • 1970-01-01
    • 2011-07-25
    • 2014-08-16
    • 1970-01-01
    • 2012-09-26
    • 2012-06-10
    相关资源
    最近更新 更多