1

在下面的工作示例中,我实现了一个自定义 MapType。该示例是基本地图类型示例的混搭,它展示了如何使用 getTile() 创建自定义地图图块,以及自定义投影示例,这样我就不必担心自己在图块坐标和地理坐标之间进行转换。

在这个简单的测试中,我只是为每个图块添加了一个自定义标记。但是,releaseTile() 中的瓦片清理速度很慢。为什么它很慢,有没有更好的方法在自定义地图图块中创建可点击对象?

<!DOCTYPE html>
<html>
  <head>
    <title>Basic map types</title>
    <link href="default.css" rel="stylesheet">
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
    <script>
/** @constructor */
function CoordMapType() {
}

var map;
var TILE_SIZE = 256;
var chicago = new google.maps.LatLng(41.850033,-87.6500523);


CoordMapType.prototype.tileSize = new google.maps.Size(TILE_SIZE,TILE_SIZE);
CoordMapType.prototype.maxZoom = 19;


var projection = new MercatorProjection();
createCustomMarker = function(tile_coord, zoom) {
  // put the position in the center of the tile
  var num_tiles = 1 << zoom;
  var pixel_coord = new google.maps.Point(
    (tile_coord.x + .5) * TILE_SIZE,
    (tile_coord.y + .5) * TILE_SIZE
  );
  var world_coord = new google.maps.Point(
    pixel_coord.x / num_tiles,
    pixel_coord.y / num_tiles
    );
  var custom_position = projection.fromPointToLatLng(world_coord);

  var contentString = '<div id="content">'+
      '<h1 id="firstHeading" class="firstHeading">A Heading</h1>'+
      '<div id="bodyContent">'+
        '<p>' +
        'tile: ' + tile_coord.x + ', ' + tile_coord.y + '<br>' +
        'zoom:' + zoom;
        '</p>' +
      '</div>'+
      '</div>';

  var infowindow = new google.maps.InfoWindow({
      content: contentString
    });

  var marker = new google.maps.Marker({
      position: custom_position,
      map: map,
      title: 'custom_marker',
      icon: {
        path: google.maps.SymbolPath.CIRCLE,
        scale: 4,
        strokeColor: '#1122FF',
        fillColor: '#1122FF'
      }
    });

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

  return marker;
}


CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
  var div = ownerDocument.createElement('div');
  div.innerHTML = coord;
  div.style.width = this.tileSize.width + 'px';
  div.style.height = this.tileSize.height + 'px';
  div.style.fontSize = '10';
  div.style.borderStyle = 'solid';
  div.style.borderWidth = '1px';
  div.style.borderColor = '#AAAAAA';
  div.custom_markers = [];
  div.custom_markers.push(createCustomMarker(coord, zoom));

  return div;
};


CoordMapType.prototype.releaseTile = function(tile) {
  var length = tile.custom_markers.length;
  var custom_marker = null;
  for (var i = 0; i < length; i++) {
    // clean up the markers in this tile
    custom_marker = tile.custom_markers[i];
    google.maps.event.clearListeners(custom_marker);
    custom_marker.setMap(null);
    custom_marker = null;
  }
};

CoordMapType.prototype.name = 'Tile #s';
CoordMapType.prototype.alt = 'Tile Coordinate Map Type';

var coordinateMapType = new CoordMapType();

function bound(value, opt_min, opt_max) {
  if (opt_min != null) value = Math.max(value, opt_min);
  if (opt_max != null) value = Math.min(value, opt_max);
  return value;
}

function degreesToRadians(deg) {
  return deg * (Math.PI / 180);
}

function radiansToDegrees(rad) {
  return rad / (Math.PI / 180);
}

/** @constructor */
function MercatorProjection() {
  this.pixelOrigin_ = new google.maps.Point(TILE_SIZE / 2,
      TILE_SIZE / 2);
  this.pixelsPerLonDegree_ = TILE_SIZE / 360;
  this.pixelsPerLonRadian_ = TILE_SIZE / (2 * Math.PI);
}

MercatorProjection.prototype.fromLatLngToPoint = function(latLng,
    opt_point) {
  var me = this;
  var point = opt_point || new google.maps.Point(0, 0);
  var origin = me.pixelOrigin_;

  point.x = origin.x + latLng.lng() * me.pixelsPerLonDegree_;

  // Truncating to 0.9999 effectively limits latitude to 89.189. This is
  // about a third of a tile past the edge of the world tile.
  var siny = bound(Math.sin(degreesToRadians(latLng.lat())), -0.9999,
      0.9999);
  point.y = origin.y + 0.5 * Math.log((1 + siny) / (1 - siny)) *
      -me.pixelsPerLonRadian_;
  return point;
};

MercatorProjection.prototype.fromPointToLatLng = function(point) {
  var me = this;
  var origin = me.pixelOrigin_;
  var lng = (point.x - origin.x) / me.pixelsPerLonDegree_;
  var latRadians = (point.y - origin.y) / -me.pixelsPerLonRadian_;
  var lat = radiansToDegrees(2 * Math.atan(Math.exp(latRadians)) -
      Math.PI / 2);
  return new google.maps.LatLng(lat, lng);
};



function initialize() {
  var mapOptions = {
    zoom: 10,
    center: chicago,
    streetViewControl: false,
    mapTypeId: 'coordinate',
    mapTypeControlOptions: {
      mapTypeIds: ['coordinate'],
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
    }
  };
  map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);

  google.maps.event.addListener(map, 'maptypeid_changed', function() {
    var showStreetViewControl = map.getMapTypeId() != 'coordinate';
    map.setOptions({'streetViewControl': showStreetViewControl});
  });

  // Now attach the coordinate map type to the map's registry
  map.mapTypes.set('coordinate', coordinateMapType);
}

google.maps.event.addDomListener(window, 'load', initialize);

    </script>
  </head>
  <body>
    <div id="map-canvas"></div>
  </body>
</html>
4

0 回答 0