| … | … | @@ -658,6 +658,14 @@ def api_coarse(): |
| 658 | 658 | ci2 = int(request.args["ci2"]); cj2 = int(request.args["cj2"]) |
| 659 | 659 | if (ci2 - ci1) * (cj2 - cj1) > 90000: |
| 660 | 660 | raise ValueError("coarse region too large") |
| 661 | # np.gradient needs >= 2 elements per axis, so a 1-px-thin request dies |
| 662 | # inside hillshade with a confusing message. The app always asks for a |
| 663 | # large box, but a deep zoom could produce a thin one. Grow it here and |
| 664 | # crop after shading, the same trick the tile apron uses. |
| 665 | pad_i = max(0, 2 - (ci2 - ci1)) |
| 666 | pad_j = max(0, 2 - (cj2 - cj1)) |
| 667 | ci2 += pad_i |
| 668 | cj2 += pad_j |
| 661 | 669 | q = (f"{app.config['TD_URL']}/coarse?i1={ci1}&j1={cj1}&i2={ci2}&j2={cj2}") |
| 662 | 670 | with urllib.request.urlopen(q, timeout=1800) as r: |
| 663 | 671 | h = int(r.headers["X-Height"]); w = int(r.headers["X-Width"]) |
| … | … | @@ -672,9 +680,11 @@ def api_coarse(): |
| 672 | 680 | else: |
| 673 | 681 | rgb = colourise_array(elev, 7680.0, view, vmin, vmax, |
| 674 | 682 | float(request.args.get("exag", 1.0))) |
| 683 | if pad_i or pad_j: |
| 684 | rgb = rgb[:rgb.shape[0] - pad_i or None, :rgb.shape[1] - pad_j or None] |
| 675 | 685 | resp = Response(to_png(rgb), mimetype="image/png") |
| 676 | 686 | resp.headers["Cache-Control"] = "public, max-age=3600" |
| 677 | | resp.headers["X-Height"] = str(h); resp.headers["X-Width"] = str(w) |
| 687 | resp.headers["X-Height"] = str(rgb.shape[0]); resp.headers["X-Width"] = str(rgb.shape[1]) |
| 678 | 688 | resp.headers["X-Elev"] = f"{elev.min():.0f},{elev.max():.0f}" |
| 679 | 689 | return resp |
| 680 | 690 | except Exception as e: |