UNPKG

3.5 kBJavaScriptView Raw
1// NOCOMPILE
2goog.require('ol.Map');
3goog.require('ol.View');
4goog.require('ol.layer.Image');
5goog.require('ol.layer.Tile');
6goog.require('ol.proj');
7goog.require('ol.source.BingMaps');
8goog.require('ol.source.Raster');
9
10function growRegion(inputs, data) {
11 var image = inputs[0];
12 var seed = data.pixel;
13 var delta = parseInt(data.delta);
14 if (!seed) {
15 return image;
16 }
17
18 seed = seed.map(Math.round);
19 var width = image.width;
20 var height = image.height;
21 var inputData = image.data;
22 var outputData = new Uint8ClampedArray(inputData);
23 var seedIdx = (seed[1] * width + seed[0]) * 4;
24 var seedR = inputData[seedIdx];
25 var seedG = inputData[seedIdx + 1];
26 var seedB = inputData[seedIdx + 2];
27 var edge = [seed];
28 while (edge.length) {
29 var newedge = [];
30 for (var i = 0, ii = edge.length; i < ii; i++) {
31 // As noted in the Raster source constructor, this function is provided
32 // using the `lib` option. Other functions will NOT be visible unless
33 // provided using the `lib` option.
34 var next = next4Edges(edge[i]);
35 for (var j = 0, jj = next.length; j < jj; j++) {
36 var s = next[j][0], t = next[j][1];
37 if (s >= 0 && s < width && t >= 0 && t < height) {
38 var ci = (t * width + s) * 4;
39 var cr = inputData[ci];
40 var cg = inputData[ci + 1];
41 var cb = inputData[ci + 2];
42 var ca = inputData[ci + 3];
43 // if alpha is zero, carry on
44 if (ca === 0) {
45 continue;
46 }
47 if (Math.abs(seedR - cr) < delta && Math.abs(seedG - cg) < delta &&
48 Math.abs(seedB - cb) < delta) {
49 outputData[ci] = 255;
50 outputData[ci + 1] = 0;
51 outputData[ci + 2] = 0;
52 outputData[ci + 3] = 255;
53 newedge.push([s, t]);
54 }
55 // mark as visited
56 inputData[ci + 3] = 0;
57 }
58 }
59 }
60 edge = newedge;
61 }
62 return {data: outputData, width: width, height: height};
63}
64
65function next4Edges(edge) {
66 var x = edge[0], y = edge[1];
67 return [
68 [x + 1, y],
69 [x - 1, y],
70 [x, y + 1],
71 [x, y - 1]
72 ];
73}
74
75var key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
76
77var imagery = new ol.layer.Tile({
78 source: new ol.source.BingMaps({key: key, imagerySet: 'Aerial'})
79});
80
81var raster = new ol.source.Raster({
82 sources: [imagery.getSource()],
83 operationType: 'image',
84 operation: growRegion,
85 // Functions in the `lib` object will be available to the operation run in
86 // the web worker.
87 lib: {
88 next4Edges: next4Edges
89 }
90});
91
92var rasterImage = new ol.layer.Image({
93 opacity: 0.7,
94 source: raster
95});
96
97var map = new ol.Map({
98 layers: [imagery, rasterImage],
99 target: 'map',
100 view: new ol.View({
101 center: ol.proj.fromLonLat([-119.07, 47.65]),
102 zoom: 11
103 })
104});
105
106var coordinate;
107
108map.on('click', function(event) {
109 coordinate = event.coordinate;
110 raster.changed();
111});
112
113var thresholdControl = document.getElementById('threshold');
114
115raster.on('beforeoperations', function(event) {
116 // the event.data object will be passed to operations
117 var data = event.data;
118 data.delta = thresholdControl.value;
119 if (coordinate) {
120 data.pixel = map.getPixelFromCoordinate(coordinate);
121 }
122});
123
124function updateControlValue() {
125 document.getElementById('threshold-value').innerText = thresholdControl.value;
126}
127updateControlValue();
128
129thresholdControl.addEventListener('input', function() {
130 updateControlValue();
131 raster.changed();
132});