1
1
import React from 'react' ;
2
2
import moment from 'moment' ;
3
3
import { getBounds } from './helpers' ;
4
+ import { cmap } from './render' ;
5
+
6
+ export function getFeatures ( features ) {
7
+ var keys = Object . keys ( features ) ;
8
+ return keys . map ( item => features [ item ] ) ;
9
+ }
10
+
11
+ export function processFeatures ( features ) {
12
+ const finalReport = new Map ( ) ;
13
+ const analyzedFeatures = features . map ( feature =>
14
+ analyzeFeature ( feature [ 0 ] , feature [ 1 ] )
15
+ ) ;
16
+ const keys = [ 'addedTags' , 'changedValues' , 'deletedTags' ] ;
17
+ analyzedFeatures . map ( item =>
18
+ keys . map ( key =>
19
+ item . get ( key ) . forEach ( tag => {
20
+ if ( finalReport . get ( tag ) ) {
21
+ finalReport . set ( tag , finalReport . get ( tag ) . concat ( [ item . get ( 'id' ) ] ) ) ;
22
+ } else {
23
+ finalReport . set ( tag , [ item . get ( 'id' ) ] ) ;
24
+ }
25
+ } )
26
+ )
27
+ ) ;
28
+ return finalReport ;
29
+ }
30
+
31
+ export function analyzeFeature ( newVersion , oldVersion ) {
32
+ var oldVersionKeys = Object . keys ( oldVersion . properties . tags ) ;
33
+ var newVersionKeys = Object . keys ( newVersion . properties . tags ) ;
34
+ var addedTags = newVersionKeys . filter (
35
+ tag => oldVersionKeys . indexOf ( tag ) === - 1
36
+ ) ;
37
+ var deletedTags = oldVersionKeys . filter (
38
+ tag => newVersionKeys . indexOf ( tag ) === - 1
39
+ ) ;
40
+ var changedValues = newVersionKeys
41
+ . filter (
42
+ tag => addedTags . indexOf ( tag ) === - 1 && deletedTags . indexOf ( tag ) === - 1
43
+ )
44
+ . filter (
45
+ tag => newVersion . properties . tags [ tag ] !== oldVersion . properties . tags [ tag ]
46
+ ) ;
47
+ var result = new Map ( ) ;
48
+ result
49
+ . set ( 'id' , newVersion . properties . id )
50
+ . set ( 'addedTags' , addedTags . map ( tag => `Added tag ${ tag } ` ) )
51
+ . set ( 'deletedTags' , deletedTags . map ( tag => `Deleted tag ${ tag } ` ) )
52
+ . set (
53
+ 'changedValues' ,
54
+ changedValues . map ( tag => `Changed value of tag ${ tag } ` )
55
+ ) ;
56
+ return result ;
57
+ }
58
+
59
+ export function selectFeature ( id : number ) {
60
+ if ( ! id || ! cmap ) return ;
61
+ cmap . emit ( 'selectFeature' , 'node|way' , id ) ;
62
+ }
63
+
64
+ function FeatureListItem ( props ) {
65
+ return (
66
+ < li >
67
+ < span className = "cmap-pointer " onClick = { ( ) => selectFeature ( props . id ) } >
68
+ { props . id }
69
+ </ span >
70
+ </ li >
71
+ ) ;
72
+ }
73
+
74
+ export class ChangeItem extends React . PureComponent {
75
+ constructor ( props ) {
76
+ super ( props ) ;
77
+ this . state = {
78
+ opened : false
79
+ } ;
80
+ this . tag = props . change [ 0 ] ;
81
+ this . value = props . change [ 1 ] ;
82
+ this . handleChange = this . handleChange . bind ( this ) ;
83
+ }
84
+ handleChange ( ) {
85
+ this . setState ( { opened : ! this . state . opened } ) ;
86
+ }
87
+ render ( ) {
88
+ return (
89
+ < div >
90
+ < h7
91
+ className = "cmap-sub-heading cmap-pointer"
92
+ onClick = { this . handleChange }
93
+ >
94
+ { this . state . opened ? '▼' : '▶' }
95
+ { this . tag }
96
+ </ h7 >
97
+ < ul
98
+ className = "cmap-vlist"
99
+ style = { {
100
+ display : this . state . opened ? 'block' : 'none'
101
+ } }
102
+ >
103
+ { this . value . map ( ( id , k ) => < FeatureListItem id = { id } key = { k } /> ) }
104
+ </ ul >
105
+ </ div >
106
+ ) ;
107
+ }
108
+ }
4
109
5
110
export class Sidebar extends React . PureComponent {
6
111
constructor ( props ) {
7
112
super ( props ) ;
8
113
this . state = {
9
114
actions : true ,
10
115
type : false ,
116
+ changes : false ,
11
117
mapStyle : false ,
12
118
user : false
13
119
} ;
120
+ this . changeReport = [ ] ;
121
+ this . changedFeatures = processFeatures (
122
+ getFeatures ( this . props . result . featureMap ) . filter (
123
+ item => item . length === 2 && item [ 0 ] . properties . action === 'modify'
124
+ )
125
+ ) . forEach ( ( featureIDs , tag ) => this . changeReport . push ( [ tag , featureIDs ] ) ) ;
126
+
14
127
this . toggleUser = this . toggleUser . bind ( this ) ;
15
128
this . toggleActions = this . toggleActions . bind ( this ) ;
16
129
this . toggleType = this . toggleType . bind ( this ) ;
130
+ this . toggleChanges = this . toggleChanges . bind ( this ) ;
17
131
this . toggleMapStyle = this . toggleMapStyle . bind ( this ) ;
18
132
}
19
133
toggleUser ( ) {
@@ -31,6 +145,11 @@ export class Sidebar extends React.PureComponent {
31
145
type : ! this . state . type
32
146
} ) ;
33
147
}
148
+ toggleChanges ( ) {
149
+ this . setState ( {
150
+ changes : ! this . state . changes
151
+ } ) ;
152
+ }
34
153
toggleMapStyle ( ) {
35
154
this . setState ( {
36
155
mapStyle : ! this . state . mapStyle
@@ -95,7 +214,7 @@ export class Sidebar extends React.PureComponent {
95
214
className = "cmap-hlist-item cmap-noselect cmap-pointer cmap-c-link-osmhv"
96
215
href = {
97
216
'http://osmhv.openstreetmap.de/changeset.jsp?id=' +
98
- changesetId
217
+ changesetId
99
218
}
100
219
>
101
220
OSM HV
@@ -107,8 +226,8 @@ export class Sidebar extends React.PureComponent {
107
226
className = "cmap-hlist-item cmap-noselect cmap-pointer cmap-c-link-josm"
108
227
href = {
109
228
'http://127.0.0.1:8111/import?url=http://www.openstreetmap.org/api/0.6/changeset/' +
110
- changesetId +
111
- '/download'
229
+ changesetId +
230
+ '/download'
112
231
}
113
232
>
114
233
JOSM
@@ -120,9 +239,9 @@ export class Sidebar extends React.PureComponent {
120
239
className = "cmap-hlist-item cmap-noselect cmap-pointer cmap-c-link-id"
121
240
href = {
122
241
'http://preview.ideditor.com/release#map=15/' +
123
- center . lat +
124
- '/' +
125
- center . lng
242
+ center . lat +
243
+ '/' +
244
+ center . lng
126
245
}
127
246
>
128
247
iD
@@ -166,7 +285,7 @@ export class Sidebar extends React.PureComponent {
166
285
className = "cmap-hlist-item cmap-noselect cmap-pointer cmap-u-link-disc"
167
286
href = {
168
287
'http://resultmaps.neis-one.org/osm-discussion-comments?uid=' +
169
- userId
288
+ userId
170
289
}
171
290
>
172
291
Discussions
@@ -178,8 +297,8 @@ export class Sidebar extends React.PureComponent {
178
297
className = "cmap-hlist-item cmap-noselect cmap-pointer cmap-u-link-comm"
179
298
href = {
180
299
'http://resultmaps.neis-one.org/osm-discussion-comments?uid=115894' +
181
- userId +
182
- '&commented'
300
+ userId +
301
+ '&commented'
183
302
}
184
303
>
185
304
Comments
@@ -258,7 +377,7 @@ export class Sidebar extends React.PureComponent {
258
377
value = "nodes"
259
378
defaultChecked = "true"
260
379
id = "cmap-type-selector-nodes"
261
- onChange = { filterLayers }
380
+ onClick = { filterLayers }
262
381
/>
263
382
< span className = "cmap-label-text" > Nodes</ span >
264
383
</ label >
@@ -289,6 +408,19 @@ export class Sidebar extends React.PureComponent {
289
408
</ li >
290
409
</ ul >
291
410
</ section >
411
+ < section className = "cmap-filter-changes-section cmap-pb3" >
412
+ < h6 className = "cmap-heading pointer" onClick = { this . toggleChanges } >
413
+ { this . state . changes ? '▼' : '▶' } Tags added / updated / deleted
414
+ </ h6 >
415
+ < ul
416
+ className = "cmap-sub-hlist"
417
+ style = { { display : this . state . changes ? 'block' : 'none' } }
418
+ >
419
+ { this . changeReport
420
+ . sort ( )
421
+ . map ( ( change , k ) => < ChangeItem key = { k } change = { change } /> ) }
422
+ </ ul >
423
+ </ section >
292
424
< section className = "cmap-map-style-section cmap-pb3" >
293
425
< h6 className = "cmap-heading pointer" onClick = { this . toggleMapStyle } >
294
426
{ this . state . mapStyle ? '▼' : '▶' } Map style
0 commit comments