Created
May 7, 2014 14:35
-
-
Save ellisonbg/d1452797ff7f39f14cf6 to your computer and use it in GitHub Desktop.
Leaflet Widget
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "", | |
"signature": "sha256:e326949333731906c832325f25b7c4f5633c74a1508bfc79426c0df81f91b658" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"from __future__ import print_function\n", | |
"from IPython.utils.traitlets import Float, Unicode, Int, link, Tuple, List, link\n", | |
"from IPython.html import widgets\n", | |
"from IPython.html.widgets import interact, interactive, fixed\n", | |
"from IPython.display import display" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%html\n", | |
"\n", | |
"<link rel=\"stylesheet\" href=\"http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css\" />" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"\n", | |
"<link rel=\"stylesheet\" href=\"http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css\" />" | |
], | |
"metadata": {}, | |
"output_type": "display_data", | |
"text": [ | |
"<IPython.core.display.HTML object>" | |
] | |
} | |
], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class LeafletWidget(widgets.DOMWidget):\n", | |
"\n", | |
" _view_name = Unicode('LeafletWidgetView', sync=True)\n", | |
" location = List((32.3226932,-90.9019257), sync=True)\n", | |
" width = Unicode('600px', sync=True)\n", | |
" height = Unicode('400px', sync=True)\n", | |
" zoom_start = Int(12, sync=True)\n", | |
" zoom = Int(12, sync=True)\n", | |
" max_zoom = Int(18, sync=True)\n", | |
" min_zoom = Int(1, sync=True)\n", | |
" tiles_url = Unicode('http://otile1.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', sync=True)\n", | |
" tiles_attr = Unicode('Map data (c) <a href=\"http://openstreetmap.org\">OpenStreetMap</a> contributors', sync=True)\n", | |
" _south = Float()\n", | |
" _north = Float()\n", | |
" _east = Float()\n", | |
" _west = Float()\n", | |
"\n", | |
" @property\n", | |
" def north(self):\n", | |
" return self._north\n", | |
"\n", | |
" @property\n", | |
" def south(self):\n", | |
" return self._south\n", | |
"\n", | |
" @property\n", | |
" def east(self):\n", | |
" return self._east\n", | |
"\n", | |
" @property\n", | |
" def west(self):\n", | |
" return self._west\n", | |
"\n", | |
" @property\n", | |
" def bounding_polygon(self):\n", | |
" return [(self.north,self.west),(self.north,self.east),(self.south,self.east),(self.south,self.west)]\n", | |
" \n", | |
" def __init__(self, **kwargs):\n", | |
" super(LeafletWidget, self).__init__(**kwargs)\n", | |
" self.on_msg(self._handle_msg)\n", | |
"\n", | |
" def _handle_msg(self, msg):\n", | |
" content = msg['content']['data']['content']\n", | |
" if content.get('method') == 'update_bounds':\n", | |
" self._north = content['data']['north']\n", | |
" self._south = content['data']['south']\n", | |
" self._east = content['data']['east']\n", | |
" self._west = content['data']['west']\n", | |
"\n", | |
" def add_polygon(self, locations):\n", | |
" self.send({\n", | |
" 'method': 'add_polygon',\n", | |
" 'locations': locations\n", | |
" })\n", | |
" \n", | |
" def add_circle_marker(self, location, radius=10):\n", | |
" self.send({\n", | |
" 'method': 'add_circle_marker',\n", | |
" 'location': location,\n", | |
" 'radius': radius\n", | |
" })\n", | |
" \n", | |
" def add_geojson(self, data=None, style=None, filename=None):\n", | |
" style = {} if style is None else style\n", | |
" if filename:\n", | |
" with open(filename) as f:\n", | |
" data = json.load(f)\n", | |
" msg = {'method': 'add_geojson', 'data': data}\n", | |
" if style is not None:\n", | |
" msg['style'] = style\n", | |
" self.send(msg)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%javascript\n", | |
"\n", | |
"require.config({paths: {leaflet: \"http://cdn.leafletjs.com/leaflet-0.7.2/leaflet\"}});\n", | |
"\n", | |
"require([\"widgets/js/widget\", \"leaflet\"], function(WidgetManager, leaflet) {\n", | |
" \n", | |
" var LeafletWidgetView = IPython.DOMWidgetView.extend({\n", | |
" \n", | |
" initialize: function (options) {\n", | |
" LeafletWidgetView.__super__.initialize.apply(this, arguments);\n", | |
" },\n", | |
"\n", | |
" render: function () {\n", | |
" this.$el.width(this.model.get('width')).height(this.model.get('height'));\n", | |
" this.model.on('displayed', this.render_leaflet, this);\n", | |
" },\n", | |
"\n", | |
" render_leaflet: function () {\n", | |
" var that = this;\n", | |
" this.map = leaflet.map(this.$el.get(0));\n", | |
" this.map.setView(this.model.get('location'), this.model.get('zoom_start'));\n", | |
" leaflet.tileLayer(this.model.get('tiles_url'), {\n", | |
" attribution: this.model.get('tiles_attr'),\n", | |
" maxZoom: this.model.get('max_zoom'),\n", | |
" minZoom: this.model.get('min_zoom'),\n", | |
" }).addTo(this.map);\n", | |
" this.leaflet_events();\n", | |
" this.model_events();\n", | |
" this.model.on('msg:custom', this.handle_msg, this);\n", | |
" this.update_bounds();\n", | |
" },\n", | |
" \n", | |
" leaflet_events: function () {\n", | |
" var that = this;\n", | |
" this.map.on('moveend', function (e) {\n", | |
" var c = e.target.getCenter();\n", | |
" that.model.set('location', [c.lat, c.lng]);\n", | |
" that.touch();\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" this.map.on('zoomend', function (e) {\n", | |
" var z = e.target.getZoom();\n", | |
" that.model.set('zoom', z);\n", | |
" that.touch();\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" },\n", | |
"\n", | |
" update_bounds: function () {\n", | |
" var that = this;\n", | |
" var b = that.map.getBounds();\n", | |
" var o = {north: b.getNorth(), south: b.getSouth(), east: b.getEast(), west: b.getWest()};\n", | |
" that.send({method:'update_bounds', data:o});\n", | |
" },\n", | |
"\n", | |
" model_events: function () {\n", | |
" var that = this;\n", | |
" this.model.on('change:zoom', function () {\n", | |
" that.map.setZoom(that.model.get('zoom'));\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" this.model.on('change:location', function () {\n", | |
" that.map.panTo(that.model.get('location'));\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" },\n", | |
" \n", | |
" handle_msg: function (content) {\n", | |
" switch(content.method) {\n", | |
" case 'add_polygon':\n", | |
" this.add_polygon(content.locations);\n", | |
" break;\n", | |
" case 'add_circle_marker':\n", | |
" this.add_circle_marker(content.location, content.radius);\n", | |
" break;\n", | |
" case 'add_geojson':\n", | |
" this.add_geojson(content.data, content.style);\n", | |
" break;\n", | |
" }\n", | |
" },\n", | |
"\n", | |
" add_polygon: function (locations) {\n", | |
" leaflet.polygon(locations).addTo(this.map);\n", | |
" },\n", | |
" \n", | |
" add_circle_marker: function (location, radius) {\n", | |
" leaflet.circleMarker(location, {radius:radius}).addTo(this.map);\n", | |
" },\n", | |
"\n", | |
" add_geojson: function (data, style) {\n", | |
" leaflet.geoJson(data, {style: style}).addTo(this.map);\n", | |
" },\n", | |
" \n", | |
" });\n", | |
" \n", | |
" WidgetManager.register_widget_view('LeafletWidgetView', LeafletWidgetView);\n", | |
"});" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"javascript": [ | |
"\n", | |
"require.config({paths: {leaflet: \"http://cdn.leafletjs.com/leaflet-0.7.2/leaflet\"}});\n", | |
"\n", | |
"require([\"widgets/js/widget\", \"leaflet\"], function(WidgetManager, leaflet) {\n", | |
" \n", | |
" var LeafletWidgetView = IPython.DOMWidgetView.extend({\n", | |
" \n", | |
" initialize: function (options) {\n", | |
" LeafletWidgetView.__super__.initialize.apply(this, arguments);\n", | |
" },\n", | |
"\n", | |
" render: function () {\n", | |
" this.$el.width(this.model.get('width')).height(this.model.get('height'));\n", | |
" this.model.on('displayed', this.render_leaflet, this);\n", | |
" },\n", | |
"\n", | |
" render_leaflet: function () {\n", | |
" var that = this;\n", | |
" this.map = leaflet.map(this.$el.get(0));\n", | |
" this.map.setView(this.model.get('location'), this.model.get('zoom_start'));\n", | |
" leaflet.tileLayer(this.model.get('tiles_url'), {\n", | |
" attribution: this.model.get('tiles_attr'),\n", | |
" maxZoom: this.model.get('max_zoom'),\n", | |
" minZoom: this.model.get('min_zoom'),\n", | |
" }).addTo(this.map);\n", | |
" this.leaflet_events();\n", | |
" this.model_events();\n", | |
" this.model.on('msg:custom', this.handle_msg, this);\n", | |
" this.update_bounds();\n", | |
" },\n", | |
" \n", | |
" leaflet_events: function () {\n", | |
" var that = this;\n", | |
" this.map.on('moveend', function (e) {\n", | |
" var c = e.target.getCenter();\n", | |
" that.model.set('location', [c.lat, c.lng]);\n", | |
" that.touch();\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" this.map.on('zoomend', function (e) {\n", | |
" var z = e.target.getZoom();\n", | |
" that.model.set('zoom', z);\n", | |
" that.touch();\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" },\n", | |
"\n", | |
" update_bounds: function () {\n", | |
" var that = this;\n", | |
" var b = that.map.getBounds();\n", | |
" var o = {north: b.getNorth(), south: b.getSouth(), east: b.getEast(), west: b.getWest()};\n", | |
" that.send({method:'update_bounds', data:o});\n", | |
" },\n", | |
"\n", | |
" model_events: function () {\n", | |
" var that = this;\n", | |
" this.model.on('change:zoom', function () {\n", | |
" that.map.setZoom(that.model.get('zoom'));\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" this.model.on('change:location', function () {\n", | |
" that.map.panTo(that.model.get('location'));\n", | |
" that.update_bounds();\n", | |
" });\n", | |
" },\n", | |
" \n", | |
" handle_msg: function (content) {\n", | |
" switch(content.method) {\n", | |
" case 'add_polygon':\n", | |
" this.add_polygon(content.locations);\n", | |
" break;\n", | |
" case 'add_circle_marker':\n", | |
" this.add_circle_marker(content.location, content.radius);\n", | |
" break;\n", | |
" case 'add_geojson':\n", | |
" this.add_geojson(content.data, content.style);\n", | |
" break;\n", | |
" }\n", | |
" },\n", | |
"\n", | |
" add_polygon: function (locations) {\n", | |
" leaflet.polygon(locations).addTo(this.map);\n", | |
" },\n", | |
" \n", | |
" add_circle_marker: function (location, radius) {\n", | |
" leaflet.circleMarker(location, {radius:radius}).addTo(this.map);\n", | |
" },\n", | |
"\n", | |
" add_geojson: function (data, style) {\n", | |
" leaflet.geoJson(data, {style: style}).addTo(this.map);\n", | |
" },\n", | |
" \n", | |
" });\n", | |
" \n", | |
" WidgetManager.register_widget_view('LeafletWidgetView', LeafletWidgetView);\n", | |
"});" | |
], | |
"metadata": {}, | |
"output_type": "display_data", | |
"text": [ | |
"<IPython.core.display.Javascript object>" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w = LeafletWidget()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w.location" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 7, | |
"text": [ | |
"[32.3226932, -90.9019257]" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w.bounding_polygon" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 8, | |
"text": [ | |
"[(32.380831284098235, -91.0049057006836),\n", | |
" (32.380831284098235, -90.79891204833984),\n", | |
" (32.26478149037512, -90.79891204833984),\n", | |
" (32.26478149037512, -91.0049057006836)]" | |
] | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w.zoom = 14" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w.add_polygon(w.bounding_polygon)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w.add_circle_marker(w.location)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 12 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import json" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"w.add_geojson(filename='demo.json',style=dict(color='red',weight=1,opacity=0.3))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"with open('demo.json') as f:\n", | |
" data = json.load(f)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 188 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"data.keys()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 190, | |
"text": [ | |
"[u'type', u'features']" | |
] | |
} | |
], | |
"prompt_number": 190 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"data['type']" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 191, | |
"text": [ | |
"u'FeatureCollection'" | |
] | |
} | |
], | |
"prompt_number": 191 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f = data['features']" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 193 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"type(f)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 194, | |
"text": [ | |
"list" | |
] | |
} | |
], | |
"prompt_number": 194 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"len(f)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 195, | |
"text": [ | |
"20" | |
] | |
} | |
], | |
"prompt_number": 195 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f0 = f[0]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 196 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"type(f0)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 197, | |
"text": [ | |
"dict" | |
] | |
} | |
], | |
"prompt_number": 197 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f0.keys()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 198, | |
"text": [ | |
"[u'geometry', u'type', u'id', u'properties']" | |
] | |
} | |
], | |
"prompt_number": 198 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f0['type']" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 199, | |
"text": [ | |
"u'Feature'" | |
] | |
} | |
], | |
"prompt_number": 199 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f0['geometry']['type']" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 203, | |
"text": [ | |
"u'MultiPolygon'" | |
] | |
} | |
], | |
"prompt_number": 203 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f0['properties']" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 204, | |
"text": [ | |
"{}" | |
] | |
} | |
], | |
"prompt_number": 204 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [] | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment