Google Map Click Event Issue with Kohana PHP - google-maps

So this gets auto generated through the controller and I think I'm just overlooking something but the output is just like this
google.load("maps", "2.x", {"language" : "en"});
function initialize() {
if (GBrowserIsCompatible()) {
// Initialize the GMap
var map = new google.maps.Map2(document.getElementById("map"));
map.addControl(new google.maps.SmallMapControl());
map.setCenter(new google.maps.LatLng(30.226632, -97.935056), 10, G_NORMAL_MAP);
// Build custom marker icons
var tinyIcon = new google.maps.Icon();
tinyIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
tinyIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
tinyIcon.iconSize = new google.maps.Size(12,20);
tinyIcon.shadowSize = new google.maps.Size(22,20);
tinyIcon.iconAnchor = new google.maps.Point(6,20);
tinyIcon.infoWindowAnchor = new google.maps.Point(5,1);
// Show map points
var m1 = new google.maps.Marker(new google.maps.LatLng(35.2602340, -93.7939480), {icon:tinyIcon,bouncy:1});
google.maps.Event.addListener(m1, "click", function()
{
m1.openInfoWindowHtml(
'1<br />test,TX'
);
});
map.addOverlay(m1);
var m2 = new google.maps.Marker(new google.maps.LatLng(35.2810510, -93.8246510), {icon:tinyIcon,bouncy:1});
google.maps.Event.addListener(m2, "click", function()
{
m2.openInfoWindowHtml(
'test<br />test,Texas'
);
});
map.addOverlay(m2);
}
google.setOnLoadCallback(initialize);
So when i go to use a trigger event
google.maps.event.trigger(markers[m3], 'click');
Nothing happens, and I cant figure out the correct trigger to make it do so...

Based on the code sample you posted there is no markers[m3] defined, wouldn't you need to use google.maps.event.trigger(m2, 'click'); ? (m3 isn't defined at all in that code sample)

Related

Google Maps Data Layer, Click on geometry programmatically

I have a google map where I load geometry data to the data layer using geoJSON. I bind to the following event in the data layer.
map.data.addListener('click', function (event) { console.log(event);});
How can I trigger this event manually? I know I can trigger the click event on a marker manually, but it is triggered through google.maps.event.
That should be done with google.maps.event.trigger.
Try this (not sure):
// invoke a click
google.maps.event.trigger(map.data, 'click');
While Emmanuel's answer is technically correct, I would like to expand on it because I struggled for 2-3 hours to get this working.
In my code, I have a predefined click event function which was using feature object.
Here is my click event where I have used feature object:
transLayerData.addListener('click', function (event) {
var lfeature = event.feature;
var html = lfeature.getProperty('popupInfo');
infowindow.setContent(html);
infowindow.setPosition(event.latLng);
infowindow.setOptions({pixelOffset: new google.maps.Size(0,-34)});
infowindow.open(myMap);
});
If you are using a feature object in your predefined data layer click function (like above) , it is important that you pass the feature object and you create an event object with feature object in it.
Here is my code which gets the lat and long out of feature object and creates an event object:
var featureGeometry = feature.getGeometry();
var lsType = featureGeometry.getType();
var isLineData = false;
var lsType = featureGeometry.getType();
if ((lsType == 'LineString') || (lsType == 'MultiLineString') || (lsType == 'LinearRing') || (lsType == 'Polygon') | (lsType == 'MultiPolygon')) {
isLineData = true;
}
var featurePosition;
if (isLineData) {
// will center the map on the first vertex of the first LineString
var tmp = featureGeometry.getAt(0);
featurePosition = featureGeometry.getAt(0);
// following will set line's storke weight to 10
feature.setProperty('strokeWeight', 10);
} else{
featurePosition = featureGeometry.get();
}
myMap.setZoom(10);
myMap.setCenter(featurePosition);
var llat = featurePosition.lat();
var llong = featurePosition.lng();
// Creating event with the feature object is important. Especially if you have your very own feature click method defined
var lEvent = {
stop: null,
latLng: new google.maps.LatLng(llat, llong),
feature: feature,
}
// transLayerData is your data layer object.
// This is how I have defined my translayer object:
// transLayerData = new google.maps.Data({ map: myMap });
if (!isLineData) {
google.maps.event.trigger(transLayerData, 'click', lEvent);
} else {
google.maps.event.trigger(transLayerData, 'mouseover', lEvent);
}
}

