Draggable markers on Google transit map - javascript

I'm trying to create a transit map (with bus/metro indications) using Google Maps, but when I create the "start" and "end" markers from inputs (with autocomplete addresses), there's no way to drag any marker despite set drag option as true.
Changing the travelMode option to google.maps.TravelMode.DRIVING the draggin' is enabled. And going back this property to google.maps.TravelMode.TRANSIT the daggin' goes back to disabled.
There's a way to solve this issue?
Code:
var directionsService;
var directionsDisplay;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 14,
center: {lat: -32.89, lng: -68.845} // Mendoza.
});
directionsService = new google.maps.DirectionsService;
directionsDisplay = new google.maps.DirectionsRenderer({
draggable: true,
map: map,
panel: document.getElementById('right-panel')
});
directionsDisplay.addListener('directions_changed', function() {
var addresses = directionsDisplay.getDirections().routes[0].legs[0];
document.getElementById('from').value = addresses.start_address;
document.getElementById('to').value = addresses.end_address;
});
google.maps.event.addDomListener(document.getElementById('go'), 'click', displayRoute);
var input_from = document.getElementById('from');
var autocomplete = new google.maps.places.Autocomplete(input_from);
autocomplete.bindTo('bounds', map);
var input_to = document.getElementById('to');
var autocomplete = new google.maps.places.Autocomplete(input_to);
autocomplete.bindTo('bounds', map);
displayRoute();
}
function displayRoute() {
directionsService.route({
origin: document.getElementById('from').value,
destination: document.getElementById('to').value,
//travelMode: google.maps.TravelMode.DRIVING,
travelMode: google.maps.TravelMode.TRANSIT
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
console.log(response);
directionsDisplay.setDirections(response);
} else {
alert('Could not display directions due to: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initMap);

Unfortunately, the "draggable" mode is not permited to the TRANSIT travel mode. Just now I'm trying to find a way and I found your question by the way.
EDIT
As the google documentation says:
Users may modify cycling, walking or driving directions displayed
using a DirectionsRenderer dynamically if they are draggable, allowing
a user to select and alter routes by clicking and dragging the
resulting paths on the map. You indicate whether a renderer's display
allows draggable directions by setting its draggable property to true.
Transit directions cannot be made draggable.
Check it here: https://developers.google.com/maps/documentation/javascript/directions#TransitOptions
We will have to find another way... if I find it I'll make you know, if you find it first I'll be grateful if you told me.

The "solution" (hack) I found, using trial and error, is to prevent to show the markers the API creates:
var directionsDisplay = new m.DirectionsRenderer({
suppressMarkers: true, // Supressing the default markers
map: map,
// another options...
});
And implement my own function to show markers:
function placeMarker(e, t) {
t < 2 && (markers[t] = new m.Marker({
position: e,
draggable: true, // YES! It's draggable!
map: map
}), m.event.addListener(markers[t], "dragend", function() {
geocodePosition(markers[t].getPosition(), t);
}), markers[t].setVisible(true), geocodePosition(markers[t].getPosition(), t), arrangeBounds());
}
Then, the markers are draggable using a Google transit map... The solution is late but, I hope, not least.

Related

dynamic route with Google directions API

Initially I have two points on map. One of them being origin and other being destination.
The origin is dragable while destination is fixed.
When drawing the map for first time after page load, I have some default value for origin, while destination point gets value from database.Initial Loading works fine. I am able to draw route between origin and destination.
I draw directions on map using this below function
function calcRoute() {
var request = {
origin:myLatLng1,
destination:myLatLng,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
Now I have a event listener whenever my origin marker is draged, it gets the new latlong of the new position of orign marker, then I call the same function above to get new route.
function togglePos(){
myLatLng1 = new google.maps.LatLng(marker1.getPosition());
calcRoute();
}
This is where I am facing problem, I am not able to redraw new route between the new marked origin and the same old destination.
This is my initialize function if any1 needs it.
function initialize() {
var mapOptions = {
zoom: 13,
center: myLatLng
};
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
directionsDisplay.setMap(map);
var image = 'myimage.png';
marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
});
marker1 = new google.maps.Marker({
position: myLatLng1,
map: map,
draggable: true
});
google.maps.event.addListener(marker1, 'dragend', togglePos);
calcRoute();
}
I am not getting any javascript error.
I am building something like this.
https://developers.google.com/maps/documentation/javascript/examples/directions-simple
But instead of selecting it from drop down box, I am calling the function when marker is moved.
Fiddle link: http://jsfiddle.net/FvqAL/4/
But i have no idea why its not working on fiddle :|
I made some changes in calc route, now whenever it is called, it get marker1 position and draw route through it.
function calcRoute() {
var request = {
origin:marker1.getPosition(),
destination:myLatLng,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
Here is final fiddle if you want to check it out.
Thanks for helping :)

jQuery GeoComplete - get Location when marker is dragged

Using http://ubilabs.github.com/geocomplete/examples/draggable.html as an example.
jQuery("#geocomplete").bind("geocode:dragged", function(event, latLng){
jQuery("input[name=lat]").val(latLng.lat());
jQuery("input[name=lng]").val(latLng.lng());
});
I am able to get the marker position in form of lat lng after the marker is dragged. But I am not able to get current location of the marker after being dragged.
I want to update my location text box on the current position of marker after being dragged.
I managed to find a better work around!
The work around you that Nadeeshani posted isn't very precise and it centres the map to a nearest address.
I managed to fix this by using the google geocoded, test the following code.
var options = {
map: "#mapnew",
country: 'uk',
mapOptions: {
streetViewControl: false,
mapTypeId : google.maps.MapTypeId.HYBRID
},
markerOptions: {
draggable: true
}
};
$("#address").geocomplete(options).bind("geocode:result", function(event, result){
$('#logs').html(result.formatted_address);
var map = $("#address").geocomplete("map");
map.setZoom(18);
map.setCenter(result.geometry.location);
});
$("#address").bind("geocode:dragged", function(event, latLng){
console.log('Dragged Lat: '+latLng.lat());
console.log('Dragged Lng: '+latLng.lng());
var map = $("#address").geocomplete("map");
map.panTo(latLng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': latLng }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
var road = results[0].address_components[1].long_name;
var town = results[0].address_components[2].long_name;
var county = results[0].address_components[3].long_name;
var country = results[0].address_components[4].long_name;
$('#logs').html(road+' '+town+' '+county+' '+country);
}
}
});
});
See my JSFiddle Example
This may not be a 100% perfect solution, but I too had the same issue and this is how I got through it. This is kind of a workaround.
$("#geocomplete").bind("geocode:dragged", function(event, latLng){
$("input[name=lat]").val(latLng.lat());
$("input[name=lng]").val(latLng.lng());
$("#geocomplete").geocomplete("find", latLng.toString());
});
The only problem here is the map is setting to its default zomm size since the autocomplete is sort of re initializing here.
Hope this will help
I am not sure if this is the same issue, but my 'find' also returned the incorrect result when doing more then one 'find'. It seems it is because the 'bounds' are set on subsequent finds, and the wrong results are return.
As a workaround, I changed the "jquery.geocomplete.js" file as follow, by adding this line:
request.bounds = this.options.bounds;
just before this line (352):
this.geocoder.geocode(request, $.proxy(this.handleGeocode, this));
then the find should work as per normal:
$("#geocomplete").geocomplete("find", latLng.toString());

Google maps v3: adding a new map when function 'failure' called

On the contact page of my site two things can happen:
The user has geolocation enabled, and a map (map-canvas) will display a route from their location to a predefined location dest. This feature works fine.
The user doesn't have geolocation enabled or chooses not to allow it. An alert will show (works fine), and some text will be added to the directions-panel (works fine). The third thing I want to happen in this scenario is a new map be added to map-canvas that is centred on dest, this feature doesn't seem to be working and I can't figure out why.
Code below should give a good representation of the above:
<script type="text/javascript">
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var dest = "Unit 20, Tallaght Business Centre, Whitestown Road, Tallaght Business Park, Ireland";//53.282882, -6.383155
var ourLocation = {lat : 53.282882, lng : -6.383155}//centre attribute of the map must be a LatLng object and not hardcoded as above
function initGeolocation() {
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition( success, failure );
}
}
//create a new map centered on user's location, display route and show directions
function success(position) {
directionsDisplay = new google.maps.DirectionsRenderer();
coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
}
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById("directions-panel"));
calcRoute();
}
//calculate the route from user's location to 'dest'
function calcRoute() {
var start = coords;
var end = dest;
var request = {
origin:start,
destination:end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
//tell user geoloc isn't enabled and just plot 'ourLocation' on 'map-canvas'
function failure() {
alert("Your browser does not have geolocation enabled so we can't give you directions to our office. Enable geolocation and try again, or consult the map for our address.");
$("#directions-error-message").css({
visibility: 'visible'
});
var destMapOptions = {
zoom:13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(ourLocation.lat, ourLocation.lng)
}
map = new google.maps.Map(document.getElementById("map-canvas"), destMapOptions);
}
</script>
Anyone have any ideas why this isn't working? All help appreaciated.
EDIT: Working version above
You need to pass the map a LatLng object for it's centre, not an address. You will need to use Googles LocalSearch services to make that work.
var dest = {
lat : 53.282882,
lng : -6.383155
}
var destMapOptions = {
zoom:12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(dest.lat,dest.lng)
}
Also, as you have map declared as a var already maybe use that rather than a function scoped variable for the map.
The center attribute of the map options must be a LatLng object. You've got it hardcoded as an address string.

Google maps API: Directions result not showing

I'm creating my own styled map using Google Maps JS API. I wanted to add directions functionality to map, i followed the official tutorial (Under Displaying the DirectionsResult title), but the final route is not appearing...
I debugged my code and I found, than directionsService.route function returns google.maps.DirectionsStatus.OK and directionsDisplay.setDirections(result) is really called with no JS error... So directions are successfully computed but not showed in my map. A tried to turn off special map styling but even on default map style it is not appearing. Any ideas where could the problem be?
OK, some code...:
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyAB2gbXmG... ...mNs66iPr8&sensor=false&callback=directions_init"></script>
<script type="text/javascript">
var map;
var zoom = 11;
var directionsDisplay;
var directionsService;
function gmap_init(){
var styleArray = [ /*here is style but even if its commented its not working*/];
var alterMapStyle = new google.maps.StyledMapType(styleArray, {name: "ALTER style"});
var latlng = new google.maps.LatLng(/*lat, lng*/);
var myOptions = {
zoom: zoom,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
panControl: false,
zoomControl: false,
scaleControl: false,
streetViewControl: false
};
map = new google.maps.Map(document.getElementById("gmap"), myOptions);
map.mapTypes.set('ALTER_style', alterMapStyle);
map.setMapTypeId('ALTER_style');
}
function directions_init(){
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
display_route();
}
function display_route(){
var request = {
origin: 'Place A',
destination:'Place B',
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
//program got here without error
directionsDisplay.setDirections(result);
}
});
}
Not sure if it's the source of your problems, but it's sure worth a shot...
From your script input
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyAB2gbXmG... ...mNs66iPr8&sensor=false&callback=directions_init"></script>
I assume the directions_init function is called after api script has been downloaded, which probably is before page's onload event, thus your map object has not been initiated and is null. So practically you are calling
directionsDisplay.setMap(null);
Try calling directions_init from gmap_init or on any event that is triggered after onload.

