【问题标题】:Street view API 3 (add custom minimap) close button Street view and Pegman街景 API 3(添加自定义小地图)关闭按钮街景和街景小人
【发布时间】:2012-06-02 09:07:31
【问题描述】:

在我的脚本中,当您将街景小人放到地图上时,它会加载带有自定义小地图的街景视图。您可以看到带有街景小人的小地图并将其移动到街景中,并且效果很好。

但是,当您单击街景视图上的关闭按钮时,小地图和街景视图会正常关闭,但街景小人不会返回到其默认位置。它会留在地图上,并且无法重新投放。

我想在街景关闭时将街景小人移回默认位置,如果您再次将其放在地图上以像第一次一样加载街景。

在线代码 http://jsbin.com/ayejim/edit#preview

这是我的函数initialize:

    function initialize() {
var lifestyle = [{}];
  var myOptions = {
    zoom: CITY_MAP_ZOOMING_FACT,
    center: new google.maps.LatLng(CITY_MAP_CENTER_LAT, CITY_MAP_CENTER_LNG),
    mapTypeId: google.maps.MapTypeId.<?php echo $maptype;?>

  }
   map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
   map.setOptions({styles: lifestyle});

    /////////////////////////////
    var g = google.maps;
    var pano, mini;
    var mapdiv = document.getElementById("map_canvas");

    pano = map.getStreetView();


  /** Listen to panorama's visibility changes to detect
  * when pegman is dropped onto the map
  * and when Street view is closed
  */

  g.event.addListener(pano, "visible_changed", function() {
   // Street view activated by dropping pegman
   if (!mini && pano.getVisible()) {
    // Container for mini map and close button

    var c = document.createElement("div");
    c.id = "minimap";
    c.style.visibility = "visible";

    var d = document.createElement("div");
    d.id = "closebutton";
    d.onclick = function() {
    // Toggles button icon and moves copyright notice
     var terms = document.getElementById("note");
//    var terms = mapdiv.childNodes[1].childNodes[2];
      if (c.style.visibility == "visible") {
        c.style.visibility = "hidden";
        d.className = "closed";
        terms.style.marginRight = "24px";
      }
      else {
       c.style.visibility = "visible";
       d.className = "";
       terms.style.marginRight = "170px";
      }
    };

    c.appendChild(d);
    mapdiv.appendChild(c);
    mapdiv.appendChild(d);

    mini = new g.Map(c, {
      center: pano.getPosition(),
      zoom: 15,
      mapTypeId: "roadmap",
      disableDefaultUI: true,
      streetViewControl: true,
      streetView: pano,
      styles: lifestyle

    });

    /** Moves the 'Terms' notice to the left
    * to ensure it's not covered up.
    * There are two such notices in the document.
    * Make sure to catch the right ones.
    */
    g.event.addListener(mini, "tilesloaded", function() {
     var terms = mini.getDiv().firstChild.childNodes[2];
     terms.style.marginRight = "24px";
     var sv_terms = mapdiv.childNodes[1].childNodes[2];
     sv_terms.id = "note";
     sv_terms.style.marginRight = "170px";
     sv_terms.style.zIndex = "1";
   });
    // Binds mini map's center to pano position
    mini.bindTo("center", pano, "position");

    // Street view finished by click on Street view close button
   } else if (mini instanceof g.Map && !pano.getVisible()) {
     mapdiv.removeChild(document.getElementById("minimap"));
    **//initialize(); if try call initialize again pegman back default position but map back to default position too like the first time.and markers hide , i don't know why this happens**
   }
 });
 /////////////////////////
   mgr = new MarkerManager( map );
   google.maps.event.addListener(mgr, 'loaded', function() {
      if (markers) {
         for (var level in markers) {
            google.maps.event.addDomListener( document.getElementById( level ), 'click', function() {
               setCategoryVisiblity( this.id, this.checked );
            });
            for (var i = 0; i < markers[level].length; i++) {

               var details = markers[level][i];
               var image = new google.maps.MarkerImage(details.icons,new google.maps.Size(PIN_POINT_ICON_WIDTH, PIN_POINT_ICON_HEIGHT));
               var myLatLng = new google.maps.LatLng(details.location[0], details.location[1]);
               <?php if(get_current_city_set_zooming_opt() == '1') { ?>
                 multimarkerdata[i]  = new google.maps.LatLng(details.location[0], details.location[1]);
               <?php } ?>
               markers[level][i] = new google.maps.Marker({
                  title: details.name,
                  position: myLatLng,
                  icon: image,
                  clickable: true,
                  draggable: false,
                  flat: true,
                  animation: google.maps.Animation.DROP
               });


            attachMessage(markers[level][i], details.message);
            }
            mgr.addMarkers( markers[level], 0 );
         }
          <?php if(get_current_city_set_zooming_opt() == '1') { ?>
             var latlngbounds = new google.maps.LatLngBounds();

            for ( var j = 0; j < multimarkerdata.length; j++ )
                {
                 latlngbounds.extend( multimarkerdata[ j ] );
                }
               map.fitBounds( latlngbounds );
          <?php } ?>
         mgr.refresh();
      }
   });

    // but that message is not within the marker's instance data 
    function attachMessage(marker, msg) {
      var myEventListener = google.maps.event.addListener(marker, 'click', function() {
      if (pano.getVisible()) { 
        infowindow.open(pano, marker); 
      } else { 
      infowindow = new google.maps.InfoWindow(
          { content: String(msg) 
          });
        infowindow.open(map, marker); 
      } 
         if (infowindow) infowindow.close();
        infowindow = new google.maps.InfoWindow(
          { content: String(msg) 
          });
         infowindow.open(map,marker);
      });
    }

}

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

