如何从ImageMapType切换回法线贴图

时间:2015-10-15 20:59:50

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

我不确定如何从ImageMapType切换回法线贴图。代码中描述的问题如下(伪代码):

    var myMap;
    var curLabLocation = new google.maps.LatLng(36.415793, -121.084421);
    var mapOptions = {
      zoom: 21,
      streetViewControl: false,
      center: curLabLocation,
      mapTypeId: google.maps.MapTypeId.MAP
    };
    var $map = $('#map-canvas');

    myMap = new google.maps.Map($map[0], mapOptions);


    // A) Switch to image type map. NO problem
    var imageMapType = new google.maps.ImageMapType({
      getTileUrl: function(coord, zoom) {
          // Simply empty. How to delete this????? After B)
          // this function still working, which prevent
          // normal map to show up.
          return null;
      },
      tileSize: new google.maps.Size(256, 256),

      maxZoom: 23,
      minZoom: 22,
      name: 'image type map'
    });


    myMap.mapTypes.set('imagetypemap', imageMapType);
    myMap.setMapTypeId('imagetypemap');

   // Now, it works fine with ImageMapType.


   // B) Switch back to normal map. Problem is the map is empty due
   // to getTileUrl: function(coord, zoom) {} still working.
   myMap.setMapTypeId(google.maps.MapTypeId.MAP);

   // I tried this. But not working. myMap.overlayMapTypes.length=0   before clear() is called. So, this is not right way to clear ImageMapType.

   myMap.overlayMapTypes.clear();
   myMap.setMapTypeId(google.maps.MapTypeId.MAP);

我是否需要重新创建地图对象?有没有办法不重新创建地图对象?如果不是,该怎么做?

1 个答案:

答案 0 :(得分:0)

google.maps.MapTypeId.MAP未定义,内置MapTypeIds为

  • google.maps.MapTypeId.HYBRID
  • google.maps.MapTypeId.ROADMAP
  • google.maps.MapTypeId.SATELLITE
  • google.maps.MapTypeId.TERRAIN

演示:



function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 0, lng: 0},
    zoom: 1,
    streetViewControl: false,
    mapTypeControl:false,
    mapTypeIds:[google.maps.MapTypeId.ROADMAP],
    noClear:true
  }),
  btn=document.getElementById('mt');
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(btn);
  google.maps.event.addDomListener(btn,'click',function(){
       map.setMapTypeId((this.value==='moon')
                          ? 'moon'
                          : google.maps.MapTypeId.ROADMAP);
                          
 });
  google.maps.event.addListener(map,'maptypeid_changed',function(){
       btn.value=(this.getMapTypeId()==='moon')
                  ?'earth'
                  :'moon'
  });
  var moonMapType = new google.maps.ImageMapType({
    getTileUrl: function(coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
          return null;
        }
        var bound = Math.pow(2, zoom);
        return 'http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw' +
            '/' + zoom + '/' + normalizedCoord.x + '/' +
            (bound - normalizedCoord.y - 1) + '.jpg';
    },
    tileSize: new google.maps.Size(256, 256),
    maxZoom: 9,
    minZoom: 0,
    radius: 1738000,
    name: 'Moon'
  });

  map.mapTypes.set('moon', moonMapType);
  map.setMapTypeId('moon');
}

// Normalizes the coords that tiles repeat across the x axis (horizontally)
// like the standard Google map tiles.
function getNormalizedCoord(coord, zoom) {
  var y = coord.y;
  var x = coord.x;

  // tile range in one direction range is dependent on zoom level
  // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
  var tileRange = 1 << zoom;

  // don't repeat across y-axis (vertically)
  if (y < 0 || y >= tileRange) {
    return null;
  }

  // repeat across x-axis
  if (x < 0 || x >= tileRange) {
    x = (x % tileRange + tileRange) % tileRange;
  }

  return {x: x, y: y};
}
&#13;
html, body,#map {
        height: 100%;
        margin: 0;
        padding: 0;
      }
&#13;
<div id="map"><input type="button" id="mt"></div>
<script async defer  src="https://maps.googleapis.com/maps/api/js?v=3&callback=initMap"></script>
&#13;
&#13;
&#13;

