Plotting bus route with Google Maps - javascript

I'm working on a property rental site. On the site I'd like to have a Google map, with all of the properties marked, and the local bus routes drawn, so that renters can see the proximity of the properties to the route.
I've achieved the first part of the problem; I've plotted the properties using markers. Now I need to add the bus route.
I've looked in to this and I can't quite work out the best way to achieve it. I looked at polylines and at using this tool, but the route is complex and would take hundreds of co-ordinates.
There is some kind of route api, as in this post but apparently it can only take 8 waypoints. Is that right?
Ideally I'd like to draw the map by selecting a start point, an end point, and dragging the route into place; and then somehow importing that route into what I have.
Here is the exact route that I want to import: http://www2.warwick.ac.uk/services/accommodation/landlords/12busroutes/.
My code to plot the properties is:
var siteRoot = "<?php bloginfo('stylesheet_directory');?>/";
var markers = [
<?php
$my_query = new WP_Query( 'post_type=properties' );
while ($my_query->have_posts()) : $my_query->the_post();
kdev_maps('list');
endwhile; // end of the loop.
?>
];
function googlemap() {
jQuery('#map_canvas').css({'height': '400px'});
// Create the map
// No need to specify zoom and center as we fit the map further down.
var map = new google.maps.Map(document.getElementById("map_canvas"), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
});
// Create the shared infowindow with two DIV placeholders
// One for a text string, the other for the StreetView panorama.
var content = document.createElement("div");
var title = document.createElement("div");
var boxText = document.createElement("div");
var myOptions = {
content: boxText
,disableAutoPan: false
,maxWidth: 0
,pixelOffset: new google.maps.Size(-117,-200)
,zIndex: null
,boxStyle: {
background: "url('"+siteRoot+"images/house-icon-flat.png') no-repeat"
,opacity: 1
,width: "240px"
,height: "190px"
}
,closeBoxMargin: "10px 0px 2px 2px"
,closeBoxURL: "http://kdev.langley.com/wp-content/themes/langley/images/close.png"
,infoBoxClearance: new google.maps.Size(1, 1)
,isHidden: false
,pane: "floatPane"
,enableEventPropagation: false
};
var infoWindow = new InfoBox(myOptions);
var MarkerImage = siteRoot+'images/house-web-marker.png';
// Create the markers
for (index in markers) addMarker(markers[index]);
function addMarker(data) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.lat, data.lng),
map: map,
title: data.title,
content: data.html,
icon: MarkerImage
});
google.maps.event.addListener(marker, "click", function() {
infoWindow.open(map, this);
title.innerHTML = marker.getTitle();
infoWindow.setContent(marker.content);
infoWindow.open(map, marker);
jQuery(".innerinfo").parent().css({'overflow':'hidden', 'margin-right':'10px'});
});
}
// Zoom and center the map to fit the markers
// This logic could be conbined with the marker creation.
// Just keeping it separate for code clarity.
var bounds = new google.maps.LatLngBounds();
for (index in markers) {
var data = markers[index];
bounds.extend(new google.maps.LatLng(data.lat, data.lng));
}
map.fitBounds(bounds);
var origcent = new google.maps.LatLng(map.getCenter());
// Handle the DOM ready event to create the StreetView panorama
// as it can only be created once the DIV inside the infowindow is loaded in the DOM.
closeInfoWindow = function() {
infoWindow.close();
};
google.maps.event.addListener(map, 'click', closeInfoWindow);
google.maps.event.addListener(infoWindow, 'closeclick', function()
{
centermap();
});
function centermap()
{
map.setCenter(map.fitBounds(bounds));
}
}
jQuery(window).resize(function() {
googlemap();
});
Any help is much appreciated.

Its worth looking at two things:
1) The GTFS format (https://developers.google.com/transit/gtfs/reference) this is a csv-based format that allows someone to cross reference transit times and routes, if you are lucky then the data will have been assembled for you for your transit authority :)
2) If you can pull in the coordinates then you can make a line feature as long as you want (within the bounds of browser capacity). This is done in much the same way as you pull in markers, except you pull the features you want into a polyline:
like this (from gmaps docs):
var flightPlanCoordinates = [
new google.maps.LatLng(37.772323, -122.214897),
new google.maps.LatLng(21.291982, -157.821856),
new google.maps.LatLng(-18.142599, 178.431),
new google.maps.LatLng(-27.46758, 153.027892)
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
you will build your array from php, of course :)
hope that helps.