How to initialize a google maps on pageinit without repeatingly loading the google map api script

I would like to be able to load the Google.maps API only once for alle my pages.
Then i would like to be able to use geolocation or loading a map into a page anywhere on my web app.
The problem is that I cant figure out to seperate API loading and map initialization.
Which means i need to load the API each time I create a map.
I have referenced most of my code further down in the post but i suppose the following code is the problem.That piece of code takes care of the API Loading but at the same time it takes care of setting the initialize() function as a callback function and calling it.
var script = document.createElement("script");
script.type = "text/javascript";
script.src ="http://maps.googleapis.com/maps/api/js?key=mykey&sensor=false&callback=initialize";
document.body.appendChild(script);
How do i load the api once, lets say in the header, and then create a new map each time I go to specific page. WIthout loading the maps API again. (Note that im using Jquery mobile so my header only gets loaded one time for a session.)
I get this error:
Warning: you have included the Google Maps API multiple times on this page. This may cause unexpected errors.
Ii would like to tell you my setup.
-Im using Google Map APi v3
-I'm loading the API dynamically after the page has loaded.
-I'm using Jquery mobile, which means the page with google maps only gets partially reloaded when you visit it.
-Im using google maps for two things to show the map and for geolocation.
-I'm using the Google map api on several pages.
Im interacting with the map in 3 different places: In a header javascript see code below
A header javascript
A javascript in the body
The DIV in the body that holds the map.
Here is my code for the javascript that handles loading the API, showing the map, markers etc:
<script>
$('.error').hide();
//search criterias
var radius;
var timerange;
var type;
//user position variables
var userposition = false;
var mylatitudedegree = "=55.698";
var mylongitudedegree = "=12.579";
//map variables
var mapready = false;
var map;
var bound;
var markersArray = [];
//array for keeping track of the markers
var markercenter;
//hack
var pageinit = 0;
var initializer = 0;
var triggersearch = 0;
var loadscripts = 0;
var isgooglemapsloaded = false;
$( '#soegsagside' ).live( 'pageinit',function(event)
{
pageinit++;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(setPosition, function(error) {
alert('Din location er ikke tilgængelig! Error code: ' + error.code);
userposition = false;
}, {
maximumAge : 60000,
timeout : 10000,
enableHighAccuracy : true
});
}
else {
alert("Din browser tillader ikke, at vise din lokation!");
userposition = false;
}
loadScript();
$("#search_filter_button").click(function() {
//hide the "skal udfyldes" labels
$('.error').hide();
// validate and process form here
radius = $("select#choose_radius_select").val();
if (radius == "vælg") {
$("label#radius_error").show();
$("select#choose_radius_select").focus();
return false;
}
timerange = $("select#choose_timerange_select").val();
if (timerange == "vælg") {
$("label#timerange_error").show();
$("select#choose_timerange_select").focus();
return false;
}
type = $("select#vælg_type").val();
if (type == "vælg") {
$("label#select_type_error").show();
$("select#vælg_type").focus();
return false;
}
//------------------post to php script ---------------
var dataString = 'radius=' + radius + '&timerange=' + timerange + '&type=' + type + '&mylatitudedegree=' + mylatitudedegree + '&mylongitudedegree=' + mylongitudedegree;
$.ajax({
type : "POST",
url : "soegsagDB.php",
data : dataString,
success : function(data) {
$('#søgeresultater').html(data);
$('#søgeresultater').trigger('create');
clearOverlays();
createtaskmarkers();
findCenterOfMarkers();
if (userposition) {
usergeoposition = new google.maps.LatLng(mylatitudedegree, mylongitudedegree);
map.setCenter(usergeoposition);
createuserposition(usergeoposition);
} else {
map.setCenter(markercenter);
}
expandMapBoundForMarkers()
}
});
//end of post search query to server
return false;
});
//end of click seach button
});
//end of page ready
function setPosition(position) {
userposition = true;
myposition = position.coords;
mylatitudedegree = position.coords.latitude;
mylongitudedegree = position.coords.longitude;
var milli = new Date();
}
//function for clearing the markerArray
function clearOverlays() {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
}
//Function for initializing the map, which is called when the map is created
function initialize() {
initializer++;
bound = new google.maps.LatLngBounds();
var mapOptions = {
zoom : 13,
center : new google.maps.LatLng(55, 12),
mapTypeId : google.maps.MapTypeId.ROADMAP
}
//Create a map
map = new google.maps.Map(document.getElementById("map"), mapOptions);
mapready = true;
$("#search_filter_button").trigger('click');//Trigger click on the search button
triggersearch++;
}
//create user positio marker
function createuserposition(usergeoposition) {
var userPositionMarker = new google.maps.Marker({
position : usergeoposition,
map : map,
title : "Din position",
});
markersArray.push(userPositionMarker);
}
function createtaskmarkers() {
//Create the markers of the tasks
//1. find the task <li> that contain the data and loop through each one
//2. for each task collect the dato into variables and create markers and infowindows
//3. calculate center of point
//4. extendt map area to contain all points
var data = $.map($('li'), function(element) {
if (element.hasAttribute("data-latitude")) {
var tempPos = new google.maps.LatLng($(element).attr('data-latitude'), $(element).attr('data-longitude'));
var link = $(element).attr('data-link');
var title = $(element).attr('data-title');
var type = $(element).attr('data-type');
var date = $(element).attr('data-date');
tempMarker = new google.maps.Marker({
position : tempPos,
map : map,
title : title,
});
tempMarker.setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png')
var tempContentString = '<div style="width: 200px; height: 100px;">' + date + '<br></br>' + '<b>' + type + ' , ' + title + '</b>' + '</div>';
//Create infowindow
var tempInfowindow = new google.maps.InfoWindow({
content : tempContentString
});
//add market to markerArray
markersArray.push(tempMarker);
//Create event with infowindow
google.maps.event.addListener(tempMarker, 'click', function() {
tempInfowindow.open(map, this);
});
}
});
}
function findCenterOfMarkers() {
//calculate center of markers and change mapcenter to that
var sumlatitude = 0;
var sumlongitude = 0;
for ( position = 0; position < markersArray.length; position++) {
sumlatitude += markersArray[position].getPosition().lat();
sumlongitude += markersArray[position].getPosition().lat();
}
avglatitude = sumlatitude / markersArray.length;
avglongitude = sumlongitude / markersArray.length;
markercenter = new google.maps.LatLng(avglatitude, avglongitude);
}
function expandMapBoundForMarkers() {
//Extend bounds for map to fit all markers into map
for (var i in markersArray) {
bound.extend(markersArray[i].getPosition());
}
map.fitBounds(bound);
}
//loads the google maps api with KEY and appends the script to the document body
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyC8wZ6RmFySy0DnWvrUaA-2OJqcM1_AOIc&sensor=false&callback=initialize";
document.body.appendChild(script);
}
</script>
The only thing in the body of the page that has to do with the maps. Is the DIV that the map is loaded into.
<div id="map" style="width: 80%; height: 280px; margin: auto; background-color: gray">Kortet loader, vent venligst.</div> <!--alternative for full screen style="position:absolute;top:30px;bottom:50px;left:0;right:0;"-->
The API is also loaded in a common header script. Because I in general need to load it on other pages.
<script src='http://maps.google.com/maps/api/js?sensor=false'></script>
<script type="text/javascript">
$(document).ready( function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=mynamespace.init_google_maps";
document.body.appendChild(script);
$(document).bind('pageinit', function() {
//do stuff here that happens each time a new page is loaded
});
});
});
</script>
the api is loaded once inside .ready(). you can create a new map in the callback that was passed to .bind() which is called each time a new page loads or is inserted. you can initialize the map inside mynamespace. mynamespace is a .js file included on the page

