Last active
August 24, 2016 09:03
-
-
Save ResidentMario/13e902fd16fca628cc3fc826600bd2fe to your computer and use it in GitHub Desktop.
New York City Sample Bike Path (D3)
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>A Week in the Life of a CitiBike</title> | |
<style type="text/css"> | |
html { height: 100% } | |
body { height: 100%; margin: 0; padding: 0 } | |
#map-canvas { height: 100% } | |
</style> | |
<link href='https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css' | |
rel='stylesheet' type='text/css'/> | |
<meta http-equiv="X-UA-Compatible" content="IE=Edge"> | |
</head> | |
<body> | |
<div id="map-canvas"></div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script> | |
<script src="https://d3js.org/d3.v3.js"></script> | |
<script src="https://d3js.org/d3-queue.v3.js"></script> | |
<script src="L.D3SvgOverlay.js"></script> | |
<script> | |
// Initializes the basemap. | |
var map = L.map("map-canvas",{center:[40.773889, -73.983611],zoom:12}); | |
L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', { | |
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> © <a href="http://cartodb.com/attributions">CartoDB</a>', | |
subdomains: 'abcd', | |
maxZoom: 19 | |
}).addTo(map); | |
// D3-SVG-Overlay callback wrapper. Leaflet is used only for the base map, all of the programmatic action occurs | |
// in d3 code inside of this callback. | |
var mapOverlay = L.d3SvgOverlay(function(sel,proj){ | |
// Paints a single sampler path. | |
function paintPath(linearray) { | |
console.log(linearray); | |
// Define x and y conversions. | |
var line = d3.svg.line() | |
.x(function(d) { console.log(d); return proj.latLngToLayerPoint(d).x}) | |
.y(function(d) { console.log(d); return proj.latLngToLayerPoint(d).y}); | |
console.log(line); | |
sel.append("path") | |
.datum(linearray) | |
.attr({ | |
"class": "sample-line", | |
"d": line, | |
"fill": "transparent", | |
"stroke": "steelblue", | |
"stroke-width": 0.1, | |
"shape-rendering": "crispEdges" | |
}) | |
} | |
function paintPathSampler() { | |
d3.json("path_sampler.json", function (data) { | |
console.log(data[0]); | |
paintPath(data[0]); | |
paintPath(data[1]); | |
}); | |
} | |
paintPathSampler(); | |
}); | |
// Add overlay to map. | |
mapOverlay.addTo(map); | |
</script> | |
</body> | |
</html> |
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
/** | |
* Copyright 2015 Teralytics AG | |
* | |
* @author Kirill Zhuravlev <[email protected]> | |
* | |
*/ | |
(function (factory) { | |
if (typeof define === 'function' && define.amd) { | |
define(['leaflet', 'd3'], factory); | |
} else if (typeof module === 'object' && module.exports) { | |
module.exports = factory(require('leaflet', 'd3')); | |
} else { | |
factory(L, d3); | |
} | |
}(function (L, d3) { | |
// Check requirements | |
if (typeof d3 == "undefined") { | |
throw "D3 SVG Overlay for Leaflet requires D3 library loaded first"; | |
} | |
if (typeof L == "undefined") { | |
throw "D3 SVG Overlay for Leaflet requires Leaflet library loaded first"; | |
} | |
// Tiny stylesheet bundled here instead of a separate file | |
if (L.version >= "1.0") { | |
d3.select("head") | |
.append("style").attr("type", "text/css") | |
.text("g.d3-overlay *{pointer-events:visiblePainted;}"); | |
} | |
// Class definition | |
L.D3SvgOverlay = (L.version < "1.0" ? L.Class : L.Layer).extend({ | |
includes: (L.version < "1.0" ? L.Mixin.Events : []), | |
_undef: function(a){ return typeof a == "undefined" }, | |
_options: function (options) { | |
if (this._undef(options)) { | |
return this.options; | |
} | |
options.zoomHide = this._undef(options.zoomHide) ? false : options.zoomHide; | |
options.zoomDraw = this._undef(options.zoomDraw) ? true : options.zoomDraw; | |
return this.options = options; | |
}, | |
_disableLeafletRounding: function(){ | |
this._leaflet_round = L.Point.prototype._round; | |
L.Point.prototype._round = function(){ return this; }; | |
}, | |
_enableLeafletRounding: function(){ | |
L.Point.prototype._round = this._leaflet_round; | |
}, | |
draw: function () { | |
this._disableLeafletRounding(); | |
this._drawCallback(this.selection, this.projection, this.map.getZoom()); | |
this._enableLeafletRounding(); | |
}, | |
initialize: function (drawCallback, options) { // (Function(selection, projection)), (Object)options | |
this._options(options || {}); | |
this._drawCallback = drawCallback; | |
}, | |
// Handler for "viewreset"-like events, updates scale and shift after the animation | |
_zoomChange: function (evt) { | |
this._disableLeafletRounding(); | |
var newZoom = this._undef(evt.zoom) ? this.map._zoom : evt.zoom; // "viewreset" event in Leaflet has not zoom/center parameters like zoomanim | |
this._zoomDiff = newZoom - this._zoom; | |
this._scale = Math.pow(2, this._zoomDiff); | |
this.projection.scale = this._scale; | |
this._shift = this.map.latLngToLayerPoint(this._wgsOrigin) | |
._subtract(this._wgsInitialShift.multiplyBy(this._scale)); | |
var shift = ["translate(", this._shift.x, ",", this._shift.y, ") "]; | |
var scale = ["scale(", this._scale, ",", this._scale,") "]; | |
this._rootGroup.attr("transform", shift.concat(scale).join("")); | |
if (this.options.zoomDraw) { this.draw() } | |
this._enableLeafletRounding(); | |
}, | |
onAdd: function (map) { | |
this.map = map; | |
var _layer = this; | |
// SVG element | |
if (L.version < "1.0") { | |
map._initPathRoot(); | |
this._svg = d3.select(map._panes.overlayPane) | |
.select("svg"); | |
this._rootGroup = this._svg.append("g"); | |
} else { | |
this._svg = L.svg(); | |
map.addLayer(this._svg); | |
this._rootGroup = d3.select(this._svg._rootGroup).classed("d3-overlay", true); | |
} | |
this._rootGroup.classed("leaflet-zoom-hide", this.options.zoomHide); | |
this.selection = this._rootGroup; | |
// Init shift/scale invariance helper values | |
this._pixelOrigin = map.getPixelOrigin(); | |
this._wgsOrigin = L.latLng([0, 0]); | |
this._wgsInitialShift = this.map.latLngToLayerPoint(this._wgsOrigin); | |
this._zoom = this.map.getZoom(); | |
this._shift = L.point(0, 0); | |
this._scale = 1; | |
// Create projection object | |
this.projection = { | |
latLngToLayerPoint: function (latLng, zoom) { | |
zoom = _layer._undef(zoom) ? _layer._zoom : zoom; | |
var projectedPoint = _layer.map.project(L.latLng(latLng), zoom)._round(); | |
return projectedPoint._subtract(_layer._pixelOrigin); | |
}, | |
layerPointToLatLng: function (point, zoom) { | |
zoom = _layer._undef(zoom) ? _layer._zoom : zoom; | |
var projectedPoint = L.point(point).add(_layer._pixelOrigin); | |
return _layer.map.unproject(projectedPoint, zoom); | |
}, | |
unitsPerMeter: 256 * Math.pow(2, _layer._zoom) / 40075017, | |
map: _layer.map, | |
layer: _layer, | |
scale: 1 | |
}; | |
this.projection._projectPoint = function(x, y) { | |
var point = _layer.projection.latLngToLayerPoint(new L.LatLng(y, x)); | |
this.stream.point(point.x, point.y); | |
}; | |
this.projection.pathFromGeojson = | |
d3.geo.path().projection(d3.geo.transform({point: this.projection._projectPoint})); | |
// Compatibility with v.1 | |
this.projection.latLngToLayerFloatPoint = this.projection.latLngToLayerPoint; | |
this.projection.getZoom = this.map.getZoom.bind(this.map); | |
this.projection.getBounds = this.map.getBounds.bind(this.map); | |
this.selection = this._rootGroup; | |
if (L.version < "1.0") map.on("viewreset", this._zoomChange, this); | |
// Initial draw | |
this.draw(); | |
}, | |
// Leaflet 1.0 | |
getEvents: function() { return {zoomend: this._zoomChange}; }, | |
onRemove: function (map) { | |
if (L.version < "1.0") { | |
map.off("viewreset", this._zoomChange, this); | |
this._rootGroup.remove(); | |
} else { | |
this._svg.remove(); | |
} | |
}, | |
addTo: function (map) { | |
map.addLayer(this); | |
return this; | |
} | |
}); | |
L.D3SvgOverlay.version = "2.2"; | |
// Factory method | |
L.d3SvgOverlay = function (drawCallback, options) { | |
return new L.D3SvgOverlay(drawCallback, options); | |
}; | |
})); |
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
[[[40.76529, -73.98208], [40.76476, -73.98225], [40.76457, -73.98232], [40.76441, -73.98238], [40.76438, -73.98239], [40.76434, -73.98241], [40.76423, -73.98245], [40.76412, -73.98249], [40.76405, -73.98252], [40.76402, -73.98254], [40.76396, -73.98257], [40.76351, -73.98281], [40.76339, -73.98288], [40.7633, -73.98293], [40.76318, -73.983], [40.76282, -73.98321], [40.76273, -73.98326], [40.76264, -73.98332], [40.76219, -73.9836], [40.76207, -73.98368], [40.76178, -73.98387], [40.76145, -73.98411], [40.7608, -73.98452], [40.76072, -73.98456], [40.76052, -73.98465], [40.76013, -73.98487], [40.76013, -73.98487], [40.75999, -73.98453], [40.75984, -73.98418], [40.75984, -73.98418], [40.75952, -73.98441], [40.7592, -73.98461], [40.75858, -73.98507], [40.75833, -73.98526], [40.75796, -73.98553], [40.75778, -73.98568], [40.75734, -73.986], [40.7567, -73.98648], [40.75603, -73.98695], [40.75603, -73.98695], [40.75582, -73.98644], [40.75582, -73.98644], [40.75505, -73.98668], [40.75434, -73.98691], [40.75362, -73.98713], [40.75332, -73.98723], [40.75303, -73.98732], [40.75291, -73.98735], [40.75218, -73.98754], [40.75187, -73.98761], [40.75183, -73.98762], [40.75145, -73.98771], [40.7512, -73.98774], [40.7507, -73.98783], [40.75036, -73.98789], [40.74988, -73.98798], [40.74968, -73.98804], [40.74957, -73.98809], [40.74948, -73.98814], [40.74925, -73.9883], [40.74924, -73.9883], [40.74923, -73.98829], [40.74919, -73.98819], [40.74912, -73.98804], [40.74912, -73.98802], [40.74911, -73.98802], [40.7491, -73.98801], [40.749, -73.98803], [40.74898, -73.98805], [40.74896, -73.98807], [40.74894, -73.98808], [40.74881, -73.9881], [40.74869, -73.98812], [40.74863, -73.98813], [40.74858, -73.98814], [40.74845, -73.98817], [40.74831, -73.9882], [40.74811, -73.98824], [40.74754, -73.98836], [40.74735, -73.98839], [40.74721, -73.98841], [40.74713, -73.98843], [40.74707, -73.98844], [40.74679, -73.98849], [40.74604, -73.98858], [40.74582, -73.98867], [40.74559, -73.98872], [40.7453, -73.98877], [40.74455, -73.9889], [40.74435, -73.98894], [40.74412, -73.98899], [40.74392, -73.98903], [40.7438, -73.98904], [40.74368, -73.98905], [40.74337, -73.98911], [40.74316, -73.98915], [40.74303, -73.98917], [40.74294, -73.98919], [40.74261, -73.98924], [40.74257, -73.98924], [40.74253, -73.98924], [40.74252, -73.98923], [40.7425, -73.98922], [40.74231, -73.98902], [40.74231, -73.98902], [40.74225, -73.98906], [40.7419, -73.98931], [40.7418, -73.9894], [40.74155, -73.98959], [40.74087, -73.9901], [40.74025, -73.99053], [40.73967, -73.99096], [40.73908, -73.99139], [40.73849, -73.99181], [40.73792, -73.99222], [40.73732, -73.99267], [40.73669, -73.99315], [40.73624, -73.99347], [40.73618, -73.99352], [40.73602, -73.99363], [40.7353, -73.99416], [40.73467, -73.99459], [40.73403, -73.99507], [40.73344, -73.99552], [40.73284, -73.99594], [40.73225, -73.99638], [40.73185, -73.99668], [40.73141, -73.99698], [40.73141, -73.99698], [40.73147, -73.9971], [40.73216, -73.9985], [40.73222, -73.99863], [40.73222, -73.99863], [40.73211, -73.99873], [40.73164, -73.99913], [40.73105, -73.99962], [40.73105, -73.99962], [40.73067, -73.99886], [40.73067, -73.99886], [40.73046, -73.99903]]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment