#!/usr/bin/env python3 """Regenerates the committed vector/SLD fixtures in test/acceptance/data/. The fixtures are committed, so this script is only needed to rebuild them. Requires the GDAL command-line tool ogr2ogr (GeoPackage conversion). python3 test/acceptance/lib/make_fixtures.py Values are deterministic: district KATO codes and names come from stubs/districts.geojson (14 districts of North Kazakhstan region), the indicator values follow a fixed formula, so re-running yields identical files. """ import json import os import subprocess import sys import tempfile HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.abspath(os.path.join(HERE, "..", "..", "..")) DATA = os.path.abspath(os.path.join(HERE, "..", "data")) def ring_bbox(coords): xs, ys = [], [] def walk(c): if isinstance(c[0], (int, float)): xs.append(c[0]) ys.append(c[1]) else: for x in c: walk(x) walk(coords) return min(xs), min(ys), max(xs), max(ys) def population(i, kato, year): # Values quoted in the protocol (Приложение 7, F16/F17) are kept verbatim. fixed = { ("591000000", 2022): 47567.6, ("591000000", 2023): 48311.2, ("591000000", 2024): 49120.5, ("595000000", 2022): 46862.7, ("595000000", 2023): 48268.6, ("595000000", 2024): 49205.8, } if (kato, year) in fixed: return fixed[(kato, year)] return round(20000 + 1750.3 * i + 812.4 * (year - 2022) + (i * 37 % 11) * 13.1, 1) def livestock(i, year): return int(30000 + 2311 * i + 977 * (year - 2022) + (i * 53 % 17) * 41) def main(): with open(os.path.join(ROOT, "stubs", "districts.geojson"), encoding="utf-8") as f: districts = json.load(f)["features"] os.makedirs(DATA, exist_ok=True) # 1. plain vector: 4 plot polygons spanning lon 69.0..71.7, lat 53.6..55.0 plots = [] boxes = [ (69.0, 53.6, 69.6, 54.0), (69.9, 54.2, 70.5, 54.7), (70.6, 53.7, 71.1, 54.1), (71.2, 54.5, 71.7, 55.0), ] for n, (x0, y0, x1, y1) in enumerate(boxes, 1): plots.append({ "type": "Feature", "properties": {"plot_id": n, "name": "Участок %d" % n, "area_ha": round((x1 - x0) * (y1 - y0) * 7000, 1)}, "geometry": {"type": "Polygon", "coordinates": [[[x0, y0], [x1, y0], [x1, y1], [x0, y1], [x0, y0]]]}, }) write_json("plots_nko.geojson", {"type": "FeatureCollection", "features": plots}) # 2. vector_with_kato (GeoJSON): population per district, Y2022..Y2024 pop = [] live = [] for i, d in enumerate(districts): p = d["properties"] kato = str(p["kato"]) x0, y0, x1, y1 = ring_bbox(d["geometry"]["coordinates"]) pt = {"type": "Point", "coordinates": [round((x0 + x1) / 2, 5), round((y0 + y1) / 2, 5)]} props = {"kato": kato, "district": p["name_ru"]} for y in (2022, 2023, 2024): props["Y%d" % y] = population(i, kato, y) pop.append({"type": "Feature", "properties": props, "geometry": pt}) lprops = {"KATO_CODE": kato, "district": p["name_ru"]} for y in (2022, 2023, 2024): lprops["H_%d" % y] = livestock(i, y) live.append({"type": "Feature", "properties": lprops, "geometry": pt}) write_json("population_kato.geojson", {"type": "FeatureCollection", "features": pop}) # 3. vector_with_kato (GeoPackage): cattle per district, H_2022..H_2024 with tempfile.TemporaryDirectory() as tmp: src = os.path.join(tmp, "livestock.geojson") with open(src, "w", encoding="utf-8") as f: json.dump({"type": "FeatureCollection", "features": live}, f, ensure_ascii=False) dst = os.path.join(DATA, "livestock_kato.gpkg") if os.path.exists(dst): os.remove(dst) subprocess.run(["ogr2ogr", "-f", "GPKG", "-nln", "livestock", "-a_srs", "EPSG:4326", dst, src], check=True) # 4. SLD styles write_text("style.sld", sld("ndvi", "NDVI gradient", [("0.0", "#a50026"), ("0.5", "#ffffbf"), ("1.0", "#006837")])) write_text("group_style.sld", sld("group", "Group fallback style", [("0", "#f7fbff"), ("100000", "#08306b")])) write_text("style.txt", "not an SLD file\n") print("fixtures written to", DATA) def sld(name, title, stops): entries = "\n".join( ' ' % (c, q) for q, c in stops) return """ %s %s %s """ % (name, title, entries) def write_json(name, obj): with open(os.path.join(DATA, name), "w", encoding="utf-8") as f: json.dump(obj, f, ensure_ascii=False, indent=1) f.write("\n") def write_text(name, text): with open(os.path.join(DATA, name), "w", encoding="utf-8") as f: f.write(text) if __name__ == "__main__": sys.exit(main())