Street view API 3 (add custom minimap) close button Street view and Pegman
In my script, when you drop the pegman on to the map, it loads Street View with a custom minimap. You can see the minimap with the pegman and move it for Street View, and it works fine.
However, when you click the close button on the street view, the minimap and Street View close fine but the pegman doesn't return to its default position. It stays on the map, and can't be re-dropped.
I want to move the pegman back to default position when Street View is closed, and if you drop it on map again to load Street View like the first time.
online code http://jsbin.com/ayejim/edit#preview
This is my function 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);
Not entirely sure why the current code is not working, but I'm also a little skeptic on the approach you're taking in the current code. Why not make a separate div for the panorama (streetview) and do some styling to the map_canvas div to replicate your current method (instead of using the minimap div). I've created a basis in this jsfiddle ( http://jsfiddle.net/svigna/FnrbX/embedded/result/ and http://jsfiddle.net/svigna/FnrbX/ for source code) that you can check out and possible use as a foundation for your solution.
Allow me to walk you through my code - with a little bit of looking into the streetView class properties and jquery I'm sure your question could be solved.
<body onload="initialize()">
<div id="container">
<div id="map_canvas" class="bigmap"></div>
<div id="pano" class="bigmap" style="display:none"></div>
</div>
first thing is first, in the mark-up we want to declare a div for the map and a div for the panorama, which will be bound to the map. We declare it in a container for styling purposes (when we want to overlap the map over the panorama). Notice the style of the panorama is initially set to display:none
otherwise you'll be seeing a grayed out region (which is the pano without any location data because the pegman is not set).
#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;
}
The styling here is essentially set to make it possible for the map_canvas div to overlap over the pano div when the pegman gets dropped. I used the concept from this solution for div overlapping ( How to overlay one div over another div). The .minimap and .bigmap classes make it easy to switch the map_canvas from one view to another, which will make more sense in the javascript section below.
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);
up to this point in the javascript we initialize all the map contents. it is pretty self explanatory, to look into the properties that are set in here have a look at the google maps api v3 reference - i found it to be very useful.
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');
});
});
}
Note: the event listeners are still declared in the initialize() function. But essentially we listen for a change in the panorama visibility, but that alone is not enough to determine if there is actual data in the pano div element. Remember when we set the pano div display to none, well we can use jquery to check for the visibility. If it's visible, that means it is NOT the initial drop of the pegman - if it's hidden then that's where we change the class of the map_canvas to minimap. Also note that we listen for the closeclick in the "visible_changed" listener. This is because visible_changed also includes the closeclick action, so by putting it inside we're binding the listener to the other. Once the closeclick is triggered, we hide the pano div and change the map_canvas back to it's normal size.
The great thing about this approach is the native "closeclick" action on the streetView removes the pegman from the map it's set to and returns it back to normal (which is what you wanted in your problem). Also, to go back to your original position you can simply do a map.panTo()
on the "closeclick" event listener to the initial location.
I hope this what you were looking for, if it's far off then my apologies! I know it's essentially asking you to redesign your current code structure - but just thought this approach was much simpler and seems to do the same thing you want done.
链接地址: http://www.djcxy.com/p/75862.html