Google maps call with Ajax, why do I have to click twice? - javascript

I am currently plotting markers on google maps using ajax (Using a modified version of the overlapping spiderfy script (https://github.com/jawj/OverlappingMarkerSpiderfier).
This all works and I then need to load the ajax on the click of my search button. When I click the button once it does not load, a second click however it does. What do I need to alter in this script to get this to work please?
<script>
function loadMapData()
{
var markers = [];
$.ajax({
type: "GET",
url: "maps2.php",
success: function(data)
{
for (var i = 0; i < data.length; i++)
{
markers.push({
lon: data[i].long,
lat: data[i].lat,
h: data[i].city,
d: data[i].post_title
});
}
window.mapData = markers;
}
});
var gm = google.maps;
var map = new gm.Map(document.getElementById('map_canvas'), {
mapTypeId: gm.MapTypeId.TERRAIN,
center: new gm.LatLng(50.806748, -1.079407), zoom: 12, // whatevs: fitBounds will override
scrollwheel: false
});
var iw = new gm.InfoWindow();
var oms = new OverlappingMarkerSpiderfier(map,
{markersWontMove: true, markersWontHide: true});
var usualColor = 'eebb22';
var spiderfiedColor = 'ffee22';
var iconWithColor = function (color) {
return 'http://chart.googleapis.com/chart?chst=d_map_xpin_letter&chld=pin|+|' +
color + '|000000|ffff00';
}
var shadow = new gm.MarkerImage(
'https://www.google.com/intl/en_ALL/mapfiles/shadow50.png',
new gm.Size(37, 34), // size - for sprite clipping
new gm.Point(0, 0), // origin - ditto
new gm.Point(10, 34) // anchor - where to meet map location
);
oms.addListener('click', function (marker) {
iw.setContent(marker.desc);
iw.open(map, marker);
});
oms.addListener('spiderfy', function (markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setIcon(iconWithColor(spiderfiedColor));
markers[i].setShadow(null);
}
iw.close();
});
oms.addListener('unspiderfy', function (markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setIcon(iconWithColor(usualColor));
markers[i].setShadow(shadow);
}
});
var bounds = new gm.LatLngBounds();
for (var i = 0; i < window.mapData.length; i++) {
var datum = window.mapData[i];
var loc = new gm.LatLng(datum.lat, datum.lon);
bounds.extend(loc);
var marker = new gm.Marker({
position: loc,
title: datum.h,
map: map,
icon: iconWithColor(usualColor),
shadow: shadow
});
marker.desc = datum.d;
oms.addMarker(marker);
}
//map.fitBounds(bounds);
// for debugging/exploratory use in console
window.map = map;
window.oms = oms;
}
</script>
<div class="col-md-3"><input type="button" value="Search" class="loadAjaxMap" /></div>
<script>
$( ".loadAjaxMap" ).click(function() {
loadMapData();
});
</script>
<div id="map_canvas"></div>

