Skip to content

Commit f28775d

Browse files
MV88offtherailz
authored andcommitted
Update annotation vector styler (#3504)
1 parent 218b7e3 commit f28775d

71 files changed

Lines changed: 5285 additions & 1605 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,10 @@
7878
"//": "replace react-sortable-items with official on npm when it will support React 15",
7979
"dependencies": {
8080
"@carnesen/redux-add-action-listener-enhancer": "0.0.1",
81-
"@mapbox/geojsonhint": "^2.0.1",
81+
"@mapbox/geojsonhint": "2.0.1",
8282
"@mapbox/togeojson": "0.16.0",
8383
"@turf/bbox": "4.1.0",
84+
"@turf/center": "5.1.5",
8485
"@turf/great-circle": "5.1.5",
8586
"@turf/inside": "4.1.0",
8687
"@turf/line-intersect": "4.1.0",

web/client/actions/__tests__/annotations-test.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const {
3535
addText, ADD_TEXT,
3636
CHANGE_FORMAT, changeFormat,
3737
changedProperties, CHANGED_PROPERTIES,
38-
changeStyler, CHANGE_STYLER,
3938
toggleUnsavedStyleModal, TOGGLE_STYLE_MODAL,
4039
startDrawing, START_DRAWING,
4140
toggleUnsavedChangesModal, TOGGLE_CHANGES_MODAL,
@@ -67,14 +66,15 @@ const {
6766
CHANGED_SELECTED, changeSelected,
6867
SET_INVALID_SELECTED, setInvalidSelected,
6968
TOGGLE_GEOMETRY_MODAL, toggleUnsavedGeometryModal,
70-
resetCoordEditor, RESET_COORD_EDITOR,
71-
changeRadius, CHANGE_RADIUS,
72-
changeText, CHANGE_TEXT,
69+
RESET_COORD_EDITOR, resetCoordEditor,
70+
CHANGE_RADIUS, changeRadius,
71+
CHANGE_TEXT, changeText,
7372
CONFIRM_DELETE_FEATURE, confirmDeleteFeature,
7473
OPEN_EDITOR, openEditor,
7574
TOGGLE_DELETE_FT_MODAL, toggleDeleteFtModal,
7675
ADD_NEW_FEATURE, addNewFeature,
77-
LOAD_ANNOTATIONS, loadAnnotations
76+
LOAD_ANNOTATIONS, loadAnnotations,
77+
UPDATE_SYMBOLS, updateSymbols
7878
} = require('../annotations');
7979

8080
describe('Test correctness of the annotations actions', () => {
@@ -199,12 +199,7 @@ describe('Test correctness of the annotations actions', () => {
199199
const result = toggleUnsavedStyleModal();
200200
expect(result.type).toEqual(TOGGLE_STYLE_MODAL);
201201
});
202-
it('changeStyler', () => {
203-
const stylerType = "marker";
204-
const result = changeStyler(stylerType);
205-
expect(result.type).toEqual(CHANGE_STYLER);
206-
expect(result.stylerType).toEqual(stylerType);
207-
});
202+
208203
it('save annotation', () => {
209204
const result = saveAnnotation('1', {
210205
name: 'changed'
@@ -334,6 +329,16 @@ describe('Test correctness of the annotations actions', () => {
334329
const result = download();
335330
expect(result.type).toEqual(DOWNLOAD);
336331
});
332+
it('updateSymbols', () => {
333+
const symbols = [{name: "symbol1"}, {name: "symbol2"}];
334+
let result = updateSymbols(symbols);
335+
expect(result.type).toEqual(UPDATE_SYMBOLS);
336+
expect(result.symbols.length).toEqual(2);
337+
expect(result.symbols[0].name).toEqual(symbols[0].name);
338+
339+
result = updateSymbols();
340+
expect(result.symbols.length).toEqual(0);
341+
});
337342
it('load annotations', () => {
338343
const result = loadAnnotations([]);
339344
expect(result.type).toEqual(LOAD_ANNOTATIONS);

web/client/actions/annotations.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const CLOSE_ANNOTATIONS = 'ANNOTATIONS:CLOSE';
3131
const CONFIRM_CLOSE_ANNOTATIONS = 'ANNOTATIONS:CONFIRM_CLOSE';
3232
const CANCEL_CLOSE_ANNOTATIONS = 'ANNOTATIONS:CANCEL_CLOSE';
3333
const START_DRAWING = 'ANNOTATIONS:START_DRAWING';
34-
const CHANGE_STYLER = 'ANNOTATIONS:CHANGE_STYLER';
3534
const UNSAVED_CHANGES = 'ANNOTATIONS:UNSAVED_CHANGES';
3635
const TOGGLE_CHANGES_MODAL = 'ANNOTATIONS:TOGGLE_CHANGES_MODAL';
3736
const TOGGLE_GEOMETRY_MODAL = 'ANNOTATIONS:TOGGLE_GEOMETRY_MODAL';
@@ -50,6 +49,17 @@ const HIGHLIGHT_POINT = 'ANNOTATIONS:HIGHLIGHT_POINT';
5049
const TOGGLE_DELETE_FT_MODAL = 'ANNOTATIONS:TOGGLE_DELETE_FT_MODAL';
5150
const CONFIRM_DELETE_FEATURE = 'ANNOTATIONS:CONFIRM_DELETE_FEATURE';
5251
const CHANGE_FORMAT = 'ANNOTATIONS:CHANGE_FORMAT';
52+
const UPDATE_SYMBOLS = 'ANNOTATIONS:UPDATE_SYMBOLS';
53+
const ERROR_SYMBOLS = 'ANNOTATIONS:ERROR_SYMBOLS';
54+
55+
const updateSymbols = (symbols = []) => ({
56+
type: UPDATE_SYMBOLS,
57+
symbols
58+
});
59+
const setErrorSymbol = (symbolErrors) => ({
60+
type: ERROR_SYMBOLS,
61+
symbolErrors
62+
});
5363

5464
function loadAnnotations(features, override = false) {
5565
return {
@@ -312,12 +322,7 @@ function changeRadius(radius, components) {
312322
components
313323
};
314324
}
315-
function changeStyler(stylerType) {
316-
return {
317-
type: CHANGE_STYLER,
318-
stylerType
319-
};
320-
}
325+
321326
function changeText(text, components) {
322327
return {
323328
type: CHANGE_TEXT,
@@ -349,7 +354,6 @@ module.exports = {
349354
CONFIRM_CLOSE_ANNOTATIONS,
350355
CANCEL_CLOSE_ANNOTATIONS,
351356
START_DRAWING, startDrawing,
352-
CHANGE_STYLER, changeStyler,
353357
UNSAVED_CHANGES, setUnsavedChanges,
354358
UNSAVED_STYLE, setUnsavedStyle,
355359
TOGGLE_CHANGES_MODAL, toggleUnsavedChangesModal,
@@ -391,5 +395,7 @@ module.exports = {
391395
TOGGLE_GEOMETRY_MODAL, toggleUnsavedGeometryModal,
392396
SET_INVALID_SELECTED, setInvalidSelected,
393397
CHANGE_FORMAT, changeFormat,
394-
CHANGED_SELECTED, changeSelected
398+
CHANGED_SELECTED, changeSelected,
399+
UPDATE_SYMBOLS, updateSymbols,
400+
ERROR_SYMBOLS, setErrorSymbol
395401
};

web/client/components/map/leaflet/Feature.jsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88

99
const PropTypes = require('prop-types');
1010
const React = require('react');
11-
const {isEqual} = require('lodash');
11+
const {isEqual, isArray, castArray} = require('lodash');
1212
const assign = require('object-assign');
13+
const axios = require('axios');
1314

1415
const {geometryToLayer} = require('../../../utils/leaflet/Vector');
16+
const {createStylesAsync} = require('../../../utils/VectorStyleUtils');
1517

1618
class Feature extends React.Component {
1719
static propTypes = {
@@ -34,14 +36,16 @@ class Feature extends React.Component {
3436
}
3537

3638
componentWillReceiveProps(newProps) {
37-
if (!isEqual(newProps.properties, this.props.properties) || !isEqual(newProps.geometry, this.props.geometry) || !isEqual(newProps.style, this.props.style)) {
38-
this.props.container.removeLayer(this._layer);
39+
// TODO check if shallow comparison is enough properties and geometry
40+
if (isEqual(newProps.properties, this.props.properties) || isEqual(newProps.geometry, this.props.geometry) || (newProps.features !== this.props.features) || (newProps.style !== this.props.style)) {
41+
newProps.container.removeLayer(this._layer);
3942
this.createLayer(newProps);
4043
}
4144
}
4245

4346
shouldComponentUpdate(nextProps) {
44-
return !isEqual(nextProps.properties, this.props.properties) || !isEqual(nextProps.geometry, this.props.geometry);
47+
// TODO check if shallow comparison is enough properties and geometry
48+
return isEqual(nextProps.properties, this.props.properties) || isEqual(nextProps.geometry, this.props.geometry) || (nextProps.features !== this.props.features);
4549
}
4650

4751
componentWillUnmount() {
@@ -56,14 +60,15 @@ class Feature extends React.Component {
5660

5761
createLayer = (props) => {
5862
if (props.geometry) {
59-
this.addFeature(props);
63+
this.addFeature({...props, style: props.style && castArray(props.style) || undefined});
6064
}
6165
if (props.features) {
6266
// supporting FeatureCollection
6367
props.features.forEach(f => {
6468
let newProps = assign({}, props, {
6569
type: f.type,
6670
geometry: f.geometry,
71+
style: f.style && castArray(f.style) || undefined,
6772
properties: f.properties
6873
});
6974
this.addFeature(newProps);
@@ -72,14 +77,24 @@ class Feature extends React.Component {
7277
};
7378

7479
addFeature(props) {
80+
if (isArray(props.style)) {
81+
let promises = createStylesAsync(props.style);
82+
axios.all(promises).then((styles) => {
83+
this.addLayer(props, styles);
84+
});
85+
} else {
86+
this.addLayer(props, props.style);
87+
}
88+
}
89+
addLayer(props, styles) {
7590
this._layer = geometryToLayer({
7691
type: props.type,
7792
geometry: props.geometry,
7893
styleName: props.styleName,
7994
properties: props.properties,
8095
msId: props.msId
8196
}, {
82-
style: props.style
97+
style: styles
8398
});
8499
props.container.addLayer(this._layer);
85100
this._layer.on('click', (event) => {

web/client/components/map/leaflet/__tests__/Feature-test.jsx

Lines changed: 18 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,11 @@ describe('leaflet Feature component', () => {
5555
container={container}
5656
style={style}
5757
geometry={geometry}/>, document.getElementById("container"));
58+
setTimeout(() => {
59+
expect(lineString._layer).toExist();
60+
expect({...lineString._layer.options}).toEqual({...style});
61+
}, 0);
5862

59-
expect(lineString._layer).toExist();
60-
expect({...lineString._layer.options}).toEqual({...style, highlight: undefined});
61-
62-
const styleWithFeatureType = {
63-
color: '#3388ff',
64-
weight: 4,
65-
LineString: {
66-
color: '#ffaa33',
67-
weight: 10
68-
}
69-
};
70-
71-
lineString = ReactDOM.render(<Feature
72-
type={type}
73-
container={container}
74-
style={styleWithFeatureType}
75-
geometry={geometry}/>, document.getElementById("container"));
76-
77-
expect(lineString._layer).toExist();
78-
expect({...lineString._layer.options}).toEqual({...styleWithFeatureType.LineString, highlight: undefined});
7963
});
8064

8165

@@ -112,30 +96,11 @@ describe('leaflet Feature component', () => {
11296

11397
expect(multiLineString._layer).toExist();
11498

115-
layersKeys = Object.keys(multiLineString._layer._layers);
116-
firstLayer = multiLineString._layer._layers[layersKeys[0]];
117-
expect({...firstLayer.options}).toEqual({...style, highlight: undefined});
118-
119-
const styleWithFeatureType = {
120-
color: '#3388ff',
121-
weight: 4,
122-
MultiLineString: {
123-
color: '#ffaa33',
124-
weight: 10
125-
}
126-
};
127-
128-
multiLineString = ReactDOM.render(<Feature
129-
type={type}
130-
container={container}
131-
style={styleWithFeatureType}
132-
geometry={geometry}/>, document.getElementById("container"));
133-
134-
expect(multiLineString._layer).toExist();
135-
136-
layersKeys = Object.keys(multiLineString._layer._layers);
137-
firstLayer = multiLineString._layer._layers[layersKeys[0]];
138-
expect({...firstLayer.options}).toEqual({...styleWithFeatureType.MultiLineString, highlight: undefined});
99+
setTimeout(() => {
100+
layersKeys = Object.keys(multiLineString._layer._layers);
101+
firstLayer = multiLineString._layer._layers[layersKeys[0]];
102+
expect({...firstLayer.options}).toEqual({...style});
103+
}, 0);
139104
});
140105

141106
it('test Polygon style', () => {
@@ -168,30 +133,11 @@ describe('leaflet Feature component', () => {
168133
style={style}
169134
geometry={geometry}/>, document.getElementById("container"));
170135

171-
expect(polygon._layer).toExist();
172-
expect({...polygon._layer.options}).toEqual({...style, highlight: undefined});
173-
174-
const styleWithFeatureType = {
175-
color: '#3388ff',
176-
weight: 4,
177-
dashArray: '',
178-
fillColor: 'rgba(51, 136, 255, 0.2)',
179-
Polygon: {
180-
color: '#ffaa33',
181-
weight: 10,
182-
dashArray: '10 5',
183-
fillColor: '#333333'
184-
}
185-
};
186-
187-
polygon = ReactDOM.render(<Feature
188-
type={type}
189-
container={container}
190-
style={styleWithFeatureType}
191-
geometry={geometry}/>, document.getElementById("container"));
136+
setTimeout(() => {
137+
expect(polygon._layer).toExist();
138+
expect({...polygon._layer.options}).toEqual({...style});
139+
}, 0);
192140

193-
expect(polygon._layer).toExist();
194-
expect({...polygon._layer.options}).toEqual({...styleWithFeatureType.Polygon, highlight: undefined});
195141
});
196142

197143
it('test MultiPolygon style', () => {
@@ -235,31 +181,12 @@ describe('leaflet Feature component', () => {
235181

236182
expect(multiPolygon._layer).toExist();
237183

238-
layersKeys = Object.keys(multiPolygon._layer._layers);
239-
firstLayer = multiPolygon._layer._layers[layersKeys[0]];
240-
expect({...firstLayer.options}).toEqual({...style, highlight: undefined});
184+
setTimeout(() => {
185+
layersKeys = Object.keys(multiPolygon._layer._layers);
186+
firstLayer = multiPolygon._layer._layers[layersKeys[0]];
187+
expect({...firstLayer.options}).toEqual({...style});
188+
}, 0);
241189

242-
const styleWithFeatureType = {
243-
color: '#3388ff',
244-
weight: 4,
245-
dashArray: '',
246-
fillColor: 'rgba(51, 136, 255, 0.2)',
247-
MultiPolygon: {
248-
color: '#ffaa33',
249-
weight: 10,
250-
dashArray: '10 5',
251-
fillColor: '#333333'
252-
}
253-
};
254-
255-
multiPolygon = ReactDOM.render(<Feature
256-
type={type}
257-
container={container}
258-
style={styleWithFeatureType}
259-
geometry={geometry}/>, document.getElementById("container"));
260190

261-
layersKeys = Object.keys(multiPolygon._layer._layers);
262-
firstLayer = multiPolygon._layer._layers[layersKeys[0]];
263-
expect({...firstLayer.options}).toEqual({...styleWithFeatureType.MultiPolygon, highlight: undefined});
264191
});
265192
});

web/client/components/map/leaflet/plugins/VectorLayer.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ var createVectorLayer = function(options) {
3737
return L.circleMarker(latlng, options.style || defaultStyle);
3838
} : null,
3939
hideLoading: hideLoading,
40-
style: options.nativeStyle || options.style || defaultStyle
40+
style: options.nativeStyle || options.style || defaultStyle // TODO ol nativeStyle should not be taken from the store
4141
});
4242
layer.setOpacity = (opacity) => {
4343
const style = assign({}, layer.options.style || defaultStyle, {opacity: opacity, fillOpacity: opacity});

0 commit comments

Comments
 (0)