<edit/>

问题的根源似乎是一个内部函数,它计算地图的minZoom / maxZoom(不是maptypes),例如创建缩放控件。当两个mapTypes的minZoom / maxZoom范围不相交时,问题就出现了。

可能的修复:在某处执行以下代码(在创建地图之前)。 它会覆盖内置的Map方法setMapTypeId。 最初,它会删除mapTypes的minZoom / maxZoom值,并将它们存储在另一个对象中。当首先设置mapType时,将丢弃Map的minZoom / maxZoom值(如果有的话),并且在设置新的mapType之后,将根据mapType的存储设置设置Map的minZoom / maxZoom。 。

(
    function(gm){
      var f=gm.prototype.setMapTypeId;
      gm.prototype.setMapTypeId=function(t){
        if(this.mapTypes){
          var that  = this,
              mt    = this.mapTypes.get(t);
              zr    = {minZoom:null,maxZoom:null};
          if(!mt.get('zr')){
            for(var k in zr){
              zr[k]=mt[k]||null;
              delete mt[k];
            }
            mt.set('zr',zr);
          }
          that.setValues({minZoom:null,maxZoom:null});
          f.call(this,t);
          that.setValues(mt.get('zr'));
        }
      }
    }(google.maps.Map)
  );

<强>演示:

&#13;
&#13;
function initMap() {

  (
    function(gm){
      var f=gm.prototype.setMapTypeId;
      gm.prototype.setMapTypeId=function(t){
        if(this.mapTypes){
          var that  = this,
              mt    = this.mapTypes.get(t);
              zr    = {minZoom:null,maxZoom:null};
          if(!mt.get('zr')){
            for(var k in zr){
              zr[k]=mt[k]||null;
              delete mt[k];
              
            }
            mt.set('zr',zr);
          }
          that.setValues({minZoom:null,maxZoom:null});
          f.call(this,t);
          that.setValues(mt.get('zr'));
        }
      }
    }(google.maps.Map)
  );
  
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 0, lng: 0},
    zoom: 1,
    streetViewControl: false,
    mapTypeControl:false,
    mapTypeIds:[google.maps.MapTypeId.ROADMAP],
    noClear:true
  }),
  btn=document.getElementById('mt');
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(btn);
  google.maps.event.addDomListener(btn,'click',function(){
       map.setMapTypeId((this.value==='moon')
                          ? 'moon'
                          : google.maps.MapTypeId.ROADMAP);
                          
 });
  google.maps.event.addListener(map,'maptypeid_changed',function(){
       btn.value=(this.getMapTypeId()==='moon')
                  ?'earth'
                  :'moon'
  });
  var moonMapType = new google.maps.ImageMapType({
    getTileUrl: function(coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
          return null;
        }
        var bound = Math.pow(2, zoom);
        return 'https://i.stack.imgur.com/mA4e2.jpg?s=256&g=1';
    },
    tileSize: new google.maps.Size(256, 256),
    maxZoom: 23,
    minZoom: 22,
    radius: 1738000,
    name: 'Moon'
  });

  map.mapTypes.set('moon', moonMapType);
  map.setMapTypeId('moon');
}

// Normalizes the coords that tiles repeat across the x axis (horizontally)
// like the standard Google map tiles.
function getNormalizedCoord(coord, zoom) {
  var y = coord.y;
  var x = coord.x;

  // tile range in one direction range is dependent on zoom level
  // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
  var tileRange = 1 << zoom;

  // don't repeat across y-axis (vertically)
  if (y < 0 || y >= tileRange) {
    return null;
  }

  // repeat across x-axis
  if (x < 0 || x >= tileRange) {
    x = (x % tileRange + tileRange) % tileRange;
  }

  return {x: x, y: y};
}
&#13;
html, body,#map {
        height: 100%;
        margin: 0;
        padding: 0;
      }
&#13;
<div id="map"><input type="button" id="mt"></div>
<script async defer  src="https://maps.googleapis.com/maps/api/js?v=3&callback=initMap"></script>
&#13;
&#13;
&#13;

https://developers.google.com/maps/documentation/javascript/reference?hl=en&csw=1#MapTypeId