-
Notifications
You must be signed in to change notification settings - Fork 0
/
legacy-geocoder.js
108 lines (100 loc) · 3.35 KB
/
legacy-geocoder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
* Raster-based geocoder, using an off-screen canvas
*/
d3.geo.rasterCoder = function () {
// projection is arbitrary, so let's use a fast one
var projection = d3.geo.equirectangular(),
canvas = document.createElement("canvas"),
context = canvas.getContext("2d"),
// XXX: determine canvas size based on precision parameter
canvasMax = 960,
colorMap,
features;
function coder(point) {
var coords = projection(point),
pixel = context.getImageData(~~coords[0], ~~coords[1], 1, 1).data;
return pixel[3] ? features[colorMap[d3.rgb(pixel[0], pixel[1], pixel[2])]] : null;
}
function redrawCanvas() {
// get the bounding box for the data
var left = Infinity,
bottom = -Infinity,
right = -Infinity,
top = Infinity;
// reset projection
projection
.scale(1)
.translate([0, 0]);
features.forEach(function(feature) {
d3.geo.bounds(feature).forEach(function(coords) {
coords = projection(coords);
var x = coords[0],
y = coords[1];
if (x < left) left = x;
if (x > right) right = x;
if (y > bottom) bottom = y;
if (y < top) top = y;
});
});
// projected size
var pWidth = Math.abs(right - left),
pHeight = Math.abs(bottom - top),
widthDetermined = pWidth > pHeight,
aspect = pWidth / pHeight,
// pixel size
width = widthDetermined ? canvasMax : ~~(canvasMax * aspect),
height = widthDetermined ? ~~(canvasMax / aspect) : canvasMax,
scale = width / pWidth;
canvas.width = width;
canvas.height = height;
// set x translation
transX = -left * scale,
// set y translation
transY = -top * scale;
// update projection
projection
.scale(scale)
.translate([transX, transY]);
// set up projection
var path = d3.geo.path()
.projection(projection)
.context(context),
// set up colors
colors = d3.scale.linear()
.domain([0, features.length])
.range(['#000000', '#ffffff']);
var borderColors = d3.scale.linear()
.domain([0, features.length])
.range(['#400000', '#FF0000']);
colorMap = {};
// clear canvas with a different color
context.clearRect(0, 0, width, height);
features.forEach(function(feature, i) {
var color = colors(i);
colorMap[color] = i;
context.fillStyle = color;
context.strokeStyle = color;
context.beginPath();
path(feature);
context.fill();
context.stroke();
});
}
// for debugging
coder.canvas = function () {
return canvas;
};
coder.features = function(x) {
if (!arguments.length) return features;
features = x;
if (features) redrawCanvas();
return coder;
};
coder.size = function(x) {
if (!arguments.length) return canvasMax;
canvasMax = x;
if (features) redrawCanvas();
return coder;
};
return coder;
};