Skip to content

Instantly share code, notes, and snippets.

@poezn
Created October 23, 2012 05:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poezn/3936833 to your computer and use it in GitHub Desktop.
Save poezn/3936833 to your computer and use it in GitHub Desktop.
just another inlet to tributary
{"endpoint":"","display":"svg","public":true,"require":[],"tab":"edit","display_percent":0.7,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01}
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
var svg = d3.select("svg");
g = svg.append('g');
d3.geo.albersUsa = function() {
var alaska, albersUsa, hawaii, lower48, puertoRico;
albersUsa = function(coordinates) {
var lat, lon;
lon = coordinates[0];
lat = coordinates[1];
return (lat > 52.7 ? alaska : (lon < -140 ? hawaii : (lat < 21 ? puertoRico : lower48)))(coordinates);
};
lower48 = d3.geo.albers();
alaska = d3.geo.albers().origin([-160, 60]).parallels([55, 65]);
hawaii = d3.geo.albers().origin([-160, 20]).parallels([8, 18]);
puertoRico = d3.geo.albers().origin([-60, 10]).parallels([8, 18]);
albersUsa.scale = function(x) {
if (!arguments.length) {
return lower48.scale();
}
lower48.scale(x);
alaska.scale(x * .6);
hawaii.scale(x);
puertoRico.scale(x * 1.5);
return albersUsa.translate(lower48.translate());
};
albersUsa.translate = function(x) {
var dx, dy, dz;
if (!arguments.length) {
return lower48.translate();
}
dz = lower48.scale() / 1000;
dx = x[0];
dy = x[1];
lower48.translate(x);
alaska.translate([dx - 309 * dz, dy + 228 * dz]);
hawaii.translate([dx - 79 * dz, dy + 285 * dz]);
puertoRico.translate([dx + 580 * dz, dy + 430 * dz]);
return albersUsa;
};
return albersUsa.scale(lower48.scale());
};
//
var geo = tb['geo'];
//console.log(geo);
var path;
var x = 531, y = 351;
var simplify = d3.simplify()
.topology(true)
.area(0)
.projection(d3.geo.albersUsa().scale(250).translate([x, y]));
var xy = d3.geo.albersUsa()
.scale(1013)
.translate([x, y])
path = d3.geo.path().projection(function(d) { return [d[0], d[1]]; });
//path = d3.geo.path().projection(xy)
var minArea = 1.9;
function copy(d) {
return Array.isArray(d) ? d.map(copy)
: typeof d === "number" || typeof d === "string" ? d
: copyObject(d);
}
function copyObject(d) {
var o = {};
for (var k in d) o[k] = copy(d[k]);
return o;
}
var geography = copy(geo);
simplify.project(geography);
//console.log(geography);
var sh = g.selectAll("path.previewshapes")
.data(geography.features, function(d) {
return d.properties.ID;
})
.enter().append("path")
.attr("class", "previewshapes")
.attr("d", function(d, i) {
return path(simplify.area(minArea)(d));
})
.style({
"stroke-width": 0,
"fill-opacity": 1,
fill: this.color
});
g.attr('transform', 'scale(3)')
(function() {
d3.simplify = function() {
var projection = d3.geo.albers(),
heap,
minArea = 3,
topology = false;
var triangulateCoordinates = {
MultiPolygon: triangulateMultiPolygon,
Polygon: triangulatePolygon,
MultiLineString: triangulatePolygon,
LineString: triangulateLineString
};
var simplifyCoordinates = {
MultiPolygon: simplifyMultiPolygon,
Polygon: simplifyPolygon,
MultiLineString: simplifyPolygon,
LineString: simplifyLineString
};
function simplify(object) {
var type = object.type;
if (type === "FeatureCollection") {
return {
type: "FeatureCollection",
features: object.features.map(simplifyFeature).filter(nonemptyFeature)
};
}
return (type === "Feature" ? simplifyFeature : simplifyGeometry)(object);
}
simplify.project = function(feature) {
var maxArea = 0,
triangle;
heap = minHeap();
triangulate(feature);
while (triangle = heap.pop()) {
// If the area of the current point is less than that of the previous point
// to be eliminated, use the latter’s area instead. This ensures that the
// current point cannot be eliminated without eliminating previously-
// eliminated points.
if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;
else maxArea = triangle[1][2];
if (triangle.previous) {
triangle.previous.next = triangle.next;
triangle.previous[2] = triangle[2];
update(triangle.previous);
} else if (!topology) {
triangle[0][2] = triangle[1][2];
}
if (triangle.next) {
triangle.next.previous = triangle.previous;
triangle.next[0] = triangle[0];
update(triangle.next);
} else if (!topology) {
triangle[2][2] = triangle[1][2];
}
}
function update(triangle) {
heap.remove(triangle);
triangle[1][2] = area(triangle);
heap.push(triangle);
}
heap = null;
return feature;
};
function triangulate(object) {
if (topology) triangulateTopology(object);
else {
var type = object.type;
if (type === "FeatureCollection") object.features.forEach(triangulateFeature);
else (type === "Feature" ? triangulateFeature : triangulateGeometry)(object);
}
}
function triangulateTopology(object) {
var id = 0,
ringId = 0,
idByRings = {},
ringByPoint = {},
type = object.type,
topologyCoordinates = {
MultiPolygon: topologyMultiPolygon,
Polygon: topologyPolygon,
MultiLineString: topologyPolygon,
LineString: topologyLineString
},
triangulateCoordinates = {
MultiPolygon: triangulateMultiPolygon,
Polygon: triangulatePolygon,
MultiLineString: triangulatePolygon,
LineString: triangulateLineString0
};
if (type === "FeatureCollection") {
object.features.forEach(topologyFeature);
object.features.forEach(triangulateFeature);
} else if (type === "Feature") {
topologyFeature(object);
triangulateFeature(object);
} else {
topologyGeometry(object);
triangulateGeometry(object);
}
function topologyFeature(feature) { return topologyGeometry(feature.geometry); }
function topologyGeometry(geometry) {
var type = geometry.type;
if (type === "GeometryCollection") geometry.geometries.forEach(topologyGeometry);
else topologyCoordinates[type](geometry.coordinates);
}
function topologyMultiPolygon(multiPolygon) { multiPolygon.forEach(topologyPolygon); }
function topologyLineString(lineString) { topologyPolygon([lineString]); }
function topologyPolygon(polygon) {
polygon.forEach(function(ring) {
++ringId;
ring.forEach(function(point) {
point = point.join(",");
var key = ringByPoint.hasOwnProperty(point) ? ringByPoint[point] + ":" + ringId : ringId;
ringByPoint[point] = idByRings.hasOwnProperty(key) ? idByRings[key] : (idByRings[key] = ++id);
});
});
}
function triangulateFeature(feature) { triangulateGeometry(feature.geometry); }
function triangulateGeometry(geometry) {
var type = geometry.type;
if (type === "GeometryCollection") geometry.geometries.forEach(topologyGeometry);
else geometry.coordinates = triangulateCoordinates[type](geometry.coordinates);
}
function triangulateMultiPolygon(multiPolygon) { return multiPolygon.map(triangulatePolygon); }
function triangulatePolygon(polygon) { return polygon.map(triangulateLineString0); }
function triangulateLineString0(lineString) {
var result = [],
id0,
i0 = 0;
lineString.forEach(function(point, i) {
var id = ringByPoint[point.join(",")];
if (id !== id0) {
if (id0) {
var chain = triangulateLineString(lineString.slice(i0, i0 = i));
chain[0][2] = chain[chain.length - 1][2] = Infinity;
result = result.concat(chain);
}
id0 = id;
}
});
var chain = triangulateLineString(i0 ? lineString.slice(i0) : lineString);
chain[0][2] = chain[chain.length - 1][2] = Infinity;
return result.concat(chain);
}
}
function triangulateFeature(feature) {
triangulateGeometry(feature.geometry);
}
function triangulateGeometry(geometry) {
var type = geometry.type;
if (type === "GeometryCollection") geometry.geometries.forEach(triangulateGeometry);
else geometry.coordinates = triangulateCoordinates[type](geometry.coordinates);
}
function triangulateMultiPolygon(multiPolygon) {
return multiPolygon.map(triangulatePolygon);
}
function triangulatePolygon(polygon) {
return polygon.map(triangulateLineString);
}
function triangulateLineString(lineString) {
var points = lineString.map(projection),
triangle,
triangles = [];
for (var i = 1, n = lineString.length - 1; i < n; ++i) {
triangle = points.slice(i - 1, i + 2);
triangle[1][2] = area(triangle);
triangles.push(triangle);
heap.push(triangle);
}
points[0][2] = points[n][2] = 0;
for (var i = 0, n = triangles.length; i < n; ++i) {
triangle = triangles[i];
triangle.previous = triangles[i - 1];
triangle.next = triangles[i + 1];
}
return points;
}
function simplifyFeature(feature) {
return {
type: "Feature",
geometry: simplifyGeometry(feature.geometry)
};
}
function simplifyGeometry(geometry) {
var type = geometry.type;
return type === "GeometryCollection"
? {type: type, geometries: geometry.geometries.map(simplifyGeometry).filter(nonemptyGeometry)}
: {type: type, coordinates: simplifyCoordinates[type](geometry.coordinates)};
}
function simplifyMultiPolygon(multiPolygon) {
return multiPolygon.map(simplifyPolygon).filter(length);
}
function simplifyPolygon(polygon) {
return polygon.map(simplifyLineString).filter(length);
}
function simplifyLineString(lineString) {
return lineString.filter(filterLineString);
}
function filterLineString(point) {
return point[2] >= minArea;
}
simplify.projection = function(_) {
if (!arguments.length) return projection;
projection = _;
return simplify;
};
simplify.area = function(_) {
if (!arguments.length) return minArea;
minArea = +_;
return simplify;
};
simplify.topology = function(_) {
if (!arguments.length) return topology;
topology = !!_;
return simplify;
};
return simplify;
};
function compare(a, b) {
return a[1][2] - b[1][2];
}
function area(t) {
return Math.abs((t[0][0] - t[2][0]) * (t[1][1] - t[0][1]) - (t[0][0] - t[1][0]) * (t[2][1] - t[0][1]));
}
function minHeap() {
var heap = {},
array = [];
heap.push = function() {
for (var i = 0, n = arguments.length; i < n; ++i) {
var object = arguments[i];
up(object.index = array.push(object) - 1);
}
return array.length;
};
heap.pop = function() {
var removed = array[0],
object = array.pop();
if (array.length) {
array[object.index = 0] = object;
down(0);
}
return removed;
};
heap.remove = function(removed) {
var i = removed.index,
object = array.pop();
if (i !== array.length) {
array[object.index = i] = object;
(compare(object, removed) < 0 ? up : down)(i);
}
return i;
};
function up(i) {
var object = array[i];
while (i > 0) {
var up = ((i + 1) >> 1) - 1,
parent = array[up];
if (compare(object, parent) >= 0) break;
array[parent.index = i] = parent;
array[object.index = i = up] = object;
}
}
function down(i) {
var object = array[i];
while (true) {
var right = (i + 1) << 1,
left = right - 1,
down = i,
child = array[down];
if (left < array.length && compare(array[left], child) < 0) child = array[down = left];
if (right < array.length && compare(array[right], child) < 0) child = array[down = right];
if (down === i) break;
array[child.index = i] = child;
array[object.index = i = down] = object;
}
}
return heap;
}
function nonemptyFeature(d) { return nonemptyGeometry(d.geometry); }
function nonemptyGeometry(d) {
return length(d.type === "GeometryCollection"
? d.geometries : d.coordinates);
}
function length(d) { return d.length; }
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment