Pingul commited on
Commit
a668f53
·
verified ·
1 Parent(s): 00d5206

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -42
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app.py (versión optimizada)
2
  import io
3
  import os
4
  import logging
@@ -40,44 +40,22 @@ def get_cog_reader():
40
  return _cog_reader
41
 
42
  # ============================================================================
43
- # OPTIMIZACIÓN 2: Encoding Terrain-RGB más rápido (vectorizado eficiente)
44
  # ============================================================================
45
- def encode_terrainrgb_fast(arr: np.ndarray) -> np.ndarray:
46
  """
47
- Versión optimizada de Terrain-RGB encoding.
48
- Usa operaciones in-place y evita copias innecesarias.
49
  """
50
- # Clamp valores
51
- arr = np.clip(arr, -10000, 9000, out=arr)
52
-
53
- # Escala Mapbox
54
- arr *= 10.0
55
- arr += 100000.0 # (arr + 10000) * 10
56
-
57
- # Descomposición RGB más eficiente
58
- arr_int = arr.astype(np.uint32)
59
-
60
- R = (arr_int >> 16) & 0xFF
61
- G = (arr_int >> 8) & 0xFF
62
- B = arr_int & 0xFF
63
-
64
- # Stack directo sin copies intermedias
65
- return np.stack([R, G, B], axis=-1).astype(np.uint8)
66
-
67
- # Alternativa aún más rápida si numexpr está disponible:
68
- try:
69
- import numexpr as ne
70
- def encode_terrainrgb_fast(arr: np.ndarray) -> np.ndarray:
71
- arr = np.clip(arr, -10000, 9000)
72
- scaled = ne.evaluate("(arr + 10000.0) * 10.0")
73
-
74
- R = np.floor(scaled / 65536.0).astype(np.uint8)
75
- G = np.floor((scaled % 65536.0) / 256.0).astype(np.uint8)
76
- B = (scaled % 256.0).astype(np.uint8)
77
-
78
- return np.stack([R, G, B], axis=-1)
79
- except ImportError:
80
- pass # Usa la versión sin numexpr
81
 
82
  # ============================================================================
83
  # OPTIMIZACIÓN 3: Cache LRU para tiles
@@ -103,15 +81,15 @@ def get_tile_cached(z: int, x: int, y: int) -> bytes:
103
  raise TileOutsideBounds(f"All NaN for tile {z}/{x}/{y}")
104
 
105
  # Reemplazar NaN con valor base
106
- np.nan_to_num(elev, copy=False, nan=-10000.0)
107
 
108
- # Encode a Terrain-RGB
109
- rgb = encode_terrainrgb_fast(elev)
110
 
111
  # Convertir a PNG con compresión rápida
112
  img = Image.fromarray(rgb, "RGB")
113
  buf = io.BytesIO()
114
- img.save(buf, format="PNG", compress_level=1) # compress_level=1 es MUY importante
115
 
116
  return buf.getvalue()
117
 
@@ -200,8 +178,16 @@ def debug_tile(z: int, x: int, y: int):
200
 
201
  # Grayscale simple
202
  a = np.where(np.isfinite(elev), elev, 0)
203
- vmin, vmax = np.nanpercentile(a[a != 0], [2, 98]) if np.any(a != 0) else (0, 1)
204
- norm = np.clip((a - vmin) / (vmax - vmin + 1e-8), 0, 1)
 
 
 
 
 
 
 
 
205
  gray = (norm * 255).astype(np.uint8)
206
 
207
  rgb = np.stack([gray, gray, gray], axis=-1)
 
1
+ # app.py (versión optimizada - ARREGLADA)
2
  import io
3
  import os
4
  import logging
 
40
  return _cog_reader
41
 
42
  # ============================================================================
43
+ # OPTIMIZACIÓN 2: Encoding Terrain-RGB (tu versión original, funciona bien)
44
  # ============================================================================
45
+ def encode_terrainrgb(arr: np.ndarray) -> np.ndarray:
46
  """
47
+ Convierte elevación en metros a Terrain-RGB (Mapbox spec).
 
48
  """
49
+ arr = np.array(arr, dtype=np.float32)
50
+ arr = np.clip(arr, -10000, 9000)
51
+ arr = (arr + 10000.0) * 10.0 # mapbox scale
52
+
53
+ R = np.floor(arr / (256.0 * 256.0))
54
+ G = np.floor((arr - R * 256.0 * 256.0) / 256.0)
55
+ B = np.floor(arr - R * 256.0 * 256.0 - G * 256.0)
56
+
57
+ rgb = np.stack([R, G, B], axis=-1).astype(np.uint8)
58
+ return rgb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  # ============================================================================
61
  # OPTIMIZACIÓN 3: Cache LRU para tiles
 
81
  raise TileOutsideBounds(f"All NaN for tile {z}/{x}/{y}")
82
 
83
  # Reemplazar NaN con valor base
84
+ elev = np.nan_to_num(elev, nan=-10000.0)
85
 
86
+ # Encode a Terrain-RGB (tu función original)
87
+ rgb = encode_terrainrgb(elev)
88
 
89
  # Convertir a PNG con compresión rápida
90
  img = Image.fromarray(rgb, "RGB")
91
  buf = io.BytesIO()
92
+ img.save(buf, format="PNG", compress_level=1) # compress_level=1 es clave
93
 
94
  return buf.getvalue()
95
 
 
178
 
179
  # Grayscale simple
180
  a = np.where(np.isfinite(elev), elev, 0)
181
+ if np.any(a != 0):
182
+ vmin = np.nanpercentile(a[a != 0], 2)
183
+ vmax = np.nanpercentile(a[a != 0], 98)
184
+ else:
185
+ vmin, vmax = 0, 1
186
+
187
+ if vmin == vmax:
188
+ vmax = vmin + 1
189
+
190
+ norm = np.clip((a - vmin) / (vmax - vmin), 0, 1)
191
  gray = (norm * 255).astype(np.uint8)
192
 
193
  rgb = np.stack([gray, gray, gray], axis=-1)