Skip to content

Instantly share code, notes, and snippets.

@nenriquez
Forked from dbr/livemap.py
Created August 1, 2017 20:02
Show Gist options
  • Save nenriquez/57929c917396bd21d814940f48fa7536 to your computer and use it in GitHub Desktop.
Save nenriquez/57929c917396bd21d814940f48fa7536 to your computer and use it in GitHub Desktop.
Live Google Map marker update with Tornado
"""Playing with tornado.websocket, to add markers to a Google Map using WebSockets
$ pip install tornado
$ python livemap.py --port=8888
Open http://localhost:8888 in one window
Each time http://localhost:8888/ping is opened in a second window, a
new marker is added to the map (at a random location)
Written with tornado==2.3
"""
import os
import json
import logging
import tornado.ioloop
import tornado.web
import tornado.websocket
from tornado.options import define, options
log = logging.getLogger(__name__)
WEBSOCKS = []
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.redirect("/static/map.html")
class RandomLatLngSender(tornado.web.RequestHandler):
"""When an HTTP request is sent to /ping,
this class sends a random lat/lng coord out
over all websocket connections
"""
def get(self):
global WEBSOCKS
log.debug("pinging: %r" % WEBSOCKS)
import random
latlng = {
'lat': random.randint(-90, 90),
'lng': random.randint(-45, 45),
'title': "Thing!",
}
data = json.dumps(latlng)
for sock in WEBSOCKS:
sock.write_message(data)
class WebSocketBroadcaster(tornado.websocket.WebSocketHandler):
"""Keeps track of all websocket connections in
the global WEBSOCKS variable.
"""
def __init__(self, *args, **kwargs):
super(EchoWebSocket, self).__init__(*args, **kwargs)
def open(self):
log.info("Opened socket %r" % self)
global WEBSOCKS
WEBSOCKS.append(self)
def on_message(self, message):
log.info(u"Got message from websocket: %s" % message)
def on_close(self):
log.info("Closed socket %r" % self)
global WEBSOCKS
WEBSOCKS.remove(self)
settings = {
# FIXME: Should really move maps.html into static/, and change the last
# empty quotes to "static" (it's in same dir for gist)
'static_path': os.path.join(os.path.dirname(os.path.abspath(__file__)), ""),
}
print settings
application = tornado.web.Application([
(r"/", MainHandler),
(r"/ping", RandomLatLngSender),
(r"/sock", WebSocketBroadcaster),
],
**settings)
if __name__ == "__main__":
define("port", default=8888, help="Run server on a specific port", type=int)
tornado.options.parse_command_line()
application.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
<!DOCTYPE html>
<html>
<head>
<title>Live Map</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" src="https://raw.github.com/HPNeo/gmaps/master/gmaps.js"></script>
<link href='http://fonts.googleapis.com/css?family=Convergence|Bitter|Droid+Sans|Ubuntu+Mono' rel='stylesheet' type='text/css' />
<script type="text/javascript">
var map;
$(document).ready(function(){
map = new GMaps({
div: '#map',
lat: -12.043333,
lng: -77.028333
});
});
</script>
<style type="text/css" media="screen">
#map {
position:absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
</style>
</head>
<body>
<p>Loading...</p>
<div id="map"></div>
<script type="text/javascript">
var sock;
$(document).ready(function(){
sock = new WebSocket("ws://../sock");
sock = new WebSocket("ws://localhost:8888/sock");
sock.onopen = function(){ console.log("Connected websocket"); };
sock.onerror = function(){ console.log("Websocket error"); };
sock.onmessage = function(evt){
var latlng = JSON.parse(evt.data);
console.log("Got marker at " + latlng.lat + ", " + latlng.lng, latlng);
map.setZoom(3);
map.setCenter(latlng.lat, latlng.lng);
map.addMarker(latlng);
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment