如何在放大地图的 google 地图上添加超链接?

How to add hyperlinks on google maps which zoom into the map?

我有一张将在网站上使用的地图。然而,目前我能够放大和缩小的唯一方法是使用滚动条或双击地图,但我想要的是在地图上显示地点名称,然后例如当用户点击一个国家时地图放大了。因此,如果有人知道如何执行此操作,请指导我。我查看了 Google 地图 API 但找不到符合我要求的内容。

下面是我目前的代码:

var JP = JP || {};

(function() {
    var Map = function() {
        var self = this;

        this.map = null;
        this.mapCanvas = null;
        this.markers = [];
        this.mapOptions = {
            maxZoom: 9,
            minZoom:2,
            zoom: 3,
            center: new google.maps.LatLng(14.397, 30.644),
            scrollwheel: false,
            mapTypeControl: false,
            streetViewControl: false,
            zoomControlOptions: {
                position: google.maps.ControlPosition.LEFT_BOTTOM
            },
            panControlOptions: {
                position: google.maps.ControlPosition.LEFT_BOTTOM
            }
        }
        this.mapType = new google.maps.StyledMapType([
            {
                featureType: "all",
                elementType: "all",
                stylers: [
                    { visibility: "off" },  // Hide everything
                    { lightness: 100 }  // Makes the land white
                ]
            }, {
                featureType: "water",
                elementType: "geometry",
                stylers: [
                    { visibility: "on" },  // Show water, but no labels
                    { lightness: -9 },  // Must be < 0 to compensate for the "all" lightness
                    { saturation: -100 }
                ]
            }
        ]);
        this.overlay = null;

        this.init = function() {
            self.mapCanvas = $("#mapCanvas")[0];

            self.map = new google.maps.Map(self.mapCanvas, self.mapOptions);
            self.map.mapTypes.set('styledMapType', self.mapType);
            self.map.setMapTypeId('styledMapType');

            self.overlay = new google.maps.OverlayView();
            self.overlay.draw = function() {};
            self.overlay.setMap(self.map);

            // This is a stop-gap measure to minimize the effect of
            // a bug we haven't solved yet.

            google.maps.event.addListener(self.map, 'dragstart', function() {
                $(".message").not("#messageTemplate").remove();
            });
        }

        this.newMarker = function(lat, lng) {
            // Used for randomizing marker image
            var offset = Math.floor(Math.random() * 3) * 16;
            // Custom marker
            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(lat, lng),
                icon: new google.maps.MarkerImage(
                    'ideasforworldmap/static/img/map/dot.png',
                    new google.maps.Size(16, 16),
                    new google.maps.Point(0, offset),
                    new google.maps.Point(8, 8)
                )
            });

            return marker;
        }

        this.markLocations = function(locations) {
            var i = locations.length;
            while (i--) {
                var loc = locations[i];

                // Make new marker
                var marker = self.newMarker(loc.lat, loc.lng);
                self.markers.push(marker);

                // Tack on some extra data
                marker.message = loc;

                // Handle mouseover event
                google.maps.event.addListener(marker, 'mouseover', function() {

                    // Get screen xy
                    var pos = self.latLngPixel(this.getPosition());

                    // Create an overlay
                    var overlay = self.createOverlay( this.message, pos );

                    // Add it to the dom
                    $(self.mapCanvas).after(overlay);
                });

                // Stagger animation onto the map
                if (i < 50) {
                    marker.setAnimation(google.maps.Animation.DROP);
                    setTimeout((function(marker) {
                        return function() {
                            marker.setMap(self.map);
                        }
                    })(marker), i*200 + Math.random()*500+500);
                } else {
                    marker.setAnimation(null);
                    marker.setMap(self.map);
                }
            }
        }

        this.createOverlay = function(message, position) {

            var overlay = $("#messageTemplate").clone();

            overlay.attr("id", message.id);
            overlay.attr("href", "/ideasforworldmap/messages/"+ message.id +".html")

            // Position it at the marker
            overlay.css({
                left: position.x - 52,
                top: position.y - 52,
            });

            // Use distance from center to decide when to hide
            var radius = 50;
            var radiusSq = radius * radius;

            var checkDistance = function(event) {
                var dx = event.pageX - position.x;
                var dy = event.pageY - position.y;

                if( dx*dx + dy*dy > radiusSq ) {

                    $(window).unbind("mousemove", checkDistance);
                    overlay.data("MessageBubble").disappear(250);
                    setTimeout(function() {
                        overlay.remove();
                    }, 250);
                }
            }

            $(window).bind("mousemove", checkDistance);

            // Make it a message bubble
            overlay.messageBubble();

            var dom = overlay.data("MessageBubble").dom;
            dom.original.text( message.text );
            dom.translated.text( message.text_ja );
            dom.by.text( "By " + message.author );
            //dom.from.text( "From: " + message.location );

            if (dom.by.text() == "By " || dom.by.text() == "By Your name" || dom.by.text() == "By 名前(ローマ字)") {
                dom.by.text("");
            }

            if (dom.from.text() == "From: " || dom.from.text() == "From: Your location" || dom.from.text() == "From: 地名(ローマ字)") {
                dom.from.text("");
            }

            overlay.data("MessageBubble").disappear(0);
            setTimeout(function(){overlay.data("MessageBubble").appear(250);}, 20);

            return overlay;
        }

        this.latLngPixel = function(latLng) {
            var projection = self.overlay.getProjection();
            return projection.fromLatLngToContainerPixel(latLng);
        }
    }

    JP.map = new Map();
})();

