Google Maps widget with traffic

widgetgallery
googlemaps
Tags: #<Tag:0x00007fe056f67dc0> #<Tag:0x00007fe056f67c80>

(Bastiaan van Haastrecht) #1

Hello,

NEW 2018-02-27: Added distance and travel time calculation between two locations. It calculates the avarage travel time, and with current traffic conditions. Import the new widget and get the new ‘maps.html’ file.

I’ve created another widget for HABpanel. For me it’s handy to check the current traffic conditions prior to go to work. Therefore I created an widget that uses Google Maps API and displays the current traffic on the map. It auto reloads the traffic on 10 seconds interval.

I’ve also used the Night color schema so it better fits the default theme of HABpanel.

Screenshot:

Widget:
googlemaps.json.widget

Get your Goolge Maps API key here.

Installation

  • Import the downloaded widget to your HABpanel.
  • Place the map.html file within your /conf/html/google-maps/ folder.
  • In the settings of the widget:
    • Set ServerPath to the location of your map.html (/static/google-maps/map.html).
    • Set to your preferred zoom level.
    • Set to your position in latitude and longitude.
    • Set your desired height, the width is auto filling from widget frame.
    • If you would like travel time calculation, Enable Travel time check.
    • For travel time, install HTTP binding.
    • For travel time, set origin. Replace spaces with ‘+’ plus sign.
    • For travel time, set destination. Replace spaces with ‘+’ plus sign.
    • Set your Google Maps API key.

Travel time widget

If you wan’t, you can get google Maps travel times ext. in a Item and display it in Dummy widgets.

  • Install HTTP binding thru PaperUi / Add-Ons
  • Install JSONPath transformation thru PaperUi / Add-Ons

Create a ‘googlemaps.items’ file in ‘/conf/items’. Change the value’s in the URL to your liking.

String	GoogleMaps_me_distance				"Distance [%s]"		(gGoogleMaps)	{ http="<[https://maps.googleapis.com/maps/api/distancematrix/json?origins=Amsterdam&destinations=Rotterdam&language=NL&departure_time=now&traffic_model=best_guess&mode=driving&key=YOUR_API_KEY:300000:JSONPATH($.rows[0].elements[0].distance.text)]" }
String	GoogleMaps_me_duration				"Duration [%s]"		(gGoogleMaps)	{ http="<[https://maps.googleapis.com/maps/api/distancematrix/json?origins=Amsterdam&destinations=Rotterdam&language=NL&departure_time=now&traffic_model=best_guess&mode=driving&key=YOUR_API_KEY:300000:JSONPATH($.rows[0].elements[0].duration.text)]" }
String	GoogleMaps_me_duration_traffic		"Duration [%s]"		(gGoogleMaps)	{ http="<[https://maps.googleapis.com/maps/api/distancematrix/json?origins=Amsterdam&destinations=Rotterdam&language=NL&departure_time=now&traffic_model=best_guess&mode=driving&key=YOUR_API_KEY:300000:JSONPATH($.rows[0].elements[0].duration_in_traffic.text)]" }

String	GoogleMaps_wife_distance			"Distance [%s]"		(gGoogleMaps)	{ http="<[https://maps.googleapis.com/maps/api/distancematrix/json?origins=Amsterdam&destinations=Haarlem&language=NL&departure_time=now&traffic_model=best_guess&mode=driving&key=YOUR_API_KEY:300000:JSONPATH($.rows[0].elements[0].distance.text)]" }
String	GoogleMaps_wife_duration			"Duration [%s]"		(gGoogleMaps)	{ http="<[https://maps.googleapis.com/maps/api/distancematrix/json?origins=Amsterdam&destinations=Haarlem&language=NL&departure_time=now&traffic_model=best_guess&mode=driving&key=YOUR_API_KEY:300000:JSONPATH($.rows[0].elements[0].duration.text)]" }
String	GoogleMaps_wife_duration_traffic	"Duration [%s]"		(gGoogleMaps)	{ http="<[https://maps.googleapis.com/maps/api/distancematrix/json?origins=Amsterdam&destinations=Haarlem&language=NL&departure_time=now&traffic_model=best_guess&mode=driving&key=YOUR_API_KEY:300000:JSONPATH($.rows[0].elements[0].duration_in_traffic.text)]" }

