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