Google Maps API 3 Directions - Adding trip duration and distance to infoWindow - google-maps-api-3

I'm so close on this one right now, but can't quite get the result I'm looking for. This is an attempt to pull a series of geolocations - along with a title and text. These are then assigned to markers which are populated on a google map. My ultimate goal is to get the distance and duration of travel between each of the markers and the 'map-center' marker (hub if you will) and populate it in the infoWindow when an individual marker is clicked.
So far I've got every aspect of this working EXCEPT getting the distance/duration to populate correctly in the infoWindow. I can successfully populate a div outside of the 'map-canvas' with innerHTML.
If I either try to print an assigned var or change the content of a div within the infoWindow, the function only works on the first click event. After that the infoWindow shows up blank. Here is the working script:
<head>
<meta charset="utf-8" />
<title>Towns Hub</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<style>
.wrapper {position:relative;width:500px;height:300px;margin:30px auto;}
#map {width:500px;height:300px;}
.container{position:absolute;bottom:0;left:0;width:100%;z-index:999;}
.trav-det{border:1px solid #000;float:left;padding:7px;font-size:1.5em;background: rgba(255,255,255, .85);}
</style>
</head>
<body>
<div class="wrapper">
<div class="container">
<div class='trav-det' id='distance_road'></div>
<div class='trav-det' id='duration'></div>
</div>
<div id="map"></div>
</div>
<script>
var map;
var arrMarkers = [];
var infowindow = new google.maps.InfoWindow();
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
function mapInit(){
directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: true,
preserveViewport:true
});
var latlng = new google.maps.LatLng(45.18929617,-109.24727440);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"),myOptions);
directionsDisplay.setMap(map);
var marker1 = new google.maps.Marker({
position: new google.maps.LatLng(45.18929617,-109.24727440),
map: map,
title: 'Red Lodge, MT',
icon: 'http://mywebsite.com/images/orange-marker.png'
});
$.getJSON("hub.txt", {}, function(data){
$.each(data.places, function(i, item){
var marker = new google.maps.Marker({
position: new google.maps.LatLng(item.lat, item.lng),
map: map,
title: item.title
});
arrMarkers[i] = marker;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent("<p><strong>" + item.title + "</strong><br>"+ item.description +"</p>");
calcRoute(this.getPosition());
infowindow.open(map, this);
});
function calcRoute(drive_end) {
var start = new google.maps.LatLng(45.18929617,-109.24727440);
var end = drive_end;
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.DirectionsUnitSystem.IMPERIAL
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
distance = response.routes[0].legs[0].distance.text;
duration = response.routes[0].legs[0].duration.text;
document.getElementById("distance_road").innerHTML = distance;
document.getElementById("duration").innerHTML = duration;
}
});
}
});
});
}
google.maps.event.addDomListener(window, 'load', mapInit);
</script>
text file:
{"places": [{
"title": "Cooke City, MT",
"description": "TEXT",
"lat": 45.02009497,
"lng": -109.93234595
},
{
"title": "Silver Gate, MT",
"description": "TEXY",
"lat": 45.00687965,
"lng": -109.98979568
},
{
"title": "Absarokee, MT",
"description": "TEXT",
"lat": 45.52004697,
"lng": -109.44136186
},
{
"title": "Billings, MT",
"description": "TEXT",
"lat": 45.78333000,
"lng": -108.50000000
},
{
"title": "Bridger, MT",
"description": "TEXT",
"lat": 45.28568200,
"lng": -108.90821700
},
{
"title": "Cody, WY",
"description": "TEXT",
"lat": 44.52313500,
"lng": -109.07561100
},
{
"title": "Columbus, MT",
"description": "TEXT",
"lat": 45.62617100,
"lng": -109.25712600
},
{
"title": "Gardiner, MT",
"description": "TEXT",
"lat": 45.03049875,
"lng": -110.70471900
},
{
"title": "Nye, MT",
"description": "TEXT",
"lat": 45.43584263,
"lng": -109.80859757
},
{
"title": "Joliet, MT",
"description": "TEXT",
"lat": 45.48287830,
"lng": -108.97241592
}]}
Any ideas about populating the duration/distance in the infoWindow?
Help appreciated!
Thanks,
Sam
ps I apologize for any ugly scripting. I'm learning as I go and appreciate any thoughts on making this script more efficient!

i might be wrong but from looking at your code:
<div class="wrapper">
<div class="container">
<div class='trav-det' id='distance_road'></div>
<div class='trav-det' id='duration'></div>
</div>
</div>
you are poulating divs in the dom with the distance/duration.
assuming the info is appearing in the divs ok...
to get it into the info window you would need to use:
infowindow.setContent(" distance: "+distance+"<br> duration: "+duration+" ")

