Google Map Direction Render Alternate Route How To Select Desired Path - javascript

I am working on google map directions I am following the google's navigation app.
I am able to get all the possible alternative routes by DirectionsService and can give the polylines different colors I want the user to be able to select his desired path just bu clicking on the poly lines some how have have not found any thing for this.
My code:
directionsService.route(request, function(response, status) {
var points = [];
if (status == google.maps.DirectionsStatus.OK) {
try {
var polycolour = "";
var Opacity = 0;
//var PolyLine = '';
for (var i = 0, len = response.routes.length; i < len; i++) {
if (i == 0) {
polycolour = "Blue";
Opacity = 5;
}
else {
polycolour = "grey";
Opacity = 2;
}
directionsDisplay = new google.maps.DirectionsRenderer({
map: map,
directions: response,
routeIndex: i,
draggable : true,
polylineOptions: {
strokeColor: polycolour,
strokeWeight: Opacity
}
});
var infowindow2 = new google.maps.InfoWindow();
//var step = 10;
//alert(angular.toJson(response.routes[0].legs[0].steps[i]));
infowindow2.setContent(""+((response.routes[i].legs[0].distance.value)/1000)+" KM");
infowindow2.setPosition(response.routes[i].legs[0].steps[8].end_location);
infowindow2.open(map);
}
//directionsDisplay.setMap(map);
google.maps.event.addListener(directionsDisplay, 'click', function(){
alert("helo");
});
//for (var k = 0, len = response.routes.length; k < len; k++) {
//var myRoute = response.routes[k].legs[0];
//for (var i = 0; i < myRoute.steps.length; i++) {
//for (var j = 0; j < myRoute.steps[i].lat_lngs.length; j++) {
// points.push(myRoute.steps[i].lat_lngs[j]);
//}
//}
//var routLine = new google.maps.Polyline(
//{
//path: points,
//strokeColor: "Red",
//strokeOpacity: 0.5,
// strokeWeight: 10
// }
// );
// }
// routLine.setMap(map)
// Add a listener for the rightclick event on the routLine
//google.maps.event.addListener(routLine, 'click', function(e){
//try {
//alert(angular.toJson(e));
//}
//catch (err)
//{
// alert(err);
//}
// });
//alert(angular.toJson(response.routes[0].legs[0].steps));
//google.maps.event.addListener(PolyLine, 'routeindex_changed', function() {
//alert("Bingo");
//computeTotalDistance(directionsDisplay.getRouteIndex());
//});
//alert(response.routes.length);
//directionsDisplay.setDirections(response);
}
catch (err)
{
alert(err);
}
}
});

