I'm trying to place multiple markers on a map. For this, I followed this procedure
https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete?csw=1
Demo
But here, once user starts typing for another marker, then first marker is getting replaced by the second marker. For this, I initialized the marker inside autocomplete function so that it creates another marker as user enters second one. This worked fine. Another marker is getting pinned. But onclicking the marker, it will not produce infowindow since the infowindow is inside autocomplete function.
I need infowindow for all markers.
<script>
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-33.8688, 151.2195),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var input = /** #type {HTMLInputElement} */(document.getElementById('searchTextField'));
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var marker = new google.maps.Marker({
map: map
});
infowindow.close();
marker.setVisible(false);
input.className = '';
var place = autocomplete.getPlace();
if (!place.geometry) {
// Inform the user that the place was not found and return.
input.className = 'notfound';
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
marker.setIcon(/** #type {google.maps.Icon} */({
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(35, 35),
}));
if (address.length != 0) {
address = place.name + ', ' + address;
} else {
address = place.name;
}
marker.setPosition(place.geometry.location);
marker.setTitle(address);
marker.setVisible(true);
infowindow.setContent('<div><strong>' + marker.title + '</strong><br>');
infowindow.open(map, marker);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Here infowindow will not work since there is no action listener for this. so I wrote the below code.
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
But it wont work as marker is out of scope variable here. How to do this? Please help
Use a createMarker function to hold function closure on the infowindow content.
<script type="text/javascript">
var map = null;
var infowindow = new google.maps.InfoWindow();
function createMarker(place) {
var marker = new google.maps.Marker({
map: map
});
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
marker.setIcon(/** #type {google.maps.Icon} */({
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(35, 35),
}));
if (address.length != 0) {
address = place.name + ', ' + address;
} else {
address = place.name;
}
marker.setPosition(place.geometry.location);
marker.setTitle(address);
marker.setVisible(true);
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent('<div><strong>' + marker.title + '</strong><br>');
infowindow.open(map, marker);
});
google.maps.event.trigger(marker, 'click');
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-33.8688, 151.2195),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var input = /** #type {HTMLInputElement} */(document.getElementById('searchTextField'));
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindow.close();
input.className = '';
var place = autocomplete.getPlace();
if (!place.geometry) {
// Inform the user that the place was not found and return.
input.className = 'notfound';
return;
}
createMarker(place);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
working example
Related
I have tried implementing a marker cluster into my code from the Google Developers Documentation but no joy so far. https://developers.google.com/maps/documentation/javascript/marker-clustering
Here is the snippet of code from my .JS file paying attention to the function showAllCustomers(allData) where I want to implement the Marker Clusterer:
var map;
var geocoder;
//Code to load the map with center point of Monterey MA
function initMap() {
var monterey = {lat: 42.181613, lng: -73.215013};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: monterey,
mapTypeId: google.maps.MapTypeId.HYBRID,
labels: true,
});
//collect customer data and geocoder object - declare geocoder as global
var cusdata = JSON.parse(document.getElementById('data').innerHTML);
geocoder = new google.maps.Geocoder();
codeAddress(cusdata);
var allData = JSON.parse(document.getElementById('allData').innerHTML);
showAllCustomers(allData)
var searchData = JSON.parse(document.getElementById('searchData').innerHTML);
showSearchedCustomer(searchData)
}
function showAllCustomers(allData) {
//declare info window variable outside of loop to allow to clear when selecting other markers
var infoWind = new google.maps.InfoWindow;
Array.prototype.forEach.call(allData, function(data){
var content = document.createElement('div');
var strong = document.createElement('strong');
strong.textContent = [data.lastName + ' ' + data.physicalAddress];
content.appendChild(strong);
//add image to infowindow - you are also able to add image path to mysql and then append dynamically
var img = document.createElement('img');
img.src = 'images/santahat.png';
img.style.width = '50px';
content.appendChild(img);
//Create markers for customer locations and customize
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.latitude, data.longitude),
map: map,
icon: iconBase + 'homegardenbusiness.png'
});
// Add event listener to open info window and show customer name
marker.addListener('mouseover', function(){
infoWind.setContent(content);
infoWind.open(map, marker);
//add event listener to zoom in to clicked customer
google.maps.event.addListener(marker, 'click', function() {
map.panTo(this.getPosition());
map.setZoom(20);
});
});
})
}
Here is my attempt to add the MarkerClusterer (code same as previous up to this point):
//Create markers for customer locations and customize
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.latitude, data.longitude),
map: map,
icon: iconBase + 'homegardenbusiness.png'
});
//create marker clusterer to group data
var markerCluster = new MarkerClusterer(map, [], {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
// Add event listener to open info window and show customer name
marker.addListener('mouseover', function(){
infoWind.setContent(content);
infoWind.open(map, marker);
//add event listener to zoom in to clicked customer
google.maps.event.addListener(marker, 'click', function() {
map.panTo(this.getPosition());
map.setZoom(20);
});
});
markerCluster.addMarker(marker);
})
}
Functioning JS file:
var map;
var geocoder;
//Code to load the map with center point of Monterey MA
function initMap() {
var monterey = {lat: 42.181613, lng: -73.215013};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: monterey,
mapTypeId: google.maps.MapTypeId.HYBRID,
labels: true,
});
//collect customer data and geocoder object - declare geocoder as global
var cusdata = JSON.parse(document.getElementById('data').innerHTML);
geocoder = new google.maps.Geocoder();
codeAddress(cusdata);
var allData = JSON.parse(document.getElementById('allData').innerHTML);
showAllCustomers(allData);
var searchData = JSON.parse(document.getElementById('searchData').innerHTML);
showSearchedCustomer(searchData)
}
function showAllCustomers(allData) {
//declare info window variable outside of loop to allow to clear when selecting other markers
var infoWind = new google.maps.InfoWindow;
//Create marker clusterer to group data
var markerCluster = new MarkerClusterer(map, [], {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
Array.prototype.forEach.call(allData, function(data){
var content = document.createElement('div');
var strong = document.createElement('strong');
strong.textContent = [data.lastName + ' ' + data.physicalAddress];
content.appendChild(strong);
//add image to infowindow - you are also able to add image path to mysql and then append dynamically
var img = document.createElement('img');
img.src = 'images/santahat.png';
img.style.width = '50px';
content.appendChild(img);
//Create markers for customer locations and customize
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.latitude, data.longitude),
map: map,
icon: iconBase + 'homegardenbusiness.png'
});
markerCluster.addMarker(marker);
// Add event listener to open info window and show customer name
marker.addListener('mouseover', function(){
infoWind.setContent(content);
infoWind.open(map, marker);
//add event listener to zoom in to clicked customer
google.maps.event.addListener(marker, 'click', function() {
map.panTo(this.getPosition());
map.setZoom(20);
});
});
})
}
//google maps geocoding code for address to collect lat lng from customer addresses
function codeAddress(cusdata) {
Array.prototype.forEach.call(cusdata, function(data){
var address = data.lastName + ' ' + data.physicalAddress;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == 'OK') {
map.setCenter(results[0].geometry.location);
//create object that collects the lat and lng data and pass function to update customers lat lng
var points = {};
points.id = data.id;
points.latitude = map.getCenter().lat();
points.longitude = map.getCenter().lng();
updateCustomersWithLatLng(points);
//add code to check the result status from geocode request and if we get an OVER_QUERY_LIMIT error we try again after slight delay // Jay 20201208-1015
} else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(function() {
codeAddress(cusdata);
}, 100);
} // else {
// alert("Geocode was not successful for the following reason:"
// + status);
// }
});
});
}
//create update customers function that updates db using ajax call
function updateCustomersWithLatLng(points) {
$.ajax({
url:"action.php",
method:"post",
data: points,
success: function(res) {
console.log(res)
}
})
}
//When search customers is clicked create function to zoom in to the searched customer
function showSearchedCustomer(searchData) {
// var searchedCus = { ? };
// map = new google.maps.Map(document.getElementById("map"), {
// zoom: 20,
// center: searchedCus,
// });
//declare info window vairable outside of loop to allow to clear if selecting other markers
var infoWind = new google.maps.InfoWindow;
Array.prototype.forEach.call(searchData, function(data){
var content = document.createElement('div');
var strong = document.createElement('strong');
strong.textContent = [data.lastName + ' ' + data.physicalAddress];
content.appendChild(strong);
//add image to infowindow - you are also able to add image path to mysql and then append dynamically
var img = document.createElement('img');
img.src = 'images/santahat.png';
img.style.width = '50px';
content.appendChild(img);
//Create marker for searched customer location and customize
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.latitude, data.longitude),
map: map,
icon: iconBase + 'homegardenbusiness.png'
});
// Add event listner to open info window and show customer name
marker.addListener('mouseover', function(){
infoWind.setContent(content);
infoWind.open(map, marker);
});
});
}
I am using google map api with contain location function .... i am retrieving latitude longitude from database i am using foreach loop to get result.If marker is within polygon it will stop foreach but problem it is not showing any result. Result come out is from last row query how can i fix it.It is showing me only last row from database .Below is my code
<?php
if(!empty($zone)){
foreach($zone as $findzone)
{
$exploded_data=explode('),',$findzone['zone_latlog']);
$count=count($exploded_data);
?>
<script>
var latitude = document.getElementById('latitude').value;
var longitude = document.getElementById('longitude').value;
var map;
var coord1 = new google.maps.LatLng(latitude, longitude);
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(33.714760, 73.083160),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var bermudaTriangle = new google.maps.Polygon({
map: map,
paths: [
<?php
for($i=0;$i<$count;$i++){
echo "new google.maps.LatLng".$exploded_data[$i]."),";
}
?>
]
});
var bounds = new google.maps.LatLngBounds();
for (var i=0; i<bermudaTriangle.getPath().getLength(); i++) {
bounds.extend(bermudaTriangle.getPath().getAt(i));
}
bounds.extend(coord1);
var marker1 = new google.maps.Marker({
map: map,
position: coord1
});
map.setCenter(bounds.getCenter());
map.setZoom(11);
checkInPolygon(marker1, bermudaTriangle);
}
google.maps.event.addDomListener(window, "load", initialize);
function checkInPolygon(marker, polygon) {
var infowindow = new google.maps.InfoWindow();
var html = "";
if (google.maps.geometry.poly.containsLocation(marker.getPosition(), polygon)) {
html = "inside polygon";
} else {
html = "outside polygon";
}
infowindow.setContent(html);
infowindow.open(map, marker);
}
</script>
<?php
}}?>
How to fix that problem that show me only only that polygon that has my latitude longitude marker
I have set of markers in my google map. And at the right side of my map I have list of places marked in the map. Now upon clicking the places the color of the pin/marker should be changed. For this I thought I would delete the marker with latitude and longitude(which I will get on clicking the places link) and place a new marker with new image. But I dont know how to delete a marker with latitude and longitude or by place. Please help.
<script type='text/javascript'>
$(document).ready(function() {
var map = null;
var infowindow = new google.maps.InfoWindow();
function createMarker(place) {
var marker = new google.maps.Marker({
map: map
});
var address = place.formatted_address;
marker.setPosition(place.geometry.location);
marker.setTitle(address);
marker.setVisible(true);
address = address + 'B <a class="link" href="#" title="Want to go" alt="' + address + '">W</a> <a class="link" href="#" alt="' + address + '" title="Favourite">F</a>';
$('#trip_location').append(address);
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent('<div><strong>' + marker.title + '</strong><br>');
infowindow.open(map, marker);
});
google.maps.event.trigger(marker, 'click');
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-33.8688, 151.2195),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
var input = /** #type {HTMLInputElement} */(document.getElementById('searchTextField'));
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindow.close();
input.className = '';
var place = autocomplete.getPlace();
if (!place.geometry) {
// Inform the user that the place was not found and return.
input.className = 'notfound';
return;
}
var location = place.geometry.location;
var address = place.formatted_address;
createMarker(place);
});
}
$('#trip_location').on('click', '.link', function(e) {
e.preventDefault();
var location = $(this).attr('alt');
});
$('.clear').click(function() {
$('#searchTextField').val('');
});
google.maps.event.addDomListener(window, 'load', initialize);
});
I will be adding multiple markers to google map through google's autocomplete. And the places of the markers will be listed on the right side of the page. When the user clicks the places, it should replace the marker icon.
Instead of deleting and replacing, you could keep a reference to each marker that is associated with a place and just call setIcon on it passing the new setting. See documentation: https://developers.google.com/maps/documentation/javascript/reference#Marker
EDIT: New code in question.
Added markers array to contain the markers, used data attribute to hold marker id, pull markerid attribute value when link element click event is fired.
NOTE: Not tested, so it may be buggy.
$(document).ready(function() {
var map = null;
var markers = [];
var infowindow = new google.maps.InfoWindow();
function createMarker(place) {
var marker = new google.maps.Marker({
map: map
});
var address = place.formatted_address;
marker.setPosition(place.geometry.location);
marker.setTitle(address);
marker.setVisible(true);
markers.push(marker);
address = address + 'W <a class="link" href="#" alt="' + address + '" title="Favourite" data-markerid='" + (markers.length - 1) + "'>F</a>';
$('#trip_location').append(address);
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent('<div><strong>' + marker.title + '</strong><br>');
infowindow.open(map, marker);
});
google.maps.event.trigger(marker, 'click');
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-33.8688, 151.2195),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
var input = /** #type {HTMLInputElement} */(document.getElementById('searchTextField'));
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindow.close();
input.className = '';
var place = autocomplete.getPlace();
if (!place.geometry) {
// Inform the user that the place was not found and return.
input.className = 'notfound';
return;
}
var location = place.geometry.location;
var address = place.formatted_address;
createMarker(place);
});
}
$('#trip_location').on('click', '.link', function(e) {
e.preventDefault();
var location = $(this).attr('alt');
var markerid = $(this).data('markerid');
var marker = markers[markerid];
});
$('.clear').click(function() {
$('#searchTextField').val('');
});
google.maps.event.addDomListener(window, 'load', initialize);
});
I want to show a polyline with markers and window-info from array point (from a ajax page)
This is index Page codes:
var gmarkers = [];
var map = null;
function initialize() {
var myOptions = {
zoom: 15,
center: new google.maps.LatLng(27.332702, 53.177137),
// mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
}
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
function myclick(i) {
google.maps.event.trigger(gmarkers[i], "click");
}
function createMarker(latlng, name, html) {
var contentString = html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
// save the info we need to use later for the side_bar
gmarkers.push(marker);
}
My Ajax Page:
var polylines = [];
var beaches = [
['Bondi Beach',10,15, 4],
['Coogee Beach',11,16, 5],
['Cronulla Beach',13,15, 3],
['Manly Beach',13,17, 2],
['Maroubra Beach',12,10, 1]
];
for (var i = 0; i < beaches.length; i++) {
var beach = beaches[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var polylines = new google.maps.LatLng(beach[1], beach[2]);
var marker = createMarker(myLatLng,"This place",beach[0])
}
var routes = new google.maps.Polyline({
path: polylines,
strokeColor: "#FF0000",
strokeOpacity: 0.6,
strokeWeight: 4
});
routes.setMap(map);
After I call the Ajax Page , markers add with window-info , but route polyline don't show , where is the problem ?
After I call the Ajax Page , markers add with window-info , but route polyline don't show , where is the problem ?
Yes. polylines is an array here:
var polylines = [];
Here you overwrite it with a single google.maps.LatLng:
var polylines = new google.maps.LatLng(beach[1], beach[2]);
You probably want to do this instead:
polylines.push(new google.maps.LatLng(beach[1], beach[2]));
I am trying to pass dynamic data from mysql then creating multiple markers on google.
Here is my html code.
<div ng-app="mapsApp" ng-controller="MapCtrl">
<div class="map">
<div id="map" style="width: 100%;height:738px;"></div>
</div>
</div>
Here is the angularjs Script.
//Angular App Module and Controller
var investup = angular.module('mapsApp', [])
investup.controller('MapCtrl', function ($scope, $compile) {
var cities = [
{
title: 'xyz',
city : '<img src="images/xxx.jpg" />',
lat : 12.2917925,
long : 76.6704174
},
{
title: 'Add to Cart',
city : '<button class="org-btn" ng-click="cartone()" style="display:block;font-size:12px;margin:0 auto 0 auto;">Add to Cart</button>',
lat : 12.2725645,
long : 76.6705986
},
];
//Define your locations: HTML content for the info window, latitude, longitude
var popup = [
['<img src="images/xyz.jpg" />'],
['<img src="images/xyz.jpg"/>'],
];
// Setup the different icons and shadows
var iconURLPrefix = 'http://maps.google.com/mapfiles/ms/icons/';
var icons = [iconURLPrefix + 'red-dot.png', iconURLPrefix + 'purple-dot.png']
var iconsLength = icons.length;
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(12.2982778, 76.6903664),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false,
panControl: false,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
}
}
$scope.popup = popup;
$scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
var activeInfoWindow;
var activeInfoWindow2;
var iconCounter = 0;
$scope.markers = [];
for (i = 0; i < cities.length; i++) {
var createMarker = function (info) {
var marker = new google.maps.Marker({map: $scope.map,icon: icons[iconCounter],position: new google.maps.LatLng(info.lat, info.long),popup: popup[i][0]});
google.maps.event.addListener(marker, 'click', function() {
if(activeInfoWindow2 != null)
activeInfoWindow2.close();
var contentString = "<div><h2>" + info.city + "</h2></div>";
var compiled = $compile(contentString)($scope);
var infoWindow = new google.maps.InfoWindow({ content: compiled[0] });
infoWindow.open($scope.map, marker);
activeInfoWindow = infoWindow;
});
google.maps.event.addListener(marker, 'mouseover', function() {
var contentString = "<div><h2>" + marker.popup + "</h2></div>";
var compiled = $compile(contentString)($scope);
var infoWindow = new google.maps.InfoWindow({ content: compiled[0] });
infoWindow.open($scope.map, marker);
activeInfoWindow2 = infoWindow;
if(activeInfoWindow != null)
activeInfoWindow.close();
});
google.maps.event.addListener(marker, 'mouseout', function() {
if(activeInfoWindow2 != null)
activeInfoWindow2.close();
});
$scope.markers.push(marker);
}
createMarker(cities[i]);
iconCounter++;
}
$scope.openInfoWindow = function(e, selectedMarker) {
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
});
Here is the screenshot of the result
This is the static code when i'm placing php code in cities and popup section to not showing the result.
Problem is when i don't how to call php code in angularJS. Kindly help me.
Thanks in advance.
1- You probably would need to use a framework to handle JSON serialization for you.
For the sake of simplicity you can use this library (https://github.com/mevdschee/php-crud-api), and copy api.php to the server root directory.
2- Using $http:
investup.controller('MapCtrl', function($scope, $compile, $http) {
$http.get('/api.php/cities').success(function(response) {
var cities = response.cities;
// the rest of controller function body
}).catch(handleError);
})