The XmlHttpRequest is asynchronous. You need to use the data in the callback function when it is available.
function loadMapData()
{
var markers = [];
$.ajax({
type: "GET",
url: "maps2.php",
success: function(data)
{
for (var i = 0; i < data.length; i++)
{
markers.push({
lon: data[i].long,
lat: data[i].lat,
h: data[i].city,
d: data[i].post_title
});
}
window.mapData = markers;
var gm = google.maps;
var map = new gm.Map(document.getElementById('map_canvas'), {
mapTypeId: gm.MapTypeId.TERRAIN,
center: new gm.LatLng(50.806748, -1.079407), zoom: 12, // whatevs: fitBounds will override
scrollwheel: false
});
var iw = new gm.InfoWindow();
var oms = new OverlappingMarkerSpiderfier(map,
{markersWontMove: true, markersWontHide: true});
var usualColor = 'eebb22';
var spiderfiedColor = 'ffee22';
var iconWithColor = function (color) {
return 'http://chart.googleapis.com/chart?chst=d_map_xpin_letter&chld=pin|+|' +
color + '|000000|ffff00';
}
var shadow = new gm.MarkerImage(
'https://www.google.com/intl/en_ALL/mapfiles/shadow50.png',
new gm.Size(37, 34), // size - for sprite clipping
new gm.Point(0, 0), // origin - ditto
new gm.Point(10, 34) // anchor - where to meet map location
);
oms.addListener('click', function (marker) {
iw.setContent(marker.desc);
iw.open(map, marker);
});
oms.addListener('spiderfy', function (markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setIcon(iconWithColor(spiderfiedColor));
markers[i].setShadow(null);
}
iw.close();
});
oms.addListener('unspiderfy', function (markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setIcon(iconWithColor(usualColor));
markers[i].setShadow(shadow);
}
});
var bounds = new gm.LatLngBounds();
for (var i = 0; i < window.mapData.length; i++) {
var datum = window.mapData[i];
var loc = new gm.LatLng(datum.lat, datum.lon);
bounds.extend(loc);
var marker = new gm.Marker({
position: loc,
title: datum.h,
map: map,
icon: iconWithColor(usualColor),
shadow: shadow
});
marker.desc = datum.d;
oms.addMarker(marker);
}
//map.fitBounds(bounds);
// for debugging/exploratory use in console
window.map = map;
window.oms = oms;
}
});
}

You could try just calling the loadMapData() function onClick and removing your second script altogether:
<input type="button" value="Search" class="loadAjaxMap" onClick="loadMapData();" />

Related

Smoothly move google maps marker