If you use free google maps you can use a start point, end point and 8 way point. In google maps api premiere you can use 23 way point for routing vehicles

Related

Google maps stop showing points v3

Hi i have trouble to find what case a problem to showing the way point on goggle maps as there were no changes in the code for a wile. way point stop showing about last week. im not familiar with google api
var map = null;
var markerArray = []; //create a global array to store markers
var myPoints =
[ [52.664167, -8.509825,' HQ','favicon.ico'] ,[52.836346, -6.913117,'point 1','http://maps.google.com/mapfiles/ms/icons/red.png ' ],[52.836202, -6.912101,'point2','http://maps.google.com/mapfiles/ms/icons/red.png ' ]];
function initialize() {
var myOptions = {
zoom:7,
center: new google.maps.LatLng(53.112, -7.448),
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map"), myOptions);
var mcOptions = {
gridSize: 30,
maxZoom: 15
};
var mc = new MarkerClusterer(map, [], mcOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Add markers to the map
// Set up markers based on the number of elements within the myPoints array
for(var i=0; i<myPoints.length; i++){
createMarker(new google.maps.LatLng(myPoints[i][0], myPoints[i][1]), myPoints[i][2], myPoints[i][3]);
}
mc.addMarkers(markerArray , true);
}
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 50)
});
function createMarker(latlng, html, icons) {
var contentString = html;
var links = icons;
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: links ,
zIndex: Math.round(latlng.lat() * -100000) << 5
});
// marker.setAnimation(google.maps.Animation.BOUNCE);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
markerArray.push(marker); //push local var marker into global array
}
window.onload = initialize;
<script src="https://maps.googleapis.com/maps/api/js?v=3"
type="text/javascript"></script>
<div id="map" style="width: 800px; height: 750px;" ></div>
Any suggestions?
It seems that you are using MarkerClusterer which is a part of google maps utility library, which was moved recently. Somebody probably referenced the library straight from code.google.com/svn/... in your project, where it's not available anymore and that's why it's broken. You need to find all libraries which are referenced from https://google-maps-utility-library-v3.googlecode.com/svn and replace then with your own links.
Check this SO question, user had very similar issues to yours.
Also! check this question and answers on SO!!, there are users who experienced issues with the same library, to get more information. Read all answers, as replacing https://google-maps-utility-library-v3.googlecode.com/svn with https://rawgit.com/googlemaps/... is not a correct solution, you should download the library assets into your project and reference them from there or use CDN (but not git!).

Google Maps v3 Zooming specific location

