-
Notifications
You must be signed in to change notification settings - Fork 2
/
map-view.js
124 lines (107 loc) · 3.76 KB
/
map-view.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/******************************************************************************
*
* Copyright (c) 2017, the Perspective Authors.
*
* This file is part of the Perspective library, distributed under the terms of
* the Apache License 2.0. The full license can be found in the LICENSE file.
*
*/
import {getMapData, getDataExtents} from "../data/data";
import {baseMap} from "./base-map";
import {categoryColorMap} from "../style/categoryColors";
import {linearColorScale} from "../style/linearColors";
import {showLegend, hideLegend} from "../legend/legend";
import {categoryShapeMap} from "../style/categoryShapes";
import {lightenRgb} from "../style/computed";
const ol = window.ol;
const {Vector: VectorLayer} = ol.layer;
const {Vector: VectorSource} = ol.source;
const {Feature} = ol;
const {fromLonLat} = ol.proj;
const {Point} = ol.geom;
const MIN_SIZE = 1;
const MAX_SIZE = 10;
const DEFAULT_SIZE = 2;
function mapView(container, config) {
const data = getMapData(config);
const extents = getDataExtents(data);
const map = baseMap(container);
const useLinearColors = extents.length > 2;
const colorScale = useLinearColors ? linearColorScale(container, extents[2]) : null;
const colorMap = useLinearColors ? d => colorScale(d.cols[2]) : categoryColorMap(container, data);
const sizeMap = sizeMapFromExtents(extents);
const shapeMap = categoryShapeMap(container, data);
const vectorSource = new VectorSource({
features: data.map(point => featureFromPoint(point, colorMap, sizeMap, shapeMap)),
wrapX: false
});
baseMap.initialiseView(container, vectorSource);
const vectorLayer = new VectorLayer({source: vectorSource, updateWhileInteracting: true, renderMode: "image"});
map.map.addLayer(vectorLayer);
// Update the tooltip component
map.tooltip
.config(config)
.vectorSource(vectorSource)
.regions(false)
.onHighlight(onHighlight)
.data(data);
if (useLinearColors) {
showLegend(container, colorScale, extents[2]);
} else {
hideLegend(container);
}
}
mapView.resize = container => {
baseMap.resize(container);
};
function featureFromPoint(point, colorMap, sizeMap, shapeMap) {
const feature = new Feature(new Point(fromLonLat(point.cols)));
const fillAndStroke = colorMap(point);
if (fillAndStroke) {
feature.setProperties({
category: point.category,
scale: sizeMap(point) / 4,
style: {
fill: fillAndStroke.fill,
stroke: fillAndStroke.stroke
},
data: point
});
// Use custom shapes
feature.setStyle(shapeMap(point));
}
return feature;
}
function onHighlight(feature, highlighted) {
const featureProperties = feature.getProperties();
const oldStyle = featureProperties.oldStyle || featureProperties.style;
const style = highlighted
? {
stroke: lightenRgb(oldStyle.stroke, 0.25),
fill: lightenRgb(oldStyle.stroke, 0.5)
}
: oldStyle;
feature.setProperties({
oldStyle,
style
});
}
function sizeMapFromExtents(extents) {
if (extents.length > 3) {
// We have the size value
const range = extents[3].max - extents[3].min;
return point => ((point.cols[3] - extents[3].min) / range) * (MAX_SIZE - MIN_SIZE) + MIN_SIZE;
}
return () => DEFAULT_SIZE;
}
mapView.plugin = {
type: "map_points",
name: "Map Points",
max_size: 25000,
initial: {
type: "number",
count: 2,
names: ["Longitude", "Latitude", "Color", "Size"]
}
};
export default mapView;