/*================================================================================================================\ + + Project : GoData-ECom Express + Filename : BlindSpot.js + Module Name : Map + Purpose : For Finding Blind Spots on Google Map + Coded By : Rahul Garg & Parul Gupta + +================================================================================================================*/ /** * For Finding Blind Spots on Google Map * @module Map */ //----------------- Global variables and functions ------------------// var map; var markersArray = []; var polygonObj = {}; //var duration = 1800; var duration = 5400; var globalDistance = 30; var globalAngle = 20; var geoCoder = new google.maps.Geocoder(); var directionsDisplay=[]; var directionsService; /** * Prototype to convert number into radian */ Number.prototype.toRad = function () { return this * Math.PI / 180; } /** * Prototype to convert number into degree */ Number.prototype.toDeg = function () { return this * 180 / Math.PI; } /** * Prototype to get destination points from given latlng */ google.maps.LatLng.prototype.destinationPoint = function (brng, dist) { dist = dist / 6371; brng = brng.toRad(); var lat1 = this.lat().toRad(), lon1 = this.lng().toRad(); var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) + Math.cos(lat1) * Math.sin(dist) * Math.cos(brng)); var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) * Math.cos(lat1), Math.cos(dist) - Math.sin(lat1) * Math.sin(lat2)); if (isNaN(lat2) || isNaN(lon2)) return null; return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg()); } /** * Find end points on circle drawn around start point * @method findPointInCircle * @param start point and distance * @return array of end points * @for BlindSpot */ function findPointInCircle(marker, radius) { var pointsArray = []; var markerLatLng = marker.getPosition(); for (var i = 0; i <= 360; i = i + globalAngle) { var point = markerLatLng.destinationPoint(i, radius); pointsArray.push(point); } return pointsArray; } /** * Recursive function to draw polygon on different end points * @method createNewPolygon * @param start point, distance and index point * @for BlindSpot */ var tempObj = {}; function createNewPolygon(marker, distance, index) { var radii = distance ? distance : globalDistance; // globalAngle = 30; var circlePoints = findPointInCircle(marker, radii); var checkDistances = calculateDistances(marker.getPosition(), circlePoints, function (distanceData) { if (distanceData) { for (var i = 0; i < distanceData.rows[0].elements.length; i++) { if (distanceData.rows[0].elements[0].status !== 'OK') { var z = endMarkerArray.length - 19; //console.log(z); for (var i = endMarkerArray.length; i > z; i--) { if (endMarkerArray[i]) { endMarkerArray[i].setMap(map); } } alert("Out of Coverage for this Van."); $("#div_load").hide(); var startPosition; startPosition = GLOBAL_MARKER; marker.position = startPosition; marker.setMap(map); var oldPolygon = GLOBAL_POLYGON; oldPolygon.setMap(map); //var paths = directionObj[marker.customInfo]; //for (var y = 0; y < paths.length; y++) { // console.log(paths.length); // paths[y].setMap(map); //} //paths = ""; delete GLOBAL_MARKER; delete GLOBAL_POLYGON; } else { for (var endMark = 0; endMark < endMarkerArray.length; endMark++) { if (endMarkerArray[endMark]) { if (endMarkerArray[endMark].customInfo == parseInt(marker.customInfo, 10)) { console.log(endMarkerArray[endMark].customInfo, marker.customInfo); endMarkerArray[endMark].setMap(null); endMarkerArray[endMark] = ""; } } } // for (var i = 0; i < distanceData.rows[0].elements.length; i++) { if (distanceData.rows[0].elements[i].duration) { if (distanceData.rows[0].elements[i].duration.value > duration) { if (!tempObj[i]) { (function (i) { setTimeout(function () { drawPath(marker, circlePoints[i]); }, 40); }(i)); tempObj[i] = circlePoints[i]; } } } if (i === distanceData.rows[0].elements.length - 1) { if (Object.keys(tempObj).length === 19) { drawPolygon(tempObj, index); $("#div_load").hide(); obj = {}; } else { setTimeout(function () { createNewPolygon(marker, radii + 15, index); }, 20); } } } } } }); } /** * Function to draw marker on start points * @method plotMarker * @param latitude, longitude and title of marker * @return marker * @for BlindSpot */ var GLOBAL_MARKER = {}; var GLOBAL_POLYGON = {}; var endMarkerArray = []; function plotMarker(lat, lng, title, addressTitle) { var marker = new google.maps.Marker({ position: new google.maps.LatLng(lat, lng), map: map, draggable: true, customInfo: String(title), title: addressTitle }); marker.setIcon('http://google-maps-icons.googlecode.com/files/truck.png'); var info; //on drag start google.maps.event.addListener(marker, "dragstart", function (event) { var markerOldPosition = this.getPosition(); GLOBAL_MARKER = markerOldPosition; info = marker.customInfo; if (polygonObj[parseInt(info, 10)]) { GLOBAL_POLYGON = polygonObj[parseInt(info, 10)]; } for (var endMark = 0; endMark < endmarkerArr.length; endMark++) { if (endmarkerArr[endMark].customInfo == parseInt(marker.customInfo, 10)) { console.log(endmarkerArr[endMark].customInfo, marker.customInfo); endMarkerArray.push(endmarkerArr[endMark]); } } }); //on drag end google.maps.event.addListener(marker, 'dragend', function (event) { $("#div_load").show(); info = marker.customInfo; var markerNewPositin = marker.getPosition(); var lat = markerNewPositin.lat(); var lon = markerNewPositin.lng(); for (var i = 0; i < endmarkerArr.length; i++) { if (endmarkerArr[i]) { if (endmarkerArr[i].customInfo == parseInt(marker.customInfo, 10)) { endmarkerArr[i].setMap(null); endmarkerArr[i] = ""; } else { endmarkerArr[i].setMap(map); } } } getReverseGeoCode(new google.maps.LatLng(lat, lon), function (address) { marker.setTitle(address); }); if (polygonObj[parseInt(info, 10)]) { var polygon = polygonObj[parseInt(info, 10)]; var paths = directionObj[marker.customInfo]; for (var z = 0; z < paths.length; z++) { paths[z].setMap(null); } polygon.setMap(null); tempObj = {}; createNewPolygon(marker, '', parseInt(info, 10)); } }); markersArray.push(marker); return marker; } /** * Function to calculate distance between start point and end point * @method calculateDistances * @param start point, destination point * @for BlindSpot */ var callbackReference = ""; function calculateDistances(sourcePoint, destinationPoints, callback) { callbackReference = callback; var service = new google.maps.DistanceMatrixService(); service.getDistanceMatrix({ origins: [sourcePoint], destinations: destinationPoints, travelMode: google.maps.TravelMode.DRIVING, avoidHighways: false, avoidTolls: false }, function (response, status) { if (response === null) { setTimeout(function () { calculateDistances(sourcePoint, destinationPoints, callbackReference); }, 20); } if (status == google.maps.DistanceMatrixStatus.OK) { callback(response); } if (status == google.maps.DistanceMatrixStatus.ZERO_RESULTS) { alert("Out of Coverage for this Van"); callback(null); } }); } /** * Function to draw polygon on different end points * @method drawPolygon * @for BlindSpot */ var endmarkerArr = []; function drawPolygon(obj, currentI) { var latLngArr = []; for (var i = 0; i < 19; i++) { latLngArr.push(obj[i]); } var polygon = new google.maps.Polygon({ path: latLngArr, geodesic: true, strokeColor: '#FFFFFF', //fillColor: '#00FF00', strokeOpacity: 1.0, strokeWeight: 2, map: map }); // add a marker at each coordinate for (var i = 0; i < latLngArr.length; i++) { var marker = new google.maps.Marker({ position: latLngArr[i], map: map, customInfo: currentI, //customInfo1: latLngArr[i], draggable: true }); marker.setIcon('../../Scripts/map_api/icons/red_circle.png'); endmarkerArr.push(marker); var startMarker = markersArray[currentI]; bindMarker(startMarker, marker, latLngArr, i, polygon); //polygonObj[currentI] = polygon; } polygonObj[currentI] = polygon; // console.log(endmarkerArr); } var endMarkPos; var endmarkCoords; function bindMarker(startMarker, endMarker, arrCoords, i, polygon) { //google.maps.event.addListener(endMarker, 'dragstart', function (e) { // //console.log(directionObj[startMarker.customInfo]); // var paths = directionObj[startMarker.customInfo]; // for (var y = 0; y < paths.length; y++) { // //console.log(i , paths[y]); // paths[y].setMap(null); // } // //var path = drawPath(startMarker, endMarker.position); // //pathEnd.push(path); //}); //google.maps.event.addListener(endMarker, 'dragend', function (e) { // arrCoords[i] = e.latLng; // //console.log(arrCoords[i]); // polygon.setPath(arrCoords); // drawPath(startMarker, arrCoords[i]); // var endPointCoords = []; // for (var j = 0; j < endmarkerArr.length; j++) { // if (endmarkerArr[j].customInfo == endMarker.customInfo) { // //console.log(endmarkerArr[j].customInfo, endMarker.customInfo); // endPointCoords.push(endmarkerArr[j].position); // } // } // for (var z = 0; z < endPointCoords.length; z++) { // if (endPointCoords[z] !== arrCoords[i]) { // console.log("endpoint" + endPointCoords[z]); // //(function (i) { // // setTimeout(function () { // drawPath(startMarker, endPointCoords[z]); // // }, 40); // //}(i)); // } // else { // console.log("arrcoords" + arrCoords[i]); // //(function (i) { // // setTimeout(function () { // drawPath(startMarker, arrCoords[i]); // // }, 40); // //}(i)); // } // } // // var info = startMarker.customInfo; // //var paths = directionObj[startMarker.customInfo]; // //for (var y = 0; y < paths.length; y++) { // // if (y !== i) { // // paths[y].setMap(map); // // // console.log(y, i); // // //if (y == i) { // // // var path = drawPath(startMarker, arrCoords[i]); // // // paths[y].setMap(null); // // // paths[y].setMap(path); // // //} // // } // // else { // // paths[y].setMap(null); // // drawPath(startMarker, arrCoords[i]); // // console.log(y, i); // // } // //} //}); google.maps.event.addListener(endMarker, 'dragstart', function (e) { endmarkCoords = e.latLng; //endMarkPos = endMarker.getPosition(); //console.log(e.latLng); }); google.maps.event.addListener(endMarker, 'dragend', function (e) { var endCoords = []; arrCoords[i] = e.latLng; endCoords.push(arrCoords[i]); var checkDuration = calculateDistances(startMarker.getPosition(), endCoords, function (distanceData) { for (var j = 0; j < distanceData.rows[0].elements.length; j++) { if (distanceData) { console.log(distanceData.rows[0].elements[j].duration.value); if (distanceData.rows[0].elements[j].duration.value <= duration) { //console.log("if"+duration); polygon.setPath(arrCoords); drawPath(startMarker, arrCoords[i]); } else { // console.log("else" + duration); var thisDuration = duration / 60; alert("SLA Duration does not match for new selected location. Duration > " + thisDuration + " mins"); endMarker.position = endmarkCoords; endMarker.setMap(map); arrCoords[i] = endmarkCoords; polygon.setPath(arrCoords); } } } }); //polygon.setPath(arrCoords); //drawPath(startMarker, arrCoords[i]); //var endPointCoords = []; //for (var j = 0; j < endmarkerArr.length; j++) { // if (endmarkerArr[j].customInfo === endMarker.customInfo) { // //console.log("Check"+endmarkerArr[j].customInfo1, endMarker.customInfo1); // endPointCoords.push(endmarkerArr[j]); // } //} //var paths = directionObj[startMarker.customInfo]; // //console.log(paths); //for (var y = 0; y < paths.length; y++) { // console.log(paths[y]); //if (paths[y].position) { // paths[y].setMap(null); // console.log("pth dltd"); //} else { // console.log("no pth dltd"); //} //} //for (var z = 0; z < endPointCoords.length; z++) { // //console.log("hi"+endPointCoords[z].customInfo1,endMarker.customInfo1); // if (endPointCoords[z].customInfo1 === endMarker.customInfo1) { // endPointCoords[z].position = arrCoords[i]; // console.log("In if"); // for (var j = 0; j < endmarkerArr.length; j++) { // console.log("In for"); // //console.log(endmarkerArr[j].position, endmarkCoords[i]); // if (endmarkerArr[j].customInfo1 === endMarker.customInfo1) { // endmarkerArr[j].position = arrCoords[i]; // console.log("lat long changed from array"); // } // } // } // else { // console.log("gadbad"); // } // var paths = directionObj[startMarker.customInfo]; // //console.log(paths); // for (var y = 0; y < paths.length; y++) { // if (y == z) { // paths[y].setMap(null); // console.log("pth dltd"); // } else { // console.log("no pth dltd"); // } // } // drawPath(startMarker, endPointCoords[z].position); //} }); } //This function reverses the Lat Lng to Get the Approxmiate Address using the Google GeoCoding. Callback the result function getReverseGeoCode(latLng, callback) { // Get google map LatLng object with the latLng in params //var latlng = new google.maps.LatLng(latLng.lat(), latLng.lng()); var latlng = latLng; //Use google geocode library to get results geoCoder.geocode({ 'latLng': latlng }, function (results, status) { //If status is Ok if (status == google.maps.GeocoderStatus.OK) { //Find most intensive search result and callback it if (results[0]) { callback(results[0].formatted_address); //Else callback no result found } else { callback('No results found'); } } //return false return false; }); } var global_markers_array = ""; /** * Function to initialize google map * @method initialize * @for BlindSpot */ function initialize() { $("#div_load").show(); var mapOptions = { zoom: 7, center: new google.maps.LatLng(26.1357, 73.644) }; map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); directionsService = new google.maps.DirectionsService(); var markerArray = []; var latLng = new google.maps.LatLng(28.2705, 76.8494); getReverseGeoCode(latLng, function (address1) { var marker = plotMarker(28.2705, 76.8494, 0, address1); markerArray.push(marker); var latLng = new google.maps.LatLng(26.294418643816307, 74.52888013916015); getReverseGeoCode(latLng, function (address1) { //console.log("parul"); var marker2 = plotMarker(26.294418643816307, 74.52888013916015, 1, address1); markerArray.push(marker2); var latLng = new google.maps.LatLng(27.067107172375003, 75.83240944824229); getReverseGeoCode(latLng, function (address1) { //console.log("parul"); var marker3 = plotMarker(27.067107172375003, 75.83240944824229, 2, address1); markerArray.push(marker3); var latLng = new google.maps.LatLng(25.157429750286358, 73.84637099914539); getReverseGeoCode(latLng, function (address1) { //console.log("parul"); var marker4 = plotMarker(25.157429750286358, 73.84637099914539, 3, address1); markerArray.push(marker4); var latLng = new google.maps.LatLng(23.935450590389035, 73.57129184570317); getReverseGeoCode(latLng, function (address1) { // console.log("parul"); var marker5 = plotMarker(23.935450590389035, 73.57129184570317, 4, address1); markerArray.push(marker5); // x(); //call function if address is null function y() { setTimeout(function () { var latLng = new google.maps.LatLng(23.167493599251735, 72.70889165039057); geoCoder.geocode({ 'latLng': latLng }, function (results, status) { if (!results) { y(); } else { var marker6 = plotMarker(23.167493599251735, 72.70889165039057, 5, results[0].formatted_address); markerArray.push(marker6); function z() { setTimeout(function () { var latLng = new google.maps.LatLng(22.18484892398956, 73.18498234863273); geoCoder.geocode({ 'latLng': latLng }, function (results, status) { if (results === null) { z(); } else { var marker7 = plotMarker(22.18484892398956, 73.18498234863273, 6, results[0].formatted_address); markerArray.push(marker7); global_markers_array = markerArray; x(); } }); }, 40); } z(); } }); }, 40); } y(); }); }); }); }); }); function x() { var currentIndex = 0; var obj = {}; // Function call to create marker on start point function callForMarker() { if (markerArray[currentIndex]) { doTheMagic(markerArray[currentIndex]); } else { $("#div_load").hide(); } } //recursive function to calculate distance and draw polygons on end points function doTheMagic(marker, distance) { var radii = distance ? distance : globalDistance; var circlePoints = findPointInCircle(marker, radii); var checkDistances = calculateDistances(marker.getPosition(), circlePoints, function (distanceData) { for (var i = 0; i < distanceData.rows[0].elements.length; i++) { if (distanceData.rows[0].elements[i].status !== 'OK') { if (!obj[i]) { (function (i) { setTimeout(function () { drawPath(marker, circlePoints[i]); }, 40); }(i)); obj[i] = circlePoints[i]; } } else { if (distanceData.rows[0].elements[i].duration) { if (distanceData.rows[0].elements[i].duration.value > duration) { if (!obj[i]) { //(function (i) { // drawPath(marker, circlePoints[i]); //}(i)); (function (i) { setTimeout(function () { drawPath(marker, circlePoints[i]); }, 40); }(i)); obj[i] = circlePoints[i]; } } } } if (i === distanceData.rows[0].elements.length - 1) { if (Object.keys(obj).length === 19) { drawPolygon(obj, currentIndex); obj = {}; currentIndex++; callForMarker(); } else { setTimeout(function () { doTheMagic(marker, radii + 15); }, 20); } } } }); } addDropDown(map); callForMarker(); } } var directionObj = {}; function drawPath(marker, endPoint) { // console.log(endPoint); if(!directionObj[marker.customInfo]) { directionObj[marker.customInfo]= []; } var rendererOptions = { map: map, suppressMarkers: true, polylineOptions: { strokeColor: "#00FF00" } } var displayDisplay = new google.maps.DirectionsRenderer(rendererOptions); directionObj[marker.customInfo].push(displayDisplay); var request = { origin: marker.position, destination: endPoint, travelMode: google.maps.TravelMode.DRIVING }; // Route the directions and pass the response to a // function to create markers for each step. directionsService.route(request, function (response, status) { if (status == google.maps.DirectionsStatus.OK) { displayDisplay.setOptions({ preserveViewport: true }); displayDisplay.setDirections(response); } //else { // console.log("no path"); //} }); } //Add drop down control function addDropDown(map) { var dropdown = document.getElementById('dropdown-holder'); map.controls[google.maps.ControlPosition.TOP_RIGHT].push(dropdown); var label = document.getElementById('div_sla_duration'); map.controls[google.maps.ControlPosition.TOP_RIGHT].push(label); } /** * function to create polygon around a marker if duration is changed * @method getDurationById * @for BlindSpot */ function getDurationById(i) { $("#div_load").show(); var id = i; var id1 = "item1"; var id2 = "item2"; var id3 = "item3"; var id4 = "item4"; var id5 = "item5"; var markersArray = global_markers_array; var text = document.getElementById(id).innerHTML; document.getElementById("div_selected_item").innerHTML = text; document.getElementById("drop_down_menu").style.display == "none"; if (id == "item1") { document.getElementById(id).style.backgroundColor = "lightgrey"; document.getElementById(id2).style.backgroundColor = "white"; document.getElementById(id3).style.backgroundColor = "white"; document.getElementById(id4).style.backgroundColor = "white"; document.getElementById(id5).style.backgroundColor = "white"; duration = 5400; globalDistance = 30; } else if (id == "item2") { document.getElementById(id).style.backgroundColor = "lightgrey"; document.getElementById(id1).style.backgroundColor = "white"; document.getElementById(id3).style.backgroundColor = "white"; document.getElementById(id4).style.backgroundColor = "white"; document.getElementById(id5).style.backgroundColor = "white"; //duration = 1800; duration = 7200; globalDistance = 30; } else if (id == "item3") { document.getElementById(id).style.backgroundColor = "lightgrey"; document.getElementById(id1).style.backgroundColor = "white"; document.getElementById(id2).style.backgroundColor = "white"; document.getElementById(id4).style.backgroundColor = "white"; document.getElementById(id5).style.backgroundColor = "white"; //duration = 3600; duration = 10800; globalDistance = 50; } else if (id == "item4") { document.getElementById(id).style.backgroundColor = "lightgrey"; document.getElementById(id1).style.backgroundColor = "white"; document.getElementById(id2).style.backgroundColor = "white"; document.getElementById(id3).style.backgroundColor = "white"; document.getElementById(id5).style.backgroundColor = "white"; //duration = 5400; duration = 14400; globalDistance = 70; } else if (id == "item5") { document.getElementById(id).style.backgroundColor = "lightgrey"; document.getElementById(id1).style.backgroundColor = "white"; document.getElementById(id2).style.backgroundColor = "white"; document.getElementById(id3).style.backgroundColor = "white"; document.getElementById(id4).style.backgroundColor = "white"; duration = 18000; globalDistance = 90; } else { duration = 5400; globalDistance = 30; } for (i = 0; i < markersArray.length; i++) { markersArray[i].setMap(map); } var currentIndex = 0; var obj = {}; // Function call to create marker on start point function callForMarker() { if (markersArray[currentIndex]) { doTheMagic(markersArray[currentIndex]); } else { $("#div_load").hide(); } } //recursive function to calculate distance and draw polygons on end points function doTheMagic(marker, distance) { var radii = distance ? distance : globalDistance; var circlePoints = findPointInCircle(marker, radii); var checkDistances = calculateDistances(marker.getPosition(), circlePoints, function (distanceData) { for (var i = 0; i < distanceData.rows[0].elements.length; i++) { if (distanceData.rows[0].elements[i].status !== 'OK') { if (!obj[i]) { (function (i) { setTimeout(function () { drawPath(marker, circlePoints[i]); }, 40); }(i)); obj[i] = circlePoints[i]; } } else { if (distanceData.rows[0].elements[i].duration) { if (distanceData.rows[0].elements[i].duration.value > duration) { if (!obj[i]) { (function (i) { setTimeout(function () { drawPath(marker, circlePoints[i]); }, 40); }(i)); obj[i] = circlePoints[i]; } } } } if (i === distanceData.rows[0].elements.length - 1) { if (Object.keys(obj).length === 19) { drawPolygon(obj, currentIndex); obj = {}; currentIndex++; callForMarker(); } else { setTimeout(function () { doTheMagic(marker, radii + 15); }, 20); } } } }); } //call on change of duration and remove previous polygons for (i = 0; i < markersArray.length; i++) { var info = markersArray[i].customInfo; polygonObj[parseInt(info, 10)].setMap(null); var paths = directionObj[info]; for (var z = 0; z < paths.length; z++) { paths[z].setMap(null); } } callForMarker(); for (var i = 0; i < endmarkerArr.length; i++) { if (endmarkerArr[i]) { endmarkerArr[i].setMap(null); //console.log(endmarkerArr[i]); endmarkerArr[i] = ""; } } } //--------------- load map function ---------------// google.maps.event.addDomListener(window, 'load', initialize);