final
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ test
|
|||||||
|
|
||||||
# Virtual environments
|
# Virtual environments
|
||||||
.venv
|
.venv
|
||||||
|
.32-bit
|
||||||
|
|||||||
268
algam.py
Normal file
268
algam.py
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
from lxml import etree
|
||||||
|
from difflib import SequenceMatcher
|
||||||
|
import openpyxl
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
class xlsx_filer():
|
||||||
|
|
||||||
|
def save_file(self):
|
||||||
|
if os.path.isfile(self.path):
|
||||||
|
try:
|
||||||
|
self.workbook.save(self.path)
|
||||||
|
except PermissionError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
current_datetime = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
file_name = f"/xml_{current_datetime}.xlsx"
|
||||||
|
self.workbook.save(self.path + file_name)
|
||||||
|
|
||||||
|
self.workbook.close()
|
||||||
|
|
||||||
|
def update_data(self):
|
||||||
|
self.sheet.cell(row=1, column=1).value = "№ п/п"
|
||||||
|
self.sheet.cell(row=1, column=2).value = "Раздел КПТР"
|
||||||
|
self.sheet.cell(row=1, column=3).value = "Кадастровый номер"
|
||||||
|
self.sheet.cell(row=1, column=4).value = "Кадастровый квартал"
|
||||||
|
self.sheet.cell(row=1, column=5).value = "Вид объекта"
|
||||||
|
self.sheet.cell(row=1, column=6).value = "Площадь ЗУ"
|
||||||
|
self.sheet.cell(row=1, column=7).value = "Погрешность определения площади"
|
||||||
|
self.sheet.cell(row=1, column=8).value = "Наличие координат"
|
||||||
|
self.sheet.cell(row=1, column=9).value = "Пояснения"
|
||||||
|
row = self.sheet.max_row+1
|
||||||
|
for object in self.data:
|
||||||
|
self.sheet.cell(row=row, column=1).value = row-1
|
||||||
|
self.sheet.cell(row=row, column=2).value = object.section_KPTR
|
||||||
|
self.sheet.cell(row=row, column=3).value = object.cadastral_number
|
||||||
|
self.sheet.cell(row=row, column=4).value = object.cadastral_quarter
|
||||||
|
self.sheet.cell(row=row, column=5).value = object.object_type
|
||||||
|
self.sheet.cell(row=row, column=6).value = object.land_plot_area
|
||||||
|
self.sheet.cell(row=row, column=7).value = object.error_in_determining_area
|
||||||
|
self.sheet.cell(row=row, column=8).value = object.availability_coordinates
|
||||||
|
self.sheet.cell(row=row, column=9).value = object.explanations
|
||||||
|
row += 1
|
||||||
|
|
||||||
|
def __init__(self,data=[], path=""):
|
||||||
|
self.data = data
|
||||||
|
self.path = path
|
||||||
|
if os.path.isdir(path):
|
||||||
|
self.workbook = openpyxl.Workbook()
|
||||||
|
self.sheet = self.workbook.create_sheet("Новый лист")
|
||||||
|
|
||||||
|
|
||||||
|
class Data_farame():
|
||||||
|
def __init__(self,section_KPTR,cadastral_number,cadastral_quarter,object_type,land_plot_area,error_in_determining_area,availability_coordinates,explanations):
|
||||||
|
self.section_KPTR = section_KPTR #Раздел КПТР
|
||||||
|
self.cadastral_number = cadastral_number #Кадастровый номер
|
||||||
|
self.cadastral_quarter = cadastral_quarter #Кадастровый квартал
|
||||||
|
self.object_type = object_type #Вид объекта
|
||||||
|
self.land_plot_area = land_plot_area #Площадь ЗУ
|
||||||
|
self.error_in_determining_area = error_in_determining_area #Погрешность определения площади
|
||||||
|
self.availability_coordinates = availability_coordinates #наличие координат
|
||||||
|
self.explanations = explanations #Пояснения
|
||||||
|
|
||||||
|
|
||||||
|
class super_visor():
|
||||||
|
|
||||||
|
def find_best_match(self,input_str: str) -> str:
|
||||||
|
keywords = {
|
||||||
|
"FormParcels":"Образование ЗУ",
|
||||||
|
"SpecifyParcels":"Уточнение ЗУ",
|
||||||
|
"CadastralErrorsParcels":"Исправление ЗУ",
|
||||||
|
"ExistObjectsRealty":"Уточнение ОКС",
|
||||||
|
"CadastralErrorsOKS":"Исправление ОКС"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Сравниваем коэффициент схожести (0.0 - 1.0) строки с каждым ключевым словом
|
||||||
|
best_match = max(keywords, key=lambda word: SequenceMatcher(None, input_str, word.lower()).ratio())
|
||||||
|
return keywords[best_match]
|
||||||
|
|
||||||
|
def chec_kad_number(self,atrebut):
|
||||||
|
if '@attributes' in atrebut:
|
||||||
|
if 'CadastralNumber' in atrebut['@attributes']:
|
||||||
|
return atrebut['@attributes']['CadastralNumber']
|
||||||
|
if 'Definition' in atrebut['@attributes']:
|
||||||
|
return atrebut['@attributes']['Definition']
|
||||||
|
if 'CadastralNumber' in atrebut:
|
||||||
|
if '#text' in atrebut['CadastralNumber'][0]:
|
||||||
|
return atrebut['CadastralNumber'][0]['#text']
|
||||||
|
return "нет"
|
||||||
|
|
||||||
|
def get_cad_block(self,cad_block):
|
||||||
|
temp = ""
|
||||||
|
for item in cad_block:
|
||||||
|
temp += f"{item['#text']}, "
|
||||||
|
return temp
|
||||||
|
|
||||||
|
def chec_cad_block(self, atrebut):
|
||||||
|
if 'CadastralBlocks' in atrebut:
|
||||||
|
if 'CadastralBlock' in atrebut['CadastralBlocks'][0]:
|
||||||
|
return self.get_cad_block(atrebut['CadastralBlocks'][0]['CadastralBlock'])
|
||||||
|
if 'CadastralBlock' in atrebut:
|
||||||
|
return atrebut['CadastralBlock'][0]['#text']
|
||||||
|
return "нет"
|
||||||
|
|
||||||
|
def get_object_type(self,type:str):
|
||||||
|
if type == "002001002000":
|
||||||
|
return "Здание"
|
||||||
|
if type == "002001004000":
|
||||||
|
return "Сооружение"
|
||||||
|
if type == "002001005000":
|
||||||
|
return "Объект"
|
||||||
|
|
||||||
|
def chec_object_type(self, atrebut):
|
||||||
|
if 'ObjectType' in atrebut:
|
||||||
|
return self.get_object_type(atrebut['ObjectType'][0]['#text'])
|
||||||
|
return "нет"
|
||||||
|
|
||||||
|
def chec_area(self,atrebut):
|
||||||
|
if "Area" in atrebut:
|
||||||
|
if "Area" in atrebut['Area'][0]:
|
||||||
|
if '#text' in atrebut['Area'][0]['Area'][0]:
|
||||||
|
return atrebut['Area'][0]['Area'][0]['#text']
|
||||||
|
return "нет"
|
||||||
|
|
||||||
|
def chec_inaccuracy(self, atrebut):
|
||||||
|
if "Area" in atrebut:
|
||||||
|
if "Inaccuracy" in atrebut['Area'][0]:
|
||||||
|
if '#text' in atrebut['Area'][0]['Inaccuracy'][0]:
|
||||||
|
return atrebut['Area'][0]['Inaccuracy'][0]['#text']
|
||||||
|
return "нет"
|
||||||
|
|
||||||
|
def chec_koordinat(self,atrebut):
|
||||||
|
if 'EntitySpatial' in atrebut:
|
||||||
|
if 'SpatialElement' in atrebut['EntitySpatial'][0]:
|
||||||
|
return "да"
|
||||||
|
else:
|
||||||
|
return "нет"
|
||||||
|
else:
|
||||||
|
return "нет"
|
||||||
|
|
||||||
|
def chec_explanations(self,atrebut):
|
||||||
|
if 'Explanations' in atrebut:
|
||||||
|
return atrebut['Explanations'][0]['#text']
|
||||||
|
if 'Explanation' in atrebut:
|
||||||
|
return atrebut['Explanation'][0]['#text']
|
||||||
|
return "нет"
|
||||||
|
|
||||||
|
def chec_object(self, atrebut):
|
||||||
|
if '@attributes' in atrebut:
|
||||||
|
if 'CadastralNumber' in atrebut['@attributes']:
|
||||||
|
return True
|
||||||
|
if 'Definition' in atrebut['@attributes']:
|
||||||
|
return True
|
||||||
|
if 'CadastralNumber' in atrebut:
|
||||||
|
if '#text' in atrebut['CadastralNumber'][0]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def return_data(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
def __init__(self, xml):
|
||||||
|
self.data = []
|
||||||
|
i = 0
|
||||||
|
for section_name, section_data in xml.get('Package', [{}])[0].items():
|
||||||
|
for group in section_data:
|
||||||
|
if isinstance(group, dict):
|
||||||
|
for item_type, item_list in group.items():
|
||||||
|
for obj in item_list:
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
if self.chec_object(obj):
|
||||||
|
self.data.append(
|
||||||
|
Data_farame(
|
||||||
|
section_KPTR=self.find_best_match(section_name),
|
||||||
|
cadastral_number=self.chec_kad_number(obj),
|
||||||
|
cadastral_quarter=self.chec_cad_block(obj),
|
||||||
|
object_type=self.chec_object_type(obj),
|
||||||
|
land_plot_area=self.chec_area(obj),
|
||||||
|
error_in_determining_area=self.chec_inaccuracy(obj),
|
||||||
|
availability_coordinates=self.chec_koordinat(obj),
|
||||||
|
explanations=self.chec_explanations(obj)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
i += 1
|
||||||
|
if i == 785:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for inner_key, inner_items in obj.items():
|
||||||
|
for real_obj in inner_items:
|
||||||
|
if isinstance(real_obj, dict):
|
||||||
|
if self.chec_object(real_obj):
|
||||||
|
self.data.append(
|
||||||
|
Data_farame(
|
||||||
|
section_KPTR=self.find_best_match(section_name),
|
||||||
|
cadastral_number=self.chec_kad_number(real_obj),
|
||||||
|
cadastral_quarter=self.chec_cad_block(real_obj),
|
||||||
|
object_type=self.chec_object_type(real_obj),
|
||||||
|
land_plot_area=self.chec_area(real_obj),
|
||||||
|
error_in_determining_area=self.chec_inaccuracy(real_obj),
|
||||||
|
availability_coordinates=self.chec_koordinat(real_obj),
|
||||||
|
explanations=self.chec_explanations(real_obj)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for inner_key, inner_items in obj.items():
|
||||||
|
for real_obj_real in inner_items:
|
||||||
|
for real_wtf in real_obj_real:
|
||||||
|
|
||||||
|
test_item = real_obj_real[real_wtf][0]
|
||||||
|
if self.chec_object(test_item):
|
||||||
|
self.data.append(
|
||||||
|
Data_farame(
|
||||||
|
section_KPTR=self.find_best_match(real_wtf),
|
||||||
|
cadastral_number=self.chec_kad_number(test_item),
|
||||||
|
cadastral_quarter=self.chec_cad_block(test_item),
|
||||||
|
object_type=self.chec_object_type(test_item),
|
||||||
|
land_plot_area=self.chec_area(test_item),
|
||||||
|
error_in_determining_area=self.chec_inaccuracy(test_item),
|
||||||
|
availability_coordinates=self.chec_koordinat(test_item),
|
||||||
|
explanations=self.chec_explanations(test_item)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
i += 1
|
||||||
|
if i == 785:
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Parser():
|
||||||
|
|
||||||
|
def lxml_to_dict(self, element):
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
# Обрабатываем атрибуты (если есть)
|
||||||
|
if element.attrib:
|
||||||
|
result["@attributes"] = element.attrib
|
||||||
|
|
||||||
|
# Обрабатываем текстовое содержимое (если есть)
|
||||||
|
if element.text and element.text.strip():
|
||||||
|
result["#text"] = element.text.strip()
|
||||||
|
|
||||||
|
# Группируем все дочерние элементы в списки
|
||||||
|
children_by_tag = {}
|
||||||
|
for child in element:
|
||||||
|
child_tag = child.tag
|
||||||
|
if child_tag not in children_by_tag:
|
||||||
|
children_by_tag[child_tag] = []
|
||||||
|
children_by_tag[child_tag].append(self.lxml_to_dict(child))
|
||||||
|
|
||||||
|
# Добавляем в результат (всегда списками)
|
||||||
|
for tag, children in children_by_tag.items():
|
||||||
|
result[tag] = children # Всегда массив, даже если элемент один
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def __init__(self, dir_xml=[], save_dir=""):
|
||||||
|
xlsx_file = xlsx_filer(path=save_dir)
|
||||||
|
for item in dir_xml:
|
||||||
|
tree = etree.parse(item)
|
||||||
|
temp = self.lxml_to_dict(tree.getroot())
|
||||||
|
new_data = super_visor(temp)
|
||||||
|
xlsx_file.data = new_data.return_data()
|
||||||
|
xlsx_file.path = save_dir
|
||||||
|
xlsx_file.update_data()
|
||||||
|
xlsx_file.save_file()
|
||||||
83
algam1.py
Normal file
83
algam1.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import os
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import pandas as pd
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# === 🔧 НАСТРОЙКИ (меняйте под себя) ===
|
||||||
|
FOLDER_WITH_XMLS = r"C:\Users\jze9\Documents\work\git\kadastr12\test" # Папка с XML-файлами
|
||||||
|
OUTPUT_XLSX_FILE = r"C:\Users\jze9\Documents\work\git\kadastr12\result.xlsx" # Куда сохранить результат
|
||||||
|
|
||||||
|
# === ⛏ ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ===
|
||||||
|
def extract_text(elem, tag):
|
||||||
|
node = elem.find(f".//{tag}")
|
||||||
|
return node.text.strip() if node is not None and node.text else ""
|
||||||
|
|
||||||
|
def has_spatial(elem):
|
||||||
|
return elem.find(".//SpatialElement") is not None
|
||||||
|
|
||||||
|
def collect_explanations(elem):
|
||||||
|
return " ".join(e.text.strip() for e in elem.findall(".//Explanation") if e.text and e.text.strip())
|
||||||
|
|
||||||
|
def process_section(tree, tag, label, records, is_zemel=True):
|
||||||
|
section = tree.find(f".//{tag}")
|
||||||
|
if section is None:
|
||||||
|
return
|
||||||
|
subtag = next(iter(section), None)
|
||||||
|
if subtag is None:
|
||||||
|
return
|
||||||
|
for item in section.findall(f".//{subtag.tag}"):
|
||||||
|
rec = {
|
||||||
|
"Раздел КПТР": label,
|
||||||
|
"Кадастровый номер": extract_text(item, "CadastralNumber"),
|
||||||
|
"Кадастровый квартал": extract_text(item, "CadastralBlock"),
|
||||||
|
"Вид объекта": extract_text(item, "ObjectType"),
|
||||||
|
"Площадь ЗУ": extract_text(item.find("Area") or item, "Area") if is_zemel else "",
|
||||||
|
"Погрешность определения площади": extract_text(item.find("Area") or item, "Inaccuracy") if is_zemel else "",
|
||||||
|
"наличие координат": "да" if has_spatial(item) else "нет",
|
||||||
|
"Пояснения": collect_explanations(item),
|
||||||
|
}
|
||||||
|
records.append(rec)
|
||||||
|
|
||||||
|
# === 🚀 ОСНОВНОЙ КОД ===
|
||||||
|
def main():
|
||||||
|
records = []
|
||||||
|
for file in os.listdir(FOLDER_WITH_XMLS):
|
||||||
|
if not file.lower().endswith(".xml"):
|
||||||
|
continue
|
||||||
|
xml_path = os.path.join(FOLDER_WITH_XMLS, file)
|
||||||
|
try:
|
||||||
|
tree = ET.parse(xml_path)
|
||||||
|
except ET.ParseError as e:
|
||||||
|
print(f"❌ Ошибка в файле {file}: {e}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
root = tree.getroot()
|
||||||
|
process_section(root, "FormParcels", "Образование ЗУ", records)
|
||||||
|
process_section(root, "SpecifyParcels", "Уточнение ЗУ", records)
|
||||||
|
process_section(root, "CadastralErrorsParcels", "Исправление ЗУ", records)
|
||||||
|
process_section(root, "ExistNewObjectsRealty", "Уточнение ОКС", records, is_zemel=False)
|
||||||
|
process_section(root, "CadastralErrorsOKS", "Исправление ОКС", records, is_zemel=False)
|
||||||
|
|
||||||
|
if not records:
|
||||||
|
print("⚠️ Нет данных для экспорта.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for i, rec in enumerate(records, 1):
|
||||||
|
rec["№ п/п"] = i
|
||||||
|
|
||||||
|
df = pd.DataFrame(records, columns=[
|
||||||
|
"№ п/п",
|
||||||
|
"Раздел КПТР",
|
||||||
|
"Кадастровый номер",
|
||||||
|
"Кадастровый квартал",
|
||||||
|
"Вид объекта",
|
||||||
|
"Площадь ЗУ",
|
||||||
|
"Погрешность определения площади",
|
||||||
|
"наличие координат",
|
||||||
|
"Пояснения",
|
||||||
|
])
|
||||||
|
df.to_excel(OUTPUT_XLSX_FILE, index=False)
|
||||||
|
print(f"✔️ Файл успешно сохранён: {OUTPUT_XLSX_FILE}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
110
main.py
110
main.py
@@ -1,83 +1,43 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog
|
||||||
|
import algam
|
||||||
|
import glob
|
||||||
import os
|
import os
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
import pandas as pd
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# === 🔧 НАСТРОЙКИ (меняйте под себя) ===
|
def Pars():
|
||||||
FOLDER_WITH_XMLS = r"C:\Users\jze9\Documents\work\git\kadastr12\test" # Папка с XML-файлами
|
def get_all_xml_files(directory):
|
||||||
OUTPUT_XLSX_FILE = r"C:\Users\jze9\Documents\work\git\kadastr12\result.xlsx" # Куда сохранить результат
|
"""Возвращает список полных путей ко всем .xml файлам в директории"""
|
||||||
|
return glob.glob(os.path.join(os.path.abspath(directory), "*.xml"))
|
||||||
|
algam.Parser(dir_xml=get_all_xml_files(xml_entry.get()),save_dir=directory_entry.get())
|
||||||
|
|
||||||
# === ⛏ ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ===
|
root = tk.Tk()
|
||||||
def extract_text(elem, tag):
|
root.title("Parser12")
|
||||||
node = elem.find(f".//{tag}")
|
font = ("Arial", 12)
|
||||||
return node.text.strip() if node is not None and node.text else ""
|
root.configure(bg="#B85C38")
|
||||||
|
options = [""]
|
||||||
|
|
||||||
def has_spatial(elem):
|
#путь для сохранения файлов
|
||||||
return elem.find(".//SpatialElement") is not None
|
def open_directory(event, entry):
|
||||||
|
directory_path = filedialog.askdirectory()
|
||||||
|
entry.delete(0, tk.END)
|
||||||
|
entry.insert(0, directory_path)
|
||||||
|
|
||||||
def collect_explanations(elem):
|
|
||||||
return " ".join(e.text.strip() for e in elem.findall(".//Explanation") if e.text and e.text.strip())
|
# первое поле с списком
|
||||||
|
xml_label = tk.Label(root, text="директория xml", font=font)
|
||||||
|
xml_label.pack(anchor="w")
|
||||||
|
xml_entry = tk.Entry(root, font=font, width=70)
|
||||||
|
xml_entry.pack(anchor="w")
|
||||||
|
xml_entry.bind("<Button-1>", lambda event: open_directory(event, xml_entry))
|
||||||
|
|
||||||
def process_section(tree, tag, label, records, is_zemel=True):
|
directory_label = tk.Label(root, text="Выберите директорию для сохранения:", font=font)
|
||||||
section = tree.find(f".//{tag}")
|
directory_label.pack(anchor="w")
|
||||||
if section is None:
|
directory_entry = tk.Entry(root, font=font, width=70)
|
||||||
return
|
directory_entry.pack(anchor="w")
|
||||||
subtag = next(iter(section), None)
|
directory_entry.bind("<Button-1>", lambda event: open_directory(event, directory_entry))
|
||||||
if subtag is None:
|
|
||||||
return
|
|
||||||
for item in section.findall(f".//{subtag.tag}"):
|
|
||||||
rec = {
|
|
||||||
"Раздел КПТР": label,
|
|
||||||
"Кадастровый номер": extract_text(item, "CadastralNumber"),
|
|
||||||
"Кадастровый квартал": extract_text(item, "CadastralBlock"),
|
|
||||||
"Вид объекта": extract_text(item, "ObjectType"),
|
|
||||||
"Площадь ЗУ": extract_text(item.find("Area") or item, "Area") if is_zemel else "",
|
|
||||||
"Погрешность определения площади": extract_text(item.find("Area") or item, "Inaccuracy") if is_zemel else "",
|
|
||||||
"наличие координат": "да" if has_spatial(item) else "нет",
|
|
||||||
"Пояснения": collect_explanations(item),
|
|
||||||
}
|
|
||||||
records.append(rec)
|
|
||||||
|
|
||||||
# === 🚀 ОСНОВНОЙ КОД ===
|
# кнопка
|
||||||
def main():
|
empty_button = tk.Button(root, text="->", command=Pars, font=font)
|
||||||
records = []
|
empty_button.pack(side="right", padx=10, pady=10)
|
||||||
for file in os.listdir(FOLDER_WITH_XMLS):
|
|
||||||
if not file.lower().endswith(".xml"):
|
|
||||||
continue
|
|
||||||
xml_path = os.path.join(FOLDER_WITH_XMLS, file)
|
|
||||||
try:
|
|
||||||
tree = ET.parse(xml_path)
|
|
||||||
except ET.ParseError as e:
|
|
||||||
print(f"❌ Ошибка в файле {file}: {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
root = tree.getroot()
|
root.mainloop()
|
||||||
process_section(root, "FormParcels", "Образование ЗУ", records)
|
|
||||||
process_section(root, "SpecifyParcels", "Уточнение ЗУ", records)
|
|
||||||
process_section(root, "CadastralErrorsParcels", "Исправление ЗУ", records)
|
|
||||||
process_section(root, "ExistNewObjectsRealty", "Уточнение ОКС", records, is_zemel=False)
|
|
||||||
process_section(root, "CadastralErrorsOKS", "Исправление ОКС", records, is_zemel=False)
|
|
||||||
|
|
||||||
if not records:
|
|
||||||
print("⚠️ Нет данных для экспорта.")
|
|
||||||
return
|
|
||||||
|
|
||||||
for i, rec in enumerate(records, 1):
|
|
||||||
rec["№ п/п"] = i
|
|
||||||
|
|
||||||
df = pd.DataFrame(records, columns=[
|
|
||||||
"№ п/п",
|
|
||||||
"Раздел КПТР",
|
|
||||||
"Кадастровый номер",
|
|
||||||
"Кадастровый квартал",
|
|
||||||
"Вид объекта",
|
|
||||||
"Площадь ЗУ",
|
|
||||||
"Погрешность определения площади",
|
|
||||||
"наличие координат",
|
|
||||||
"Пояснения",
|
|
||||||
])
|
|
||||||
df.to_excel(OUTPUT_XLSX_FILE, index=False)
|
|
||||||
print(f"✔️ Файл успешно сохранён: {OUTPUT_XLSX_FILE}")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
39
main.spec
Normal file
39
main.spec
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['main.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=[],
|
||||||
|
hiddenimports=[],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
noarchive=False,
|
||||||
|
optimize=0,
|
||||||
|
)
|
||||||
|
pyz = PYZ(a.pure)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='main',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=False,
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
icon=['favicon.ico'],
|
||||||
|
)
|
||||||
181
main1.py
181
main1.py
@@ -1,181 +0,0 @@
|
|||||||
from lxml import etree
|
|
||||||
from difflib import SequenceMatcher
|
|
||||||
|
|
||||||
data=[]
|
|
||||||
class Data_farame():
|
|
||||||
def __init__(self,section_KPTR,cadastral_number,cadastral_quarter,object_type,land_plot_area,error_in_determining_area,availability_coordinates,explanations):
|
|
||||||
self.section_KPTR = section_KPTR #Раздел КПТР
|
|
||||||
self.cadastral_number = cadastral_number #Кадастровый номер
|
|
||||||
self.cadastral_quarter = cadastral_quarter #Кадастровый квартал
|
|
||||||
self.object_type = object_type #Вид объекта
|
|
||||||
self.land_plot_area = land_plot_area #Площадь ЗУ
|
|
||||||
self.error_in_determining_area = error_in_determining_area #Погрешность определения площади
|
|
||||||
self.availability_coordinates = availability_coordinates #наличие координат
|
|
||||||
self.explanations = explanations #Пояснения
|
|
||||||
|
|
||||||
|
|
||||||
class super_visor():
|
|
||||||
|
|
||||||
def find_best_match(self,input_str: str) -> str:
|
|
||||||
keywords = {
|
|
||||||
"FormParcels":"Образование ЗУ",
|
|
||||||
"SpecifyParcels":"Уточнение ЗУ",
|
|
||||||
"CadastralErrorsParcels":"Исправление ЗУ",
|
|
||||||
"ExistObjectsRealty":"Уточнение ОКС",
|
|
||||||
"CadastralErrorsOKS":"Исправление ОКС"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Сравниваем коэффициент схожести (0.0 - 1.0) строки с каждым ключевым словом
|
|
||||||
best_match = max(keywords, key=lambda word: SequenceMatcher(None, input_str, word.lower()).ratio())
|
|
||||||
return keywords[best_match]
|
|
||||||
|
|
||||||
def chec_kad_number(self,atrebut):
|
|
||||||
if '@attributes' in atrebut:
|
|
||||||
if 'CadastralNumber' in atrebut['@attributes']:
|
|
||||||
return atrebut['@attributes']['CadastralNumber']
|
|
||||||
if 'CadastralNumber' in atrebut:
|
|
||||||
if '#text' in atrebut['CadastralNumber'][0]:
|
|
||||||
return atrebut['CadastralNumber'][0]['#text']
|
|
||||||
return "нет"
|
|
||||||
|
|
||||||
def get_cad_block(self,cad_block):
|
|
||||||
temp = ""
|
|
||||||
for item in cad_block:
|
|
||||||
temp += f"{item['#text']}, "
|
|
||||||
return temp
|
|
||||||
|
|
||||||
def chec_cad_block(self, atrebut):
|
|
||||||
if 'CadastralBlocks' in atrebut:
|
|
||||||
if 'CadastralBlock' in atrebut['CadastralBlocks'][0]:
|
|
||||||
return self.get_cad_block(atrebut['CadastralBlocks'][0]['CadastralBlock'])
|
|
||||||
if 'CadastralBlock' in atrebut:
|
|
||||||
return atrebut['CadastralBlock'][0]['#text']
|
|
||||||
return "нет"
|
|
||||||
|
|
||||||
def get_object_type(self,type:str):
|
|
||||||
if type == "002001002000":
|
|
||||||
return "Здание"
|
|
||||||
if type == "002001004000":
|
|
||||||
return "Сооружение"
|
|
||||||
if type == "002001005000":
|
|
||||||
return "Объект"
|
|
||||||
|
|
||||||
def chec_object_type(self, atrebut):
|
|
||||||
if 'ObjectType' in atrebut:
|
|
||||||
return self.get_object_type(atrebut['ObjectType'][0]['#text'])
|
|
||||||
return "нет"
|
|
||||||
|
|
||||||
def chec_area(self,atrebut):
|
|
||||||
if "Area" in atrebut:
|
|
||||||
if "Area" in atrebut['Area'][0]:
|
|
||||||
if '#text' in atrebut['Area'][0]['Area'][0]:
|
|
||||||
return atrebut['Area'][0]['Area'][0]['#text']
|
|
||||||
return "нет"
|
|
||||||
|
|
||||||
def chec_inaccuracy(self, atrebut):
|
|
||||||
if "Area" in atrebut:
|
|
||||||
if "Inaccuracy" in atrebut['Area'][0]:
|
|
||||||
if '#text' in atrebut['Area'][0]['Inaccuracy'][0]:
|
|
||||||
return atrebut['Area'][0]['Inaccuracy'][0]['#text']
|
|
||||||
return "нет"
|
|
||||||
|
|
||||||
def chec_koordinat(self,atrebut):
|
|
||||||
if 'EntitySpatial' in atrebut:
|
|
||||||
if 'SpatialElement' in atrebut['EntitySpatial'][0]:
|
|
||||||
return "да"
|
|
||||||
else:
|
|
||||||
return "нет"
|
|
||||||
else:
|
|
||||||
return "нет"
|
|
||||||
|
|
||||||
def chec_explanations(self,atrebut):
|
|
||||||
if 'Explanations' in atrebut:
|
|
||||||
return atrebut['Explanations'][0]['#text']
|
|
||||||
return "нет"
|
|
||||||
|
|
||||||
def chec_object(self, atrebut):
|
|
||||||
if '@attributes' in atrebut:
|
|
||||||
if 'CadastralNumber' in atrebut['@attributes']:
|
|
||||||
return True
|
|
||||||
if 'CadastralNumber' in atrebut:
|
|
||||||
if '#text' in atrebut['CadastralNumber'][0]:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __init__(self, xml):
|
|
||||||
i = 0
|
|
||||||
for section_name, section_data in xml.get('Package', [{}])[0].items():
|
|
||||||
for group in section_data:
|
|
||||||
if isinstance(group, dict):
|
|
||||||
for item_type, item_list in group.items():
|
|
||||||
for obj in item_list:
|
|
||||||
if isinstance(obj, dict):
|
|
||||||
if self.chec_object(obj):
|
|
||||||
data.append(
|
|
||||||
Data_farame(
|
|
||||||
section_KPTR=self.find_best_match(section_name),
|
|
||||||
cadastral_number=self.chec_kad_number(obj),
|
|
||||||
cadastral_quarter=self.chec_cad_block(obj),
|
|
||||||
object_type=self.chec_object_type(obj),
|
|
||||||
land_plot_area=self.chec_area(obj),
|
|
||||||
error_in_determining_area=self.chec_inaccuracy(obj),
|
|
||||||
availability_coordinates=self.chec_koordinat(obj),
|
|
||||||
explanations=self.chec_explanations(obj)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
for inner_key, inner_items in obj.items():
|
|
||||||
for real_obj in inner_items:
|
|
||||||
if isinstance(real_obj, dict):
|
|
||||||
data.append(
|
|
||||||
Data_farame(
|
|
||||||
section_KPTR=self.find_best_match(section_name),
|
|
||||||
cadastral_number=self.chec_kad_number(real_obj),
|
|
||||||
cadastral_quarter=self.chec_cad_block(real_obj),
|
|
||||||
object_type=self.chec_object_type(real_obj),
|
|
||||||
land_plot_area=self.chec_area(real_obj),
|
|
||||||
error_in_determining_area=self.chec_inaccuracy(real_obj),
|
|
||||||
availability_coordinates=self.chec_koordinat(real_obj),
|
|
||||||
explanations=self.chec_explanations(real_obj)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def lxml_to_dict(element):
|
|
||||||
result = {}
|
|
||||||
|
|
||||||
# Обрабатываем атрибуты (если есть)
|
|
||||||
if element.attrib:
|
|
||||||
result["@attributes"] = element.attrib
|
|
||||||
|
|
||||||
# Обрабатываем текстовое содержимое (если есть)
|
|
||||||
if element.text and element.text.strip():
|
|
||||||
result["#text"] = element.text.strip()
|
|
||||||
|
|
||||||
# Группируем все дочерние элементы в списки
|
|
||||||
children_by_tag = {}
|
|
||||||
for child in element:
|
|
||||||
child_tag = child.tag
|
|
||||||
if child_tag not in children_by_tag:
|
|
||||||
children_by_tag[child_tag] = []
|
|
||||||
children_by_tag[child_tag].append(lxml_to_dict(child))
|
|
||||||
|
|
||||||
# Добавляем в результат (всегда списками)
|
|
||||||
for tag, children in children_by_tag.items():
|
|
||||||
result[tag] = children # Всегда массив, даже если элемент один
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
#tree = etree.parse('C:/Users/jze9/Downloads/12. ХМЛ КПТР в ексель/Исходные данные/Карта-план в хмл прмиер Копейск на кк 74 30 0104002/MapPlanTerritory_EA8F3032-3AF5-4FE2-9A0D-72BCCF94DF06.xml')
|
|
||||||
#tree = etree.parse('C:/Users/jze9/Downloads/12. ХМЛ КПТР в ексель/Исходные данные/Карта-план в хмл прмиер Копейск на кк 74 30 0104002/MapPlanTerritory_54F3719F-2ED8-48FF-8442-9813191EBA51.xml')
|
|
||||||
tree = etree.parse('C:/Users/jze9/Downloads/12. ХМЛ КПТР в ексель/Исходные данные/Карта-план в хмл прмиер Копейск на кк 74 30 0104002/MapPlanTerritory_E2DF5B75-E136-48DA-BB4C-8887BA4ABF46.xml')
|
|
||||||
xml_dict = lxml_to_dict(tree.getroot())
|
|
||||||
|
|
||||||
temp = super_visor(xml_dict)
|
|
||||||
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
@@ -7,4 +7,5 @@ requires-python = ">=3.12"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bs4>=0.0.2",
|
"bs4>=0.0.2",
|
||||||
"lxml>=5.4.0",
|
"lxml>=5.4.0",
|
||||||
|
"openpyxl>=3.1.5",
|
||||||
]
|
]
|
||||||
|
|||||||
23
uv.lock
generated
23
uv.lock
generated
@@ -27,6 +27,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/51/bb/bf7aab772a159614954d84aa832c129624ba6c32faa559dfb200a534e50b/bs4-0.0.2-py2.py3-none-any.whl", hash = "sha256:abf8742c0805ef7f662dce4b51cca104cffe52b835238afc169142ab9b3fbccc", size = 1189, upload-time = "2024-01-17T18:15:48.613Z" },
|
{ url = "https://files.pythonhosted.org/packages/51/bb/bf7aab772a159614954d84aa832c129624ba6c32faa559dfb200a534e50b/bs4-0.0.2-py2.py3-none-any.whl", hash = "sha256:abf8742c0805ef7f662dce4b51cca104cffe52b835238afc169142ab9b3fbccc", size = 1189, upload-time = "2024-01-17T18:15:48.613Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "et-xmlfile"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lxml"
|
name = "lxml"
|
||||||
version = "5.4.0"
|
version = "5.4.0"
|
||||||
@@ -69,6 +78,18 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/fc/14/c115516c62a7d2499781d2d3d7215218c0731b2c940753bf9f9b7b73924d/lxml-5.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:bcb7a1096b4b6b24ce1ac24d4942ad98f983cd3810f9711bcd0293f43a9d8b9f", size = 3814606, upload-time = "2025-04-23T01:47:39.028Z" },
|
{ url = "https://files.pythonhosted.org/packages/fc/14/c115516c62a7d2499781d2d3d7215218c0731b2c940753bf9f9b7b73924d/lxml-5.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:bcb7a1096b4b6b24ce1ac24d4942ad98f983cd3810f9711bcd0293f43a9d8b9f", size = 3814606, upload-time = "2025-04-23T01:47:39.028Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openpyxl"
|
||||||
|
version = "3.1.5"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "et-xmlfile" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "soupsieve"
|
name = "soupsieve"
|
||||||
version = "2.7"
|
version = "2.7"
|
||||||
@@ -85,12 +106,14 @@ source = { virtual = "." }
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "bs4" },
|
{ name = "bs4" },
|
||||||
{ name = "lxml" },
|
{ name = "lxml" },
|
||||||
|
{ name = "openpyxl" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "bs4", specifier = ">=0.0.2" },
|
{ name = "bs4", specifier = ">=0.0.2" },
|
||||||
{ name = "lxml", specifier = ">=5.4.0" },
|
{ name = "lxml", specifier = ">=5.4.0" },
|
||||||
|
{ name = "openpyxl", specifier = ">=3.1.5" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
Reference in New Issue
Block a user