First you need to tell the request that you want alternative routes, like this
// for example
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
travelMode: google.maps.TravelMode[DRIVING]
};
Then you have multiple response.routes objects (notice, sometimes you only get 1 route).
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
for(var i in response.routes ) {
// ...
}
}
}
Now you can use response.routes[i] as the source for direction render.
Or you make your own polyline. Use response.routes[i].overview_path as the path
var line = new google.maps.Polyline({
path: response.routes[i].overview_path,
strokeColor: "#ff0000", // you might want different colors per suggestion
strokeOpacity: 0.7,
strokeWeight: 3
});
line.setMap(map);
Here is an functioning example.
Just change your API key.
As you asked for, clicking on a route highlights it
UPDATE: I like it this way.
Both grey lines and colored lines are generated. But highlighting only shows 1 of the suggestions on the map.
The big, grey line is nice to click on. So it gets the click event instead of the colored line.
This is also the easiest way to avoid the Z-index problem.
And I store data (duration, distance), that I show on an infoWindow
<!DOCTYPE html>
<html>
<head>
<title>Google Map Direction Render Alternate Route How To Select Desired Path</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 90%;
}
</style>
</head>
<body>
<form id="form">
<input id="from" placeholder="From" value="Brussel" />
<input id="to" placeholder="To" value="Antwerpen" />
<input type="submit" value="GO" />
</form>
<div id="map"></div>
<div id="info">
Stackoverflow
</div>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
<script>
var map;
var directionsService;
var polylines = [];
var shadows = [];
var data = [];
var infowindow;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.84659376378408, lng: 4.3531406857355215},
zoom: 12,
mapTypeId: 'terrain'
});
google.maps.event.addDomListener(document.getElementById('form'), 'submit', function(e) {
calcRoute(
document.getElementById('from').value,
document.getElementById('to').value
);
// prevent the form from really submitting
e.preventDefault();
return false;
});
directionsService = new google.maps.DirectionsService();
// get the bounds of the polyline
// http://stackoverflow.com/questions/3284808/getting-the-bounds-of-a-polyine-in-google-maps-api-v3
google.maps.Polyline.prototype.getBounds = function(startBounds) {
if(startBounds) {
var bounds = startBounds;
}
else {
var bounds = new google.maps.LatLngBounds();
}
this.getPath().forEach(function(item, index) {
bounds.extend(new google.maps.LatLng(item.lat(), item.lng()));
});
return bounds;
};
}
// this function calculates multiple suggested routes.
// We will draw 3 (broad stroke) suggested routs in grey. These are broad to click on them easier.
// We duplicate these routes with a thin, colored line; only route 0 is shown.
function calcRoute(start, end) {
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
unitSystem: google.maps.UnitSystem.METRIC,
travelMode: google.maps.TravelMode['DRIVING']
};
directionsService.route(request, function(response, status) {
// clear former polylines
for(var j in polylines ) {
polylines[j].setMap(null);
shadows[j].setMap(null);
}
polylines = [];
shadows = [];
data = [];
if (status == google.maps.DirectionsStatus.OK) {
var bounds = new google.maps.LatLngBounds();
for(var i in response.routes) {
// let's make the first suggestion highlighted;
var hide = (i==0 ? false : true);
var shadow = drawPolylineShadow(response.routes[i].overview_path, '#666666');
var line = drawPolyline(response.routes[i].overview_path, '#0000ff', hide);
polylines.push(line);
shadows.push(shadow);
// let's add some data for the infoWindow
data.push({
distance: response.routes[i].legs[0].distance,
duration: response.routes[i].legs[0].duration,
end_address: response.routes[i].legs[0].end_address,
start_address: response.routes[i].legs[0].start_address,
end_location: response.routes[i].legs[0].end_location,
start_location: response.routes[i].legs[0].start_location
});
bounds = line.getBounds(bounds);
google.maps.event.addListener(shadow, 'click', function(e) {
// detect which route was clicked on
var index = shadows.indexOf(this);
highlightRoute(index, e);
});
}
map.fitBounds(bounds);
}
});
}
// this makes one of the colored routes visible.
function highlightRoute(index, e) {
for(var j in polylines ) {
if(j==index) {
//var color = '#0000ff';
polylines[j].setMap(map);
// feel free to customise this string
var contentString =
'<span>'+ data[j].distance.text +'</span><br/>'+
'<span>'+ data[j].duration.text +'</span><br/>'+
'<span>route: '+ j +'</span><br/>'+
//'From: <span>'+ data[j].start_address +'</span><br/>'+
//'To: <span>'+ data[j].end_address +'</span><br/>'+
'';
if(e) {
var position = new google.maps.LatLng(e.latLng.lat(), e.latLng.lng());
// it may be needed to close the previous infoWindow
if(infowindow) {
infowindow.close();
infowindow = null;
}
infowindow = new google.maps.InfoWindow({
content: contentString,
position: position,
map: map
});
//infowindow.open(map, polylines[j]);
}
}
else {
polylines[j].setMap(null);
}
}
}
// returns a polyline.
// if hide is set to true, the line is not put on the map
function drawPolyline(path, color, hide) {
var line = new google.maps.Polyline({
path: path,
strokeColor: color,
strokeOpacity: 0.9,
strokeWeight: 3
});
if(! hide) {
line.setMap(map);
}
return line;
}
function drawPolylineShadow(path, color, hide) {
var line = new google.maps.Polyline({
path: path,
strokeColor: color,
strokeOpacity: 0.4,
strokeWeight: 7
});
if(! hide) {
line.setMap(map);
}
return line;
}
google.maps.event.addDomListener(window, 'load', initMap);
</script>
</body>
</html>
earlier code. this changes the color of the polyLine
<!DOCTYPE html>
<html>
<head>
<title>Suggested routes</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 90%;
}
</style>
</head>
<body>
<form id="form">
<input id="from" placeholder="From" value="Brussel" />
<input id="to" placeholder="To" value="Antwerpen" />
<input type="submit" value="GO" />
</form>
<div id="map"></div>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
<script>
var map;
var directionsService;
var polylines = [];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.84659376378408, lng: 4.3531406857355215},
zoom: 12,
mapTypeId: 'terrain'
});
google.maps.event.addDomListener(document.getElementById('form'), 'submit', function(e) {
calcRoute(
document.getElementById('from').value,
document.getElementById('to').value
);
// prevent the form from really submitting
e.preventDefault();
return false;
});
directionsService = new google.maps.DirectionsService();
// get the bounds of the polyline
// http://stackoverflow.com/questions/3284808/getting-the-bounds-of-a-polyine-in-google-maps-api-v3
google.maps.Polyline.prototype.getBounds = function(startBounds) {
if(startBounds) {
var bounds = startBounds;
}
else {
var bounds = new google.maps.LatLngBounds();
}
this.getPath().forEach(function(item, index) {
bounds.extend(new google.maps.LatLng(item.lat(), item.lng()));
});
return bounds;
};
}
function calcRoute(start, end) {
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
unitSystem: google.maps.UnitSystem.METRIC,
travelMode: google.maps.TravelMode['DRIVING']
};
directionsService.route(request, function(response, status) {
// clear former polylines
for(var j in polylines ) {
polylines[j].setMap(null);
}
polylines = [];
if (status == google.maps.DirectionsStatus.OK) {
var bounds = new google.maps.LatLngBounds();
// draw the lines in reverse orde, so the first one is on top (z-index)
for(var i=response.routes.length - 1; i>=0; i-- ) {
// let's make the first suggestion highlighted;
if(i==0) {
var color = '#0000ff';
}
else {
var color = '#999999';
}
var line = drawPolyline(response.routes[i].overview_path, color);
polylines.push(line);
bounds = line.getBounds(bounds);
google.maps.event.addListener(line, 'click', function() {
// detect which route was clicked on
var index = polylines.indexOf(this);
highlightRoute(index);
});
}
map.fitBounds(bounds);
}
});
}
function highlightRoute(index) {
for(var j in polylines ) {
if(j==index) {
var color = '#0000ff';
}
else {
var color = '#999999';
}
polylines[j].setOptions({strokeColor: color});
}
}
function drawPolyline(path, color) {
var line = new google.maps.Polyline({
path: path,
strokeColor: color,
strokeOpacity: 0.7,
strokeWeight: 3
});
line.setMap(map);
return line;
}
google.maps.event.addDomListener(window, 'load', initMap);
</script>
</body>
</html>

Related

Show form in google maps in expanded mode on a webpage

I am trying to fix a bug in existing code.
I'm new to javascript and css.
The program was developed in .net vistual studio.
The problem is this: I have a page that has a map where I make a circle in a region of it. The behavior the system should have is when I click the circle button, the system should open a form with information from the region where I made the circle. However, when I expand the map, the form is hidden behind the map. Can anyone tell me how I can bring this form forward in the expanded map form? In the attached image, the window behind the map appears in blue.
click to see map image
function configPontosMapa(sender, args) {
var label, marker, dataItem, location, circle, coordenadas, polygon, tableView, lats,
lngs, idPonto, nome, barra, shape, idPtoGlobalAux;
var dataItems = $find(gridPontos).get_masterTableView().get_dataItems();
var latlngBounds = new google.maps.LatLngBounds();
mapa.ClearMap();
MapaLabel.ClearLabels();
clearMapaBotao();
clearMapaBotaoSubPonto();
for (var i = 0; i < dataItems.length; i++) {
dataItem = dataItems[i];
idPonto = dataItem.getDataKeyValue("IdPontoGeografico");
idPtoGlobalAux = dataItem.getDataKeyValue("IdPontoGlobal");
nome = dataItem.getDataKeyValue("Nome");
lats = dataItem.getDataKeyValue("LatitudesFormatadas").split('|');
lngs = dataItem.getDataKeyValue("LongitudesFormatadas").split('|');
if (lats.length == 1) {
location = new google.maps.LatLng(parseFloat(lats[0]), parseFloat(lngs[0]));
var raio = parseFloat(dataItem.getDataKeyValue("Raio"));
if (!raio) {
raio = 1;
}
circle = new google.maps.Circle({
center: location,
radius: raio,
strokeColor: corPadrao,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: corPadrao,
fillOpacity: 0.15,
map: mapa.Mapa,
entity: idPonto,
idPontoGlobal: idPtoGlobalAux,
zIndex: 0
});
if (idPtoGlobalAux) {
barra = new MapaBarraBotao(mapa.Mapa, circle.getCenter(), circle, showModalPontoGlobal);
}
else {
barra = new MapaBarraBotao(mapa.Mapa, circle.getCenter(), circle, showModalNovoPonto);
}
circle.barraBotao = barra;
shape = circle;
mapa.NewCircleByShape(circle);
latlngBounds.union(circle.getBounds());
marker = mapa.NewMarker();
marker.bindTo('position', circle, 'center');
marker.setOptions({ ponto: circle, title: nome });
marker.setIcon('../../../Images/Ponto/MarcadorPonto1.png');
//label.bindEvents(marker);
circle.setEditable(true);
circle.barraBotao.ocultaBotaoSalvarCancelar();
google.maps.event.addListener(circle, 'rightclick', function () {
novoSubponto(this);
});
google.maps.event.addListener(circle, 'center_changed', function () {
this.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
this.barraBotao.draw(this.getCenter());
});
google.maps.event.addListener(circle, 'radius_changed', function () {
this.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
});
} else {
coordenadas = [];
for (var j = 0; j < lats.length; j++) {
coordenadas[j] = Mapa.NewLatLng(parseFloat(lats[j]), parseFloat(lngs[j]));
}
latlngBounds.extend(coordenadas[0]);
polygon = mapa.NewPolygonByPaths(coordenadas);
polygon.setEditable(true);
polygon.getPath().obj = polygon;
if (idPtoGlobalAux) {
barra = new MapaBarraBotao(mapa.Mapa, polygon.getPath().getAt(0), polygon, showModalPontoGlobal);
}
else {
barra = new MapaBarraBotao(mapa.Mapa, polygon.getPath().getAt(0), polygon, showModalNovoPonto);
}
polygon.barraBotao = barra;
shape = polygon;
polygon.setOptions({
entity: idPonto,
idPontoGlobal: idPtoGlobalAux,
barraBotao: barra,
zIndex: 0
});
marker = mapa.NewMarkerAtPoint(coordenadas[0]);
marker.setOptions({ ponto: polygon, title: nome });
marker.setIcon('../../../Images/Ponto/MarcadorPonto1.png');
polygon.barraBotao.ocultaBotaoSalvarCancelar();
polygon.marker = marker;
google.maps.event.addListener(polygon.getPath(), 'set_at', function () {
var coord = this.getAt(0);
this.obj.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
this.obj.barraBotao.draw(coord);
this.obj.label.draw(coord);
this.obj.marker.setPosition(coord);
});
google.maps.event.addListener(polygon.getPath(), 'insert_at', function () {
this.obj.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
this.obj.barraBotao.draw(this.getAt(0));
});
google.maps.event.addListener(polygon, 'rightclick', function () {
novoSubPoligono(this);
});
}
google.maps.event.addListener(marker, 'click', function () {
mapa.Mapa.setCenter(this.getPosition());
mapa.Mapa.setZoom(15);
});
if (idPonto == 0) {
label = createLabel(dataItem.getDataKeyValue("Nome"), null, shape, showModalPontoGlobal);
}
else {
label = createLabel(dataItem.getDataKeyValue("Nome"), null, shape);
}
label.bindEvents(marker);
shape.label = label;
arrayBotao.push(barra);
}
mapa.SetBoundsCircle(latlngBounds);
}
If this form has position prop then you can add z-index to this element.
z-index: 10 should do.

Google Maps JS API v3 - How to check and display distance between polygon points

I'm using google maps API to allow user draw custom polygons on the map. I need to check and display length of every single border.
I already use Geometry Library and Map Label Library to get and show computed area of polygon (also changing on 'insert_at' and 'set_at' events), but unfortunately I do not know how to get border lengths. Any help will be appreciated.
Used code sample:
var labels = [];
var allOverlays = [];
function setSelection(shape) {
selectedShape = shape;
shape.setEditable(true);
}
function initMap() {
var options = {
zoom: 14,
center: {lat: 52.250618, lng: 20.9774}
}
var map = new google.maps.Map(document.getElementById('map'), options);
var drawingManager = new google.maps.drawing.DrawingManager({
markerOption: {
draggable: false
},
polygonOptions: {
draggable: false,
fillColor: '#5C6BC0',
fillOpacity: 0.45,
strokeWeight: 0,
editable: true,
zIndex: 1
},
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['circle', 'polygon']
},
circleOptions: {
fillColor: '#5C6BC0',
fillOpacity: 0.45,
strokeWeight: 0,
editable: true,
zIndex: 1
},
map: map
});
function attachPolygonInfoWindow(polygon) {
var path = polygon.getPath();
var points = path.getArray();
var area = (google.maps.geometry.spherical.computeArea(path.getArray())).toFixed(0);
var bounds = new google.maps.LatLngBounds();
var i;
for (i = 0; i < points.length; i++) {
bounds.extend(points[i]);
}
var boundsCenter = bounds.getCenter();
var mapLabel = new MapLabel({
map: map,
fontSize: 20,
align: 'left'
});
if (!labels.length) {
labels.push(mapLabel)
}
showPolygonInfoWindow(labels, boundsCenter, area);
}
function showPolygonInfoWindow(arr, position, text) {
arr.forEach((el) => {
el.set('position', position);
el.set('text', text + 'm2')
})
}
function removePolygonInfoWindow() {
for (var i = 0; i < labels.length; i++) {
labels[i].setMap(null);
}
labels = [];
}
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
allOverlays.push(e);
if (e.type != google.maps.drawing.OverlayType.MARKER) {
drawingManager.setDrawingMode(null);
var newShape = e.overlay;
newShape.type = e.type;
google.maps.event.addListener(newShape, 'click', function() {
setSelection(newShape);
});
if (newShape.type == "polygon") {
var path = newShape.getPath();
google.maps.event.addListener(path, 'insert_at', function() {
attachPolygonInfoWindow(newShape);
});
google.maps.event.addListener(path, 'set_at', function() {
attachPolygonInfoWindow(newShape);
});
attachPolygonInfoWindow(newShape);
}
setSelection(newShape);
}
});
}
initMap();
<script src="https://maps.google.com/maps/api/js?sensor=false&libraries=drawing,geometry">
</script>
<script type="text/javascript" src="https://cdn.rawgit.com/googlemaps/js-map-label/gh-pages/src/maplabel.js"></script>
Working example Codepen
I would like to display the length of each border on the side of each border.
My suggestion would be to when you create the center label, also process thru the paths of the polygon, compute their lengths and centers; then create MapLabel objects for each and place it at the center of the side. Something like:
for (var i=0; i<polygon.getPath().getLength(); i++) {
// for each side in path, compute center and length
var start = polygon.getPath().getAt(i);
var end = polygon.getPath().getAt(i<polygon.getPath().getLength()-1 ? i+1 : 0);
var sideLength = google.maps.geometry.spherical.computeDistanceBetween(start,end);
var sideCenter = google.maps.geometry.spherical.interpolate(start, end, 0.5);
var sideLabel = new MapLabel({
map: map,
fontSize: 20,
align: "center"
});
sideLabel.set("position", sideCenter);
sideLabel.set("text", sideLength.toFixed(2)+"m");
polygon.labels.push(sideLabel);
}
proof of concept fiddle
code snippet:
var labels = [];
var allOverlays = [];
function setSelection(shape) {
selectedShape = shape;
shape.setEditable(true);
}
function initMap() {
var options = {
zoom: 14,
center: {
lat: 52.250618,
lng: 20.9774
}
};
var map = new google.maps.Map(document.getElementById("map"), options);
var drawingManager = new google.maps.drawing.DrawingManager({
polygonOptions: {
draggable: false,
fillColor: "#5C6BC0",
fillOpacity: 0.45,
strokeWeight: 0,
editable: true,
zIndex: 1
},
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ["polygon"]
},
map: map,
drawingMode: 'polygon'
});
function attachPolygonInfoWindow(polygon) {
if (!polygon.labels) polygon.labels = [];
for (var i = 0; i < polygon.labels.length; i++) {
polygon.labels[i].setMap(null);
}
polygon.labels = [];
var path = polygon.getPath();
var points = path.getArray();
var area = google.maps.geometry.spherical
.computeArea(path.getArray())
.toFixed(0);
var bounds = new google.maps.LatLngBounds();
var i;
for (i = 0; i < points.length; i++) {
bounds.extend(points[i]);
}
var boundsCenter = bounds.getCenter();
var centerLabel = new MapLabel({
map: map,
fontSize: 20,
align: "left"
});
polygon.labels.push(centerLabel);
centerLabel.set("position", bounds.getCenter());
centerLabel.set("text", area + "m2");
if (path.getLength() < 2) return;
for (var i = 0; i < polygon.getPath().getLength(); i++) {
// for each side in path, compute center and length
var start = polygon.getPath().getAt(i);
var end = polygon.getPath().getAt(i < polygon.getPath().getLength() - 1 ? i + 1 : 0);
var sideLength = google.maps.geometry.spherical.computeDistanceBetween(start, end);
var sideCenter = google.maps.geometry.spherical.interpolate(start, end, 0.5);
var sideLabel = new MapLabel({
map: map,
fontSize: 20,
align: "center"
});
sideLabel.set("position", sideCenter);
sideLabel.set("text", sideLength.toFixed(2) + "m");
polygon.labels.push(sideLabel);
}
}
function removePolygonInfoWindow() {
for (var i = 0; i < labels.length; i++) {
labels[i].setMap(null);
}
labels = [];
}
google.maps.event.addListener(drawingManager, "overlaycomplete", function(e) {
allOverlays.push(e);
if (e.type != google.maps.drawing.OverlayType.MARKER) {
drawingManager.setDrawingMode(null);
var newShape = e.overlay;
newShape.type = e.type;
google.maps.event.addListener(newShape, "click", function() {
setSelection(newShape);
});
if (newShape.type == "polygon") {
var path = newShape.getPath();
google.maps.event.addListener(path, "insert_at", function() {
attachPolygonInfoWindow(newShape);
});
google.maps.event.addListener(path, "set_at", function() {
attachPolygonInfoWindow(newShape);
});
attachPolygonInfoWindow(newShape);
}
setSelection(newShape);
}
});
}
initMap();
html,
body,
#map {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=drawing"></script>
<script src="https://cdn.jsdelivr.net/npm/js-map-label#1.0.1/src/maplabel.js"></script>

