I'm able to implement multiple markers by using the following code:
<?php foreach($dummy as $cid=>$data)
{ ?>
var myLatlng = new google.maps.LatLng(<?php echo $data['lat']; ?>,<?php echo $data['lon']; ?>);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: "<?php echo $data['name']; ?>"
});
icons[j] = marker;
maps[0] = map;
j++;
<?php
}
?>
for(var i = 0; i < icons.length; i++)
{
google.maps.event.addListener(icons[i], 'click', function(){
markerClick(icons[i], maps[0]); // this is the problem area
// markerClick(icons[0], maps[0]); // this works
// markerClick(icons[1], maps[0]); // so does this
});
}
function markerClick(marker_argument, map){
console.log(marker_argument);
}
The issue is with the google.maps.event.addListener function. If I use the variable i, then markerClick()'s console.log() returns undefined. However if I use a hardcoded value (1, 2, or 3), console.log() returns the marker object.
What baffles me is why the argument is not being passed if I use the loop variable i, but works if I hardcode a value. What am I missing here?
Wrap the .addListener loop in a JavaScript closure, and it should work!
Related
I just placed a google map on my website following the instructions from google maps API: https://developers.google.com/maps/documentation/javascript/adding-a-google-map
Copying that example works perfectly but I would like to get the position of the marker depending on a custom field created in each post from WordPress
<div id="map"></div>
<?php $lati = get_field( "gmapslat" ); ?>
<?php $lat = get_field( "gmapslng" ); ?>
<script>
function initMap() {
var lat = '<?php echo $lat; ?>';
var lng = '<?php echo $lng; ?>';
var uluru = {lat: lat, lng: lng};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: uluru
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
}
</script>
<script async defer
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDPGx6I2w6hzEmQNR2IrRKlFC9oUT-COvs&callback=initMap">
</script>
</div>
When do that the map just shows grey.
It seems there's a problem with your PHP variables. This PHP Variable $lng is not declared. So you are setting an undeclared PHP variable in Javascript variable lng.
I also noticed these lines:
<?php $lati = get_field( "gmapslat" ); ?>
<?php $lat = get_field( "gmapslng" ); ?>
Is this variable $lat value a longitude? If so, use $lng instead. Using meaningful names for variables would be helpful. Variable names must define the exact explanation of its content, regardless of programming language. Checking this blog 15 Best Practices of Variable & Method Naming might help.
Important: Use parseFloat() on each javascript variable width coordinates to return a floating point number. Else, it won't work and you'll just see a grey map. To learn more about definition and usage of parseFloat(), you can check JavaScript parseFloat() Function.
Below is a sample code using "-25.363, 131.044" as a sample coordinates returned by your PHP get_field() function:
<div id="map"></div>
<?php
function get_field($args) {
switch ($args) {
case 'gmapslat':
return '-25.363';
break;
case 'gmapslng':
return '131.044';
break;
}
}
$lat = get_field('gmapslat');
$lng = get_field('gmapslng');
?>
<script>
function initMap() {
var lat = parseFloat("<?php echo $lat; ?>");
var lng = parseFloat("<?php echo $lng; ?>");
var myLatLng = {lat: lat , lng: lng};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
Hope it could help and happy coding!
i have try to fetch lat and long value from mysql db and pass those value on google map for show location marker on map
but currently i have fetch only last rows data so indicate marker only one place
how to display all location on map??
<?php
include "config.php";
$result="select * from ds_duty_history";
$a=mysqli_query($conn,$result);
// $count_row = mysqli_num_rows($a);
while ($b = mysqli_fetch_array($a)) {
$long_d=$b['lng'];
$lat_d=$b['lat'];
$result = array(array('latitude'=>$lat_d,'longitude'=>$long_d));
}
?>
<!doctype html>
<html>
<head>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOURKEY&callback=initMap">
</script>
<script type="text/javascript">
var map;
function initialize() {
// Set static latitude, longitude value
var latlng = new google.maps.LatLng(<?php echo $lat_d; ?>, <?php echo $long_d; ?>);
// Set map options
var myOptions = {
zoom: 16,
center: latlng,
panControl: true,
zoomControl: true,
scaleControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
// Create map object with options
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
<?php
// uncomment the 2 lines below to get real data from the db
// $result = mysql_query("SELECT * FROM parkings");
// while ($row = mysql_fetch_array($result))
foreach($result as $row){ // <- remove this line
echo "addMarker(new google.maps.LatLng(".$row['latitude'].", ".$row['longitude']."), map);";}
?>
}
function addMarker(latLng, map) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: true, // enables drag & drop
animation: google.maps.Animation.DROP
});
return marker;
}
</script>
</head>
<body onload="initialize()">
<div style="float:left; position:relative; width:550px; border:0px #000 solid;">
<div id="map_canvas" style="width:550px;height:400px;border:solid black 1px;"></div>
</div>
</body>
</html>
currently display only one marker i.e last fetch record lat and long assign on map
how to display all place on map using mysql lat,long value?
The main problem you have here is that you're not actually collecting different results in your $result variable but overwrite it with the most recent one. The also seems to be some abuse of the variable $result which might be contributing to your confusion. Let's say we declare a new array and call it $rows. Then we can collect all the rows with the following code (to substitute your first snippet):
<?php
include "config.php";
$sql = "SELECT * FROM ds_duty_history";
$result = mysqli_query($conn, $sql);
$rows = [];
while ($row = mysqli_fetch_array($result)) {
$lon_d = $row['lng'];
$lat_d = $row['lat'];
// Use short-cut append syntax here so we add row and don't overwrite $rows
$rows[] = ['latitude' => $lat_d, 'longitude' => $long_d];
}
?>
Now in your display code (the second snippet) you would be able to iterate over $rows pretty much like:
foreach ($rows as $row){
// Do work with each $row here
}
Just as an aside, try to get used to using variable names that are as meaningful as possible and use new variables as much as you can. Trying to use short, generic variable names like $a will always lead to confusion since you won't know what it represents unless you find where you declared it every time. Trying to re-use a variable (like you did with $result) can make your life much more difficult since now even if you find an assignment to the variable, it is assigned many different times and (the way you used it) represents completely different types each time. Doing this one thing makes it just a little easier to get the hang of programming since at the very least you'll be able to read and make sense of your own intent when reading your own code.
Please try this code for display multiple marker on map
<script type="text/javascript">
var LocationData = <?php echo json_encode($result); ?>;
function initialize()
{
var myOptions = {zoom:12,mapTypeId: google.maps.MapTypeId.ROAD};
var map =
new google.maps.Map(document.getElementById('map-canvas'), myOptions);
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow();
for (var i in LocationData)
{
var p = LocationData[i];
var latlng = new google.maps.LatLng(p[0], p[1]);
bounds.extend(latlng);
var icon = { url: '<?php echo base_url();?>assets/frontend/assets/images/location_pin1.png', // url
scaledSize: new google.maps.Size(40, 70), // scaled size
origin: new google.maps.Point(0,0), // origin
anchor: new google.maps.Point(0, 0) // anchor
};
var marker = new google.maps.Marker({
position: latlng,
map: map,
draggable: true, // enables drag & drop
animation: google.maps.Animation.DROP
icon: icon
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = this.url;
});
}
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
I've had a look around SO and found some situations similar to mine but haven't found a solution.
I'm learning PHP, Javascript as I go along so the code may be a little off but here goes:
I have a Google map with a postcode search function working - The postcode and Lat/Long are stored in a Mysql DB. What I need now is a function to place any amount of markers on the map for specific postcodes - in time I hope to expand the function to allow something like postcode+10 miles, etc depending on the zoom level. The code below will bring back the lat/long for the markers but it sticks a "," at the end of each results and therefore when I pass it into the javascript, it's an invalid parameter - please be sure that I know that the way I'm doing all of this is in-efficient - I'm learning as I go along :)
PHP function:
// get markers Function
if(!function_exists("getMarkers"))
{
//Get Markers Function
function getMarkers()
{
//prep the query
include ('../../secure/db_conn.php');
$currentPcode = searchPostcode($_POST['postcode']);
$tsearch = $con->prepare("SELECT t.CompanyName, p.lat, p.lng FROM Traders t, cpo_data p WHERE t.Postcode LIKE p.Postcode");
$tsearch->bindParam(1,$currentPcode, PDO::PARAM_STR);
$tsearch->execute();
$tresults = $tsearch->fetchAll(PDO::FETCH_ASSOC);
foreach ($tresults as $row)
{
$Company = $row['CompanyName'];
$Tlat = (string)$row['p.lat'];
$Tlng = (string)$row['p.lng'];
}
echo $Tlat .", " .$Tlng;
}
}
Javascript:
<script src="http://maps.googleapis.com/maps/api/js?sensor=false">
</script>
<script>
//postcode function call
var myCenter=new google.maps.LatLng(<?php echo searchPostcode($_POST['postcode']); ?>);
//markers function call
var locations=new google.maps.LatLng(<?php echo getMarkers(); ?>);
function initialize()
{
var mapProp = {
center:myCenter,
zoom:14,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
var mymap=new google.maps.Map(document.getElementById("googleMap"),mapProp);
// To add the marker to the map, use the 'map' property
var marker, i;
for (i = 0; i < locations.length; i++)
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i]),
map: mymap
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i]);
infowindow.open(mymap, marker);
}
})(marker, i));
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Any help or advice will be greatly appreciated - my current knowledge is only PHP and Javascript (and as mentioned previously, it's beginners knowledge).
Forgot to add, When I use google developer tools in Chrome to analyse the page, I can see the following which confirms it is picking up the lat/long, but with a comma at the end (I think it's to do with it being an array but not sure how I deal with it):
var locations=new google.maps.LatLng(53.51139969260000, -2.54091408438000, );
If you want to place the markers fetched from the database you have two problems:
PHP Code
You echo only the last pair of lat/lng fetched:
foreach ($tresults as $row)
{
$Company = $row['CompanyName'];
$Tlat = (string)$row['p.lat'];
$Tlng = (string)$row['p.lng'];
}
echo $Tlat .", " .$Tlng;
A solution would be:
$locations = array();
foreach ($tresults as $row)
{
$Company = $row['CompanyName'];
$Tlat = (string)$row['p.lat'];
$Tlng = (string)$row['p.lng'];
$locations[] = "[" . $Tlat .", " .$Tlng . "]";
}
echo srpintf("[%s]", implode(", ", $locations);
Then in your javascript code you store an array of coordinates in locations.
Javascript code
Now in your javascript code:
var locations = <?php getMarkers(); ?>
You have now in locations the array like this:
[[53.51139969260000, -2.54091408438000], [...], ...]
Then in the loop you should access to coordinates as an array:
var marker, i;
for (i = 0; i < locations.length; i++)
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][0], locations[i][1]),
map: mymap
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0] + ", " + locations[i][1]);
infowindow.open(mymap, marker);
}
})(marker, i));
}
}
I have a map that loads and displays (correctly) a bunch of markers. The amount of markers are unlimited, so they are created before the map is initialized by running a bit of PHP in the javascript (the markers come from a database).
I want to know, if it is possible to change the marker from a simple dot, to something else when a certain zoom level is reached?
Here is some code:
<script>
var <?php echo $clinic_string; ?>; //string with marker names
var map;
function initialize() {
var kzn = new google.maps.LatLng(-28.459033,30.217037);
var mapOptions = {
zoom: 7,
center: kzn,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
<?php foreach($jsdata as $data) : ?>
marker_<?php echo $data['id'];?> = new google.maps.Marker({
position: new google.maps.LatLng(<?php echo $data['location'];?>),
map: map,
icon: 'images/reddot.gif'
});
<?php endforeach; ?>
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Let's say my zoom level reaches level 15, it needs to change the icon to images/clinic.gif.
Is this possible? And if so, how can I achieve this?
Not too hard. You need an event listener for the map object's zoom_changed event. And you can change the markers icons using the marker's setIcon function. Something like:
<?php foreach($jsdata as $data) : ?>
marker_<?php echo $data['id'];?> = new google.maps.Marker({
position: new google.maps.LatLng(<?php echo $data['location'];?>),
map: map,
icon: 'images/reddot.gif'
});
map.addListener('zoom_changed', function() {
if (map.getZoom() >= 15) {
marker_<?php echo $data['id'];?>.setIcon('images/clinic.gif');
} else { // assuming you want to change it back if they zoom back out
marker_<?php echo $data['id'];?>.setIcon('images/reddot.gif');
}
});
<?php endforeach; ?>
In fact rather than have X number of 'zoom_changed' event listeners, I think I'd rather have one array for all my markers. Then just have one event listener function, which loops over all those markers.
markers = [];
<?php foreach($jsdata as $data) : ?>
marker_<?php echo $data['id'];?> = new google.maps.Marker({
position: new google.maps.LatLng(<?php echo $data['location'];?>),
map: map,
icon: 'images/reddot.gif'
});
markers.push(marker_<?php echo $data['id'];?>);
<?php endforeach; ?>
map.addListener('zoom_changed', function() {
var image;
if (map.getZoom() >= 15) {
image = 'images/clinic.gif';
else { // assuming you want to change it back if they zoom back out
image = 'images/reddot.gif';
}
for (var i = 0; i < markers.length; i++) {
markers[i].setIcon(image);
}
});
The current code retrieves all info, displays all markers on a map and if a marker is clicked, infowindow renders showing its content. What i want to do is that i want to implement directions in this. How can i add directions in my code so that it will also add directions? This is what i want to implement:
what to implement :
var request = {
origin: start,//it will be my first row(lat and lon)
destination: end,//it will be my lastrow(lat and lon)
waypoints: waypts, // it will be all lat and lon between first and last
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status){
if (status == google.maps.DirectionsStatus.OK){
directionsDisplay.setDirections(response);
}
});
My current code in which i want to implement the above functionality mean google maps directions:
already implemented :
$("#directions").click(function(){
var lat_from_ip = $("#hidden_lat").val();
var lon_from_ip = $("#hidden_lon").val();
var latlng = new google.maps.LatLng(lat_from_ip, lon_from_ip);
var options = {zoom: 4, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP};
var map = new google.maps.Map(document.getElementById('map'), options);
$.ajax({type: "GET",
dataType: 'json',
url: url +'//abc/my_page.php',
success: function(response){
var total=response.length;
var data_array,name,type,address,lat,lon,infowindow;
var infowindow = new google.maps.InfoWindow();
for(var i=0; i < total; i++)
{
data_array=response[i];
name=data_array['name'];
address=data_array['address'];
notes=data_array['notes'];
lat=data_array['lat'];
lon=data_array['lon'];
var propPos = new google.maps.LatLng(lat,lon);
propMarker = new google.maps.Marker({
position: propPos,
map: map,
icon: icon,
zIndex: 3});
var contentString = "<div>"+name+"<br/><label class='label'>Location :</label> "+address+"<br/><label class='label'>Notes :</label> "+notes + "</div>";
function bindInfoWindow(marker, map, infowindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
}
bindInfoWindow(propMarker, map, infowindow, contentString);
} //end of for loop
} //end of for success
}); //end of for $.ajax
return;
});
Function to draw directions, call it whenever you want to show directions. You can pass some variables to it, and use them inside, to decide which markers will be start, end and waypts.
function calcRoute() {
var startpt = yourstartlatlng;
var endpt = yourendlatlng;
var waypts = [] //your waypts array, if there are more than 1 point
var request = {
origin:startpt,
destination:endpt,
waypoints: waypts,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
Example from here: Google Maps Api
EDIT:
When you have an array in php called waypts, and you want to have these values in javascript, you need to pass them to java. Its kinda messy, but thats the only way i know:
<script type="text/javascript">
var waypts = [];
<?php
$waypts= array(1, 2, 3, 4); //<-- your array, can be called like that, or just have values inside already
for($i = 0; $i < sizeof($waypts); $i++){
?>
waypts[<?php echo $i; ?>] = <?php echo $waypts[$i]; ?>; //php is interpreted before java, when site will load, these values will be inside java "waypts" variable.
<?php
}
?>
alert(""+waypts[1]);
</script>
That code will put your php variables/array into java array (alert is just to check if it did the job, you can delete it, once you understand the code). Then you can use these variables however you want. PHP is interpreted earlier than java, so in site code you will get waypts[0] = 1; cuz php code will be already replaced by values from array.
This is how to convert your php array to js array
for instance you have php array
<?php
$my_array = array("a","b","c");
?>
now in js do so
<script>
var jsArray = ["<?php echo join("\", \"", $my_array); ?>"];
alert(jsArray);
and in your domain its like this.
lets say you have php array like this.
$data ;//this is your php array
Array
(
[0] => Array
(
[lat] => 31.453795
[lon] => 74.388497
)
[1] => Array
(
[lat] => 31.454387
[lon] => 74.388541
)
[2] => Array
(
[lat] => 31.453795
[lon] => 74.388497
)
.
.
.
)
in js do so
var waypts = [];
<?php
foreach($data as $key => $value){
if(($key == '0') || ($key == count($data)-1)){
continue;
}?>
waypts.push({location: new google.maps.LatLng(<?php echo $data[$key]['lat'] ?>, <?php echo $data[$key]['lon'] ?>)});
<?php }?>