Related

Google Maps API will not display GeoJSON data

I'm trying for the first time to extract data from a GeoJSON file and display it in Google Maps. I just want to place a simple Google Maps marker at the coordinates in the geojson. Tried reading what I could on the net on the GM API and geojson but I feel like I'm missing something very simple.
Here is the main map code:
<script>
var map;
function initMap()
{
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(32.061146,34.799387),
mapTypeId: 'hybrid'
});
}
map.data.loadGeoJson('toilets.geojson');
map.data.setMap(map);
</script>
Here is the toilets.geojson file:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
34.799339175224304,
32.061136963943106
]
}
}]
}
Just want a regular marker to appear at those coordinates
One issue is the map variable is out of scope when you are loading the GeoJSON. That code needs to be inside the initMap function.
<script>
var map;
function initMap()
{
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(32.061146,34.799387),
mapTypeId: 'hybrid'
});
map.data.loadGeoJson('toilets.geojson');
map.data.setMap(map);
}
</script>
proof of concept fiddle (local JSON data
proof of concept fiddle (external JSON file)
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(32.061146, 34.799387),
mapTypeId: 'hybrid'
});
map.data.addGeoJson(geoJsonData);
map.data.setMap(map);
}
var geoJsonData = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
34.799339175224304,
32.061136963943106
]
}
}]
};
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 async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"></script>

Why FullCalendar is not showing properly?

//example data for events
[
{
"jobId": 0,
"eventId": 79,
"title": "<b>2018-07-31 00029 Markosy Postal S.A.<\/b><br><span class='eventComment'>asfdasfsd<\/span>",
"start": "\/Date(1533542400000)\/",
"end": "\/Date(1533551400000)\/",
"color": "#FFCC00"
},
{
"jobId": 0,
"eventId": 80,
"title": "<b>2018-07-31 00029 Markosy Postal S.A.<\/b><br><span class='eventComment'>sfsdgs<\/span>",
"start": "\/Date(1533637800000)\/",
"end": "\/Date(1533646800000)\/",
"color": "#FFCC00"
},
{
"jobId": 0,
"eventId": 81,
"title": "<b>2018-07-31 00029 Markosy Postal S.A.<\/b><br><span class='eventComment'>dfdf s ddfsda ds fds 2222<\/span>",
"start": "\/Date(1533722400000)\/",
"end": "\/Date(1533727800000)\/",
"color": "#FFCC00"
},
{
"jobId": 0,
"eventId": 84,
"title": "<b>2018-07-31 00029 Markosy Postal S.A.<\/b><br><span class='eventComment'>gdgdfgsd<\/span>",
"start": "\/Date(1533808800000)\/",
"end": "\/Date(1533812400000)\/",
"color": "#FFCC00"
}
]
$('#calendar').fullCalendar({
locale: 'pl',
defaultView: 'agendaWeek',
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaDay,agendaWeek,month,listWeek,year'
},
height: 'auto',
footer: false,
weekends: false,
slotEventOverlap: false,
timezone: 'local',
editable: true,
selectable: true,
events: {
url: '#Url.Action("GetGraphicCalendarEvents", "Schedule")',
textColor: 'black'
},
eventRender: function (event, element, view) {
var title = element.find('.fc-title, .fc-list-item-title');
title.html(title.text());
},
eventDrop: function (event) {
updateEventDate(event);
},
eventResize: function (event) {
updateEventDate(event);
},
select: function (startDate, endDate) {
$.ajax({
url: "#Url.Action("GraphicCalendarAddView", "Schedule")",
type: "post",
data: {
orderId: $("#OrderId").val(),
start: startDate.format("YYYY-MM-DD HH:mm:ss"),
end: endDate.format("YYYY-MM-DD HH:mm:ss")
},
success: function (result) {
if (result.hasOwnProperty("Success") && !result.Success) {
//error
} else {
//success
}
},
error: function (jqXHR, status, err) {
//error
}
});
},
eventClick: function (event) {
updateEventView(event);
}
});
I have a problem with FullCalendar https://fullcalendar.io/docs, I add some screenshot to explain my problem, When i click the button to show my calendar, but I only see not properly loaded events in calendar and when I click on any buttons of drag this thin strips it get fixed and calendar show everything properly.
I found the solution , the modal is not rendered, when the calendar is being rendered, I must add some delay.
example code: https://codepen.io/anon/pen/WKPyEN?editors=0010
$(function() {
$(".graphicPlanninngLetter").on("click", function() {
openCalendarWithView("GraphicPlanning");
});
function openCalendarWithView(action) {
showPopup("Test", "<div id='calendar'></div>");
setTimeout(function() {
$('#calendar').fullCalendar({
locale: 'pl',
defaultView: 'agendaWeek',
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaDay,agendaWeek,month,listWeek,year'
},
allDaySlot: false,
height: 'auto',
footer: false,
weekends: false,
slotEventOverlap: false,
timezone: 'local',
editable: true,
selectable: true,
events: 'https://fullcalendar.io/demo-events.json',
eventRender: function (event, element, view) {
var title = element.find('.fc-title, .fc-list-item-title');
title.html(title.text());
},
});
}, 300)
}
function showPopup(title, content, button, selector) {
if (selector == undefined)
selector = "#popup";
$(selector + " .popupTitle").html(title);
$(selector + " .popupBody").html(content);
$(selector + " .popupButtons .additionalButtons").empty().append(button);
$(selector).modal("show");
}
});