How can watch my position when I close my App with Phonegap and jquerymobile

I am using phonegap, jquerymobile the googlemap API to get my current position and to watch my position.
For this, when I lunch my map page, my position is shown with a marker and the marker move when I move.
Even if it works excpeted when I close my App (onPause).
Here is my code (you can tell me how I can perfect it :o) )
$('#home').live("pagebeforeshow", function() {
if($('#googleAPI').length != 0){
navigator.geolocation.getCurrentPosition(function(position){
//showMap('mapHome',position.coords.latitude, position.coords.longitude);// Canvas, lat, long
var latLng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
// Google Map options
var myOptions = {
zoom: 17,
//zoomControl : 1,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP////ROADMAP, SATELLITE, HYBRID and TERRAIN
};
// Create the Google Map, set options
Tracking.mapy = new google.maps.Map(document.getElementById('mapHome'), myOptions);
//addMarker(position.coords.latitude,position.coords.longitude);
},
showError,
{
enableHighAccuracy : true,
maximumAge : 2000
//maximumAge:Infinity
});
}
})
$('#home').live("pageshow", function() {
// Place and move the marker regarding to my position and deplacement
if($('#googleAPI').length != 0){
//var track_id = "me";
Tracking.watch_id = navigator.geolocation.watchPosition(
// Success
function(position){
var lat = position.coords.latitude;
var long = position.coords.longitude;
var latLng = new Array();
latLng[0] = lat;
latLng[1] = long;
//Tracking.myCoordinates.push(lat,long);
Tracking.myCoordinates.push(latLng);
addMarker(lat, long);
},
// Error
showError,
{
frequency: 1000
});
console.log('HW : WatchPosition called. Id:' + Tracking.watch_id);
}else{
Alert.show('The map API has not been loaded. Check for connection and try again. (pagebeforeshow)');
}
})
$('#home').live("pagebeforehide", function() {
if($('#googleAPI').length != 0){
//track_id = "me";
// Stop tracking the user
if (Tracking.watch_id != null) {
navigator.geolocation.clearWatch(Tracking.watch_id);
console.log('HW : WatchPosition cancelled Id:' + Tracking.watch_id);
Tracking.watch_id = null;
}
//navigator.geolocation.clearWatch(Tracking.watch_id);
//Tracking.watch_id = null;
Tracking.myCoordinates = new Array();
}else{
Alert.show('The map API has not been loaded. Check for connection and try again. (pagebeforeshide)');
}
});
The problem is when I close my App, because I still need to be alert when I go outside of my geofence. Then, as lomg as I do not stop to watch my position, I need it to be watching even if I close my position or if I lunch another app.
Then I do not know how to do when I called that Phonegap even:
document.addEventListener('pause', onPause, false);
function onPause(){}
Should I simply relunch my watch code with a different watch_id?
Any suggestion?
Many thank and happy new year
I think what you're trying to get at is running a background process using phonegap. The discussion in this link seems to say that it's only possible if you write a plugin to perform that functionality. PhoneGap doesn't have an API to do it out of the box.
Executing javascript in background using phonegap

