nakas Claude commited on
Commit
0cb48f9
·
1 Parent(s): 53c130c

Add working hover functionality with dBZ values

Browse files

- Create hover data with lat/lon coordinates mapped to dBZ values
- Sample every 10th pixel to create manageable dataset
- Add invisible CircleMarkers with tooltips showing exact dBZ values
- Convert pixel coordinates to approximate lat/lon for Canada radar bounds
- Limit to 100 hover points on map to prevent performance issues
- Add comprehensive logging for hover data creation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (2) hide show
  1. app.py +28 -25
  2. radar_analyzer.py +56 -1
app.py CHANGED
@@ -125,31 +125,34 @@ class RadarAnalysisApp:
125
  wms_layer.add_to(m)
126
  folium.LayerControl().add_to(m)
127
 
128
- # Add JavaScript for hover functionality to show dBZ values
129
- hover_script = """
130
- <script>
131
- // Function to get dBZ value at mouse position
132
- function getDBZValue(latlng) {
133
- // This would need to be connected to the analysis data
134
- // For now, show coordinates
135
- return `Lat: ${latlng.lat.toFixed(4)}, Lng: ${latlng.lng.toFixed(4)}`;
136
- }
137
-
138
- // Add hover event to map
139
- setTimeout(function() {
140
- if (window.map_data) {
141
- window.map_data.on('mousemove', function(e) {
142
- const popup = L.popup()
143
- .setLatLng(e.latlng)
144
- .setContent(getDBZValue(e.latlng))
145
- .openOn(window.map_data);
146
- });
147
- }
148
- }, 1000);
149
- </script>
150
- """
151
-
152
- m.get_root().html.add_child(folium.Element(hover_script))
 
 
 
153
 
154
  # Add info panel
155
  info_html = """
 
125
  wms_layer.add_to(m)
126
  folium.LayerControl().add_to(m)
127
 
128
+ # Add dBZ hover points if analysis data is available
129
+ if show_analysis:
130
+ try:
131
+ # Try to get the latest analysis
132
+ radar_file = self.fetch_current_radar()
133
+ if radar_file:
134
+ result = self.analyzer.analyze_radar(radar_file, "radar_legendwellcropped.png")
135
+ hover_data = result.get('hover_data', {})
136
+ hover_points = hover_data.get('points', [])
137
+
138
+ print(f"Adding {len(hover_points)} hover points to map")
139
+
140
+ # Add invisible markers for hover functionality
141
+ for point in hover_points[:100]: # Limit to 100 points to avoid overload
142
+ folium.CircleMarker(
143
+ location=[point['lat'], point['lon']],
144
+ radius=3,
145
+ popup=f"dBZ: {point['dbz']} ({point['intensity']})",
146
+ tooltip=f"dBZ: {point['dbz']}",
147
+ color='transparent',
148
+ fillColor='transparent',
149
+ fillOpacity=0,
150
+ opacity=0
151
+ ).add_to(m)
152
+
153
+ except Exception as e:
154
+ print(f"Error adding hover data: {e}")
155
+ pass
156
 
157
  # Add info panel
158
  info_html = """
radar_analyzer.py CHANGED
@@ -495,19 +495,74 @@ class CanadianRadarAnalyzer:
495
  annotated_bgr = cv2.cvtColor(annotated_image, cv2.COLOR_RGB2BGR)
496
  cv2.imwrite(output_filename, annotated_bgr)
497
 
 
 
 
498
  # Prepare results
499
  results = {
500
  'analysis': analysis,
501
  'regions': regions,
502
  'output_file': output_filename,
503
  'input_file': radar_image_path,
504
- 'legend_file': legend_path
 
505
  }
506
 
507
  return results
508
 
509
  except Exception as e:
510
  raise Exception(f"Radar analysis failed: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
 
512
  if __name__ == "__main__":
513
  # Test the analyzer
 
495
  annotated_bgr = cv2.cvtColor(annotated_image, cv2.COLOR_RGB2BGR)
496
  cv2.imwrite(output_filename, annotated_bgr)
497
 
498
+ # Create hover data for map integration
499
+ hover_data = self.create_hover_data(analysis['precipitation_map'])
500
+
501
  # Prepare results
502
  results = {
503
  'analysis': analysis,
504
  'regions': regions,
505
  'output_file': output_filename,
506
  'input_file': radar_image_path,
507
+ 'legend_file': legend_path,
508
+ 'hover_data': hover_data
509
  }
510
 
511
  return results
512
 
513
  except Exception as e:
514
  raise Exception(f"Radar analysis failed: {str(e)}")
515
+
516
+ def create_hover_data(self, dbz_map: np.ndarray) -> Dict:
517
+ """
518
+ Create simplified hover data for map integration.
519
+ Sample every Nth pixel to avoid huge datasets.
520
+ """
521
+ height, width = dbz_map.shape
522
+ sample_rate = 10 # Sample every 10th pixel to reduce data size
523
+
524
+ hover_points = []
525
+
526
+ # Canada radar bounds (approximate)
527
+ lat_min, lat_max = 42.0, 84.0
528
+ lon_min, lon_max = -142.0, -52.0
529
+
530
+ print(f"Creating hover data from {width}x{height} dBZ map...")
531
+
532
+ for y in range(0, height, sample_rate):
533
+ for x in range(0, width, sample_rate):
534
+ dbz_value = dbz_map[y, x]
535
+
536
+ if dbz_value > 0: # Only include pixels with precipitation
537
+ # Convert pixel coordinates to lat/lon (approximate)
538
+ lat = lat_max - (y / height) * (lat_max - lat_min)
539
+ lon = lon_min + (x / width) * (lon_max - lon_min)
540
+
541
+ hover_points.append({
542
+ 'lat': round(lat, 4),
543
+ 'lon': round(lon, 4),
544
+ 'dbz': round(dbz_value, 1),
545
+ 'intensity': self.categorize_dbz_simple(dbz_value)
546
+ })
547
+
548
+ print(f"Created {len(hover_points)} hover points")
549
+
550
+ return {
551
+ 'points': hover_points,
552
+ 'total_points': len(hover_points),
553
+ 'sample_rate': sample_rate
554
+ }
555
+
556
+ def categorize_dbz_simple(self, dbz_value: float) -> str:
557
+ """Simple dBZ categorization for hover display."""
558
+ if dbz_value < 1.0:
559
+ return "Very Light"
560
+ elif dbz_value < 8.0:
561
+ return "Light-Moderate"
562
+ elif dbz_value < 32.0:
563
+ return "Heavy"
564
+ else:
565
+ return "Intense"
566
 
567
  if __name__ == "__main__":
568
  # Test the analyzer