File size: 4,854 Bytes
2b279ea | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | """
Alternative approach: Create a custom Folium layer that processes tiles on-the-fly
This ensures we get the exact same clean tiles that Tab 1 displays
"""
import folium
import numpy as np
from PIL import Image
import io
import base64
from radar_processor import RadarImageProcessor
class ProcessingWmsTileLayer(folium.raster_layers.WmsTileLayer):
"""Custom WMS layer that processes tiles with American colors on-the-fly."""
def __init__(self, *args, **kwargs):
# Extract our custom processor
self.processor = kwargs.pop('processor', None)
super().__init__(*args, **kwargs)
def render(self, **kwargs):
# Get the standard WMS layer HTML
standard_html = super().render(**kwargs)
# Add JavaScript to intercept and process tiles
processing_js = """
<script>
// Intercept tile loading and process them
function processRadarTile(img) {
try {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
// Process pixels to American colors
for (var i = 0; i < data.length; i += 4) {
var r = data[i];
var g = data[i + 1];
var b = data[i + 2];
var a = data[i + 3];
if (a > 0) { // Non-transparent pixel
// Simple Canadian to American color mapping
var newColor = mapCanadianToAmerican(r, g, b);
data[i] = newColor[0]; // R
data[i + 1] = newColor[1]; // G
data[i + 2] = newColor[2]; // B
}
}
ctx.putImageData(imageData, 0, 0);
img.src = canvas.toDataURL();
} catch (e) {
console.log('Tile processing failed:', e);
}
}
function mapCanadianToAmerican(r, g, b) {
// Canadian cyan (0,255,255) -> American blue (30,144,255)
if (r < 50 && g > 200 && b > 200) return [30, 144, 255];
// Canadian bright green (0,200,0) -> American lime (0,255,0)
if (r < 50 && g > 150 && g < 250 && b < 50) return [0, 255, 0];
// Canadian yellow (255,255,0) -> American yellow (255,255,0) [same]
if (r > 200 && g > 200 && b < 100) return [255, 255, 0];
// Canadian orange (255,150,0) -> American dark orange (255,140,0)
if (r > 200 && g > 100 && g < 200 && b < 50) return [255, 140, 0];
// Canadian red (255,0,0) -> American red (255,0,0) [same]
if (r > 200 && g < 100 && b < 100) return [255, 0, 0];
// Canadian magenta (200,0,200) -> American magenta (255,0,255)
if (r > 150 && g < 100 && b > 150) return [255, 0, 255];
// Default: return original color
return [r, g, b];
}
// Hook into tile loading
setTimeout(function() {
var images = document.querySelectorAll('img[src*="geo.weather.gc.ca"]');
images.forEach(function(img) {
if (img.complete) {
processRadarTile(img);
} else {
img.onload = function() { processRadarTile(img); };
}
});
}, 1000);
</script>
"""
return standard_html + processing_js
def create_processing_radar_map(wms_url, layer_name, opacity=0.7):
"""Create a map with processing WMS layer that converts colors on-the-fly."""
# Create base map
m = folium.Map(
location=[56.1304, -106.3468], # Canada center
zoom_start=4,
tiles="OpenStreetMap"
)
# Add the processing WMS layer
processor = RadarImageProcessor()
processing_layer = ProcessingWmsTileLayer(
url=wms_url,
layers=layer_name,
version="1.3.0",
transparent=True,
format="image/png",
name="Processed Canadian Radar (American Colors)",
overlay=True,
control=True,
opacity=opacity,
processor=processor,
attr='<a href="https://eccc-msc.github.io/open-data/licence/readme_en/">ECCC</a> (Recolored)'
)
processing_layer.add_to(m)
# Add layer control
folium.LayerControl().add_to(m)
return m |