Change anchor of geojson custom icon - google maps api

Is there any way I can change the anchor for geojson points? Below a stripped down version of my project.
The problem I'm facing is that these icons start to "float" away from their location once I zoom out. (using a 40x40 square icon).
I've seen a lot similair questions on this matter, however none of the examples involved markers generated using geojson and/or changing the icon using setStyle.
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 51.822976,
lng: 4.128522
},
zoom: 8,
minZoom: 2,
maxZoom: 26,
tilt: 0,
});
var infowindow = new google.maps.InfoWindow();
var offices = new google.maps.Data();
offices.addGeoJson({
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [4.403528, 51.260561]
},
"properties": {
"Location": "Antwerp",
"Country": "BE"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [9.986818, 53.554377]
},
"properties": {
"Location": "Hamburg",
"Country": "DE"
}
}
]
});
offices.setStyle({
icon: 'images/icons/logo-bl1.png'
});
offices.setMap(map);
offices.addListener('click', function(event) {
var office_location = event.feature.getProperty("Location");
var office_country = event.feature.getProperty("Country");
infowindow.setContent(office_location + " - " + office_country);
infowindow.setPosition(event.feature.getGeometry().get());
infowindow.setOptions({
pixelOffset: new google.maps.Size(0, -30)
});
infowindow.open(map);
map.panTo(event.latLng);
});
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
}
Figured it out by adding
var officeicon = {
url: 'images/icons/logo-bl1.png',
size: new google.maps.Size(40, 40),
anchor: new google.maps.Point(20, 20)
};
and then
offices.setStyle({
icon: officeicon,

dojocharts issues in responsive

I am trying to generate a responsive dojocharts for mobile and tablets.
Here I had already trying though media queries through CSS. but its not working properly.
So anyone please suggest me how can I make my dojo chart responsive.
Below is my example for dojo responsive chart.but not working.
<script>
require(["dojox/charting/Chart",
"dojox/charting/plot2d/Pie",
"dojox/charting/action2d/Highlight",
"dojox/charting/action2d/MoveSlice",
"dojo/fx/easing",
"dojox/charting/action2d/Tooltip",
"dojox/charting/themes/MiamiNice",
"dojox/charting/widget/Legend",
"dojo/ready"
],
function(Chart, Pie, Highlight, MoveSlice, easing, Tooltip, MiamiNice, Legend, ready) {
ready(function() {
var chartTwo = new Chart("chartTwo");
chartTwo.setTheme(MiamiNice)
.addPlot("default", {
type: Pie,
font: "normal normal 11pt Tahoma",
fontColor: "black",
animate: {
duration: 1000,
easing: easing.cubicIn
},
labelOffset: -30,
radius: 150
}).addSeries("Series A", [{
"y": 101,
67,
"text": "INDIA",
"tooltip": "INDIA"
}, {
"y": 339.86,
"text": "USA",
"tooltip": "USA"
}, {
"y": 329.73,
"text": "UK",
"tooltip": "UK"
}, {
"y": 953.96,
"text": "UAE",
"tooltip": "UAE"
}]);
var anim_a = new MoveSlice(chartTwo, "default");
var anim_b = new Highlight(chartTwo, "default");
var anim_c = new Tooltip(chartTwo, "default");
chartTwo.render();
var legendTwo = new Legend({
chart: chartTwo
}, "legendTwo");
});
});
</script>
<body class="claro">
<div id="chartTwo" style="width: 600px; height: 350px;"></div>
<div id="legendTwo"></div>
So kindly request to everbody and also dojo community please suggest for this question for responsive dojocharts.

Google Maps API v3 - loading markers from xml file and integrating markercluster

Hi all and thanks for the support.
I have a website that loads GoogleMaps API v3 and places markers from a XML file and I am trying to integrate it with the MarkerCluster. No matter what I try It seems to be wrong. Can someone help? I will paste the code that renders the map and loads the data from the xml...
Can someone explain where to add the Markercluster specific code? Thank you.
PS: feel free to use the code if you like it – I've also been able to write it thanks to several examples on the web.
<script type="text/javascript" >
$(document).ready(function() {
var myLatLng = new google.maps.LatLng(21.150272,-4.636016);
MYMAP.init('#map', myLatLng, 2);
MYMAP.placeMarkers('markers/markers.xml');
});
var styles = [ { "featureType": "water", "elementType": "geometry.fill", "stylers": [ { "saturation": -100 }, { "lightness": -61 } ] },{ "featureType": "road", "elementType": "labels", "stylers": [ { "saturation": -67 }, { "visibility": "off" } ] },{ "featureType": "poi", "stylers": [ { "lightness": 40 }, { "saturation": -73 } ] },{ "featureType": "poi", "elementType": "labels", "stylers": [ { "visibility": "off" } ] },{ "featureType": "administrative.land_parcel", "elementType": "labels", "stylers": [ { "visibility": "off" } ] },{ "featureType": "administrative.neighborhood", "elementType": "labels", "stylers": [ { "visibility": "off" } ] },{ "featureType": "administrative.country", "elementType": "geometry.stroke", "stylers": [ { "color": "#ffff80" }, { "weight": 1 } ] },{ "featureType": "landscape", "stylers": [ { "saturation": -89 }, { "lightness": 25 } ] },{ "featureType": "water", "elementType": "labels", "stylers": [ { "visibility": "off" } ] } ]
var MYMAP = {
map: null,
bounds: null
}
MYMAP.init = function(selector, latLng, zoom) {
var myOptions = {
zoom:zoom,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
styles: styles,
mapTypeControl: false,
streetViewControl: false,
panControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.RIGHT_CENTER,
},
}
this.map = new google.maps.Map($(selector)[0], myOptions);
this.bounds = new google.maps.LatLngBounds();
}
MYMAP.placeMarkers = function(filename) {
$.get(filename, function(xml){
$(xml).find("marker").each(function(){
var name = $(this).find('name').text();
var facebook = $(this).find('facebook').text();
var linkedin = $(this).find('linkedin').text();
var twitter = $(this).find('twitter').text();
var photo = $(this).find('photo').text();
var ico = $(this).find('ico').text();
var city = $(this).find('city').text();
var country = $(this).find('country').text();
var email = $(this).find('email').text();
var lat = $(this).find('lat').text();
var lng = $(this).find('lng').text();
var point = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
MYMAP.bounds.extend(point);
var marker = new google.maps.Marker({
position: point,
map: MYMAP.map,
icon: 'img/'+ico+'marker.png'
});
var infoWindow = new google.maps.InfoWindow();
var html='<div class="img"><img src="markers/'+photo+'.jpg"></div><div class="txt"><p>'+name+'</p><br /><p>'+city+',<br />'+country+'</p><br /><div style="margin-top:-4px"><a target="" href="'+facebook+'"><img src="img/gosocial16/facebook.png"></a><a target="" href="'+twitter+'"><img src="img/gosocial16/twitter.png"></a><a target="" href="'+linkedin+'"><img src="img/gosocial16/linkedin.png"></a><a target="" href="'+email+'"><img style="margin-left:3px" src="img/gosocial16/email.png"></a></div></div>';
google.maps.event.addListener(MYMAP.map, 'zoom_changed', function() {
if (MYMAP.map.getZoom() < 2) MYMAP.map.setZoom(2);
});
google.maps.event.addListener(MYMAP.map, 'zoom_changed', function() {
if (MYMAP.map.getZoom() > 18) MYMAP.map.setZoom(18);
});
google.maps.event.addListener(marker, 'click', function() {
$("#close").click(function() {
infoWindow.close();
});
infoWindow.setContent(html);
infoWindow.setOptions({maxWidth:350});
infoWindow.open(MYMAP.map, marker);
});
MYMAP.map.fitBounds(MYMAP.bounds);
});
});
}
</script>
Here is an example based off of Mike Williams' v2 tutorial, ported to v3.
If you look at the documentation for MarkerClusterer, it includes this example:
var markers = [];
for (var i = 0; i < 100; i++) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude);
var marker = new google.maps.Marker({'position': latLng});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
If you add it into your existing loop, you should be able to just do this after you create the marker variable:
markers.push(marker);
Then create the marker clusterer where you currently call fitBounds. Did you try that and it didn't work?
Working example based off your code, adding the MarkerClusterer per the suggestion above; major modifications to use the marker clusterer's sample data as couldn't use yours.

Resources