raster.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from __future__ import division
  2. if __name__ == "__main__":
  3. from bokeh.io import curdoc
  4. from bokeh.plotting import Figure
  5. from bokeh.models import ColumnDataSource, CustomJS
  6. from bokeh.tile_providers import STAMEN_TONER
  7. import rasterio as rio
  8. import datashader as ds
  9. import datashader.transfer_functions as tf
  10. from datashader.colors import Hot
  11. def on_dims_change(attr, old, new):
  12. update_image()
  13. def update_image():
  14. global dims, raster_data
  15. dims_data = dims.data
  16. if not dims_data['width'] or not dims_data['height']:
  17. return
  18. xmin = max(dims_data['xmin'][0], raster_data.bounds.left)
  19. ymin = max(dims_data['ymin'][0], raster_data.bounds.bottom)
  20. xmax = min(dims_data['xmax'][0], raster_data.bounds.right)
  21. ymax = min(dims_data['ymax'][0], raster_data.bounds.top)
  22. canvas = ds.Canvas(plot_width=dims_data['width'][0],
  23. plot_height=dims_data['height'][0],
  24. x_range=(xmin, xmax),
  25. y_range=(ymin, ymax))
  26. agg = canvas.raster(raster_data)
  27. img = tf.shade(agg, cmap=Hot, how='linear')
  28. new_data = {}
  29. new_data['image'] = [img.data]
  30. new_data['x'] = [xmin]
  31. new_data['y'] = [ymin]
  32. new_data['dh'] = [ymax - ymin]
  33. new_data['dw'] = [xmax - xmin]
  34. image_source.stream(new_data, 1)
  35. # load nyc taxi data
  36. path = './data/projected.tif'
  37. raster_data = rio.open(path)
  38. # manage client-side dimensions
  39. dims = ColumnDataSource(data=dict(width=[], height=[], xmin=[], xmax=[], ymin=[], ymax=[]))
  40. dims.on_change('data', on_dims_change)
  41. dims_jscode = """
  42. var update_dims = function () {
  43. var new_data = {
  44. height: [plot.frame.height],
  45. width: [plot.frame.width],
  46. xmin: [plot.x_range.start],
  47. ymin: [plot.y_range.start],
  48. xmax: [plot.x_range.end],
  49. ymax: [plot.y_range.end]
  50. };
  51. dims.data = new_data;
  52. };
  53. if (typeof throttle != 'undefined' && throttle != null) {
  54. clearTimeout(throttle);
  55. }
  56. throttle = setTimeout(update_dims, 100, "replace");
  57. """
  58. # Create plot -------------------------------
  59. xmin = -8240227.037
  60. ymin = 4974203.152
  61. xmax = -8231283.905
  62. ymax = 4979238.441
  63. path = './data/projected.tif'
  64. fig = Figure(x_range=(xmin, xmax),
  65. y_range=(ymin, ymax),
  66. plot_height=600,
  67. plot_width=900,
  68. tools='pan,wheel_zoom')
  69. fig.background_fill_color = 'black'
  70. fig.add_tile(STAMEN_TONER, alpha=0) # used to set axis ranges
  71. fig.x_range.callback = CustomJS(code=dims_jscode, args=dict(plot=fig, dims=dims))
  72. fig.y_range.callback = CustomJS(code=dims_jscode, args=dict(plot=fig, dims=dims))
  73. fig.axis.visible = False
  74. fig.grid.grid_line_alpha = 0
  75. fig.min_border_left = 0
  76. fig.min_border_right = 0
  77. fig.min_border_top = 0
  78. fig.min_border_bottom = 0
  79. image_source = ColumnDataSource(dict(image=[], x=[], y=[], dw=[], dh=[]))
  80. fig.image_rgba(source=image_source,
  81. image='image',
  82. x='x',
  83. y='y',
  84. dw='dw',
  85. dh='dh',
  86. dilate=False)
  87. curdoc().add_root(fig)