300000 in milliseconds = update every 5 minutes. This way you have 12 x 24 = 288 API hits per day. If you have 6 feeds, that’s 1728 hits where 2400 a day are allowed by Google. If you want to update more frequently, see this post.

More Google Maps API options here.

Add a Dummy widget for every String. You can set it up like this:
image

I’m not going to build a custom widget as it’s just plain simple displaying strings.


Custom Widget: Map
Current travel time on favorit route
Script to access the BMW ConnectedDrive portal via OH
(Bauke Plugge) #2

Hi @bastiaan_van_h,

thx for the google maps widget !
Just downloaded the JSON and had some struggles with the implementation.

i have adjusted the JSON a little so it is possible to enter the server path detail of the map.html file

{
    "template": "<iframe ng-src=\"{{config.serverpath}}\" style=\"height:{{config.height}}px; width:100%; display:block; border:0px;\"></iframe>",
    "settings": [
        {
            "type": "number",
            "id": "height",
            "label": "Height",
            "default": "600",
            "description": "Map frame height"
        },
        {
            "type": "string",
            "id": "serverpath",
            "label": "Server Path",
            "default": "/static/google-maps/map.html",
            "description": "Change this value to use the correct path"
        }
    ],
    "name": "Google Maps with traffic",
    "author": "Bastiaan van Haastrecht",
    "description": "Google Maps with auto refreshing traffic layer. https://github.com/BasvanH/"
}

and maybe for a reference so poeple dont have to search: https://developers.google.com/maps/documentation/javascript/get-api-key
the link where to get the google maps api key.

again thx for sharing this widget with the community!


(Lucky) #3

Nice job! Another useful widget for HABPanel.

For me, I use a combination of HabPanel and a PIR sensor. When I walk past the kitchen panel, in the morning, it will greet me and tell me traffic/time to work, current weather, my appointments, and my news feed.


(Bauke Plugge) #4

@bastiaan_van_h

made some more adjustments to the widget:

{
    "template": "<iframe ng-src=\"{{config.serverpath + '?gm_zoomlevel=' + config.gm_zoomlevel + '&gm_latitude=' + config.gm_latitude + '&gm_longitude=' + config.gm_longitude + '&gm_apikey=' + config.gm_apikey}}\" style=\"height:{{config.height}}px; width:100%; display:block; border:0px;\"></iframe>",
    "settings": [
        {
            "type": "number",
            "id": "height",
            "label": "Height",
            "default": "600",
            "description": "Map frame height"
        },
        {
            "type": "string",
            "id": "serverpath",
            "label": "Server Path",
            "default": "/static/google-maps/map.html",
            "description": "Change this value to use the correct path"
        },
        {
            "type": "number",
            "id": "gm_zoomlevel",
            "label": "Google zoomlevel",
            "default": "12",
            "description": "Enter the required zoomlevel for googlemaps"
        },
        {
            "type": "string",
            "id": "gm_latitude",
            "label": "Latitude",
            "default": "",
            "description": "Enter the latitude for your GPS coordinates"
        },
        {
            "type": "string",
            "default": "",
            "label": "Longitude",
            "id": "gm_longitude",
            "description": "Enter the longitude for your GPS coordinates"
        },
        {
            "type": "string",
            "id": "gm_apikey",
            "label": "Google maps API key",
            "default": "<Enter your API key here !>",
            "description": "Get your API key at https://developers.google.com/maps/documentation/javascript/get-api-key"
        }
    ],
    "name": "Google Maps with traffic",
    "author": "Bastiaan van Haastrecht",
    "description": "Google Maps with auto refreshing traffic layer. https://github.com/BasvanH/"
}

now you are able to insert all the variables and those are parsed to map.html
with a little adjustment ofcourse in the map.html file:

		var gm_zoomlevel = parseInt(getQueryVariable('gm_zoomlevel'));
		var gm_latitude = parseFloat(getQueryVariable('gm_latitude'));
		var gm_longitude = parseFloat(getQueryVariable('gm_longitude'));
		var gm_apikey = getQueryVariable('gm_apikey');

		function getQueryVariable(variable)
		{
		var query = window.location.search.substring(1);
		var vars = query.split("&");
		for (var i=0;i<vars.length;i++) {
			var pair = vars[i].split("=");
				if(pair[0] == variable){return pair[1];}
			}
		return(false);
		}

only the api key I was not able to parse in the script include.

thx again and have fun


(Bastiaan van Haastrecht) #5

Hi @baukeplugge, thats a nice addition to the widget. I have added the settings and adjusted the map.html . I did need to add a peace of code in order to set the gm_apikey to the google maps API URL.

Instructions are updated.

Thanks for your contribution. (Perhaps next time fork the repository on Github).


(Mr. Yoinkz) #6

Hi Bastian,

Really nice widget!
One thing though - when I try to import the json file I get this error:
Widget import error: SyntaxError: Unexpected token < in JSON at position 6

Do you know why it does that? I did save the map.html in the directory described.

Any help is appreciated.


(Mr. Yoinkz) #7

Got it sorted - I must have downloaded the file in a wrong way.
So I got it imported, but now I’m having another error. After putting in the location and API key it throws this error when opening the Panel:

For security reasons, framing is not allowed.

What am I doing wrong?


(Mr. Yoinkz) #8

Yeah - I’m a rookie. Got it working. Same thing again - something must have happened to the download of the file.

So thank you… Looks really good!
Where can I tweak the refresh? Right now you say it is every seconds, but can that be changed?


(Bastiaan van Haastrecht) #9

Thanks @Yoinkz, its set to every 10 seconds.

You can change this in the map.html file. Edit this part:

		window.setInterval(function(){
			reloadTiles();			
		}, 10000);

10000 = 10 secs.


(Mr. Yoinkz) #10

Cool :)!

Did you play around with a knob or so to show the travel time from point a to point b as well?


(Bastiaan van Haastrecht) #11

@Yoinkz, interesting. Travel time between two locations, looks like a good candidate for a new widget. I will see what I can do.


(Mr. Yoinkz) #12

@bastiaan_van_h, I know some other people have played around with it, but I haven’t found any solutions though.

That would be really greatfull and with your map app just below to knobs that shows the travel time for him and her… that would be so perfect!


(sceppi) #13

Hi,

I really like this widget, however I cannot get it to work.
I’ve done every step as it should I think:

  • Copied the map.html to /etc/openhab2/html/google-maps/map.html
  • Requested an API key from google
  • Imported the widget in openhab
  • Made sure the settings were correct: server-path to /static/google-maps/map.html ; added the API key, entered latitude and longitude information

Now if I press preview or view the widget in action I only get a frame with in this frame another instance of habpanel. No link to google maps or anything.
I don’t understand… i’ve implemented more difficult stuff than this in openhab and never had any issues.

Any ideas what could be the cause?


(Daniel Walters) #14

I have the same issue (the preview displays a frame with HABPanel inside). If I manually navigate to the map.html with all the query parameter it works fine. So confused!


(Bastiaan van Haastrecht) #15

@sceppi @danielwalters86, what happens if you save the widget and place it on a page. Does it show the same behaviour? Tried different browser? Perhaps try to run Chrome in Incognitio mode to check if it is’t a browser cache issue.


(sceppi) #16

Hi,

See attached screenshot what I get. This time in chrome incognito where I quickly made a test page in Habpanel and then imported and configures the widget.

As you can see I get a Habpanel instance with inside a frame (which should be the google map frame) with another instance of Habpanel.

Same result in other browsers…


(Bastiaan van Haastrecht) #17

What do you think about this. You can set orgin and destination. It will then draw the prefered route on the map. It will calculate the distance, travel time and travel time with current traffic. It will update, every 10 seconds and recalculates the best route, and travel times.

Any remarks about the text box displaying the info?


(Bastiaan van Haastrecht) #18

Whats your path setting to the map.html file?
Whats the location of the map.html file in your /conf/html directory?


(Mr. Yoinkz) #19

Hey @bastiaan_van_h!

I think that this is a lovely piece og work!
Is it possible to do two calculations? Otherwise you will have to have two maps and that might get a bit crowded on a 7 inch tablet :).

But besides that, I think this is awesome and would fit in on many habpanels.


(sceppi) #20

I’ve tried many locations. Just in the main static folder (etc/openhab2/html), but also in a subfolder (etc/openhab2/html/google-maps). Of course always making sure to adjust the path in the settings of the widget to the actual location of the map.html file. I don’t understand…