【问题讨论】:

  • 这是一个不错的概念,我尝试了一些想法,我发现谷歌搜索“sticky pegman”和“pegman reset”,特别是手动设置map.getStreetView().setVisible(false);。它没有用:(我至少可以留下一个正在运行的“演示”供其他人查看并尝试解决您的问题。您要做的就是放置街景小人,关闭街景,然后返回到地图,请注意街景小人是如何“禁用”的,移动它不会重新打开新的街景视图,并且您无法将他放回起始位置。DEMO HEREjsbin.com/ayejim/edit#preview
  • 谢谢Liliana,我在帖子中添加了Demo,希望有人能帮助我,这个概念就像你说的那样好
  • 看看这个 Liliana,jsfiddle.net/spiderplant0/fubNj/7 这个演示使用 setVisible(false),当你把街景小人放到默认的街景站点时,我也不能让它在我的脚本中工作

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


【解决方案1】:

不完全确定为什么当前代码不起作用,但我对您在当前代码中采用的方法也有点怀疑。为什么不为全景图(街景)制作一个单独的 div,并对 map_canvas div 做一些样式以复制您当前的方法(而不是使用小地图 div)。我在这个 jsfiddle 中创建了一个基础(http://jsfiddle.net/svigna/FnrbX/embedded/result/ 和 http://jsfiddle.net/svigna/FnrbX/ 用于源代码),您可以查看并可能将其用作您的解决方案的基础。

请允许我向您介绍我的代码 - 稍微研究一下 streetView 类属性和 jquery,我相信您的问题可以解决。

<body onload="initialize()"> 
  <div id="container">
  <div id="map_canvas" class="bigmap"></div>
  <div id="pano" class="bigmap" style="display:none"></div>
</div>

首先,在标记中,我们要为地图声明一个 div,为全景图声明一个 div,它们将绑定到地图。我们在一个容器中声明它以用于样式目的(当我们想要将地图重叠在全景图上时)。请注意,全景图的样式最初设置为display:none,否则您将看到一个灰显的区域(这是没有任何位置数据的全景图,因为没有设置街景小人)。

#container {
  width: 940px;
  height: 640px;
  position: relative;
}
#map_canvas, 
#pano {
  position: absolute;
  top: 0;
  left: 0;
}
#map_canvas {
  z-index: 10;
}
.bigmap{
  width:100%;
  height:100%;
}

.minimap{
  width:480px;
  height:320px;
} 

这里的样式设置基本上是为了让 map_canvas div 可以在街景小人掉落时与 pano div 重叠。我将此解决方案中的概念用于 div 重叠 (How to overlay one div over another div)。 .minimap 和 .bigmap 类可以轻松地将 map_canvas 从一个视图切换到另一个视图,这在下面的 javascript 部分中会更有意义。

function initialize() {
  var fenway = new google.maps.LatLng(42.345573,-71.098326);
  var panoramaOptions = {
    enableCloseButton : true,
    visible: false
  };
  var panorama = new  google.maps.StreetViewPanorama(document.getElementById("pano"), panoramaOptions);
  var mapOptions = {
    center: fenway,
    zoom: 14,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    streetView : panorama
  };
  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

到目前为止,我们在 javascript 中初始化了所有地图内容。这是非常不言自明的,要查看此处设置的属性,请查看 google maps api v3 参考 - 我发现它非常有用。

  google.maps.event.addListener(panorama, "visible_changed", function() {
    if (panorama.getVisible() && $("#pano").is(':visible')){
        //moving the pegman around the map
    }else if(panorama.getVisible() && $("#pano").is(':hidden')){
        $("#pano").show();          
        $("#map_canvas").removeClass('bigmap');
        $("#map_canvas").addClass('minimap');
    }
    google.maps.event.addListener(panorama, "closeclick", function() {
        $("#pano").hide();  
        $("#map_canvas").removeClass('minimap');
        $("#map_canvas").addClass('bigmap');        
    });
  });        
}

注意:事件监听器仍然在 initialize() 函数中声明。但本质上,我们会监听全景可见性的变化,但仅凭这一点还不足以确定 pano div 元素中是否存在实际数据。请记住,当我们将 pano div display 设置为 none 时,我们可以使用 jquery 检查可见性。如果它是可见的,这意味着它不是街景小人的初始下降 - 如果它是隐藏的,那么这就是我们将 map_canvas 的类更改为小地图的地方。另请注意,我们在“visible_changed”侦听器中侦听 closeclick。这是因为 visible_changed 还包括 closeclick 操作,因此通过将其放入其中,我们将侦听器绑定到另一个。触发 closeclick 后,我们隐藏 pano div 并将 map_canvas 改回正常大小。

这种方法的优点在于 streetView 上的原生“closeclick”操作可将街景小人从其设置的地图中移除并将其恢复正常(这是您在问题中想要的)。此外,要回到原来的位置,您只需在“closeclick”事件侦听器上对初始位置执行 map.panTo()。

我希望这就是您要找的东西,如果距离太远,我深表歉意!我知道它本质上是要求您重新设计当前的代码结构 - 但只是认为这种方法要简单得多,并且似乎可以做您想做的事情。

【讨论】:

  • 这里有一些好东西。 +1。但是,您可能需要通过显式触发 resize 事件来确保 API 知道在隐藏和重新显示事物时调整了地图的大小。 (或者它可能只是使用 jsFiddle 的一个工件,但目前您的示例无法正确显示调整大小的地图)
  • 是的,谢谢。我发现如果我将街景小人从 480x320 视口中删除,地图就会被截断。但是调用 resize 事件可能会解决问题。
  • 我喜欢简单的答案 :) 我在这里“增强”了它jsbin.com/olayiw/edit#preview 目标是更接近 Gustavo 所拥有的行为(例如居中的街景小人),并确保大部分可用性是清洁,例如,将街景小人放在河中将恢复为大地图。然而,当街景小人被放置在他的固定位置时,我不知道如何实现这个结果。
  • 这些确实是一些不错的改进,jsbin 演示看起来很棒!不知道你遇到了什么问题,你能详细说明一下你面临的问题吗?
  • @Suvi 行为不可预测。我想要完成的是,当街景小人被拖回他原来的小矩形(在小地图的左上角)时,街景视图应该关闭并恢复大路线图。有时确实会发生这种情况,有时,街景小人被放置在控件后面的街道上,有时他留在他的矩形中,但路线图没有放大。这是一个小细节,但我不知道在哪里更新代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多