@quartic/bokehjs
Version:
Interactive, novel data visualization
149 lines (118 loc) • 4.79 kB
text/coffeescript
import {ColumnarDataSource} from "./columnar_data_source"
import {logger} from "core/logging"
import * as p from "core/properties"
export class GeoJSONDataSource extends ColumnarDataSource
type: 'GeoJSONDataSource'
{
geojson: [ p.Any ] # TODO (bev)
}
{
data: [ p.Any, {} ]
}
initialize: (options) ->
super(options)
_update_data: () -> =
_get_new_list_array: (length) -> ([] for i in [0...length])
_get_new_nan_array: (length) -> (NaN for i in [0...length])
_flatten_function: (accumulator, currentItem) ->
return accumulator.concat([[NaN, NaN, NaN]]).concat(currentItem)
_add_properties: (item, data, i, item_count) ->
for property of item.properties
if !data.hasOwnProperty(property)
data[property] =
data[property][i] = item.properties[property]
_add_geometry: (geometry, data, i) ->
switch geometry.type
when "Point"
coords = geometry.coordinates
data.x[i] = coords[0]
data.y[i] = coords[1]
data.z[i] = coords[2] ? NaN
when "LineString"
coord_list = geometry.coordinates
for coords, j in coord_list
data.xs[i][j] = coords[0]
data.ys[i][j] = coords[1]
data.zs[i][j] = coords[2] ? NaN
when "Polygon"
if geometry.coordinates.length > 1
logger.warn('Bokeh does not support Polygons with holes in, only exterior ring used.')
exterior_ring = geometry.coordinates[0]
for coords, j in exterior_ring
data.xs[i][j] = coords[0]
data.ys[i][j] = coords[1]
data.zs[i][j] = coords[2] ? NaN
when "MultiPoint"
logger.warn('MultiPoint not supported in Bokeh')
when "MultiLineString"
flattened_coord_list = geometry.coordinates.reduce()
for coords, j in flattened_coord_list
data.xs[i][j] = coords[0]
data.ys[i][j] = coords[1]
data.zs[i][j] = coords[2] ? NaN
when "MultiPolygon"
exterior_rings = []
for polygon in geometry.coordinates
if polygon.length > 1
logger.warn('Bokeh does not support Polygons with holes in, only exterior ring used.')
exterior_rings.push(polygon[0])
flattened_coord_list = exterior_rings.reduce()
for coords, j in flattened_coord_list
data.xs[i][j] = coords[0]
data.ys[i][j] = coords[1]
data.zs[i][j] = coords[2] ? NaN
else
throw new Error('Invalid type ' + geometry.type)
_get_items_length: (items) ->
count = 0
for item, i in items
geometry = if item.type == 'Feature' then item.geometry else item
if geometry.type == 'GeometryCollection'
for g, j in geometry.geometries
count += 1
else
count += 1
return count
geojson_to_column_data: () ->
geojson = JSON.parse()
if geojson.type not in ['GeometryCollection', 'FeatureCollection']
throw new Error('Bokeh only supports type GeometryCollection and FeatureCollection at top level')
if geojson.type == 'GeometryCollection'
if not geojson.geometries?
throw new Error('No geometries found in GeometryCollection')
if geojson.geometries.length == 0
throw new Error('geojson.geometries must have one or more items')
items = geojson.geometries
if geojson.type == 'FeatureCollection'
if not geojson.features?
throw new Error('No features found in FeaturesCollection')
if geojson.features.length == 0
throw new Error('geojson.features must have one or more items')
items = geojson.features
item_count =
data = {
'x': ,
'y': ,
'z': ,
'xs': ,
'ys': ,
'zs':
}
arr_index = 0
for item, i in items
geometry = if item.type == 'Feature' then item.geometry else item
if geometry.type == 'GeometryCollection'
for g, j in geometry.geometries
if item.type == 'Feature'
arr_index += 1
else
# Now populate based on Geometry type
if item.type == 'Feature'
arr_index += 1
return data