I have a problem on google maps that my marker moves too fast along the maps when coordinates for the certain marker changes, can anyone help me how can I make it smoothly moving? Thanks!
<script type="text/javascript">
var values = [];
var map;
var markers = [];
function initMap()
{
var options = {
center: {lat: -33.890542, lng: 151.274856},
zoom: 4
};
map = new google.maps.Map(document.getElementById('map'), options);
var count = 0;
setInterval(function() {
getGps();
for(var i = 0; i < markers.length; i++){
markers[i].setPosition(new google.maps.LatLng(values[count][1], values[count][2]));
count++;
}
}, 1000);
}
function getGps() {
xmlhttp.onreadystatechange=function() {
if( xmlhttp.readyState==4 && xmlhttp.status==200 ) {
var res = xmlhttp.responseText;
var split1 = res.split("|");
for(var i = 0; i <= split1.length; i++){
var split2 = split1[i].toString().split(",");
var holder1 = holder = [split2[0],split2[1],split2[2]];
values.push(holder1);
var marker1 = marker = new google.maps.Marker({map: map, icon: 'images/mapvehicle.png', draggable: true});
markers.push(marker1);
}
}
};
xmlhttp.open("POST","GpsPost",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send();
}

method fitBounds() only zooms to single marker

I have rendered a map with markers, which are saved as long lat values in a local xlsx file.
My aim is to automatically zoom to all markers, which are loaded via an input file button. For this I am using the fitbounds() method from googlemaps API.
Partial Example
function handleFile(e) {
//Get the files from Upload control
var files = e.target.files;
var i, f;
//Loop through files
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function (e) {
var data = e.target.result;
var result;
var workbook = XLSX.read(data, { type: 'binary' });
var sheet_name_list = workbook.SheetNames;
sheet_name_list.forEach(function (y) { /* iterate through sheets */
//Convert the cell value to Json
var roa = XLSX.utils.sheet_to_json(workbook.Sheets[y]);
if (roa.length > 0) {
result = roa;
}
});
//create global infoWindow object
var infoWindow = new google.maps.InfoWindow();
var i, newMarker;
var gmarkers = [];
//loop over json format
for (i = 0, length = result.length; i < length; i++) {
var data = result[i];
//extract Lat Long values from result
latLng = new google.maps.LatLng(data.Latitude, data.Longitude);
//creating a marker and putting it on the map
newMarker = new google.maps.Marker({
position: latLng,
map: map
});
gmarkers.push(newMarker);
}
for (var i=0; i < gmarkers.length; i++) {
bounds = new google.maps.LatLngBounds();
loc = new google.maps.LatLng(gmarkers[i].position.lat(), gmarkers[i].position.lng());
bounds.extend(loc);
}
map.fitBounds(bounds);
}
}
}
};
reader.readAsArrayBuffer(f);
}
But if I run my html file, it zooms just to one marker. I suppose that it is the first marker of the gmarkers array.
However I want to achieve following result, with the full extent of my uploaded marker:
In my main.html you can see my initMap() function and the function which is called if the document is ready. In the document ready function the handlefunction () is called.
var map;
//Change event to dropdownlist
$(document).ready(function(){
a = $('#input-id').fileinput({
'showUpload': false,
'showPreview': false,
'showCaption': false
});
a.change(handleFile);
});
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 48.7758459, lng: 9.1829321},
zoom: 3,
mapTypeControl: false
});
}
You have a typo in your code. Move the initialization of the bounds outside the loop.
for (var i=0; i < gmarkers.length; i++) {
bounds = new google.maps.LatLngBounds();
loc = new google.maps.LatLng(gmarkers[i].position.lat(), gmarkers[i].position.lng());
bounds.extend(loc);
}
map.fitBounds(bounds);
should be:
bounds = new google.maps.LatLngBounds();
for (var i=0; i < gmarkers.length; i++) {
loc = new google.maps.LatLng(gmarkers[i].position.lat(), gmarkers[i].position.lng());
bounds.extend(loc);
}
map.fitBounds(bounds);
proof of concept fiddle
code snippet:
var result = [{
Latitude: 37.4419,
Longitude: -122.1419
}, {
Latitude: 37.44,
Longitude: -122.14
}, {
Latitude: 40.44,
Longitude: -75.14
}]
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var gmarkers = [];
//loop over json format
for (i = 0, length = result.length; i < length; i++) {
var data = result[i];
//extract Lat Long values from result
latLng = new google.maps.LatLng(data.Latitude, data.Longitude);
//creating a marker and putting it on the map
newMarker = new google.maps.Marker({
position: latLng,
map: map
});
gmarkers.push(newMarker);
}
bounds = new google.maps.LatLngBounds();
for (var i = 0; i < gmarkers.length; i++) {
loc = new google.maps.LatLng(gmarkers[i].position.lat(), gmarkers[i].position.lng());
bounds.extend(loc);
}
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
This is another approach for your problem within 35 lines of code.
Make sure you pass the JSON object the right way and that you declare your classes within the appropriate lexical scope.
Make sure the JSON Object returns something like this:
const coords = [
{lat: 42.4, lng: 1.55},
{lat: 43.42, lng: 2.48},
{lat: 45.43, lng: 4.9}
];
Note I have changed result to a more meaningful coords array of objects.
// Create your markers without worrying about scope and without extensive For Loops
const markers = coords.map((coord) => {
return new google.maps.Marker({
position: new google.maps.LatLng(coord.lat, coord.lng),
map: map,
animation: google.maps.Animation.DROP
});
})
// Declare your bounds outside the map method (previous for loop)
const bounds = new google.maps.LatLngBounds();
// Iterate through markers and return coords for expanded viewport
markers.forEach((loc) =>{
loc = new google.maps.LatLng(loc.position.lat(), loc.position.lng());
return bounds.extend(loc);
});
map.fitBounds(bounds);
}

