1 | goog.require('ol.Map');
|
2 | goog.require('ol.View');
|
3 | goog.require('ol.extent');
|
4 | goog.require('ol.format.KML');
|
5 | goog.require('ol.interaction');
|
6 | goog.require('ol.interaction.Select');
|
7 | goog.require('ol.layer.Tile');
|
8 | goog.require('ol.layer.Vector');
|
9 | goog.require('ol.source.Cluster');
|
10 | goog.require('ol.source.Stamen');
|
11 | goog.require('ol.source.Vector');
|
12 | goog.require('ol.style.Circle');
|
13 | goog.require('ol.style.Fill');
|
14 | goog.require('ol.style.RegularShape');
|
15 | goog.require('ol.style.Stroke');
|
16 | goog.require('ol.style.Style');
|
17 | goog.require('ol.style.Text');
|
18 |
|
19 |
|
20 | var earthquakeFill = new ol.style.Fill({
|
21 | color: 'rgba(255, 153, 0, 0.8)'
|
22 | });
|
23 | var earthquakeStroke = new ol.style.Stroke({
|
24 | color: 'rgba(255, 204, 0, 0.2)',
|
25 | width: 1
|
26 | });
|
27 | var textFill = new ol.style.Fill({
|
28 | color: '#fff'
|
29 | });
|
30 | var textStroke = new ol.style.Stroke({
|
31 | color: 'rgba(0, 0, 0, 0.6)',
|
32 | width: 3
|
33 | });
|
34 | var invisibleFill = new ol.style.Fill({
|
35 | color: 'rgba(255, 255, 255, 0.01)'
|
36 | });
|
37 |
|
38 | function createEarthquakeStyle(feature) {
|
39 |
|
40 |
|
41 |
|
42 | var name = feature.get('name');
|
43 | var magnitude = parseFloat(name.substr(2));
|
44 | var radius = 5 + 20 * (magnitude - 5);
|
45 |
|
46 | return new ol.style.Style({
|
47 | geometry: feature.getGeometry(),
|
48 | image: new ol.style.RegularShape({
|
49 | radius1: radius,
|
50 | radius2: 3,
|
51 | points: 5,
|
52 | angle: Math.PI,
|
53 | fill: earthquakeFill,
|
54 | stroke: earthquakeStroke
|
55 | })
|
56 | });
|
57 | }
|
58 |
|
59 | var maxFeatureCount, vector;
|
60 | function calculateClusterInfo(resolution) {
|
61 | maxFeatureCount = 0;
|
62 | var features = vector.getSource().getFeatures();
|
63 | var feature, radius;
|
64 | for (var i = features.length - 1; i >= 0; --i) {
|
65 | feature = features[i];
|
66 | var originalFeatures = feature.get('features');
|
67 | var extent = ol.extent.createEmpty();
|
68 | var j, jj;
|
69 | for (j = 0, jj = originalFeatures.length; j < jj; ++j) {
|
70 | ol.extent.extend(extent, originalFeatures[j].getGeometry().getExtent());
|
71 | }
|
72 | maxFeatureCount = Math.max(maxFeatureCount, jj);
|
73 | radius = 0.25 * (ol.extent.getWidth(extent) + ol.extent.getHeight(extent)) /
|
74 | resolution;
|
75 | feature.set('radius', radius);
|
76 | }
|
77 | }
|
78 |
|
79 | var currentResolution;
|
80 | function styleFunction(feature, resolution) {
|
81 | if (resolution != currentResolution) {
|
82 | calculateClusterInfo(resolution);
|
83 | currentResolution = resolution;
|
84 | }
|
85 | var style;
|
86 | var size = feature.get('features').length;
|
87 | if (size > 1) {
|
88 | style = new ol.style.Style({
|
89 | image: new ol.style.Circle({
|
90 | radius: feature.get('radius'),
|
91 | fill: new ol.style.Fill({
|
92 | color: [255, 153, 0, Math.min(0.8, 0.4 + (size / maxFeatureCount))]
|
93 | })
|
94 | }),
|
95 | text: new ol.style.Text({
|
96 | text: size.toString(),
|
97 | fill: textFill,
|
98 | stroke: textStroke
|
99 | })
|
100 | });
|
101 | } else {
|
102 | var originalFeature = feature.get('features')[0];
|
103 | style = createEarthquakeStyle(originalFeature);
|
104 | }
|
105 | return style;
|
106 | }
|
107 |
|
108 | function selectStyleFunction(feature) {
|
109 | var styles = [new ol.style.Style({
|
110 | image: new ol.style.Circle({
|
111 | radius: feature.get('radius'),
|
112 | fill: invisibleFill
|
113 | })
|
114 | })];
|
115 | var originalFeatures = feature.get('features');
|
116 | var originalFeature;
|
117 | for (var i = originalFeatures.length - 1; i >= 0; --i) {
|
118 | originalFeature = originalFeatures[i];
|
119 | styles.push(createEarthquakeStyle(originalFeature));
|
120 | }
|
121 | return styles;
|
122 | }
|
123 |
|
124 | vector = new ol.layer.Vector({
|
125 | source: new ol.source.Cluster({
|
126 | distance: 40,
|
127 | source: new ol.source.Vector({
|
128 | url: 'data/kml/2012_Earthquakes_Mag5.kml',
|
129 | format: new ol.format.KML({
|
130 | extractStyles: false
|
131 | })
|
132 | })
|
133 | }),
|
134 | style: styleFunction
|
135 | });
|
136 |
|
137 | var raster = new ol.layer.Tile({
|
138 | source: new ol.source.Stamen({
|
139 | layer: 'toner'
|
140 | })
|
141 | });
|
142 |
|
143 | var map = new ol.Map({
|
144 | layers: [raster, vector],
|
145 | interactions: ol.interaction.defaults().extend([new ol.interaction.Select({
|
146 | condition: function(evt) {
|
147 | return evt.type == 'pointermove' ||
|
148 | evt.type == 'singleclick';
|
149 | },
|
150 | style: selectStyleFunction
|
151 | })]),
|
152 | target: 'map',
|
153 | view: new ol.View({
|
154 | center: [0, 0],
|
155 | zoom: 2
|
156 | })
|
157 | });
|