google map v3 how fitbounds with zoom on user's location

I am using google v3, i want to fitbounds with center on userPinLoc object, i have the following code
var bounds = new google.maps.LatLngBounds();
bounds.extend(userPinLoc)// wants to center on userPinLocation
for (i in nearestEntitiesToZoom) {
entity = nearestEntitiesToZoom[i];
var googleLatLng = new google.maps.LatLng(entity.latitude,entity.longitude);
bounds.extend(googleLatLng);
}
bounds.extend(userPinLoc);
//googleMap.setCenter(userPinLoc) this not working
googleMap.fitBounds(bounds);
any quick fix after update i am pasting new code
function setInitialZoom() {
mapZoom = googleMap.getZoom();
var bounds = new google.maps.LatLngBounds();
bounds.extend(userPinLoc);
for (i in nearestEntitiesToZoom) {
entity = nearestEntitiesToZoom[i];
var googleLatLng = new google.maps.LatLng(entity.latitude,entity.longitude);
bounds.extend(googleLatLng);
}
google.maps.event.addDomListener(googleMap, 'bounds_changed', function() {
googleMap.setCenter(userPinLoc);
});
googleMap.fitBounds(bounds);
setTimeout(function() {
google.maps.event.clearListeners(googleMap, 'bounds_changed');
}, 3000);
}
Remove the setCenter from where it is currently. You need to have an event listener for when the map's bounds change. I think when you call fitBounds, you have to wait for it to redraw before you can adjust the centre. One way would be to use a timeout, but you can simply add this to your initialize function:
google.maps.event.addDomListener(googleMap, 'bounds_changed', updateCenter);
And then create a new function to update the centre, which takes the userPinLoc value (needs to be a global variable):
function updateCenter() {
googleMap.setCenter(userPinLoc);
}