Change co-ordinate on map

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyD83DW4cuDAMp0Zf2GkEXGFqnBAewN5qko"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 400px;"></div>
<script type="text/javascript">
function init(locations){
var element = document.getElementById("map");
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
var map = new google.maps.Map(element, {
center: new google.maps.LatLng(parseInt(locations[0].lat), parseInt(locations[0].lng)),
zoom: 6,
mapTypeId: "OSM",
mapTypeControlOptions: {
mapTypeIds: mapTypeIds
}
});
var infoWindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].lat, locations[i].lng),
map: map,
draggable:true,
// title: locations[i].lat
// icon: image
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(locations[i].infowindow);
infoWindow.open(map, marker);
}
})(marker, i));
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map.mapTypes.set("OSM", new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
name: "OpenStreetMap",
maxZoom: 18
}));
}
}
// long 77.4028193 lat 23.2243851
var locations = [{"lat":"21.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"17.433282","lng":"78.426762","infowindow":" information2 "}];
var locations1 = [{"lat":"24.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"17.434282","lng":"78.426762","infowindow":" information2 "}];
window.onload = init(locations);
window.setInterval( function(){console.log("first fn");change(locations1);}, 3500);
window.setInterval( function(){console.log("second fn");change(locations);}, 1500);
function change(locations){
console.log(locations);
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {lat: parseInt(locations[0].lat), lng: parseInt(locations[0].lng)},
mapTypeId: "OSM",
mapTypeControlOptions: {
mapTypeIds: mapTypeIds
}
});
// var map = google.maps.Map(document.getElementById("map"));
var infoWindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].lat, locations[i].lng),
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(locations[i].infowindow);
infoWindow.open(map, marker);
}
})(marker, i));
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map.mapTypes.set("OSM", new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
name: "OpenStreetMap",
maxZoom: 18
}));
}
}
</script>
</body>
</html>
without reloading/refreshing googlemap markers to be replaced. Tried all the ways provided by google-map api and other blogs. nothing helping me, atlast posting here hoping someone helps me with this part.
I have copied complete code here so that it helps to get on to the issue on which I am trying to solve.
Here I do.Is this right. I modified some of your code to make sure if this what you wish. I think you just miss some detail. If this is what you want, please let me know. PS :A lot of forloop in the function change-->not a good example.XD
<script type="text/javascript">
var map;
var markersArray=[];//put all markers into this
function init(locations){
var element = document.getElementById("map");
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map = new google.maps.Map(element, {
center: new google.maps.LatLng(parseInt(locations[0].lat), parseInt(locations[0].lng)),
zoom: 6,
mapTypeId: "OSM",
mapTypeControlOptions: {
mapTypeIds: mapTypeIds
}
});
var infoWindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < locations.length; i++) {
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map.mapTypes.set("OSM", new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
name: "OpenStreetMap",
maxZoom: 18
}));
}
}
var locations = [{"lat":"21.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"20.433282","lng":"78.426762","infowindow":" information2 "}];
var locations1 = [{"lat":"24.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"22.434282","lng":"78.426762","infowindow":" information2 "}];
var counter=0;
window.onload = init(locations);
window.setInterval( function(){
if(counter%2==0)
{
change(locations1);
}
else
{
change(locations);
}
counter++;
}, 2000);
function change(locations){
for (i = 0; i < locations.length; i++)
{
if(markersArray[i]!=null)
{
markersArray[i].setMap(null);
if (i == locations.length - 1) {
markersArray = [];
}
}
}
for (i = 0; i < locations.length; i++)
{
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].lat, locations[i].lng) });
markersArray.push(marker);
}
for (i = 0; i < markersArray.length; i++)
{
markersArray[i].setMap(map);
}
}
</script>
We had a similar problem to what you are experiencing. The way we solved it was by recalculating the bounds and recentering the map each time a new location is added. So basically we have a createMarker function that has this bit of code at the end:
const map_center = bounds.getCenter();
resultsMap.setCenter(map_center);
resultsMap.panToBounds(bounds);
resultsMap.fitBounds(bounds);
Where bounds here is your map boundaries, which can be found with the google.maps.LatLngBounds() method.
EDIT: I see you want to do it without refreshing the map, I don't think resetting the bounds refreshes the map but I could be wrong about that.

Google Maps: Select previous Marker on Polyline

