@@ -2,132 +2,36 @@ import { makeBbox } from './utils';
22
33import { formatDistanceStrict } from 'date-fns' ;
44
5- // Helper function to calculate distance between two points in meters (Haversine formula)
6- function distanceBetween ( lat1 , lon1 , lat2 , lon2 ) {
7- const R = 6371000 ; // Earth's radius in meters
8- const lat1Rad = lat1 * Math . PI / 180 ;
9- const lat2Rad = lat2 * Math . PI / 180 ;
10- const dLat = ( lat2 - lat1 ) * Math . PI / 180 ;
11- const dLon = ( lon2 - lon1 ) * Math . PI / 180 ;
12-
13- const a = Math . sin ( dLat / 2 ) * Math . sin ( dLat / 2 ) +
14- Math . cos ( lat1Rad ) * Math . cos ( lat2Rad ) *
15- Math . sin ( dLon / 2 ) * Math . sin ( dLon / 2 ) ;
16- const c = 2 * Math . atan2 ( Math . sqrt ( a ) , Math . sqrt ( 1 - a ) ) ;
17-
18- return R * c ;
19- }
20-
215class Change {
226 constructor ( context , changeObj ) {
237 this . context = context ;
248 Object . assign ( this , changeObj ) ;
259 }
2610
27- fetchChangesetData ( id ) {
28- return new Promise ( ( resolve , reject ) => {
29- const cachedData = this . context . changesetCache . get ( id ) ;
30- if ( cachedData ) {
31- return resolve ( cachedData ) ;
32- }
33-
34- fetch ( `//www.openstreetmap.org/api/0.6/changeset/${ id } ` , {
35- mode : 'cors'
36- } )
37- . then ( ( response ) => response . text ( ) )
38- . then ( ( responseString ) => {
39- return new window . DOMParser ( )
40- . parseFromString ( responseString , 'text/xml' ) ;
41- } )
42- . then ( ( data ) => {
43- const changesetData = { } ;
44- const tags = data . getElementsByTagName ( 'tag' ) ;
45-
46- for ( let i = 0 ; i < tags . length ; i ++ ) {
47- const key = tags [ i ] . getAttribute ( 'k' ) ;
48- const value = tags [ i ] . getAttribute ( 'v' ) ;
49- changesetData [ key ] = value ;
50- }
51-
52- this . context . changesetCache . set ( id , changesetData ) ;
53-
54- resolve ( changesetData ) ;
55- } )
56- . catch ( ( err ) => {
57- console . log ( 'Error fetching changeset data' , err ) ;
58- reject ( err ) ;
59- } ) ;
60- } ) ;
61- }
62-
63- fetchDisplayName ( boundsCenter ) {
64- return new Promise ( ( resolve , reject ) => {
65- const CLOSE_THRESHOLD_METERS = 10000 ;
66- const closeByKey = this . context . geocodeCache . keys ( ) . find ( ( key ) => {
67- const [ lat , lon ] = key . split ( ',' ) . map ( parseFloat ) ;
68- return distanceBetween ( boundsCenter . lat , boundsCenter . lng , lat , lon ) < CLOSE_THRESHOLD_METERS ;
69- } ) ;
70-
71- if ( closeByKey ) {
72- const cachedGeocode = this . context . geocodeCache . get ( closeByKey ) ;
73- if ( cachedGeocode ) {
74- return resolve ( cachedGeocode ) ;
75- }
76- }
77-
78- const lat = boundsCenter . lat ;
79- const lon = boundsCenter . lng ;
80-
81- const nominatimUrl = `//nominatim.openstreetmap.org/reverse`
82- + `?format=json&lat=${ lat } &lon=${ lon } &zoom=5` ;
83-
84- fetch ( nominatimUrl , {
85- mode : 'cors'
86- } )
87- . then ( ( response ) => response . json ( ) )
88- . then ( ( data ) => {
89- const id = `${ lat } ,${ lon } ` ;
90- const displayName = data . display_name ;
91- this . context . geocodeCache . set ( id , displayName ) ;
92- resolve ( displayName ) ;
93- } )
94- . catch ( ( err ) => {
95- console . error ( 'Error fetching location' , err ) ;
96- reject ( err ) ;
97- } ) ;
98- } ) ;
99- }
100-
101- isRelevant ( ) {
102- return new Promise ( ( resolve ) => {
103- let commentRelevance = false ;
104- let keyRelevance = false ;
105- const mapElement = this . neu || this . old ;
11+ async isRelevant ( ) {
12+ const mapElement = this . neu || this . old ;
10613
107- if ( this . context . comment === "" && ! this . context . key ) {
108- return resolve ( true ) ;
109- }
14+ if ( this . context . comment === "" && ! this . context . key ) {
15+ return true ;
16+ }
11017
111- this . fetchChangesetData ( mapElement . changeset )
112- . then ( ( changesetData ) => {
18+ const changesetData = await this . context . changesetService . get ( mapElement . changeset ) ;
11319
114- commentRelevance =
115- this . context . comment !== "" &&
116- changesetData . comment ?. toLowerCase ( )
117- . includes ( this . context . comment . toLowerCase ( ) ) || false ;
20+ const commentRelevance =
21+ this . context . comment !== "" &&
22+ changesetData . comment ?. toLowerCase ( )
23+ . includes ( this . context . comment . toLowerCase ( ) ) || false ;
11824
119- keyRelevance = Object . keys ( mapElement . tags ) . includes ( this . context . key ) ;
25+ const keyRelevance = Object . keys ( mapElement . tags ) . includes ( this . context . key ) ;
12026
121- if ( ! ( commentRelevance || keyRelevance ) ) {
122- console . log (
123- "Skipping map element " + mapElement . id
124- + " because it didn't match filters."
125- ) ;
126- }
27+ if ( ! ( commentRelevance || keyRelevance ) ) {
28+ console . log (
29+ "Skipping map element " + mapElement . id
30+ + " because it didn't match filters."
31+ ) ;
32+ }
12733
128- return resolve ( commentRelevance | keyRelevance ) ;
129- } ) ;
130- } ) ;
34+ return commentRelevance || keyRelevance ;
13135 }
13236
13337 createTagText ( ) {
@@ -145,7 +49,7 @@ class Change {
14549 return 'a ' + mapElement . type ;
14650 }
14751
148- enhance ( ) {
52+ async enhance ( ) {
14953 console . log ( 'Enhancing change, fetching changeset + geocode...' ) ;
15054 const startTime = Date . now ( ) ;
15155 const mapElement = this . type === 'delete' ? this . old : this . neu ;
@@ -180,19 +84,16 @@ class Change {
18084
18185 this . tagText = this . createTagText ( ) ;
18286
183- return Promise . all ( [
184- this . fetchChangesetData ( this . meta . changeset ) ,
185- this . fetchDisplayName ( bounds . getCenter ( ) ) ,
186- ] ) . then ( ( [ changesetData , displayName ] ) => {
187- console . log ( `Enhance complete in ${ Date . now ( ) - startTime } ms` ) ;
188- this . meta . comment = changesetData . comment ;
189- this . meta . createdBy = changesetData . created_by ;
190- this . meta . displayName = displayName ;
191- return this ;
192- } ) . catch ( ( err ) => {
193- console . error ( `Enhance failed after ${ Date . now ( ) - startTime } ms:` , err ) ;
194- throw err ;
195- } ) ;
87+ const [ changesetData , displayName ] = await Promise . all ( [
88+ this . context . changesetService . get ( this . meta . changeset ) ,
89+ this . context . geocodeService . get ( bounds . getCenter ( ) ) ,
90+ ] ) ;
91+
92+ console . log ( `Enhance complete in ${ Date . now ( ) - startTime } ms` ) ;
93+ this . meta . comment = changesetData . comment || '' ;
94+ this . meta . createdBy = changesetData . created_by || '' ;
95+ this . meta . displayName = displayName || '' ;
96+ return this ;
19697 }
19798}
19899
0 commit comments