#!/usr/bin/env python3 """Pašvaldību reģistra datņu sagatavošana. python3 tools/build.py Izveido: data/pasvaldibas-atvk.xml reģistrs (shēma schemas/pasvaldibu-registrs-0.1.xsd) — galvenā datne data/pasvaldibas-atvk.csv tas pats saraksts tabulā (apskatei ProcessGit un lietošanai izklājlapās) exports/pasvaldibas-atvk-sdmx21.xml tas pats saraksts SDMX-ML 2.1 kodu saraksta (Codelist) formā Unikālais identifikators — ATVK kods (7 cipari). Pašvaldībām VPK ID Valsts institūciju reģistrā nepiešķir. Avots: MK 15.06.2021. noteikumi Nr. 379 „Administratīvo teritoriju un teritoriālā iedalījuma vienību klasifikatora noteikumi”, pielikums, MK 18.08.2026. noteikumu Nr. 492 redakcijā (spēkā no 22.08.2026), https://likumi.lv/ta/id/324030 """ import csv import os from xml.sax.saxutils import escape ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) VALSTSPILSETAS = [ ("0001000", "Rīga"), ("0002000", "Daugavpils"), ("0003000", "Jelgava"), ("0004000", "Jūrmala"), ("0005000", "Liepāja"), ("0006000", "Rēzekne"), ("0007000", "Ventspils"), ] NOVADI = [ ("0020000", "Aizkraukles novads"), ("0021000", "Alūksnes novads"), ("0022000", "Augšdaugavas novads"), ("0023000", "Ādažu novads"), ("0024000", "Balvu novads"), ("0025000", "Bauskas novads"), ("0026000", "Cēsu novads"), ("0027000", "Dienvidkurzemes novads"), ("0028000", "Dobeles novads"), ("0029000", "Gulbenes novads"), ("0030000", "Jelgavas novads"), ("0031000", "Jēkabpils novads"), ("0032000", "Krāslavas novads"), ("0033000", "Kuldīgas novads"), ("0034000", "Ķekavas novads"), ("0035000", "Limbažu novads"), ("0036000", "Līvānu novads"), ("0037000", "Ludzas novads"), ("0038001", "Madonas novads"), ("0039000", "Mārupes novads"), ("0040000", "Ogres novads"), ("0041000", "Olaines novads"), ("0042000", "Preiļu novads"), ("0043000", "Rēzeknes novads"), ("0044000", "Ropažu novads"), ("0045000", "Salaspils novads"), ("0046000", "Saldus novads"), ("0047000", "Saulkrastu novads"), ("0048000", "Siguldas novads"), ("0049000", "Smiltenes novads"), ("0051000", "Talsu novads"), ("0052000", "Tukuma novads"), ("0053000", "Valkas novads"), ("0054000", "Valmieras novads"), ("0056000", "Ventspils novads"), ] # Iepriekšējie ATVK kodi (teritorija mainīta) FORMER = {"0038001": ["0038000"]} ACT = ("MK 15.06.2021. noteikumi Nr. 379 „Administratīvo teritoriju un teritoriālā iedalījuma vienību klasifikatora " "noteikumi”, pielikums, MK 18.08.2026. noteikumu Nr. 492 redakcijā") URL = "https://likumi.lv/ta/id/324030" IN_FORCE = "2026-08-22" DATA_VERSION, DATA_DATE = 2, "2026-10-12" NS = "urn:pppa:vpk:pasvaldibas:0.1" def rows(): out = [(c, n, "valstspilseta") for c, n in VALSTSPILSETAS] + [(c, n, "novads") for c, n in NOVADI] return [{"atvk": c, "nosaukums": n, "tips": k, "iepriekšējie_kodi": " ".join(FORMER.get(c, []))} for c, n, k in out] def registry_xml(rs): lines = ['', f'', ' ', ' Latvijas pašvaldību reģistrs', ' ATVK — Administratīvo teritoriju un teritoriālā iedalījuma vienību klasifikators; ' 'uztur Centrālā statistikas pārvalde', f' ', f' {escape(ACT)}', f' {URL}', ' ', f' ', ' 2. versija: atribūts vpkId noņemts — pašvaldības identificē tikai ar ATVK kodu; Valsts institūciju reģistrā ' 'resors 90 slēgts un tā identifikatori atsaukti.', ' 1. versija: 42 pašvaldības (7 valstspilsētas, 35 novadi) no MK noteikumu Nr. 379 pielikuma.', ' ', ' '] for r in rs: attrs = f'atvk="{r["atvk"]}" kind="{r["tips"]}"' former = "".join(f"{x}" for x in FORMER.get(r["atvk"], [])) lines.append(f' {escape(r["nosaukums"])}{former}') lines.append("") return "\n".join(lines) + "\n" def sdmx_xml(rs): from lxml import etree M, S, C = ("http://www.sdmx.org/resources/sdmxml/schemas/v2_1/" + x for x in ("message", "structure", "common")) XL = "{http://www.w3.org/XML/1998/namespace}lang" root = etree.Element(f"{{{M}}}Structure", nsmap={"mes": M, "str": S, "com": C}) h = etree.SubElement(root, f"{{{M}}}Header") for tag, val in (("ID", f"CL_LV_PASVALDIBA_{IN_FORCE.replace('-', '')}"), ("Test", "false"), ("Prepared", f"{DATA_DATE}T00:00:00+03:00")): etree.SubElement(h, f"{{{M}}}{tag}").text = val etree.SubElement(h, f"{{{M}}}Sender", id="PPPA") cls = etree.SubElement(etree.SubElement(root, f"{{{M}}}Structures"), f"{{{S}}}Codelists") urn = "urn:sdmx:org.sdmx.infomodel.codelist" cl = etree.SubElement(cls, f"{{{S}}}Codelist", id="CL_LV_PASVALDIBA", agencyID="PPPA", version="1.0", isFinal="true", validFrom=f"{IN_FORCE}T00:00:00+03:00", urn=f"{urn}.Codelist=PPPA:CL_LV_PASVALDIBA(1.0)") def ann(parent, atype, text): a = etree.SubElement(parent, f"{{{C}}}Annotation") etree.SubElement(a, f"{{{C}}}AnnotationType").text = atype t = etree.SubElement(a, f"{{{C}}}AnnotationText") t.set(XL, "lv") t.text = text anns = etree.SubElement(cl, f"{{{C}}}Annotations") ann(anns, "AVOTS", f"{ACT}. {URL}") ann(anns, "PIEZIME", "Kods ir ATVK kods. Galvenā datne — data/pasvaldibas-atvk.xml (Pasvaldibu-registrs).") for lang, name in (("lv", "Latvijas pašvaldības (ATVK)"), ("en", "Municipalities of Latvia (ATVK)")): n = etree.SubElement(cl, f"{{{C}}}Name") n.set(XL, lang) n.text = name for r in rs: c = etree.SubElement(cl, f"{{{S}}}Code", id=r["atvk"], urn=f"{urn}.Code=PPPA:CL_LV_PASVALDIBA(1.0).{r['atvk']}") a = etree.SubElement(c, f"{{{C}}}Annotations") ann(a, "TIPS", "valstspilsēta" if r["tips"] == "valstspilseta" else "novads") n = etree.SubElement(c, f"{{{C}}}Name") n.set(XL, "lv") n.text = r["nosaukums"] return etree.tostring(root, xml_declaration=True, encoding="UTF-8", pretty_print=True) if __name__ == "__main__": rs = rows() with open(os.path.join(ROOT, "data", "pasvaldibas-atvk.xml"), "w", encoding="utf-8") as f: f.write(registry_xml(rs)) with open(os.path.join(ROOT, "data", "pasvaldibas-atvk.csv"), "w", encoding="utf-8", newline="") as f: w = csv.DictWriter(f, fieldnames=list(rs[0])) w.writeheader() w.writerows(rs) os.makedirs(os.path.join(ROOT, "exports"), exist_ok=True) with open(os.path.join(ROOT, "exports", "pasvaldibas-atvk-sdmx21.xml"), "wb") as f: f.write(sdmx_xml(rs)) print(f"{len(VALSTSPILSETAS)} valstspilsētas + {len(NOVADI)} novadi = {len(rs)}")