i'm still learning the javascript not much pro, and this is my 1st post.
JavaScript
function initialize() {
// Create the map
// No need to specify zoom and center as we fit the map further down.
var map = new google.maps.Map(document.getElementById("map_canvas"), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
});
// Create the shared infowindow with two DIV placeholders
// One for a text string, the other for the StreetView panorama.
var content = document.createElement("DIV");
var title = document.createElement("DIV");
content.appendChild(title);
var streetview = document.createElement("DIV");
streetview.style.width = "200px";
streetview.style.height = "200px";
content.appendChild(streetview);
var infowindow = new google.maps.InfoWindow({
content: content
});
var markers = [{
lat: 35.15074,
lng: -89.955992,
name: "Bob 1"
}, {
lat: 35.149425,
lng: -89.946595,
name: "Bob 2"
}, {
lat: 35.146687,
lng: -89.929837,
name: "Bob 3"
}, {
lat: 35.132264,
lng: -89.937197,
name: "Bob 4"
}];
// Create the markers
for (index in markers) addMarker(markers[index]);
function addMarker(data) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.lat, data.lng),
map: map,
title: data.name
});
google.maps.event.addListener(marker, "click", function () {
openInfoWindow(marker);
});
}
// Zoom and center the map to fit the markers
// This logic could be conbined with the marker creation.
// Just keeping it separate for code clarity.
var bounds = new google.maps.LatLngBounds();
for (index in markers) {
var data = markers[index];
bounds.extend(new google.maps.LatLng(data.lat, data.lng));
}
map.fitBounds(bounds);
// Handle the DOM ready event to create the StreetView panorama
// as it can only be created once the DIV inside the infowindow is loaded in the DOM.
var panorama = null;
var pin = new google.maps.MVCObject();
google.maps.event.addListenerOnce(infowindow, "domready", function () {
panorama = new google.maps.StreetViewPanorama(streetview, {
navigationControl: false,
enableCloseButton: false,
addressControl: false,
linksControl: false,
visible: true
});
panorama.bindTo("position", pin);
});
// Set the infowindow content and display it on marker click.
// Use a 'pin' MVCObject as the order of the domready and marker click events is not garanteed.
function openInfoWindow(marker) {
title.innerHTML = marker.getTitle();
pin.set("position", marker.getPosition());
infowindow.open(map, marker);
}
}
I had the 4 different places, then i need the 4 webpages to add, how to i tell the browser that i want zooming the specific location. let's say i wanted to zooming at "Bob 1".
Then i rename the webpage as bob1.html. Whenever i click the bob1.html the webpage will zooming zoom: 15 and the marker is center on the map
You don't need to have four different pages unless this is part of the spec?
To set the position and zoom level of the map simply call:
map.setCenter(yourLatLngOrMarkerPosition);
And to set the zoom level:
map.setZoom(yourZoomLevel);
These could be set at any point after the instantiation of the map so perhaps on button clicks or after a period of time?
Hope this helps.
Edit To take into account your requirements (mentioned in the comments) I would submit the relevant url post parameters upon clicking the link. Within the initialize function of each map page you will then need to read these out using something similar to Here (though this uses jQuery) and set the map options as appropriate.
Edit You can read the url post parameters out with php and then echo them in the appropriate places within the google maps calls.
For Example:
map.setZoom(<?php echo $_GET['urlZoomParam'];?>);
Etc.
Some general PHP/MYSQL/Google Maps stack docs: https://developers.google.com/maps/articles/phpsqlajax_v3 https://developers.google.com/maps/articles/phpsqlsearch_v3 http://theoryapp.com/online-store-locator-using-php-mysql-and-google-maps/

Using 2 methods to display markers and polylines on a Google map

I am trying to combine two separate methods to display both markers and polylines on one map. Is it possible? and if so how would I do this. Or conversely how would I add polylines to my markers sample.
From http://you.arenot.me/2010/06/29/google-maps-api-v3-0-multiple-markers-multiple-infowindows/
Without my actual code I appreciate this is a probably a wasted post.. but I am having trouble adding my code..
Perhaps that should have been my first question..
This script will add markers and draw a polyline between them:
<script>
var poly;
var map;
function initialize() {
var chicago = new google.maps.LatLng(41.879535, -87.624333);
var mapOptions = {
zoom: 7,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var polyOptions = {
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 3
}
poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
// Add a listener for the click event
google.maps.event.addListener(map, 'click', addLatLng);
}
/**
* Handles click events on a map, and adds a new point to the Polyline.
* #param {MouseEvent} mouseEvent
*/
function addLatLng(event) {
var path = poly.getPath();
// Because path is an MVCArray, we can simply append a new coordinate
// and it will automatically appear
path.push(event.latLng);
// Add a new marker at the new plotted point on the polyline.
var marker = new google.maps.Marker({
position: event.latLng,
title: '#' + path.getLength(),
map: map
});
}
</script>
Excellent Documentation available here:
https://developers.google.com/maps/documentation/javascript/reference
https://google-developers.appspot.com/maps/documentation/javascript/examples/polyline-complex
It is certainly possible to display markers and polylines on the same map:
Here is an example that displays both markers and independent polylines.
Here is an example that uses the third party geoxml3 KML parser to create them from a KML file (or using KmlLayer).

Google Maps API v3 not loading without fitbounds, zooming causing infinite loop/stackoverflow

Previous question here:
stack overflow with Google maps API (IE7 IE8)
I found the following question in the mean time: Google Maps API v3: Can I setZoom after fitBounds?
The solution there works just fine, when I have more than one marker on the map. However when I visit a subpage of groupbke.young.netaffinity.net eg. https://groupbke.young.netaffinity.net/hotels/ireland/dublin/dublin/young-testing-hotel-liege/specials/bed-and-breakfast
the map will only load if map.fitBounds() is called. On the other hand, even if the map is not loaded, it will throw a stack overflow error when I scroll above the map canvas.
Will throw a stack overflow anyway, if I try to use setZoom.
Any ideas?
var hoteldata = [
['Young Testing Hotel - Liège', 53.33932, -6.261427, '<div class="nearby-hotel"> <h1>Young Testing Hotel - Liège</h1> <div class="star-rating-1"></div><div class="clear"></div> <div class="nearby-hotel-image l"> <img src="http://groupbke.young.netaffinity.net/bookings/images/imagecache/3/0C9DBC143E18ED64059C1696A52D2941-60x60.jpg" border="1" class="imagetype1"/> </a> </div> <div class="nearby-hotel-description l"> <a class="nearby-hotel-desc" href="/hotels/ireland/dublin/dublin/young-testing-hotel-liege">Dublin\'s most luxurious design hotel is located in the heart of the city. Experience the best of both worlds when staying at this chic haven, to one side the tranquility and calm of St Stephen\'s Green and to the other, Grafton Street, Dublin\'s finest shopping avenue. From its central location, in amongst this buzzing vibrant city it is an easy stroll to explore the leading cultural, historical and leisure attractions. Or just step out to the chic shopping, high energy bars, fine dining restaurants and chattering Cafes.</a> Book Now </div> <div class="clear"></div> </div>', 4]
];
function initialize(mapid) {
var myOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
};
var bounds = new google.maps.LatLngBounds();
var map = new google.maps.Map(document.getElementById(mapid), myOptions);
var infowindow = new google.maps.InfoWindow();
var markers = [];
for (i = 0; i < hoteldata.length; i++) {
var latLng = new google.maps.LatLng(hoteldata[i][1], hoteldata[i][2]);
bounds.extend(latLng);
var img = '/images/hotel-marker.png';
if (hoteldata[i][4] == 2) {
img = '/images/country-marker.png';
}
if (hoteldata[i][4] == 3) {
img = '/images/guesthouse-marker.png';
}
if (hoteldata[i][4] == 4) {
img = '/images/hotel-self-marker.png';
}
var marker = new google.maps.Marker({
position: latLng,
icon: img,
shadow: '/images/marker-shadow.png'
});
markers.push(marker);
bindInfoWindow(marker, map, infowindow, hoteldata[i][3]);
}
var clusterStyles = [
{
opt_textColor: 'white',
url: '/images/m3-blue.png',
height: 65,
width: 64
},
{
opt_textColor: 'white',
url: '/images/m3-green.png',
height: 65,
width: 64
},
{
opt_textColor: 'white',
url: '/images/m3-orange.png',
height: 65,
width: 64
}
];
var mcOptions = {
styles: clusterStyles,
maxZoom:14
};
if (markers.length>1){
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
map.fitBounds(bounds);
google.maps.event.addListenerOnce(map, 'zoom_changed', function() {
var oldZoom = map.getZoom();
map.setZoom(oldZoom + (-7)); //Or whatever
});
} else if (markers.length == 1){
markers[0].setMap(map);
//google.maps.event.clearListeners(map, 'zoom_changed');
//google.maps.event.addListenerOnce(map, 'zoom_changed', function() {
// var oldZoom = map.getZoom();
// map.setZoom(oldZoom + (-7)); //Or whatever
// setTimeout('roomSetter(globalmap,globalzoom)',300);
//});
//google.maps.event.trigger(map,'zoom_changed');
//google.maps.event.clearListeners(map, 'zoom_changed');
//map.fitBounds(bounds);
//var oldZoom = map.getZoom();
//map.setCenter(bounds.getCenter());
//map.setZoom(oldZoom+(-7));
//map.setZoom(3);
//globalmap=map;
//globalzoom=map.getZoom()+(-7);
//setTimeout('zoomSetter(globalmap,globalzoom)',300);
}
}
var globalmap;
var globalzoom;
function zoomSetter(map, zoom){
//map.setZoom(zoom);
}
function bindInfoWindow(marker, map, infowindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
}
function initmaps() {
initialize('map_canvas');
initialize('map_thumb');
}
google.maps.event.addDomListener(window, 'load', initmaps);
I've set up 3 testpages to demonstrate the problem:
http://groupbke.young.netaffinity.net/maptest1.html
this has the setZoom() function and throws a stackoverflow error, even though this should be correct
http://groupbke.young.netaffinity.net/maptest2.html
this does nothing beyond adding the marker to the map. scroll zooming on the map still throws a stack error.
http://groupbke.young.netaffinity.net/maptest3.html
this has fitBound(), which in theory is not good, but works. can NOT adjust the zoom level after that, or it will throw a stackoverflow error. scroll zooming works.
What I was missing from the answer from my previous question was that an initial zoom level and center has to be set.
var myOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
zoom:22,
center: new google.maps.LatLng(50.820645,-0.137376)
};
Also had to change the event to 'idle' on the multi marker zooming adjustment.
if (markers.length>1){
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
map.fitBounds(bounds);
google.maps.event.addListenerOnce(map, 'idle', function() {
var oldZoom = map.getZoom();
map.setZoom(oldZoom + (-7)); //Or whatever
});
}
Works like a charm after that.
When you have only one hotel, you create a LatLngBounds object containing only one point:
for (i = 0; i < hoteldata.length; i++) {
var latLng = new google.maps.LatLng(hoteldata[i][1], hoteldata[i][2]);
bounds.extend(latLng);
...}
but you then do a map.fitBounds(bounds) — this attempts an infinite zoom. While it's arguable that the API should be able to cope with that, it's equally arguable that it will attempt to do exactly what you tell it. It's possible that IE will behave differently to Firefox and other browsers.
Where you have commented out the fitBounds() in your quoted code in the question, that is present in your online page. Since that line only applies to instances where one marker is involved and the bounds object is a single point, I would replace it with a simple setZoom() instead.
map.setZoom(16);

