Mercurial > hg > egg-tcls
comparison weather.tcl @ 430:8efbb045d44d
weather: Implement searching for nearest of measurement stations based on given lat/long coordinates.
The distance calculation is naive pythagoraean one, should be changed to "Great circle distance"
https://en.wikipedia.org/wiki/Great-circle_distance. (C implementation already done, just needs TCL-ization.)
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 08 Jan 2017 05:08:38 +0200 |
parents | 1ada0cb9bdd9 |
children | 3c816fdc302f |
comparison
equal
deleted
inserted
replaced
429:1ada0cb9bdd9 | 430:8efbb045d44d |
---|---|
284 global weather_msg_no_results weather_msg_no_data_for_location | 284 global weather_msg_no_results weather_msg_no_data_for_location |
285 global weather_msg_usage_alias weather_msg_usage_unalias weather_msg_defloc | 285 global weather_msg_usage_alias weather_msg_usage_unalias weather_msg_defloc |
286 global weather_msg_aliased weather_msg_unaliased weather_msg_no_access | 286 global weather_msg_aliased weather_msg_unaliased weather_msg_no_access |
287 global weather_msg_def_set weather_msg_def_not_set weather_msg_aliases | 287 global weather_msg_def_set weather_msg_def_not_set weather_msg_aliases |
288 global weather_msg_usage_stations weather_msg_stations weather_msg_list_station | 288 global weather_msg_usage_stations weather_msg_stations weather_msg_list_station |
289 global weather_msg_result | 289 global weather_msg_list_nearest weather_msg_usage_nearest weather_msg_usage_nearest_invalid |
290 global weather_msg_nearest_stations weather_msg_result | |
290 | 291 |
291 # Check and handle arguments | 292 # Check and handle arguments |
292 set rarglist [::textutil::split::splitx $uargs {\s+}] | 293 set rarglist [::textutil::split::splitx $uargs {\s+}] |
293 set rarg [lindex $rarglist 0] | 294 set rarg [lindex $rarglist 0] |
294 | 295 |
313 } | 314 } |
314 } | 315 } |
315 | 316 |
316 set res [join $result " ; "] | 317 set res [join $result " ; "] |
317 weather_msg $upublic $unick $uchan $weather_msg_stations [list $res] | 318 weather_msg $upublic $unick $uchan $weather_msg_stations [list $res] |
319 return 0 | |
320 } elseif {$rarg == "lahin" || $rarg == "lähin" || $rarg == "closest" || $rarg == "nearest"} { | |
321 # List stations nearest to given coordinates | |
322 set qlist [::textutil::split::splitx [join [lrange $rarglist 1 end] " "] {\s*,\s*}] | |
323 set nlist [lsearch -all -inline -not -exact $qlist ""] | |
324 if {[llength $nlist] < 2} { | |
325 weather_usage $upublic $unick $uchan $weather_msg_usage_nearest | |
326 return 0 | |
327 } | |
328 | |
329 # Check argument types | |
330 set d_lat [lindex $nlist 0] | |
331 set d_lng [lindex $nlist 1] | |
332 if {![string is double -strict $d_lat] || ![string is double -strict $d_lng]} { | |
333 weather_msg $upublic $unick $uchan $weather_msg_usage_nearest_invalid | |
334 return 0 | |
335 } | |
336 | |
337 # Calculate distances between given coordinates for each location | |
338 set result {} | |
339 foreach {ukey uvalue} [array get weather_data] { | |
340 if {![string match "w_*" $ukey]} { | |
341 set delta_lat [expr {$d_lat - [lindex $uvalue 2]}] | |
342 set delta_lng [expr {$d_lng - [lindex $uvalue 3]}] | |
343 set dist [expr { sqrt($delta_lat * $delta_lat + $delta_lng * $delta_lng) }] | |
344 lappend result [list $ukey $dist] | |
345 } | |
346 } | |
347 | |
348 # Sort the list by distance | |
349 set usorted [lsort -real -index 1 $result] | |
350 | |
351 # Create a result list for few best/first matches | |
352 set uresult {} | |
353 foreach {uval} [lrange $usorted 0 2] { | |
354 lappend uresult [weather_get_str $weather_data([lindex $uval 0]) $weather_msg_list_nearest] | |
355 } | |
356 | |
357 # Print out the result | |
358 set res [join $uresult " ; "] | |
359 weather_msg $upublic $unick $uchan $weather_msg_nearest_stations [list $d_lat $d_lng $res] | |
318 return 0 | 360 return 0 |
319 } elseif {$rarg == "vakio" || $rarg == "default" || $rarg == "vakiot" || $rarg == "defaults"} { | 361 } elseif {$rarg == "vakio" || $rarg == "default" || $rarg == "vakiot" || $rarg == "defaults"} { |
320 # List or set the default weather station name patterns for this user | 362 # List or set the default weather station name patterns for this user |
321 | 363 |
322 # Access check | 364 # Access check |