Google Maps v3 OverlayView.getProjection()

I cannot seem to figure out why the object returned by getProjection() is undefined. Here is my code:
// Handles the completion of the rectangle
var ne = recBounds.getNorthEast();
var sw = recBounds.getSouthWest();
$("#map_tools_selat").attr( 'value', sw.lat() );
$("#map_tools_nwlat").attr( 'value', ne.lat() );
$("#map_tools_selng").attr( 'value', ne.lng() );
$("#map_tools_nwlng").attr( 'value', sw.lng() );
// Set Zoom Level
$("#map_tools_zoomlevel").attr( 'value', HAR.map.getZoom()+1 );
document.getElementById("map_tools_centerLat").value = HAR.map.getCenter().lat();
document.getElementById("map_tools_centerLong").value = HAR.map.getCenter().lng();
// All this junk below is for getting pixel coordinates for a lat/lng =/
MyOverlay.prototype = new google.maps.OverlayView();
MyOverlay.prototype.onAdd = function() { }
MyOverlay.prototype.onRemove = function() { }
MyOverlay.prototype.draw = function() { }
function MyOverlay(map) { this.setMap(map); }
var overlay = new MyOverlay(HAR.map);
var projection = overlay.getProjection();
// END - all the junk
var p = projection.fromLatLngToContainerPixel(recBounds.getCenter());
alert(p.x+", "+p.y);
My error is: Cannot call method 'fromLatLngToContainerPixel' of undefined
Actually, i the reason why this happens is because the projection object is created after the map is idle after panning / zooming. So, a better solution is to listen on the idle event of the google.maps.Map object, and get a reference to the projection there:
// Create your map and overlay
var map;
MyOverlay.prototype = new google.maps.OverlayView();
MyOverlay.prototype.onAdd = function() { }
MyOverlay.prototype.onRemove = function() { }
MyOverlay.prototype.draw = function() { }
function MyOverlay(map) { this.setMap(map); }
var overlay = new MyOverlay(map);
var projection;
// Wait for idle map
google.maps.event.addListener(map, 'idle', function() {
// Get projection
projection = overlay.getProjection();
})
I kind of figured out what was going on. Even though it is still not crystal clear why this happens, I know that I had to instantiate the variable "overlay" right after instantiating my google map (HAR.map). So I practically moved that code snippet into my HAR class and now i use:
HAR.canvassOverlay.getProjection().fromLatLngToContainerPixel( recBounds.getCenter() );
So now, every time I create a map via my class "HAR" I also have a parallel OverlayView object within my class.
The Error could have been with losing scope of my class object, but I think it was more of the map event "projection_changed" not being fired. I got a hint from the map API docs for map class, under method getProjection():
"Returns the current Projection. If the map is not yet initialized (i.e. the mapType is still null) then the result is null. Listen to projection_changed and check its value to ensure it is not null."
If you are getting the similar issue, make sure that you assign your overlayView.setMAP( YOUR_MAP_OBJECT ) closely after instantiating the map object.