Google Maps API v3: Close infowindow when DOM element is clicked

I'm playing around with Google maps for the first time, so I looked at a nice tutorial over at CSS Tricks: http://css-tricks.com/google-maps-slider/ I like working with jQuery better than pure JS, and this tutorial makes a nice way to click on a place in a list to display the marker in the map.
I liked it that way, but I need to add infowindows to the marker. Which I did, but when I click on a place on the list and the map pans away, the infowindow stays open! I think it's because I need to attach the infowindow.close() to the event of clicking on a "#locations li".
Here's my code, which runs on document.ready:
$(function() {
var chicago = new google.maps.LatLng(41.924832, -87.697456),
pointToMoveTo,
first = true,
curMarker = new google.maps.Marker({}),
$el;
var myOptions = {
zoom: 10,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($("#map_canvas")[0], myOptions);
$("#locations li").click(function() {
$el = $(this);
if (!$el.hasClass("hover")) {
$("#locations li").removeClass("hover");
$el.addClass("hover");
if (!first) {
// Clear current marker
curMarker.setMap();
// Set zoom back to Chicago level
// map.setZoom(10);
}
// Move (pan) map to new location
function move(){
pointToMoveTo = new google.maps.LatLng($el.attr("data-geo-lat"), $el.attr("data-geo-long"));
map.panTo(pointToMoveTo);
}
move();
// Add new marker
curMarker = new google.maps.Marker({
position: pointToMoveTo,
map: map
});
// Infowindow: contenido
var contentString = '<p>'+$el.find("h3").html()+'</p>';
contentString += 'hola' ;
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50),
content: contentString
});
// On click, zoom map
google.maps.event.addListener(curMarker, 'click', function() {
//map.setZoom(14);
infowindow.open(map,curMarker);
});
It looks like you're creating a new InfoWindow for each marker. Quoting from the Google Maps API Docs:
If you only want one info window to display at a time (as is the behavior on Google Maps), you need only create one info window, which you can reassign to different locations or markers upon map events (such as user clicks).
Therefore, you may simply want to create one InfoWindow object just after you initialize your map, and then handle the click event handler as follows:
google.maps.event.addListener(curMarker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, curMarker);
});
Then the InfoWindow should automatically close when you click on a new marker without having to call the close() method.

Categories