1 |
|
2 |
|
3 | goog.require('ol.Map');
|
4 | goog.require('ol.View');
|
5 | goog.require('ol.extent');
|
6 | goog.require('ol.format.GeoJSON');
|
7 | goog.require('ol.layer.Vector');
|
8 | goog.require('ol.source.Vector');
|
9 | goog.require('ol.style.Fill');
|
10 | goog.require('ol.style.Stroke');
|
11 | goog.require('ol.style.Style');
|
12 |
|
13 |
|
14 | function setStyle(context) {
|
15 | context.font = '12px Calibri,sans-serif';
|
16 | context.fillStyle = '#000';
|
17 | context.strokeStyle = '#fff';
|
18 | context.lineWidth = 3;
|
19 | context.textBaseline = 'hanging';
|
20 | context.textAlign = 'start';
|
21 | }
|
22 |
|
23 |
|
24 | var textMeasureContext = document.createElement('CANVAS').getContext('2d');
|
25 | setStyle(textMeasureContext);
|
26 |
|
27 |
|
28 | var height = textMeasureContext.measureText('WI').width;
|
29 |
|
30 |
|
31 | var textCache = {};
|
32 |
|
33 | var map = new ol.Map({
|
34 | target: 'map',
|
35 | view: new ol.View({
|
36 | center: [0, 0],
|
37 | zoom: 1
|
38 | })
|
39 | });
|
40 |
|
41 | var emptyFn = function() {};
|
42 | var labelEngine = new labelgun['default'](emptyFn, emptyFn);
|
43 |
|
44 | function createLabel(canvas, text, coord) {
|
45 | var halfWidth = canvas.width / 2;
|
46 | var halfHeight = canvas.height / 2;
|
47 | var bounds = {
|
48 | bottomLeft: [Math.round(coord[0] - halfWidth), Math.round(coord[1] - halfHeight)],
|
49 | topRight: [Math.round(coord[0] + halfWidth), Math.round(coord[1] + halfHeight)]
|
50 | };
|
51 | labelEngine.ingestLabel(bounds, coord.toString(), 1, canvas, text, false);
|
52 | }
|
53 |
|
54 |
|
55 |
|
56 | function sortByWidth(a, b) {
|
57 | return ol.extent.getWidth(b.getExtent()) - ol.extent.getWidth(a.getExtent());
|
58 | }
|
59 |
|
60 | var labelStyle = new ol.style.Style({
|
61 | renderer: function(coords, state) {
|
62 | var text = state.feature.get('name');
|
63 | createLabel(textCache[text], text, coords);
|
64 | }
|
65 | });
|
66 | var countryStyle = new ol.style.Style({
|
67 | fill: new ol.style.Fill({
|
68 | color: 'rgba(255, 255, 255, 0.6)'
|
69 | }),
|
70 | stroke: new ol.style.Stroke({
|
71 | color: '#319FD3',
|
72 | width: 1
|
73 | })
|
74 | });
|
75 | var styleWithLabel = [countryStyle, labelStyle];
|
76 | var styleWithoutLabel = [countryStyle];
|
77 |
|
78 | var pixelRatio;
|
79 | var vectorLayer = new ol.layer.Vector({
|
80 | source: new ol.source.Vector({
|
81 | url: 'data/geojson/countries.geojson',
|
82 | format: new ol.format.GeoJSON()
|
83 | }),
|
84 | style: function(feature, resolution) {
|
85 | var text = feature.get('name');
|
86 | var width = textMeasureContext.measureText(text).width;
|
87 | var geometry = feature.getGeometry();
|
88 | if (geometry.getType() == 'MultiPolygon') {
|
89 | geometry = geometry.getPolygons().sort(sortByWidth)[0];
|
90 | }
|
91 | var extentWidth = ol.extent.getWidth(geometry.getExtent());
|
92 | if (extentWidth / resolution > width) {
|
93 |
|
94 | if (!(text in textCache)) {
|
95 |
|
96 | var canvas = textCache[text] = document.createElement('CANVAS');
|
97 | canvas.width = width * pixelRatio;
|
98 | canvas.height = height * pixelRatio;
|
99 | var context = canvas.getContext('2d');
|
100 | context.scale(pixelRatio, pixelRatio);
|
101 | setStyle(context);
|
102 | context.strokeText(text, 0, 0);
|
103 | context.fillText(text, 0, 0);
|
104 | }
|
105 | labelStyle.setGeometry(geometry.getInteriorPoint());
|
106 | return styleWithLabel;
|
107 | } else {
|
108 | return styleWithoutLabel;
|
109 | }
|
110 | }
|
111 | });
|
112 | vectorLayer.on('precompose', function(e) {
|
113 | pixelRatio = e.frameState.pixelRatio;
|
114 | labelEngine.destroy();
|
115 | });
|
116 | vectorLayer.on('postcompose', function(e) {
|
117 | var labels = labelEngine.getShown();
|
118 | for (var i = 0, ii = labels.length; i < ii; ++i) {
|
119 | var label = labels[i];
|
120 |
|
121 | e.context.drawImage(label.labelObject, label.minX, label.minY);
|
122 | }
|
123 | });
|
124 |
|
125 | map.addLayer(vectorLayer);
|