Zoom in to marker google.maps

I can't zoom to a marker properly.
I'm trying to switch the view to a specified marker, but can't ge tit to work.
I've tried
map.setCenter(location);
map.setZoom(20);
and
map.fitBounds(new google.maps.latLngBounds(location,location));
but in the first case, I simply get zoomed in without the center change being registered, and in the second case I get this overview over a huge area, not zoomed in at all.
Perhaps this issue could be solved by setting a timout from setcenter to setzoom, but that's an ugly hack to me, so a prettier solution would be preferred.
How do you guys do this?
Also - if the infowindow could be displayed without changing content, that would really be a plus to, but the most important thing is to zoom into the marker at the right spot, close up.
thank you very much.
The solution turned out to be
map.setZoom(17);
map.panTo(curmarker.position);
I thought I would post an answer here as people wanted some example code.
I too needed to be able to zoom in and center as soon as a marker was added to the map.
Hope this helps somebody.
function getPoint(postcode) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': postcode + ', UK'}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
map.setZoom(10);
map.panTo(marker.position);
}
else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
is this a new instance of a map object you are creating? if so you can just have an object which contains the location and zoom and then pass that object to the map when initalising it like so (taken from the Gmaps basics tutorial http://code.google.com/apis/maps/documentation/javascript/basics.html:
function initialize() {
var myLatlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}

Categories

Resources