fitBounds(bound) function not working properly

I have te following code:
var bound = new google.maps.LatLngBounds();
if (arrMarkers.length > 0) {
for (var i = 0; i < arrMarkers.length; i++) {
bound.extend(new google.maps.LatLng(arrMarkers[i].getPosition().lat(), arrMarkers[i].getPosition().lng()));
}
strDefaultLtLong = bound.getCenter();// get center from bounds
}
var image = 'Images/star.png';
var mapOptions = {
center: strDefaultLtLong,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDoubleClickZoom: true,
zoom: parseInt(strDefaultZoomLevel)
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
if (arrMarkers.length == 1) {
map.setZoom(parseInt(strDefaultZoomLevel));
}
else if (arrMarkers.length > 1) {
map.fitBounds(bound);
google.maps.event.addListener(map, 'idle', function (event) {
if (map.getZoom() > parseInt(strDefaultZoomLevel)) {
map.setZoom(parseInt(strDefaultZoomLevel));
}
});
google.maps.event.clearListeners(map, 'idle');
}
I have list of locations in arrMarkers. fitBounds() function works only if locations have different location but if list of locations has same location(Lat&Long) then it displays fully zoomed map.
How can I handle that to default zoom or particular zoom level so that listing will display appropriatly?
Thanks..
if the locations of the markers are really equal, you may compare the SW and the NE of the bounds, they should be equal too:
//if (arrMarkers.length == 1) {
if(bounds.getSouthWest().toUrlValue()
===
bounds.getNorthEast().toUrlValue()){
map.setZoom(parseInt(strDefaultZoomLevel));
}
Demo:
function init() {
var goo=google.maps,
strDefaultZoomLevel='7',
map = new goo.Map(document.getElementById('map_canvas'),
{
zoom: parseInt(strDefaultZoomLevel),
noClear:true
}),
btn=document.getElementById('btn'),
markers=[
new goo.Marker({position:{lat:11.11,lng:22.22},
icon:{
url:'http://maps.google.com/mapfiles/dir_0.png',
scaledSize:new goo.Size(48,48)
}}),
new goo.Marker({position:{lat:11.11,lng:22.22},
icon:{
url:'http://maps.google.com/mapfiles/dir_60.png',
scaledSize:new goo.Size(48,48)
}}),
new goo.Marker({position:{lat:66.66,lng:77.77},
icon:{
url:'http://maps.google.com/mapfiles/dir_0.png',
scaledSize:new goo.Size(48,48)
}})
];
map.controls[goo.ControlPosition.BOTTOM_CENTER]
.push(btn);
goo.event.addDomListener(btn,'click',function(){
for(var i=0;i<markers.length;++i){
markers[i].setMap(null);
}
this.value=(this.value==='draw equal markers')
? 'draw different markers'
: 'draw equal markers';
var arrMarkers=markers.slice.apply(markers,(this.value==='draw equal markers')
? [1,3]
: [0,2]),
bounds=new goo.LatLngBounds();
for(var i=0;i<arrMarkers.length;++i){
arrMarkers[i].setMap(map);
bounds.extend(arrMarkers[i].getPosition());
}
if(bounds.getSouthWest().toUrlValue()
===
bounds.getNorthEast().toUrlValue()){
map.setOptions({
zoom:parseInt(strDefaultZoomLevel),
center:bounds.getCenter()
});
}
else{
map.fitBounds(bounds);
}
});
google.maps.event.trigger(btn,'click');
}
html,body,#map_canvas{height:100%;margin:0;padding:0;}
#btn{font:14px bold Monospace;background:tomato;margin-bottom:12px;}
<div id="map_canvas">
<input id="btn" type="button" value="draw equal markers"/>
</div>
<script src="https://maps.googleapis.com/maps/api/js?v=3&callback=init"></script>

How to use a polygon string in google maps api

I have the following polygon string:
POLYGON ((5.031728766 52.016855117, 5.039437914 52.018712029, 5.038732065 52.01933205, 5.03880625 52.019536002, 5.036666299 52.021123062, 5.037225302 52.021436208, 5.036494826 52.021980534, 5.040069034 52.024180983, 5.041131857 52.023541011, 5.041485972 52.023745389, 5.042328698 52.023235595, 5.043167194 52.022781293, 5.043379189 52.022938683, 5.04366399 52.022788333, 5.044615961 52.023393034, 5.046878469 52.022023355, 5.047609948 52.02119413, 5.048777737 52.022018526, 5.049465821 52.022060318, 5.05135083 52.021274278999996, 5.053039915 52.020873436, 5.052288001 52.019935439, 5.052174884 52.019294199, 5.053026298 52.019318482, 5.053120663 52.018982405, 5.05237284 52.018935127, 5.051442801 52.019120203, 5.046607457 52.016128313, 5.046220739 52.015628312, 5.04412241 52.015134981, 5.043853082 52.015544473, 5.043410675 52.015932024, 5.042704158 52.016254485, 5.042235947 52.016357569, 5.040118936 52.0166409, 5.039579367 52.015163505, 5.034087326 52.015907152, 5.03224395 52.016039016, 5.031728766 52.016855117), (5.043324081 52.017406693, 5.046676295 52.019354241, 5.048003676 52.020235065, 5.046772806 52.021010583, 5.045897693 52.02180469, 5.043619067 52.020981305, 5.042189351 52.020258164, 5.039736347 52.018909018, 5.041350353 52.018037167, 5.042763839 52.01739758, 5.042763839 52.01739758, 5.043324081 52.017406693))
I would like to use it to plot a simple polygon using the Google Maps API, e.g.:
var triangleCoords = [
new google.maps.LatLng(25.774252, -80.190262),
new google.maps.LatLng(18.466465, -66.118292),
new google.maps.LatLng(32.321384, -64.75737),
new google.maps.LatLng(25.774252, -80.190262)
];
How can I:
either iterate over the text and grab the coordinates
use an alternative more efficient way with google.maps.LatLng(POLYGONTEXTSTRING)
Using modified code from this related question: Polygon array does not work in Google map API. Your string is formatted slightly differently, don't know if that was on purpose.
proof of concept fiddle
code snippet:
var map;
var bounds = new google.maps.LatLngBounds();
// your POLYGON
var polygonStr = "POLYGON ((5.031728766 52.016855117, 5.039437914 52.018712029, 5.038732065 52.01933205, 5.03880625 52.019536002, 5.036666299 52.021123062, 5.037225302 52.021436208, 5.036494826 52.021980534, 5.040069034 52.024180983, 5.041131857 52.023541011, 5.041485972 52.023745389, 5.042328698 52.023235595, 5.043167194 52.022781293, 5.043379189 52.022938683, 5.04366399 52.022788333, 5.044615961 52.023393034, 5.046878469 52.022023355, 5.047609948 52.02119413, 5.048777737 52.022018526, 5.049465821 52.022060318, 5.05135083 52.021274278999996, 5.053039915 52.020873436, 5.052288001 52.019935439, 5.052174884 52.019294199, 5.053026298 52.019318482, 5.053120663 52.018982405, 5.05237284 52.018935127, 5.051442801 52.019120203, 5.046607457 52.016128313, 5.046220739 52.015628312, 5.04412241 52.015134981, 5.043853082 52.015544473, 5.043410675 52.015932024, 5.042704158 52.016254485, 5.042235947 52.016357569, 5.040118936 52.0166409, 5.039579367 52.015163505, 5.034087326 52.015907152, 5.03224395 52.016039016, 5.031728766 52.016855117), (5.043324081 52.017406693, 5.046676295 52.019354241, 5.048003676 52.020235065, 5.046772806 52.021010583, 5.045897693 52.02180469, 5.043619067 52.020981305, 5.042189351 52.020258164, 5.039736347 52.018909018, 5.041350353 52.018037167, 5.042763839 52.01739758, 5.042763839 52.01739758, 5.043324081 52.017406693))";
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
});
drawPoly(polygonStr);
map.fitBounds(bounds);
}
function drawPoly(multipolygonWKT) {
var polylines = [];
var toReturn = [];
multipolygonWKT = multipolygonWKT.replace("POLYGON ", "");
var formattedValues = multipolygonWKT.replace("))", "");
formattedValues = formattedValues.replace("((", "");
var linesCoords = formattedValues.split("), (");
for (i = 0; i < linesCoords.length; i++) {
polylines[i] = [];
var singleLine = linesCoords[i].split(", ");
for (j = 0; j < singleLine.length; j++) {
var coordinates = singleLine[j].split(" ");
var latlng = new google.maps.LatLng(parseFloat(coordinates[1]), parseFloat(coordinates[0]));
bounds.extend(latlng);
polylines[i].push(latlng);
}
}
toReturn.push(
new google.maps.Polygon({
map: map,
paths: polylines,
strokeColor: 'red',
strokeOpacity: 1,
strokeWeight: 2,
zIndex: 1
}));
return toReturn;
}
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?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"border: 2px solid #3872ac;"></div>
Since paths parameter of google.maps.Polygon object expects the array of google.maps.LatLng to be specified, the following example demonstrates how to parse input string:
function parsePolygonPaths(svalue)
{
var result = [];
var r = /\(([^)]+)\)/g;
svalue = svalue.slice(9, -1);
while (matches = r.exec(svalue)) {
var vals = matches[1].split(',');
var coords = vals.map(function(val){
var ll = val.trim().split(' ');
return new google.maps.LatLng(ll[0], ll[1]);
});
result.push(coords);
}
return result;
}
It is assumed that input string has the following format:
POLYGON ((lat11 lng11,..lat1n,lng1n),(lat21 lng21,..lat2n,lng2n),..(latn1 lngn1,..latnn,lngnn))
Returned value:
[
[google.maps.LatLng(lat11,lng11),..google.maps.LatLng(lat1n,lng1n)]
[google.maps.LatLng(lat21,lng21),..google.maps.LatLng(lat2n,lng2n)]
..
[google.maps.LatLng(latn1,lngn1),..google.maps.LatLng(latnn,lngnn)]
]
Example
var polygonString = 'POLYGON ((5.031728766 52.016855117, 5.039437914 52.018712029, 5.038732065 52.01933205, 5.03880625 52.019536002, 5.036666299 52.021123062, 5.037225302 52.021436208, 5.036494826 52.021980534, 5.040069034 52.024180983, 5.041131857 52.023541011, 5.041485972 52.023745389, 5.042328698 52.023235595, 5.043167194 52.022781293, 5.043379189 52.022938683, 5.04366399 52.022788333, 5.044615961 52.023393034, 5.046878469 52.022023355, 5.047609948 52.02119413, 5.048777737 52.022018526, 5.049465821 52.022060318, 5.05135083 52.021274278999996, 5.053039915 52.020873436, 5.052288001 52.019935439, 5.052174884 52.019294199, 5.053026298 52.019318482, 5.053120663 52.018982405, 5.05237284 52.018935127, 5.051442801 52.019120203, 5.046607457 52.016128313, 5.046220739 52.015628312, 5.04412241 52.015134981, 5.043853082 52.015544473, 5.043410675 52.015932024, 5.042704158 52.016254485, 5.042235947 52.016357569, 5.040118936 52.0166409, 5.039579367 52.015163505, 5.034087326 52.015907152, 5.03224395 52.016039016, 5.031728766 52.016855117), (5.043324081 52.017406693, 5.046676295 52.019354241, 5.048003676 52.020235065, 5.046772806 52.021010583, 5.045897693 52.02180469, 5.043619067 52.020981305, 5.042189351 52.020258164, 5.039736347 52.018909018, 5.041350353 52.018037167, 5.042763839 52.01739758, 5.042763839 52.01739758, 5.043324081 52.017406693))';
function initialize() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var result = parsePolygonPaths(polygonString);
var bounds = new google.maps.LatLngBounds();
// Construct the polygon.
result.forEach(function(coords){
coords.forEach(function(loc){
bounds.extend(loc);
});
var poly = new google.maps.Polygon({
paths: coords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
poly.setMap(map);
});
map.fitBounds(bounds);
map.panToBounds(bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);
function parsePolygonPaths(svalue)
{
var result = [];
var r = /\(([^)]+)\)/g;
svalue= svalue.slice(9, -1);
while (matches = r.exec(svalue)) {
var vals = matches[1].split(',');
var coords = vals.map(function(val){
var ll = val.trim().split(' ');
return new google.maps.LatLng(ll[1], ll[0]);
});
result.push(coords);
}
return result;
}
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<div id="map-canvas"></div>

Add mouseover event to directionsRenderer Google Maps API v3

How can I add a mouseover event listener to the directionsRenderer when using the DirectionsService?
I know how to add a listener to a straight line but can't seem to find the object in the directionsRenderer.
For example this works:
function getStraightLine(coordinates) {
if (progress.length == 0)
progress = coordinates;
else
progress.push(coordinates[1]);
updateDistance();
var line = new google.maps.Polyline({
path: coordinates,
strokeColor: "#FF0000",
strokeOpacity: .5,
strokeWeight: 2,
map: map
});
google.maps.event.addListener(line, 'mouseover', function(){
alert("moused over straight line!");
});
return line;
}
But this doesn't:
function getDirectionsPath(coordinates) {
var directionsPath = new google.maps.DirectionsRenderer();
directionsPath.setMap(map);
var request = {
origin: coordinates[0],
destination: coordinates[1],
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
var coordinates = result.routes[0].overview_path;
if (progress.length == 0)
progress = coordinates;
else
progress = progress.concat(coordinates);
directionsPath.setDirections(result);
google.maps.event.addListener(directionsPath, 'mouseover', function(){
alert("moused over straight line!");
});
}
});
return directionsPath;
}
Instead of directionsPath I've tried result, result.routes[0], and a few others.
So what object should I use?
Will you use the 'drag' event on the 'polyline' that generated from the setDirections(directionsResult) method?
If you don't, I think you can create a 'polyline' by yourself like this:
directionsService.route(request, function (result, status)
{
var myRoute = result.routes[0].legs[0];
if (status == google.maps.DirectionsStatus.OK)
{
for (var i = 0; i < myRoute.steps.length; i++) {
for (var j = 0; j < myRoute.steps[i].lat_lngs.length; j++) {
points.push(myRoute.steps[i].lat_lngs[j]);
}
}
}
drawRoute();
}
function drawRoute()
{
var routLine = new google.maps.Polyline(
{
path: points,
strokeColor: "Red",
strokeOpacity: 0.5,
strokeWeight: 10
}
);
routLine.setMap(mapCanvas);
// Add a listener for the rightclick event on the routLine
*google.maps.event.addListener(routLine, 'mouseover', function(){
alert("moused over straight line!");
});*
}
if you have solved the problem use the method like google.maps.DirectionsRenderer().setDirections(result)?
The reason the second example doesn't work, is because there are no events associated with the object that the DirectionsRenderer() class produces. It produces a DirectionsResult object.
http://code.google.com/apis/maps/documentation/javascript/reference.html#DirectionsRenderer
Based on the docs:
http://code.google.com/apis/maps/documentation/javascript/reference.html#DirectionsResult
The DirectionsResult object contains an array of DirectionsRoutes. Using your code above, I would use the directionsPath object to get the routes: directionsPath.routes and then get the first route directionsPath.routes[0].
From there, you'll need to use the array of LatLngs in directionsPath.routes[0] to construct a polyline, with which then you can use the mouseover event.

Categories

Resources