一种选择是将国家/地区标签重新添加到地图上,然后缩放至单击的国家/地区。来自 GeoJson 的国家边界数据。请注意,您将需要调整一些数据,如本数据集中法属圭亚那,它将法国的地理中心(作为一个示例)置于大西洋中部。

概念验证代码片段:

var JP = JP || {};

(function() {
  function zoom2geometry(feature, map, info) {
    if (feature.getProperty('name') == "Antarctica") {
      return;
    }
    var bounds = new google.maps.LatLngBounds();
    if (feature.getGeometry().getType() == "Polygon") {
      var array = feature.getGeometry().getArray();
      for (var j = 0; j < array.length; j++) {
        for (var i = 0; i < array[j].getLength(); i++) {
          bounds.extend(array[j].getAt(i));
        }
      }
    } else if (feature.getGeometry().getType() == "MultiPolygon") {
      var array = feature.getGeometry().getArray();
      for (var k = 0; k < array.length; k++) {
        for (var j = 0; j < array[k].getLength(); j++) {
          for (var i = 0; i < array[k].getAt(j).getLength(); i++) {
            bounds.extend(array[k].getAt(j).getAt(i));
          }
        }
      }
    }
    map.fitBounds(bounds);
    // info.setContent(feature.getProperty("name_long"));
    // info.setPosition(bounds.getCenter());
    // info.open(map);

  }

  var Map = function() {
    var self = this;

    this.map = null;
    this.mapCanvas = null;
    this.markers = [];
    this.mapOptions = {
      maxZoom: 9,
      minZoom: 2,
      zoom: 3,
      center: new google.maps.LatLng(14.397, 30.644),
      scrollwheel: false,
      mapTypeControl: false,
      streetViewControl: false,
      zoomControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM
      },
      panControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM
      }
    };
    this.mapType = new google.maps.StyledMapType([{
      featureType: "all",
      elementType: "all",
      stylers: [{
          visibility: "off"
        }, // Hide everything
        {
          lightness: 100
        } // Makes the land white
      ]
    }, {
      featureType: "water",
      elementType: "geometry",
      stylers: [{
          visibility: "on"
        }, // Show water, but no labels
        {
          lightness: -9
        }, // Must be < 0 to compensate for the "all" lightness
        {
          saturation: -100
        }
      ]
    }, {
      featureType: "administrative.country",
      elementType: "labels.text",
      stylers: [{
        color: "#000000"
      }, {
        weight: 0.1
      }, {
        visibility: "on"
      }]
    }]);
    this.overlay = null;

    this.init = function() {
      self.mapCanvas = $("#mapCanvas")[0];

      self.map = new google.maps.Map(self.mapCanvas, self.mapOptions);
      self.map.mapTypes.set('styledMapType', self.mapType);
      self.map.setMapTypeId('styledMapType');

      self.map.data.setStyle(function(feature) {
        // Color each letter gray. Change the color when the isColorful property
        // is set to true.
        var color = 'gray';
        var opacity = 0.01;
        return { /** @type {google.maps.Data.StyleOptions} */
          fillColor: color,
          strokeColor: color,
          strokeWeight: 1,
          strokeOpacity: 0.1,
          fillOpacity: opacity
        };
      });

      self.map.data.overrideStyle(function(feature) {
        // Color each letter gray. Change the color when the isColorful property
        // is set to true.
        var color = 'gray';
        var opacity = 0.01;
        if (feature.getProperty('isColorful')) {
          color = "blue";
          opacity = 1.0;
          return { /** @type {google.maps.Data.StyleOptions} */
            fillColor: color,
            strokeColor: color,
            strokeWeight: 1,
            strokeOpacity: 0.1,
            fillOpacity: opacity
          };
        }
      });

      // When the user clicks, set 'isColorful', changing the color of the letters.
      self.map.data.addListener('click', function(event) {
        self.map.data.revertStyle();
        event.feature.setProperty('isColorful', true);
        // Color each letter gray. Change the color when the isColorful property
        // is set to true.
        var color = 'gray';
        var opacity = 0.01;
        var style = {};
        if (event.feature.getProperty('isColorful')) {
          color = "blue";
          opacity = 0.1;
        }
        style = { /** @type {google.maps.Data.StyleOptions} */
          fillColor: color,
          strokeColor: color,
          strokeWeight: 1,
          strokeOpacity: 0.1,
          fillOpacity: opacity
        };
        self.map.data.overrideStyle(event.feature, style);
      });

      self.map.data.loadGeoJson("https://api.myjson.com/bins/557lr");
      var infowindow = new google.maps.InfoWindow();
      self.map.data.addListener("click", function(evt) {
        zoom2geometry(evt.feature, self.map, infowindow);
      });
      // When the user hovers, tempt them to click by outlining the letters.
      // Call revertStyle() to remove all overrides. This will use the style rules
      // defined in the function passed to setStyle()
      self.map.data.addListener('mouseover', function(event) {
        if (event.feature.getProperty('isColorful')) {
          return;
        }
        self.map.data.overrideStyle(event.feature, {
          strokeWeight: 8,
          fillColor: "red",
          fillOpacity: 0.1
        });
      });

      self.map.data.addListener('mouseout', function(event) {
        if (!event.feature.getProperty('isColorful')) {
          self.map.data.revertStyle(event.feature);
        }
      });
      self.overlay = new google.maps.OverlayView();
      self.overlay.draw = function() {};
      self.overlay.setMap(self.map);

      // This is a stop-gap measure to minimize the effect of
      // a bug we haven't solved yet.

      google.maps.event.addListener(self.map, 'dragstart', function() {
        $(".message").not("#messageTemplate").remove();
      });
    }

    this.newMarker = function(lat, lng) {
      // Used for randomizing marker image
      var offset = Math.floor(Math.random() * 3) * 16;
      // Custom marker
      var marker = new google.maps.Marker({
        position: new google.maps.LatLng(lat, lng),
        icon: new google.maps.MarkerImage(
          'ideasforworldmap/static/img/map/dot.png',
          new google.maps.Size(16, 16),
          new google.maps.Point(0, offset),
          new google.maps.Point(8, 8))
      });

      return marker;
    }

    this.markLocations = function(locations) {
      var i = locations.length;
      while (i--) {
        var loc = locations[i];

        // Make new marker
        var marker = self.newMarker(loc.lat, loc.lng);
        self.markers.push(marker);

        // Tack on some extra data
        marker.message = loc;

        // Handle mouseover event
        google.maps.event.addListener(marker, 'mouseover', function() {

          // Get screen xy
          var pos = self.latLngPixel(this.getPosition());

          // Create an overlay
          var overlay = self.createOverlay(this.message, pos);

          // Add it to the dom
          $(self.mapCanvas).after(overlay);
        });

        // Stagger animation onto the map
        if (i < 50) {
          marker.setAnimation(google.maps.Animation.DROP);
          setTimeout((function(marker) {
            return function() {
              marker.setMap(self.map);
            }
          })(marker), i * 200 + Math.random() * 500 + 500);
        } else {
          marker.setAnimation(null);
          marker.setMap(self.map);
        }
      }
    }

    this.createOverlay = function(message, position) {

      var overlay = $("#messageTemplate").clone();

      overlay.attr("id", message.id);
      overlay.attr("href", "/ideasforworldmap/messages/" + message.id + ".html")

      // Position it at the marker
      overlay.css({
        left: position.x - 52,
        top: position.y - 52,
      });

      // Use distance from center to decide when to hide
      var radius = 50;
      var radiusSq = radius * radius;

      var checkDistance = function(event) {
        var dx = event.pageX - position.x;
        var dy = event.pageY - position.y;

        if (dx * dx + dy * dy > radiusSq) {

          $(window).unbind("mousemove", checkDistance);
          overlay.data("MessageBubble").disappear(250);
          setTimeout(function() {
            overlay.remove();
          }, 250);
        }
      }

      $(window).bind("mousemove", checkDistance);

      // Make it a message bubble
      overlay.messageBubble();

      var dom = overlay.data("MessageBubble").dom;
      dom.original.text(message.text);
      dom.translated.text(message.text_ja);
      dom.by.text("By " + message.author);
      //dom.from.text( "From: " + message.location );

      if (dom.by.text() == "By " || dom.by.text() == "By Your name" || dom.by.text() == "By 名前(ローマ字)") {
        dom.by.text("");
      }

      if (dom.from.text() == "From: " || dom.from.text() == "From: Your location" || dom.from.text() == "From: 地名(ローマ字)") {
        dom.from.text("");
      }

      overlay.data("MessageBubble").disappear(0);
      setTimeout(function() {
        overlay.data("MessageBubble").appear(250);
      }, 20);

      return overlay;
    }

    this.latLngPixel = function(latLng) {
      var projection = self.overlay.getProjection();
      return projection.fromLatLngToContainerPixel(latLng);
    }
  }

  JP.map = new Map();
})();

google.maps.event.addDomListener(window, 'load', JP.map.init);
html,
body,
#mapCanvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="mapCanvas"></div>