I'm doing an application with google maps API that have a JSON with the marker's coordinates. Then I draw polylines between the markers. I also implemented a function with a onclick event that creates a new marker inside the polyline. This marker has to show information of the previous marker in the polyline (the one taked of the JSON, not a clicked one). But I don't know how to take the previous vertex(marker) of a selected polyline.
Code:
(function() {
window.onload = function() {
var options = {
zoom: 3,
center: new google.maps.LatLng(37.09, -95.71),
mapTypeId: google.maps.MapTypeId.HYBRID,
noClear: true,
panControl: true,
scaleControl: false,
streetViewControl:false,
overviewMapControl:false,
rotateControl:false,
mapTypeControl: true,
zoomControl: false,
};
var map = new google.maps.Map(document.getElementById('map'), options);
// JSON
$.getJSON("loc.js", function(json) {
console.log(json);
});
//Marker type
var markers = [];
var arr = [];
var pinColor = "FE7569";
var pinImage = new google.maps.MarkerImage("http://labs.google.com/ridefinder/images/mm_20_red.png" + pinColor,
new google.maps.Size(21, 34),
new google.maps.Point(0,0),
new google.maps.Point(10, 34));
// JSON loop
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
arr.push(latLng);
// Create markers
var marker = new google.maps.Marker({
position: latLng,
map: map,
icon: pinImage,
});
infoBox(map, marker, data);
//Polylines
var flightPath = new google.maps.Polyline({
path: json,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
map:map
});
infoPoly(map, flightPath, data);
//Calculate polylines distance
google.maps.LatLng.prototype.kmTo = function(a){
var e = Math, ra = e.PI/180;
var b = this.lat() * ra, c = a.lat() * ra, d = b - c;
var g = this.lng() * ra - a.lng() * ra;
var f = 2 * e.asin(e.sqrt(e.pow(e.sin(d/2), 2) + e.cos(b) * e.cos
(c) * e.pow(e.sin(g/2), 2)));
return f * 6378.137;
}
google.maps.Polyline.prototype.inKm = function(n){
var a = this.getPath(n), len = a.getLength(), dist = 0;
for (var i=0; i < len-1; i++) {
dist += a.getAt(i).kmTo(a.getAt(i+1));
}
return dist;
}
}
function infoBox(map, marker, data) {
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function(e) {
salta(data.tm);
});
(function(marker, data) {
google.maps.event.addListener(marker, "click", function(e) {
salta(data.tm);
});
})(marker, data);
}
//Create onclick marker on the polyline
function infoPoly(map, flightPath, data){
google.maps.event.addListener(flightPath, 'click', function(event) {
mk = new google.maps.Marker({
map: map,
position: event.latLng,
});
markers.push(mk);
map.setZoom(17);
map.setCenter(mk.getPosition());
});
}
function drawPath() {
var coords = [];
for (var i = 0; i < markers.length; i++) {
coords.push(markers[i].getPosition());
}
flightPath.setPath(coords);
}
// Fit these bounds to the map
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < arr.length; i++) {
bounds.extend(arr[i]);
}
map.fitBounds(bounds);
//dist polylines
distpoly = flightPath.inKm();
distpolyround = Math.round(distpoly);
};
})();
If I click in the blue arrow, I create a marker on that point of the polyline. I that marker it takes the values of the previous one.
You can use the geometry library .poly namespace isLocationOnEdge method to determine which segment of the polyline the clicked point (new marker) is on.
//Create onclick marker on the polyline
function infoPoly(map, flightPath, data) {
google.maps.event.addListener(flightPath, 'click', function(event) {
mk = new google.maps.Marker({
map: map,
position: event.latLng,
});
markers.push(mk);
map.setZoom(17);
map.setCenter(mk.getPosition());
// find line segment. Iterate through the polyline checking each line segment.
// isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one,
// then use it for the test. The default value of 10e-9 for the tolerance didn't work,
// a tolerance of 10e-6 seems to work.
var betweenStr = "result no found";
var betweenStr = "result no found";
for (var i=0; i<flightPath.getPath().getLength()-1; i++) {
var tempPoly = new google.maps.Polyline({
path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i+1)]
})
if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) {
betweenStr = "between "+i+ " and "+(i+1);
}
}
(function(mk, betweenStr) {
google.maps.event.addListener(mk, "click", function(e) {
infowindow.setContent(betweenStr+"<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, mk);
// salta(data.tm);
});
})(mk, betweenStr);
google.maps.event.trigger(mk,'click');
});
proof of concept fiddle
code snippet:
var infowindow = new google.maps.InfoWindow();
(function() {
window.onload = function() {
var options = {
zoom: 3,
center: new google.maps.LatLng(37.09, -95.71),
mapTypeId: google.maps.MapTypeId.HYBRID,
};
var map = new google.maps.Map(document.getElementById('map'), options);
//Marker type
var markers = [];
var arr = [];
var pinColor = "FE7569";
var pinImage = "http://labs.google.com/ridefinder/images/mm_20_red.png";
// JSON loop
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
arr.push(latLng);
// Create markers
var marker = new google.maps.Marker({
position: latLng,
map: map,
icon: pinImage,
});
infoBox(map, marker, data);
//Polylines
var flightPath = new google.maps.Polyline({
path: json,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
infoPoly(map, flightPath, data);
}
function infoBox(map, marker, data) {
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function(e) {
infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, marker);
// salta(data.tm);
});
(function(marker, data) {
google.maps.event.addListener(marker, "click", function(e) {
infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, marker);
// salta(data.tm);
});
})(marker, data);
}
//Create onclick marker on the polyline
function infoPoly(map, flightPath, data) {
google.maps.event.addListener(flightPath, 'click', function(event) {
mk = new google.maps.Marker({
map: map,
position: event.latLng,
});
markers.push(mk);
map.setZoom(17);
map.setCenter(mk.getPosition());
// find line segment. Iterate through the polyline checking each line segment.
// isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one,
// then use it for the test. The default value of 10e-9 for the tolerance didn't work,
// a tolerance of 10e-6 seems to work.
var betweenStr = "result no found";
for (var i = 0; i < flightPath.getPath().getLength() - 1; i++) {
var tempPoly = new google.maps.Polyline({
path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i + 1)]
})
if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) {
betweenStr = "between " + i + " and " + (i + 1);
}
}
(function(mk, betweenStr) {
google.maps.event.addListener(mk, "click", function(e) {
infowindow.setContent(betweenStr + "<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, mk);
// salta(data.tm);
});
})(mk, betweenStr);
google.maps.event.trigger(mk, 'click');
});
}
function drawPath() {
var coords = [];
for (var i = 0; i < markers.length; i++) {
coords.push(markers[i].getPosition());
}
flightPath.setPath(coords);
}
// Fit these bounds to the map
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < arr.length; i++) {
bounds.extend(arr[i]);
}
map.fitBounds(bounds);
//dist polylines
distpoly = flightPath.inKm();
distpolyround = Math.round(distpoly);
};
})();
var json = [{
lat: 38.931808,
lng: -74.906606,
tm: 0
}, {
lat: 38.932442,
lng: -74.905147,
tm: 1
}, {
lat: 38.93311,
lng: -74.903473,
tm: 2
}, {
lat: 38.933777,
lng: -74.901671,
tm: 3
}, {
lat: 38.930739,
lng: -74.912528,
tm: 1000
}];
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map"></div>
INITIALIZING
When you are creating those markers in the for loop, add them to a map [Data structure] that you define (empty) before the loop. In the map markers will be stored. Their keys - concatenated lat/lng.
var initial_markers = {}; //before for loop
initial_markers[data.lat+"-"+data.lng] = marker; //after each marker initialization
Count them, so you know how many there are initial_marker_count, because you cannot get length of size of a map[data structure]
DETECTION
When you have clicked on a polyline, I don't think you can get exactly the part of polyline that is clicked, so you need to get it yourself. The steps are:
Get the coordinate of click event
Loop through the markers
Take their coordinates
Check if the clicked point on the map is on the line between those two points
If is, take the first of those two points
DETECTION PSEUDOCODE
var prev_marker;
for (var i=initial_markers; i<initial_marker_count-2; i++) {
if( isPointOnLine(initial_markers[i], initial_markers[i+1], clicked_point) {
prev_marker = initial_markers[i];
break;
}
}
The only reason I am saying that this is pseudocode, is because I don't know hor to find if point is on the line between two points in Google maps. And you should write that isPointOnLine() functions. Apart from that - the idea is given. Hope You appreciate it.

google maps clustering marker

i am trying to add clustering on my map, the code i am using is working fine but there is no clustring on it and can't figure out how should i add the cluster to this code.
(function (namespace, $, undefined) {
// map the namespace to that
var that = namespace;
var markers = [];
var dealers = [];
var googleMap;
var tmpDealer = "";
function AddMarkers(aar, map, show) {
if (aar.length > 0) {
var image = '/Files/Templates/Designs/Mobler/images/MapMarker.png';
for (var i = 0; i < aar.length; i++) {
markers.push( new google.maps.Marker({
position: new google.maps.LatLng(parseFloat( aar[i].Latitude),parseFloat(aar[i].Longitude)),
map: map,
title: aar[i].Name,
icon: image,
DealerId: aar[i].DealerId,
DealerPage: aar[i].Area
}));
}
for (var i = 0; i < markers.length; i++) {
if (show) {
google.maps.event.addListener(markers[i], "click", function () {
tmpDealer = this.DealerPage;
MoblerLandingPage.SetCookie("/Default.aspx" + tmpDealer, false);
MoblerLandingPage.SetAreaName("/Default.aspx?AreaID=" + this.DealerPage, function() {
setTimeout(function() {
var area = $.cookie("MoblerAreaName");
document.location = "http://" + document.domain + "/" + area;
}, 250);
});
});
} else {
google.maps.event.addListener(markers[i], "click", that.onMarkerClick)
}
}
}
}
var InfoBoxOptions2 = {
content: ""
, disableAutoPan: false
, maxWidth: 0
, pixelOffset: new google.maps.Size(-75, -5)
, zIndex: null
, boxClass: "DealerMapInfoBox"
, closeBoxMargin: "5px"
, closeBoxURL: "/Files/Templates/Designs/SmagOgBehag/images/infoBoxClose.png"
, infoBoxClearance: new google.maps.Size(1, 1)
, isHidden: false
, pane: "floatPane"
, enableEventPropagation: false
, alignBottom : true
};
var infoBox2 = new InfoBox(InfoBoxOptions2);
that.Initialize = function(mapId, dealerArray, show){
dealers = dealerArray;
var mapOptions = {
center: new google.maps.LatLng(56.22, 11.32),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
if(!show){
var mapOptions = {
center: new google.maps.LatLng(56.22, 11.32),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
}
googleMap = new google.maps.Map(document.getElementById(mapId), mapOptions);
if(dealerArray.constructor === Array && dealerArray.length > 0){
AddMarkers(dealers, googleMap, show);
}
if(!show){
google.maps.event.addListener(googleMap, 'click', function () {
infoBox2.close();
});
}
}
that.onMarkerClick = function(){
var marker = this;
infoBox2.content_ = $('#Dealer' + marker.DealerId + ' li a').html();
infoBox2.open(marker.map, marker);
}
that.ShowDealerOnMap = function(dealerId) {
for (var i = 0; i < markers.length; i++) {
if (markers[i].DealerId == dealerId) {
var marker = markers[i];
marker.map.setZoom(15);
marker.map.panTo(marker.getPosition())
infoBox2.content_ = $('#Dealer' + marker.DealerId).html()
infoBox2.open(marker.map, marker);
}
}
}
Did you take a look to this documentation ? You can see a working sample to use MarkerClusterer
//Create your map
var center = new google.maps.LatLng(37.4419, -122.1419);
var options = {
'zoom': 13,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), options);
//Create the clusterer and its options
var mcOptions = {gridSize: 50, maxZoom: 15};
var markers = [...]; // Create the markers you want to add and collect them into a array.
//Add the clusterer to the map, and the markers to the clusterer.
var mc = new MarkerClusterer(map, markers, mcOptions);
Please note that if you don't have a lot of markers, you'll have to change some options in order to see the clusterer working. Change the maxZoom where the clusterer works, and the size of the grid ( gridSize option).
For a complete list of all options, please refer to this document
See this:
http://www.appelsiini.net/2008/introduction-to-marker-clustering-with-google-maps
You can make clusters, rectangle based or square based.

Categories

Resources