I'm facing a problem with google map, the problem is,when i draw rout between markers it duplicated heres the image :
enter image description here
heres the makers:
var markers=[{"longitude":"-5.808954951287861","latitude":"35.77107409886168","deviceTime":"2017-03-29T14:02:36.000+0000"},
{"longitude":"-5.807401662705262","latitude":"35.77029143851354","deviceTime":"2017-03-29T14:05:36.000+0000"},
{"longitude":"-5.794769662196012","latitude":"35.77169804990058","deviceTime":"2017-03-29T14:08:36.000+0000"},
{"longitude":"-5.784207185242776","latitude":"35.76541442176138","deviceTime":"2017-03-29T14:11:36.000+0000"},
{"longitude":"-5.78417853735302","latitude":"35.76539666006973","deviceTime":"2017-03-29T14:14:36.000+0000"},
{"longitude":"-5.784050767764706","latitude":"35.76528034963732","deviceTime":"2017-03-29T14:15:52.000+0000"}];
heres the function :
storyboard.drawTrajet=function(markers){
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var labelIndex = 0;
var mapOptions = {
center: new google.maps.LatLng(markers[0].latitude, markers[0].longitude),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i];
alert(markers.length);
var myLatlng = new google.maps.LatLng(data.latitude, data.longitude);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
//icon: icons['info'].icon,
label: labels[labelIndex++ % labels.length],
position: myLatlng,
map: map
//title: 'data.title'
});
//path[z].push(marker.getPosition());
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "mouseover", function (e) {
storyboard.geocodeLatLng($scope.geocoder , map, $scope.infoWindow,data.latitude,data.longitude, false,false);
//alert( $scope.MyPos);
infoWindow.setContent('<div ><i class="fa fa-calendar" aria-hidden="true"></i> '+$filter('date')(data.deviceTime, "HH:mm:ss")
+' '+'<i class="glyphicon glyphicon-bookmark" aria-hidden="true"></i>'+$scope.MyPos
+'<div>'
+'<i class="glyphicon glyphicon-map-marker" aria-hidden="true"></i>'+data.latitude+' '
+'<i class="glyphicon glyphicon-map-marker" aria-hidden="true"></i>'+data.longitude
+'</div>'
+'</div>');
infoWindow.open(map, marker);
});
})(marker, data);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
//***********ROUTING****************//
//Initialize the Path Array
var path = new google.maps.MVCArray();
//Initialize the Direction Service
var service = new google.maps.DirectionsService();
//Set the Path Stroke Color
var poly = new google.maps.Polyline({ map: map, strokeColor: '#4986E7' });
//Loop and Draw Path Route between the Points on MAP
for (var i = 0; i < lat_lng.length; i++) {
//alert("sss");
if ((i + 1) < lat_lng.length) {
var src = lat_lng[i];
//src.setMap(null);
var des = lat_lng[i + 1];
path.push(src);
poly.setPath(path);
service.route({
origin: src,
destination: des,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
// alert("sssscvvvvvvs");
path.push(result.routes[0].overview_path[i]);
}
}
});
}
}
}
can anyone help please to resolve this problem??
I Think you should use Waypoints for this case. please see example from this.
https://developers.google.com/maps/documentation/javascript/directions#Waypoints
Related
I use the google maps api to draw a route in a embedded google map. I changed the color of the hole route but I also would like to change the color between the waypoints for example:
Start --orange--> firstWP --red-- > secondWP --orange--> firstWP --red--> secondWp --orange--> Destination
The color between firstWP to seceondWP should be changed but secondWP to FirstWP sould be the same color as the other parts of the route.
Furthermore I also need to move the map markers and the route should move/change
fitting to the new position of the map marker but keep the different color.
This is a minimal example with draggable map marker and changed color between waypoints but the route does not adapt to the new position of the map markers
var map;
var directionsService;
var directionsDisplay;
function initialize() {
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
});
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer({
draggable: true,
map: map,
suppressPolylines: true
});
calcRoute(39.2903848, -76.6121893, 42.3600825, -71.05888);
}
google.maps.event.addDomListener(window, "load", initialize);
function calcRoute(origin_lat, origin_lng, destination_lat, destination_lng) {
console.log("Entrée CALC ROUTE");
var origin = new google.maps.LatLng(origin_lat, origin_lng);
var destination = new google.maps.LatLng(destination_lat, destination_lng);
var waypointsArray = document.getElementById('waypoints').value.split("|");
var waypts = [];
for (i = 0; i < waypointsArray.length; i++) {
if (waypointsArray[i] != "") {
var waypoint = waypointsArray[i];
var waypointArray = waypoint.split(",");
var waypointLat = waypointArray[0];
var waypointLng = waypointArray[1];
console.log("waypts lat " + waypointLat);
console.log("waypts lng " + waypointLng);
waypts.push({
location: new google.maps.LatLng(waypointLat, waypointLng),
stopover: true
})
}
}
console.log("waypts " + waypts.length);
var request = {
origin: origin,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
waypoints: waypts,
provideRouteAlternatives: true
};
console.log("Calc request " + JSON.stringify(request));
directionsService.route(request, customDirectionsRenderer);
}
function customDirectionsRenderer(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var bounds = new google.maps.LatLngBounds();
var route = response.routes[0];
var path = response.routes[0].overview_path;
var legs = response.routes[0].legs;
for (i = 0; i < legs.length; i++) {
var polyline = new google.maps.Polyline({map:map, strokeColor: "blue", path:[]})
if (i == 1) {
polyline.setOptions({strokeColor: "red"});
}
var steps = legs[i].steps;
for (j = 0; j < steps.length; j++) {
var nextSegment = steps[j].path;
for (k = 0; k < nextSegment.length; k++) {
polyline.getPath().push(nextSegment[k]);
bounds.extend(nextSegment[k]);
}
}
}
polyline.setMap(map);
map.fitBounds(bounds);
}
};
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&ext=.js"></script>
<input id="waypoints" value="39.9525839,-75.1652215|40.7127837,-74.0059413" />
<div id="map_canvas"></div>
http://jsfiddle.net/westify/vop9o1n5/1/
Is it possible to do that? Or is it only possible if rerender the whole route after moved one waypoint?
One option would be to listen for the directions_changed event on the DirectionsRenderer, when that fires, redraw the directions polylines.
var firstTime = true;
google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
console.log("directions changed firstTime=" + firstTime);
// prevent infinite loop
if (firstTime) {
google.maps.event.addListenerOnce(directionsDisplay, 'directions_changed', function() {
console.log("directions changed");
customDirectionsRenderer(directionsDisplay.getDirections(), "OK");
});
}
firstTime = !firstTime;
});
proof of concept fiddle
code snippet:
var map;
var directionsService;
var directionsDisplay;
var firstTime = true;
function initialize() {
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
});
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer({
draggable: true,
map: map,
suppressPolylines: true
});
google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
console.log("directions changed firstTime=" + firstTime);
if (firstTime) {
google.maps.event.addListenerOnce(directionsDisplay, 'directions_changed', function() {
console.log("directions changed"); //+JSON.stringify(directionsDisplay.getDirections()));
customDirectionsRenderer(directionsDisplay.getDirections(), "OK");
});
}
firstTime = !firstTime;
});
calcRoute(39.2903848, -76.6121893, 42.3600825, -71.05888);
}
google.maps.event.addDomListener(window, "load", initialize);
function calcRoute(origin_lat, origin_lng, destination_lat, destination_lng) {
console.log("Entrée CALC ROUTE");
var origin = new google.maps.LatLng(origin_lat, origin_lng);
var destination = new google.maps.LatLng(destination_lat, destination_lng);
var waypointsArray = document.getElementById('waypoints').value.split("|");
var waypts = [];
for (i = 0; i < waypointsArray.length; i++) {
if (waypointsArray[i] != "") {
var waypoint = waypointsArray[i];
var waypointArray = waypoint.split(",");
var waypointLat = waypointArray[0];
var waypointLng = waypointArray[1];
console.log("waypts lat " + waypointLat);
console.log("waypts lng " + waypointLng);
waypts.push({
location: new google.maps.LatLng(waypointLat, waypointLng),
stopover: true
})
}
}
console.log("waypts " + waypts.length);
var request = {
origin: origin,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
waypoints: waypts,
provideRouteAlternatives: true
};
console.log("Calc request " + JSON.stringify(request));
directionsService.route(request, customDirectionsRenderer);
}
var polylines = [];
function customDirectionsRenderer(response, status) {
for (var i = 0; i < polylines.length; i++) {
polylines[i].setMap(null);
}
polylines = [];
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var bounds = new google.maps.LatLngBounds();
var route = response.routes[0];
var path = response.routes[0].overview_path;
var legs = response.routes[0].legs;
for (i = 0; i < legs.length; i++) {
var polyline = new google.maps.Polyline({
map: map,
strokeColor: "blue",
path: []
});
polylines.push(polyline);
if (i == 1) {
polyline.setOptions({
strokeColor: "red"
});
}
var steps = legs[i].steps;
for (j = 0; j < steps.length; j++) {
var nextSegment = steps[j].path;
for (k = 0; k < nextSegment.length; k++) {
polyline.getPath().push(nextSegment[k]);
bounds.extend(nextSegment[k]);
}
}
}
polyline.setMap(map);
map.fitBounds(bounds);
}
};
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<input id="waypoints" value="39.9525839,-75.1652215|40.7127837,-74.0059413" />
<div id="map_canvas"></div>
$(document).ready(function() {
var markers = [
{
"lat": '51.508742',
"lng": '-0.12085'
}
];
window.onload = function () {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
mapTypeId: google.maps.MapTypeId.ROADMAP,
fullscreenControl: true,
styles: [{"featureType":"administrative","elementType":"labels.text.fill","stylers":[{"color":"#6195a0"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"landscape","elementType":"geometry.fill","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#e6f3d6"},{"visibility":"on"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45},{"visibility":"simplified"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"simplified"}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#f4d2c5"},{"visibility":"simplified"}]},{"featureType":"road.highway","elementType":"labels.text","stylers":[{"color":"#4e4e4e"}]},{"featureType":"road.arterial","elementType":"geometry.fill","stylers":[{"color":"#f4f4f4"}]},{"featureType":"road.arterial","elementType":"labels.text.fill","stylers":[{"color":"#787878"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#eaf6f8"},{"visibility":"on"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"color":"#eaf6f8"}]}]
};
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
}
$("#tab_id_1 li").click(function() {
event.preventDefault();
var data_lat1 = $(this).attr('data-lat-1');
var data_lng1 = $(this).attr('data-lng-1');
var data_lat2 = $(this).attr('data-lat-2');
var data_lng2 = $(this).attr('data-lng-2');
map(data_lat1,data_lng1,data_lat2,data_lng2);
});
function map(data_lat1,data_lng1,data_lat2,data_lng2){
$("#tab_id_1 li").on("click",function(){
var markers = [
{
"lat": ''+ data_lat1 +'',
"lng": ''+ data_lng1 +''
}
,
{
"lat": ''+ data_lat2 +'',
"lng": ''+ data_lng2 +''
}
];
console.log(markers);
var mapOptions = {
zoom: 7,
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
mapTypeId: google.maps.MapTypeId.ROADMAP,
fullscreenControl: true,
styles: [{"featureType":"administrative","elementType":"labels.text.fill","stylers":[{"color":"#6195a0"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"landscape","elementType":"geometry.fill","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#e6f3d6"},{"visibility":"on"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45},{"visibility":"simplified"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"simplified"}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#f4d2c5"},{"visibility":"simplified"}]},{"featureType":"road.highway","elementType":"labels.text","stylers":[{"color":"#4e4e4e"}]},{"featureType":"road.arterial","elementType":"geometry.fill","stylers":[{"color":"#f4f4f4"}]},{"featureType":"road.arterial","elementType":"labels.text.fill","stylers":[{"color":"#787878"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#eaf6f8"},{"visibility":"on"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"color":"#eaf6f8"}]}]
};
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title,
icon: "marker-icon.png"
});
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
//***********ROUTING****************//
//Intialize the Path Array
var path = new google.maps.MVCArray();
//Intialize the Direction Service
var service = new google.maps.DirectionsService();
//Set the Path Stroke Color
var poly = new google.maps.Polyline({ map: map, strokeColor: '#f09c00', strokeOpacity: 1.0, strokeWeight: 5 });
//Loop and Draw Path Route between the Points on MAP
for (var i = 0; i < lat_lng.length; i++) {
if ((i + 1) < lat_lng.length) {
var src = lat_lng[i];
var des = lat_lng[i + 1];
path.push(src);
poly.setPath(path);
service.route({
origin: src,
destination: des,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
path.push(result.routes[0].overview_path[i]);
}
}
});
}
}
});
}
});
Help please! when the first time is pushed, nothing happens, then when you press again on one of the "li" the coordinates are sent with 1 array, the third time when the push is sent 2 arrays, the fourth time is sent 3 arrays, the fifth time is sent 4 arrays, how can I solve the problem, when I'm pushing to send only 1 array, sorry for my bad english.
<ul id="tab_id_1" class="uk-nestable" data-uk-nestable="{group:'my-group', maxDepth:1}">
<li data-lat-1="51.5501741" data-lng-1="-0.003371000000015556" data-lat-2="-33.88081" data-lng-2="-33.88081" class="uk-nestable-item">
<input type="hidden" name="id_1[]" value="9">
<div class="uk-nestable-panel">
<div>
<div class="table dd_table">
<div>Sat30</div>
<div>Nr.Q767</div>
<div>DELIVERY</div>
<div>754876</div>
<div><i class="fa fa-eye"></i></div>
</div>
</div>
</div>
</li>
<li data-lat-1="48.57340529999999" data-lng-1="7.752111300000024" data-lat-2="51.5111922" data-lng-2="51.5111922" class="uk-nestable-item">
<input type="hidden" name="id_1[]" value="7">
<div class="uk-nestable-panel">
<div>
<div class="table dd_table">
<div>Sat30</div>
<div>Nr.W996</div>
<div>DELIVERY</div>
<div>5365-64</div>
<div><i class="fa fa-eye"></i></div>
</div>
</div>
</div>
</li>
<li data-lat-1="48.57340529999999" data-lng-1="7.752111300000024" data-lat-2="52.19173" data-lng-2="52.19173" class="uk-nestable-item">
<input type="hidden" name="id_1[]" value="11">
<div class="uk-nestable-panel">
<div>
<div class="table dd_table">
<div>Sat30</div>
<div>Nr.J765</div>
<div>PICK-UP/DELIVERY</div>
<div>MD-2038/3811-558</div>
<div><i class="fa fa-eye"></i></div>
</div>
</div>
</div>
</li>
</ul>
Please remove the
$("#tab_id_1 li").on("click",function(){
re declaration inside the map function..
That should solve your problem.
I have a strange scenario with regards to a Polyline that is being drawn on the map. Before I post the code, I'll first demonstrate what happens when I make use of the normal direction services (Both calculates the resulting disctance the same = Total Distance: 62.734 km):
Now, when I draw the directions myself - this straight line appears out of nowhere:
Code snippet:
<script type="text/javascript">
var markers = [
{
"lat": '-26.2036247253418',
"lng": '28.0086193084717'
}
,
{
"lat": '-26.1259479522705',
"lng": '27.9742794036865'
}
,
{
"lat": '-25.8434619903564',
"lng": '28.2100086212158'
}
];
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var labelIndex = 0;
var totalDistance = 0;
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
//var image = 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png';
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title,
label: labels[labelIndex++ % labels.length],
//icon: image
});
latlngbounds.extend(marker.position);
(function (marker, data) {
// google.maps.event.addListener(marker, "click", function (e) {
// infoWindow.setContent(data.description);
// infoWindow.open(map, marker);
// });
})(marker, data);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
//***********ROUTING****************//
//Initialize the Path Array
var path = new google.maps.MVCArray();
//Initialize the Direction Service
var service = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer({
setMap: map
});
//Set the Path Stroke Color
var poly = new google.maps.Polyline({ map: map, strokeColor: '#4986E7' });
//Loop and Draw Path Route between the Points on MAP
for (var i = 0; i < lat_lng.length; i++) {
if ((i + 1) < lat_lng.length) {
var src = lat_lng[i];
var des = lat_lng[i + 1];
path.push(src);
//poly.strokeColor = '#'+Math.floor(Math.random()*16777215).toString(16);
poly.setPath(path);
service.route({
origin: src,
destination: des,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
var myroute = directionsDisplay.directions.routes[0];
var distance = 0;
for (i = 0; i < myroute.legs.length; i++) {
distance += myroute.legs[i].distance.value;
//for each 'leg'(route between two waypoints) we get the distance and add it to the total
}
for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
path.push(result.routes[0].overview_path[i]);
//console.log(result.routes[0].legs[0].distance);
}
totalDistance += distance;
document.getElementById('total').innerHTML = (totalDistance / 1000) + ' km';
}
});
}
}
}
</script>
<div id="dvMap"></div>
<div><p>Total Distance: <span id="total"></span></p></div>
Ok, so to solve the problem. Just remove the following line:
Reference: Google Documentation - Simple Polylines
And like that, the line is gone:
Aren't you also drawing a line between the first and last poly?
You should only draw lines between poly0 and poly1, poly1 and poly2 etc. but not poly100 and poly0 (if poly100 is the last one)
That would explain the straight line going from point B to A completing the shape. you don't want to complete the shape, so stop drawing. is there no function you can set to not complete the shape?
I only know of a very expensive work around and that is to trace back in reverse order from B to A along the same route. But that is probably not what you are looking for
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.
I am trying to display a list of the places and their phone numbers on the ride side bar. the phone numbers work when i click on the markers but show up as undefined in the side bar. any help is great thanks.
$(document).ready(function(){
var map = null;
var gmarkers = [];
var service = null;
var infowindow = new google.maps.InfoWindow({size: new google.maps.Size(150,50)});
function initialize() {
var slo = new google.maps.LatLng(35.2742, -120.6631);
map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: slo,
zoom: 11
});
service = new google.maps.places.PlacesService(map);
var request = {
location: slo,
radius: 30000,
types: ['hospital']
};
infowindow = new google.maps.InfoWindow();
service.nearbySearch(request, callback);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
if (place.icon) {
var image = new google.maps.MarkerImage(
place.icon, new google.maps.Size(71, 71),
new google.maps.Point(0, 0), new google.maps.Point(17, 34),
new google.maps.Size(25, 25));
} else var image = null;
var marker = new google.maps.Marker({
map: map,
icon: image,
position: place.geometry.location
});
var request = {
reference: place.reference
};
google.maps.event.addListener(marker,'click',function(){
service.getDetails(request, function(place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var contentStr = '<h5>'+place.name+'</h5><p>'+place.formatted_address;
if (!!place.formatted_phone_number) contentStr += '<br>'+place.formatted_phone_number;
if (!!place.website) contentStr += '<br><a target="_blank" href="'+place.website+'">'+place.website+'</a>';
contentStr += '<br>'+place.types+'</p>';
infowindow.setContent(contentStr);
infowindow.open(map,marker);
} else {
var contentStr = "<h5>No Result, status="+status+"</h5>";
infowindow.setContent(contentStr);
infowindow.open(map,marker);
}
});
});
gmarkers.push(marker);
var side_bar_html = "<a href='javascript:google.maps.event.trigger(gmarkers["+parseInt(gmarkers.length-1)+"],\"click\");'>"+place.name+"-"+place.formatted_phone_number+"</a><br>";
document.getElementById('side_bar').innerHTML += side_bar_html;
}
google.maps.event.addDomListener(window, 'load', initialize);
});
The formatted phone number displayed in the infoWindow is returned in the placeDetails response, which happens when the marker is clicked, it isn't available in the nearbySearch response, which is used to create the sidebar.