Panotour Pro 2 - Adding KML in Google Maps API v3 - google-maps

I have been working with the Google Maps API v3 in Panotour for a few days now and had been adding my own KML layers to my Panotour Maps. I had it working yesterday but today it seems to have been broken somehow.
To add my own KML layers I am basically just adding a piece of script to my project build under "\graphics\KolorMap\lib\mxn.googlev3.core".
This is the chunk of code I was piecing into the googlev3.core file. Its the KML sample from the developers website. I wanted to get it working before adding my own custom stuff.
var ctaLayer = new google.maps.KmlLayer({
url: 'http://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml'
});
ctaLayer.setMap(map);
I have added a link to the mxn.googlev3.core. If anyone knows where I need to put my code or if I need to add anything that would be much appreciated.
mxn.googlev3.core
Thanks in advance

There are still some bugs that I am sorting through and I may still need some help with them.
Below is the code excerpt from the mxn.googlev3.core file. The code is from Line 1 to about Line 140. I forget where exactly because I have added my own code.
mxn.register('googlev3', {
Mapstraction: {
init: function(element, api){
var me = this;
if (typeof google.maps.Map === 'undefined') {
throw new Error(api + ' map script not imported');
}
// by default add road map and no controls
var myOptions = {
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
mapTypeControlOptions: null,
zoomControl: false,
zoomControlOptions: null,
panControl: false,
panControlOptions: null,
scaleControl: false,
scaleControlOptions: null,
scrollwheel: true,
draggable: false,
disableDoubleClickZoom: true
};
// Background color can only be set at construction
// To provide some control, adopt any explicit element style
var backgroundColor = null;
if ( element.currentStyle ) {
backgroundColor = element.currentStyle['background-color'];
}
else if ( window.getComputedStyle ) {
backgroundColor = document.defaultView.getComputedStyle(element, null).getPropertyValue('background-color');
}
// Only set the background if a style has been explicitly set, ruling out the "transparent" default
if ( backgroundColor && 'transparent' !== backgroundColor ) {
myOptions.backgroundColor = backgroundColor;
}
// find controls
if (!this.addControlsArgs && loadoptions.addControlsArgs) {
this.addControlsArgs = loadoptions.addControlsArgs;
}
if (this.addControlsArgs) {
if (this.addControlsArgs.zoom) {
myOptions.zoomControl = true;
if (this.addControlsArgs.zoom == 'small') {
myOptions.zoomControlOptions = {style: google.maps.ZoomControlStyle.SMALL,position: google.maps.ControlPosition.TOP_LEFT};
}
if (this.addControlsArgs.zoom == 'large') {
myOptions.zoomControlOptions = {style: google.maps.ZoomControlStyle.LARGE,position: google.maps.ControlPosition.TOP_LEFT};
}
}
if (this.addControlsArgs.scale) {
myOptions.scaleControl = true;
myOptions.scaleControlOptions = {style:google.maps.ScaleControlStyle.DEFAULT,position: google.maps.ControlPosition.BOTTOM_LEFT};
}
if (this.addControlsArgs.pan) {
myOptions.panControl = true;
myOptions.panControlOptions = {position: google.maps.ControlPosition.TOP_LEFT};
}
if (this.addControlsArgs.map_type) {
myOptions.mapTypeControl = true;
myOptions.mapTypeControlOptions = {style: google.maps.MapTypeControlStyle.DEFAULT,position: google.maps.ControlPosition.TOP_RIGHT};
}
if (this.addControlsArgs.overview) {
myOptions.overviewMapControl = true;
myOptions.overviewMapControlOptions = {opened: true};
}
}
// Enable the visual refresh
google.maps.visualRefresh = true;
var map = new google.maps.Map(element, myOptions);
var fireOnNextIdle = [];
google.maps.event.addListener(map, 'idle', function() {
var fireListCount = fireOnNextIdle.length;
if (fireListCount > 0) {
var fireList = fireOnNextIdle.splice(0, fireListCount);
var handler;
while((handler = fireList.shift())){
handler();
}
}
});
// deal with click
google.maps.event.addListener(map, 'click', function(location){
me.click.fire({'location':
new mxn.LatLonPoint(location.latLng.lat(),location.latLng.lng())
});
});
// deal with zoom change
google.maps.event.addListener(map, 'zoom_changed', function(){
// zoom_changed fires before the zooming has finished so we
// wait for the next idle event before firing our changezoom
// so that method calls report the correct values
fireOnNextIdle.push(function() {
me.changeZoom.fire();
});
});
// deal with map movement
var is_dragging = false;
google.maps.event.addListener(map, 'dragstart', function() {
is_dragging = true;
});
google.maps.event.addListener(map, 'dragend', function(){
me.moveendHandler(me);
me.endPan.fire();
is_dragging = false;
});
google.maps.event.addListener(map, 'center_changed', function() {
me.endPan.fire();
});
// deal with initial tile loading
var loadListener = google.maps.event.addListener(map, 'tilesloaded', function(){
me.load.fire();
google.maps.event.removeListener( loadListener );
if (!is_dragging) {
fireOnNextIdle.push(function() {
me.endPan.fire();
});
}
});
this.maps[api] = map;
this.loaded[api] = true;
// THIS IS THE KML CODE THAT YOU NEED TO INSERT -START
var ctaLayer = new google.maps.KmlLayer({
url: 'Insert your kml here link here'
});
ctaLayer.setMap(map);
//END KML CODE SECTION
},
The "Insert your kml link here" is where you put your kml url link.
For some reason the attributes stop displaying at intermittent times. They will work and then I will go to click on a feature again to view the attributes and nothing. This is one of the bugs. I am also messing around with document links within the kml feature attribute tables. As I get deeper into this this Panoramic program is becoming more of a GIS program.
If anyone has any other ideas about this please feel free to make suggestions.

Related

Fire event after polygon is loaded

After searching the whole day, I didn't find the answer.
So the problem is:
I have a Google Map on which the user can draw. After this, the user can save it on the server. It works fine. Here is the drawing code:
var drawingManager;
var selectedShape;
var colors = ['#1E90FF', '#FF1493', '#32CD32', '#FF8C00', '#4B0082'];
var selectedColor;
var colorButtons = {};
var all_overlays = [];
var coordinates;
var polygon;
var globalGoogleSelectedColor;
var globalGooglePinWidth;
var map;
coordObj = new Object();
function clearSelection()
{
if (selectedShape)
{
deleteAllLastShape();
selectedShape.setEditable(false);
selectedShape = null;
deleteObjectContent(coordObj);
}
}
function setSelection(shape)
{
clearSelection();
selectedShape = shape;
shape.setEditable(true);
selectColor(shape.get('fillColor') || shape.get('strokeColor'));
}
function deleteAllShape()
{
console.log("deleteAllShape");
deleteObjectContent(coordObj);
for (var i=0; i < all_overlays.length; i++)
{
all_overlays[i].overlay.setMap(null);
}
all_overlays = [];
}
function deleteAllLastShape()
{
var myLenth = all_overlays.length;
if(myLenth > 1)
{
all_overlays[0].overlay.setMap(null);
all_overlays = _.rest(all_overlays);
}
}
function deleteSelectedShape()
{
if (selectedShape)
{
selectedShape.setMap(null);
deleteObjectContent(coordObj);
}
}
function selectColor(color)
{
selectedColor = color;
globalGoogleSelectedColor = selectedColor;
globalGooglePinWidth = 2; //only for Database
for (var i = 0; i < colors.length; ++i)
{
var currColor = colors[i];
colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
}
// Retrieves the current options from the drawing manager and replaces the
// stroke or fill color as appropriate.
var polylineOptions = drawingManager.get('polylineOptions');
polylineOptions.strokeColor = color;
drawingManager.set('polylineOptions', polylineOptions);
var rectangleOptions = drawingManager.get('rectangleOptions');
rectangleOptions.fillColor = color;
drawingManager.set('rectangleOptions', rectangleOptions);
var circleOptions = drawingManager.get('circleOptions');
circleOptions.fillColor = color;
drawingManager.set('circleOptions', circleOptions);
var polygonOptions = drawingManager.get('polygonOptions');
polygonOptions.fillColor = color;
drawingManager.set('polygonOptions', polygonOptions);
}
function setSelectedShapeColor(color)
{
if (selectedShape)
{
if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE)
{
selectedShape.set('strokeColor', color);
}
else
{
selectedShape.set('fillColor', color);
}
}
}
function makeColorButton(color)
{
var button = document.createElement('span');
button.className = 'color-button';
button.style.backgroundColor = color;
google.maps.event.addDomListener(button, 'click', function() {
selectColor(color);
setSelectedShapeColor(color);
});
return button;
}
function buildColorPalette()
{
var colorPalette = document.getElementById('color-palette');
for (var i = 0; i < colors.length; ++i)
{
var currColor = colors[i];
var colorButton = makeColorButton(currColor);
colorPalette.appendChild(colorButton);
colorButtons[currColor] = colorButton;
}
selectColor(colors[0]);
}
function initializeAreas()
{
map = new google.maps.Map(document.getElementById('mapBaugebieteDiv'),
{
zoom: 15,
center: new google.maps.LatLng(48.758961357888516,8.240861892700195),
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DEFAULT,
mapTypeIds: [
google.maps.MapTypeId.ROADMAP,
google.maps.MapTypeId.TERRAIN,
google.maps.MapTypeId.SATELLITE,
google.maps.MapTypeId.HYBRID
]},
disableDefaultUI: false,
zoomControl: true,
scaleControl: true,
mapTypeControl: true,
streetViewControl: true,
rotateControl: true
});
var polyOptions =
{
strokeWeight: 0,
fillOpacity: 0.45,
editable: true
};
// Creates a drawing manager attached to the map that allows the user to draw
// markers, lines, and shapes.
drawingManager = new google.maps.drawing.DrawingManager(
{
drawingMode: google.maps.drawing.OverlayType.POLYGON,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
// google.maps.drawing.OverlayType.MARKER,
// google.maps.drawing.OverlayType.CIRCLE,
google.maps.drawing.OverlayType.POLYLINE,
// google.maps.drawing.OverlayType.RECTANGLE,
google.maps.drawing.OverlayType.POLYGON
]
},
markerOptions:
{
draggable: true
},
polylineOptions:
{
editable: true
},
rectangleOptions: polyOptions,
circleOptions: polyOptions,
polygonOptions: polyOptions,
map: map
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e)
{
// Push the overlay onto an array (all_overlays):
all_overlays.push(e);
deleteAllLastShape();
if (e.type != google.maps.drawing.OverlayType.MARKER)
{
// Switch back to non-drawing mode after drawing a shape.
drawingManager.setDrawingMode(null);
// Add an event listener that selects the newly-drawn shape when the user
// mouses down on it.
var newShape = e.overlay;
newShape.type = e.type;
google.maps.event.addListener(newShape, 'click', function()
{
setSelection(newShape);
});
setSelection(newShape);
}
});
// Clear the current selection when the drawing mode is changed, or when the
// map is clicked.
google.maps.event.addListener(drawingManager, 'drawingmode_changed', clearSelection);
google.maps.event.addListener(map, 'click', clearSelection);
google.maps.event.addDomListener(document.getElementById('delete-button'), 'click', deleteSelectedShape);
google.maps.event.addDomListener(document.getElementById('delete-all-button'), 'click', deleteAllShape);
///////////////////////////////////////
// Polylgon
///////////////////////////////////////
google.maps.event.addListener(drawingManager, 'polygoncomplete', function (polygon)
{
var shapeType = 'polygon';
google.maps.event.addListener(polygon.getPath(), 'insert_at', function()
{
// New point
coordinates = (polygon.getPath().getArray());
showObjectContent(coordinates);
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
google.maps.event.addListener(polygon.getPath(), 'remove_at', function()
{
// Point was removed
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
google.maps.event.addListener(polygon.getPath(), 'set_at', function()
{
// Point was moved
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
google.maps.event.addListener(polygon, 'dragend', function()
{
// Polygon was dragged
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
///////////////////////////////////////
// Polyline
///////////////////////////////////////
google.maps.event.addListener(drawingManager, 'polylinecomplete', function (polygon)
{
var shapeType = 'polyline';
google.maps.event.addListener(polygon.getPath(), 'insert_at', function()
{
// New point
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
google.maps.event.addListener(polygon.getPath(), 'remove_at', function()
{
// Point was removed
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
google.maps.event.addListener(polygon.getPath(), 'set_at', function()
{
// Point was moved
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
google.maps.event.addListener(polygon, 'dragend', function()
{
// Polygon was dragged
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
coordinates = (polygon.getPath().getArray());
coordObj = getCoordinatesOfPolygon(polygon,shapeType);
});
buildColorPalette();
}
google.maps.event.addDomListener(window, 'load', initializeAreas);
But the big problem is, after reloading the lat/lng from the server and drawing it on the map, the event listener does not know about the new polygon:
function fillBuildingForm(getData)
{
var coord = getData['buildings']; // coordinates from the server
if(typeof coord[0] !== 'undefined')
{
var shapeType = coord[0]['shapeType'];
var color = coord[0]['color'];
var strokeOpacity = coord[0]['opacity'];
var strokeWeight = coord[0]['linewidth'];
var numberOfCoord = getObjectSize(coord);
var flightPlanCoordinates = new Array();
for (var i = 0; i < numberOfCoord; i++)
{
thisCoord = new Object();
thisCoord['lat']=parseFloat(coord[i]['lat']);
thisCoord['lng']=parseFloat(coord[i]['lng']);
flightPlanCoordinates.push(thisCoord);
};
var bermudaTriangle = new google.maps.Polygon(
{
paths: flightPlanCoordinates,
strokeColor: color,
strokeOpacity: strokeOpacity,
strokeWeight: strokeWeight,
fillColor: color,
fillOpacity: 0.35,
// bounds: flightPlanCoordinates,
editable: true,
draggable: true
});
bermudaTriangle.setMap(map); //now its drawing at the map
}
}
You can see, until now, it works perfectly:
But the user can change the polygon and want to save the new changed polygon on the server. The listener:
google.maps.event.addListener(drawingManager, 'polygoncomplete', function (polygon)
Does not recognize that the polygon has been drawn. And therefore the listener doesn't recognize when the user changes the polygon.
So the coordinates are not present in all_overlays[i].
The listener only recognizes when a polygon is drawn manually, but not in the way like the above, when it is drawn automatically.
The question: How can I send the automatically drawn polygon coordinates to the "map" object? Alternatively, how can I fire an event to "polygoncomplete", so it will recognize the new polygon?
The other idea I had: Trigger a mouse click event at the map with the coordinates, so the listener must recognize that the map has changed. But unfortunately this didn't work.
Has anybody any idea how to solve this issue?
There are not many possibilities as an event "polygon_load _complete" is not available. One suggestion is to exploit the fact that to operate on a polygon you must click it.
If you need to manage the situation when a polygon is loaded from server and the user change the shape/coordinates. you can add listener on click to every polygon during the loading phase ..
for each polygon in loading phase..
var aPoly = new google.maps.Polygon({
paths:myPaths,
.......
});
google.maps.event.addListener(aPoly, 'click', function (event) {
console.log('This polygon contain : ' + this.paths + ' coords point ');
});
In this way you can intecept the click on polygon for manage your need
your idea was a good intention, but not the end of the solution. But thank you for your hint. Because of your answer I was able finding a way.
Generally we should think, the object bermudaTriangle should have the property "paths". But it doesn't work like this way.
For getting the coordinates of the loaded Poly (loaded from server) there is a google-map function like "getPath()" or"getPaths()". It seems, that both methods are working.
Please note, I've changed the name from 'bermudaTriangle' to 'globalLoadedPoly'.
So the solution is in combination with the above code now additional:
Creating a global var:
var globalLoadedPoly;
(global is not necessary, but I did it this way for further actions)
Getting the path by function for the listeners:
var thisPolyPath = globalLoadedPoly.getPath();
Listening to events, when the loaded poly has changed:
google.maps.event.addListener(thisPolyPath, 'set_at', thisPolyHasChanged);
google.maps.event.addListener(thisPolyPath, 'insert_at', thisPolyHasChanged);
4.In the function, thisPolyHasChanged(), setting the loaded poly as the actual selection, by using the function setSelection(shape). And getting the coordinates by calling the function getCoordinatesOfLoadedPolygon
function thisPolyHasChanged()
{
// Setting the loaded poly as the new selection
// Yes, it's global, so therefore not necessary to be sent
// but like this way, it's more readable
setSelection(globalLoadedPoly);
// If you want to get the coordinates for saving
// Calling the function getCoordinatesOfLoadedPolygon
// For being more readable I send the global Object - yes, it's not necessary
coordObj = getCoordinatesOfLoadedPolygon(globalLoadedPoly,'polygon');
// do something with coordObj
// ...
}
function setSelection(shape)
{
// clearSelection is in the code I postet as the question
clearSelection();
selectedShape = shape; // setting the loaded poly as the actual poly
shape.setEditable(true); // making the loaded poly editable
selectColor(shape.get('fillColor') || shape.get('strokeColor')); //setting the color
}
function getCoordinatesOfLoadedPolygon(getPolygon,shapeType)
{
// getLength is also a google-maps function / method
var objSize = getPolygon.getPath().getLength();
for (var i = 0; i < objSize; i++)
{
// getArray is a google-maps function / method too
var thisLat = getPolygon.getPath().getArray()[i].lat();
var thisLng = getPolygon.getPath().getArray()[i].lng();
coordObj[i]=new Object();
coordObj[i]['lat']=thisLat;
coordObj[i]['lng']=thisLng;
coordObj[i]['shapeType']=shapeType;
};
return coordObj;
}
At last, if you iterate the object "coordObj" and make a console.log in firebug, it looks like this way:
0 Object { lat=51.25572693191116, lng=9.136230200529099, shapeType="polygon"}
1 Object { lat=51.80250070611026, lng=13.069335669279099, shapeType="polygon"}
2 Object { lat=49.958995050387585, lng=10.476562231779099, shapeType="polygon"}
Conclusion:
If you want to get the coordinates or other properties of a google-maps object, use the proprietary google-maps functions / methods:
// For getting the coordinates you are generally working with:
yourMapObject.getPath();
//or
yourMapObject.getPaths();
// Getting especially the latitude:
var latitude = yourMapObject.getPath().getArray()[i].lat();
// Getting especially the longitude:
var longitude = yourMapObject.getPath().getArray()[i].lng();
// Getting the number of coordinates
yourMapObject.getPath().getLength();
Don't forget to iterate over the whole object, to get all coordinates.
The solution-code could be really optimized. For being more readable, I wrote it in small steps.
I hope, I'm able helping anybody with this solution.

Google maps centered load failure

Well I'm having this problem, load the map once and everything works perfect. The second time or once update the map does not load ok, but not centered load when navigating on you can see the marks that are made but is deformed or simply lost.
I have tried several ways to solve this problem, first and most common I found was to use google.maps.event.trigger(map 'resize') but it did not work then and logic, try that whenever loading map is executed, create a new map, with the same data and focused but neither worked for me. It may be also the way I use the map. I am using the plugin of the camera in my application, the user takes a photo and this should detect where I draw the picture and display the map. Each time the view is opened, the plug of the camera, in the process of taking and show the picture is where I call the appropriate functions to load the map and this has me a bit tricky immediately loaded I have a good time locked in this problem, I found solutions serve me but only for the browser, the device does not work. I am using ionic framework and plugins cordova.
Controller :
.controller("CamaraCtrl", function($scope,$rootScope, Camera,$cordovaGeolocation,$state,$location,$ionicSideMenuDelegate) {
var posOptions = {timeout: 10000, enableHighAccuracy: false};
$cordovaGeolocation
.getCurrentPosition(posOptions)
.then(function (position) {
var latitud_actual = position.coords.latitude
var longitud_actual = position.coords.longitude
$scope.latitud = latitud_actual;
$scope.longitud = longitud_actual;
//$scope.map = new google.maps.Map(document.getElementById("mapa_ubicacion"), mapOptions);
}, function(err) {
// error
});
function initialize() {
var mapOptions = {
center: new google.maps.LatLng($scope.latitud, $scope.longitud),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
$scope.setMarker(map, new google.maps.LatLng($scope.latitud, $scope.longitud), 'Yo', '');
$scope.map = map;
}
$scope.setMarker = function(map, position, title, content) {
var marker;
var markerOptions = {
position: position,
map: map,
title: title
};
marker = new google.maps.Marker(markerOptions);
google.maps.event.addListener(marker, 'click', function () {
// close window if not undefined
if (infoWindow !== void 0) {
infoWindow.close();
}
// create new window
var infoWindowOptions = {
content: content
};
infoWindow = new google.maps.InfoWindow(infoWindowOptions);
infoWindow.open(map, marker);
});
}
$scope.mostrar_form = false;
$scope.mostrar_boton_view = false;
$scope.getPhoto = function() {
Camera.getPicture().then(function(imageURI) {
console.log(imageURI);
$scope.lastPhoto = imageURI;
$scope.mostrar_form = true;
$scope.mostrar_boton_view = false;
google.maps.event.addDomListener(window, 'load', initialize);
initialize();
}, function() {
$scope.mostrar_boton_view = true;
}, {
quality: 75,
targetWidth: 320,
targetHeight: 320,
saveToPhotoAlbum: false
});
};
$scope.getPhoto();
})
The only solution I found was to create a function that executes the map again. It should not be as optimal but at least it solved my problem.
$scope.centrar = function(){
var mapOptions = {
center: new google.maps.LatLng($scope.latitud, $scope.longitud),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
$scope.setMarker(map, new google.maps.LatLng($scope.latitud, $scope.longitud), 'Yo', '');
$scope.map = map;
}

Google maps marker, with added directions code not showing

I seem to be having trouble adding a marker to one of my maps that I have created and I just can't seem to figure out where I am going wrong with it.
The map has been added to the site fine, and I even have the directions code working which happens to be displaying markers.
What I would like would be an initial marker to display where, in this case, the school is and have an info box on click to show the address but I just can't seem to get it displaying no matter what I try.
My code for everything is as follows:-
<div id="map_canvas" style="width:100%; height:392px;float:left;"></div>
<div id="directionsPanel" style="float:left;max-width:395px; overflow:scroll;overflow-x: hidden;"></div>
<script>
//define one global Object
var myMap = {}
//init
function initialize(){
//set up map options
var mapOptions = {
center: new google.maps.LatLng(53.964304,-2.028522),
zoom: 15,
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP,
};
myMap.map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
myMap.directionsService = new google.maps.DirectionsService();
myMap.directionsDisplay = new google.maps.DirectionsRenderer();
myMap.directionsDisplay.setMap(myMap.map);
myMap.directionsDisplay.setPanel(document.getElementById("directionsPanel"));
}//end init
function createMarker(point, title, content, map) {
var marker = new google.maps.Marker({
position: point,
map: map,
title: title
});
var infowindow = new google.maps.InfoWindow({
content: content
});
google.maps.event.addListener(marker, 'click', function() {
if(curr_infw) { curr_infw.close();} // We check to see if there is an info window stored in curr_infw, if there is, we use .close() to hide the window
curr_infw = infowindow; // Now we put our new info window in to the curr_infw variable
infowindow.open(map, marker); // Now we open the window
});
return marker;
}
//directions
var calcRoute = function() {
var start = document.getElementById("start").value,
end = document.getElementById("end").value,
request = {
origin:start,
destination:end,
durationInTraffic :true,
transitOptions: {
departureTime: new Date()
},
provideRouteAlternatives : true,
travelMode: document.getElementById("travelmode").value
};
myMap.directionsService.route(request, function(result, status) {
if(status == google.maps.DirectionsStatus.OK) {
myMap.directionsDisplay.setDirections(result);
}else{
alert("something went wrong!");
}
});
}
//script loader
var loadScript = function() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyDZsY0Xbo137bDtb8wmefTogdGl82QM85s&sensor=false&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
Any help on this guys would be greatly appreciated before I end up becoming bald from pulling out all my hair lol.
Jason

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.

Show My Location on Google Maps API v3

"My Location" in Google Maps javascript API
This question was asked over half a year ago. Has Google Maps API v3 updated to use the "My Location" button found on http://maps.google.com?
My Location is the control between the Street View man and the gamepad-looking controls.
If Google Maps API doesn't provide My Location then do I need to write my own HTML5 geolocation feature using navigator.gelocation then create my own control on Google Maps?
No, but adding your own marker based on current location is easy:
var myloc = new google.maps.Marker({
clickable: false,
icon: new google.maps.MarkerImage('//maps.gstatic.com/mapfiles/mobile/mobileimgs2.png',
new google.maps.Size(22,22),
new google.maps.Point(0,18),
new google.maps.Point(11,11)),
shadow: null,
zIndex: 999,
map: // your google.maps.Map object
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(pos) {
var me = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
myloc.setPosition(me);
}, function(error) {
// ...
});
}
We have made such a component for Google Maps API v3. Anybody can use in custom projects to add a control showing current geolocation with just one line of code:
var geoloccontrol = new klokantech.GeolocationControl(map, mapMaxZoom);
after including in the HTML header this JavaScript:
<script src="https://cdn.klokantech.com/maptilerlayer/v1/index.js"></script>
See:
http://www.maptiler.com/maptilerlayer/
for an example code and documentation.
It adds the standard control to the map - and once tapped - it shows the blue circle around your location with size derived from precision of the location data available. If you don't drag the map it will keep you positioned once you move.
This control has been developed for viewer automatically generated by http://www.maptiler.com/ software - which creates tiles for map overlays and custom layers made from images and raster geodata.
you have to do it by your own. Here is a piece of code to add "Your Location" button.
HTML
<div id="map">Map will be here</div>
CSS
#map {width:100%;height: 400px;}
JS
var map;
var faisalabad = {lat:31.4181, lng:73.0776};
function addYourLocationButton(map, marker)
{
var controlDiv = document.createElement('div');
var firstChild = document.createElement('button');
firstChild.style.backgroundColor = '#fff';
firstChild.style.border = 'none';
firstChild.style.outline = 'none';
firstChild.style.width = '28px';
firstChild.style.height = '28px';
firstChild.style.borderRadius = '2px';
firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)';
firstChild.style.cursor = 'pointer';
firstChild.style.marginRight = '10px';
firstChild.style.padding = '0px';
firstChild.title = 'Your Location';
controlDiv.appendChild(firstChild);
var secondChild = document.createElement('div');
secondChild.style.margin = '5px';
secondChild.style.width = '18px';
secondChild.style.height = '18px';
secondChild.style.backgroundImage = 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-1x.png)';
secondChild.style.backgroundSize = '180px 18px';
secondChild.style.backgroundPosition = '0px 0px';
secondChild.style.backgroundRepeat = 'no-repeat';
secondChild.id = 'you_location_img';
firstChild.appendChild(secondChild);
google.maps.event.addListener(map, 'dragend', function() {
$('#you_location_img').css('background-position', '0px 0px');
});
firstChild.addEventListener('click', function() {
var imgX = '0';
var animationInterval = setInterval(function(){
if(imgX == '-18') imgX = '0';
else imgX = '-18';
$('#you_location_img').css('background-position', imgX+'px 0px');
}, 500);
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
marker.setPosition(latlng);
map.setCenter(latlng);
clearInterval(animationInterval);
$('#you_location_img').css('background-position', '-144px 0px');
});
}
else{
clearInterval(animationInterval);
$('#you_location_img').css('background-position', '0px 0px');
}
});
controlDiv.index = 1;
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(controlDiv);
}
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: faisalabad
});
var myMarker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: faisalabad
});
addYourLocationButton(map, myMarker);
}
$(document).ready(function(e) {
initMap();
});
//copy and paste this in your script section.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
alert('location not supported');
}
//callbacks
function error(msg) {
alert('error in geolocation');
}
function success(position) {
var lats = position.coords.latitude;
var lngs = position.coords.longitude;
alert(lats);
alert(lngs)
};