1743 lines
102 KiB
Plaintext
1743 lines
102 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "c2af5362",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 0. CSV координаты в шейпфайл"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"id": "6fc7c48c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import geopandas as gpd\n",
|
||
"import pandas as pd\n",
|
||
"import folium\n",
|
||
"import os"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e53da044",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Считываем проекцию в формате WKT и сохраняем ее в переменной\n",
|
||
"from pyproj import CRSa\n",
|
||
"from shapely.geometry import LineString\n",
|
||
"\n",
|
||
"csv = '4_Маршруты_shapefiles (от Волковой)\\\\Исходники\\\\Орнитологический маршрут.csv'\n",
|
||
"\n",
|
||
"df = pd.read_csv(csv, sep=';', decimal=',')\n",
|
||
"\n",
|
||
"file_name = os.path.splitext(os.path.basename(csv))[0]\n",
|
||
"\n",
|
||
"# Создаем геометрию Point из координат\n",
|
||
"geometry = gpd.points_from_xy(df['X'], df['Y'])\n",
|
||
"\n",
|
||
"# Создаем GeoDataFrame Gauss Kruger Zone 7= 20007\n",
|
||
"gdf = gpd.GeoDataFrame(df, geometry=geometry, crs=32637)\n",
|
||
"gdf.to_file(file_name + '.shp')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "82b264e1",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"gdf.explore(tiles='Esri.WorldImagery')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "ab249f7b",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### МСК координаты в шейп (далее уже в полигон)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"id": "d7f062ed",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "NameError",
|
||
"evalue": "name 'pd' is not defined",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||
"\u001b[31mNameError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 7\u001b[39m\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mshapely\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mgeometry\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m LineString\n\u001b[32m 5\u001b[39m csv = \u001b[33m'\u001b[39m\u001b[33mКладбище поселка Прикубанский.csv\u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m7\u001b[39m df = \u001b[43mpd\u001b[49m.read_csv(csv, sep=\u001b[33m'\u001b[39m\u001b[33m;\u001b[39m\u001b[33m'\u001b[39m, decimal=\u001b[33m'\u001b[39m\u001b[33m,\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 9\u001b[39m file_name = os.path.splitext(os.path.basename(csv))[\u001b[32m0\u001b[39m]\n\u001b[32m 11\u001b[39m \u001b[38;5;66;03m# Создаем геометрию Point из координат\u001b[39;00m\n",
|
||
"\u001b[31mNameError\u001b[39m: name 'pd' is not defined"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"# Считываем проекцию в формате WKT и сохраняем ее в переменной\n",
|
||
"from pyproj import CRS\n",
|
||
"from shapely.geometry import LineString\n",
|
||
"\n",
|
||
"csv = 'Кладбище поселка Прикубанский.csv'\n",
|
||
"\n",
|
||
"df = pd.read_csv(csv, sep=';', decimal=',')\n",
|
||
"\n",
|
||
"file_name = os.path.splitext(os.path.basename(csv))[0]\n",
|
||
"\n",
|
||
"# Создаем геометрию Point из координат\n",
|
||
"geometry = gpd.points_from_xy(df['Y'], df['X'])\n",
|
||
"\n",
|
||
"# Создаем GeoDataFrame Gauss Kruger Zone 7= 20007\n",
|
||
"from pyproj import CRS\n",
|
||
"with open(r'F:\\PROJECT-Colormap\\Преобразования географических проекций (СК, ГСК-2011, МСК)\\МСК23 проекции Краснодар\\MCK-23_Zone_2N.prj', 'r') as f:\n",
|
||
" msk23_2 = f.read()\n",
|
||
"\n",
|
||
"gdf = gpd.GeoDataFrame(df, geometry=geometry, crs=msk23_2)\n",
|
||
"gdf.to_file(file_name + '.shp')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"id": "77c500dd",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Shapefile с полигоном успешно сохранён: polygon.shp\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import geopandas as gpd\n",
|
||
"import pandas as pd\n",
|
||
"from shapely.geometry import Polygon\n",
|
||
"\n",
|
||
"# Читаем CSV\n",
|
||
"df = pd.read_csv('Кладбище поселка Прикубанский.csv', delimiter=';', decimal=',')\n",
|
||
"\n",
|
||
"# Сортируем по столбцу с порядком точек (N)\n",
|
||
"df_sorted = df.sort_values(by='N')\n",
|
||
"\n",
|
||
"# Создаём список координат (X, Y)\n",
|
||
"coords = list(zip(df_sorted['Y'], df_sorted['X']))\n",
|
||
"\n",
|
||
"# Убедимся, что полигон замкнут (повторяем первую точку в конце)\n",
|
||
"if coords[0] != coords[-1]:\n",
|
||
" coords.append(coords[0])\n",
|
||
"\n",
|
||
"# Создаём полигон\n",
|
||
"polygon = Polygon(coords)\n",
|
||
"\n",
|
||
"# Создаём GeoDataFrame с одним объектом\n",
|
||
"gdf = gpd.GeoDataFrame(index=[0], geometry=[polygon])\n",
|
||
"\n",
|
||
"# Создаем GeoDataFrame Gauss Kruger Zone 7= 20007\n",
|
||
"from pyproj import CRS\n",
|
||
"with open(r'F:\\PROJECT-Colormap\\Преобразования географических проекций (СК, ГСК-2011, МСК)\\МСК23 проекции Краснодар\\MCK-23_Zone_2N.prj', 'r') as f:\n",
|
||
" msk23_2 = f.read()\n",
|
||
"gdf.set_crs(msk23_2, inplace=True)\n",
|
||
"\n",
|
||
"# Сохраняем в shapefile\n",
|
||
"gdf.to_file('polygon.shp')\n",
|
||
"\n",
|
||
"print(\"Shapefile с полигоном успешно сохранён: polygon.shp\")\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0971c4df",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 1. Преобразование файлов (shapefile, DXF) в различные координатные системы (в архивы и по папкам) - ОСНОВНОЕ ПО ООПТ"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "7f795d2a-9b80-4097-861c-82525843e4dd",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Collecting folium\n",
|
||
" Downloading folium-0.20.0-py2.py3-none-any.whl.metadata (4.2 kB)\n",
|
||
"Collecting branca>=0.6.0 (from folium)\n",
|
||
" Downloading branca-0.8.2-py3-none-any.whl.metadata (1.7 kB)\n",
|
||
"Requirement already satisfied: jinja2>=2.9 in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from folium) (3.1.6)\n",
|
||
"Requirement already satisfied: numpy in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from folium) (2.4.2)\n",
|
||
"Requirement already satisfied: requests in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from folium) (2.32.5)\n",
|
||
"Collecting xyzservices (from folium)\n",
|
||
" Downloading xyzservices-2025.11.0-py3-none-any.whl.metadata (4.3 kB)\n",
|
||
"Requirement already satisfied: MarkupSafe>=2.0 in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from jinja2>=2.9->folium) (3.0.3)\n",
|
||
"Requirement already satisfied: charset_normalizer<4,>=2 in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from requests->folium) (3.4.4)\n",
|
||
"Requirement already satisfied: idna<4,>=2.5 in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from requests->folium) (3.11)\n",
|
||
"Requirement already satisfied: urllib3<3,>=1.21.1 in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from requests->folium) (2.6.3)\n",
|
||
"Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from requests->folium) (2026.1.4)\n",
|
||
"Downloading folium-0.20.0-py2.py3-none-any.whl (113 kB)\n",
|
||
"Downloading branca-0.8.2-py3-none-any.whl (26 kB)\n",
|
||
"Downloading xyzservices-2025.11.0-py3-none-any.whl (93 kB)\n",
|
||
"Installing collected packages: xyzservices, branca, folium\n",
|
||
"\n",
|
||
" ---------------------------------------- 3/3 [folium]\n",
|
||
"\n",
|
||
"Successfully installed branca-0.8.2 folium-0.20.0 xyzservices-2025.11.0\n",
|
||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||
]
|
||
},
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\n",
|
||
"[notice] A new release of pip is available: 25.3 -> 26.0.1\n",
|
||
"[notice] To update, run: C:\\Users\\Lenovo\\AppData\\Local\\Python\\pythoncore-3.14-64\\python.exe -m pip install --upgrade pip\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"pip install folium"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"id": "a0c1ced4",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import geopandas as gpd\n",
|
||
"import pandas as pd\n",
|
||
"import folium\n",
|
||
"import os"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "68144dd6",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Функция создания списка шейпфайлов для обработки\n",
|
||
"def shp_lst(folder):\n",
|
||
" lst = []\n",
|
||
" for file in os.listdir(folder):\n",
|
||
" if file.endswith(\".shp\"):\n",
|
||
" lst.append(os.path.join(folder, file))\n",
|
||
" print(lst[:2], '\\n', f'Всего: {len(lst)} файл(-а, -ов)')\n",
|
||
" return lst"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"id": "7075b191",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<Geographic 2D CRS: EPSG:4326>\n",
|
||
"Name: WGS 84\n",
|
||
"Axis Info [ellipsoidal]:\n",
|
||
"- Lat[north]: Geodetic latitude (degree)\n",
|
||
"- Lon[east]: Geodetic longitude (degree)\n",
|
||
"Area of Use:\n",
|
||
"- name: World.\n",
|
||
"- bounds: (-180.0, -90.0, 180.0, 90.0)\n",
|
||
"Datum: World Geodetic System 1984 ensemble\n",
|
||
"- Ellipsoid: WGS 84\n",
|
||
"- Prime Meridian: Greenwich"
|
||
]
|
||
},
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"# Считываем проекцию в формате WKT и сохраняем ее в переменной\n",
|
||
"from pyproj import CRS\n",
|
||
"with open(r'c:\\ГИС-проекты\\2025 - ООПТ\\ООПТ из Программы\\MSK23_prj\\Russia_Cadastre_23_1.prj', 'r') as f:\n",
|
||
" #wkt = f.read()\n",
|
||
" msk23_1 = f.read()\n",
|
||
"# crs = CRS.from_wkt(wkt)\n",
|
||
"\n",
|
||
"with open(r'c:\\ГИС-проекты\\2025 - ООПТ\\ООПТ из Программы\\MSK23_prj\\Russia_Cadastre_23_2.prj', 'r') as f:\n",
|
||
" msk23_2 = f.read()\n",
|
||
"\n",
|
||
"# msk23_1 = '+proj=tmerc +lat_0=0 +lon_0=37.98333333333 +k=1 +x_0=1300000 +y_0=-4511057.628 +ellps=krass +towgs84=23.57,-140.95,-78.9,0,0,0,0.22 +units=m +no_defs'\n",
|
||
"# msk23_2 = '+proj=tmerc +lat_0=0 +lon_0=40.98333333333 +k=1 +x_0=2300000 +y_0=-4511057.628 +ellps=krass +towgs84=23.57,-140.95,-78.9,0,0,0,0.22 +units=m +no_defs'\n",
|
||
"\n",
|
||
"# Границы районов края со столбцом зон МСК23\n",
|
||
"gdf_boundary = gpd.read_file(r'c:\\ГИС-проекты\\2025 - ООПТ\\ООПТ из Программы\\Слои КК\\Borders-adm-MSK-Zone.shp')\n",
|
||
"# Преобразуем в WGS84\n",
|
||
"gdf_boundary = gdf_boundary.to_crs(4326)\n",
|
||
"gdf_boundary.crs"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"id": "5b2973a2",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Создадим два фрейма с зонам МСК23 в проекции 4326 (для простоты)\n",
|
||
"msk23_1_boundary = gdf_boundary[gdf_boundary['MSK23_Zone']==1].union_all()\n",
|
||
"msk23_1_boundary = gpd.GeoDataFrame({'geometry': [msk23_1_boundary]}, crs=gdf_boundary.crs)\n",
|
||
"\n",
|
||
"msk23_2_boundary = gdf_boundary[gdf_boundary['MSK23_Zone']==2].union_all()\n",
|
||
"msk23_2_boundary = gpd.GeoDataFrame({'geometry': [msk23_2_boundary]}, crs=gdf_boundary.crs)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"id": "4c032512",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Словарь для создания папки для района\n",
|
||
"rayon_dic = {\n",
|
||
" 'esk': 'Ейский район',\n",
|
||
" 'kvk': 'Кавказский район',\n",
|
||
" 'kln': 'Калининский район',\n",
|
||
" 'knv': 'Каневской район',\n",
|
||
" 'krl': 'Крыловский район',\n",
|
||
" 'krm': 'Крымский район',\n",
|
||
" 'ksh': 'Кущевский район',\n",
|
||
" 'mst': 'Мостовской район',\n",
|
||
" 'nvk': 'Новокубанский район',\n",
|
||
" 'pvl': 'Павловский район',\n",
|
||
" 'tbl': 'Тбилисский район',\n",
|
||
" 'tps': 'Туапсинский район',\n",
|
||
" 'usp': 'Успенский район',\n",
|
||
" 'ulb': 'Усть-Лабинский район',\n",
|
||
" 'anp': 'Анапский район',\n",
|
||
" 'brh': 'Брюховецкий район',\n",
|
||
" 'glj': 'Геленджикский район',\n",
|
||
" 'nvp': 'Новопокровский район',\n",
|
||
" 'nvr': 'Новороссийск',\n",
|
||
" 'otr': 'Отрадненский район',\n",
|
||
" 'sch': 'Сочи',\n",
|
||
" 'svr': 'Северский район',\n",
|
||
" 'tmr': 'Темрюкский район',\n",
|
||
" 'shr': 'Щербиновский район'\n",
|
||
"} "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"id": "3bea704d",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"['C:\\\\ГИС-проекты\\\\2025 - ООПТ\\\\ООПТ из Программы\\\\Input_processing\\\\nvr-vasilevskie_osypi_pp_orz-new.shp'] \n",
|
||
" Всего: 1 файл(-а, -ов)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"folder = r'C:\\ГИС-проекты\\2025 - ООПТ\\ООПТ из Программы\\Input_processing'\n",
|
||
"shp_lst = shp_lst(folder)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 29,
|
||
"id": "11a13016-0a7e-4746-8d1a-b70b2039aade",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Collecting ezdxf\n",
|
||
" Downloading ezdxf-1.4.3-py3-none-any.whl.metadata (9.9 kB)\n",
|
||
"Collecting pyparsing>=2.0.1 (from ezdxf)\n",
|
||
" Downloading pyparsing-3.3.2-py3-none-any.whl.metadata (5.8 kB)\n",
|
||
"Requirement already satisfied: typing_extensions>=4.6.0 in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from ezdxf) (4.15.0)\n",
|
||
"Requirement already satisfied: numpy in c:\\users\\lenovo\\appdata\\local\\python\\pythoncore-3.14-64\\lib\\site-packages (from ezdxf) (2.4.2)\n",
|
||
"Collecting fonttools (from ezdxf)\n",
|
||
" Downloading fonttools-4.61.1-cp314-cp314-win_amd64.whl.metadata (116 kB)\n",
|
||
"Downloading ezdxf-1.4.3-py3-none-any.whl (1.3 MB)\n",
|
||
" ---------------------------------------- 0.0/1.3 MB ? eta -:--:--\n",
|
||
" ---------------------------------------- 0.0/1.3 MB ? eta -:--:--\n",
|
||
" ---------------------------------------- 0.0/1.3 MB ? eta -:--:--\n",
|
||
" ------- -------------------------------- 0.3/1.3 MB ? eta -:--:--\n",
|
||
" ------- -------------------------------- 0.3/1.3 MB ? eta -:--:--\n",
|
||
" --------------- ------------------------ 0.5/1.3 MB 663.7 kB/s eta 0:00:02\n",
|
||
" --------------- ------------------------ 0.5/1.3 MB 663.7 kB/s eta 0:00:02\n",
|
||
" ----------------------- ---------------- 0.8/1.3 MB 626.9 kB/s eta 0:00:01\n",
|
||
" ----------------------- ---------------- 0.8/1.3 MB 626.9 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ------------------------------- -------- 1.0/1.3 MB 588.7 kB/s eta 0:00:01\n",
|
||
" ---------------------------------------- 1.3/1.3 MB 371.6 kB/s 0:00:03\n",
|
||
"Downloading pyparsing-3.3.2-py3-none-any.whl (122 kB)\n",
|
||
"Downloading fonttools-4.61.1-cp314-cp314-win_amd64.whl (2.3 MB)\n",
|
||
" ---------------------------------------- 0.0/2.3 MB ? eta -:--:--\n",
|
||
" ---------------------------------------- 0.0/2.3 MB ? eta -:--:--\n",
|
||
" ---------------------------------------- 0.0/2.3 MB ? eta -:--:--\n",
|
||
" ---- ----------------------------------- 0.3/2.3 MB ? eta -:--:--\n",
|
||
" ---- ----------------------------------- 0.3/2.3 MB ? eta -:--:--\n",
|
||
" ---- ----------------------------------- 0.3/2.3 MB ? eta -:--:--\n",
|
||
" --------- ------------------------------ 0.5/2.3 MB 389.7 kB/s eta 0:00:05\n",
|
||
" --------- ------------------------------ 0.5/2.3 MB 389.7 kB/s eta 0:00:05\n",
|
||
" --------- ------------------------------ 0.5/2.3 MB 389.7 kB/s eta 0:00:05\n",
|
||
" ------------- -------------------------- 0.8/2.3 MB 463.1 kB/s eta 0:00:04\n",
|
||
" ------------- -------------------------- 0.8/2.3 MB 463.1 kB/s eta 0:00:04\n",
|
||
" ------------- -------------------------- 0.8/2.3 MB 463.1 kB/s eta 0:00:04\n",
|
||
" ------------------ --------------------- 1.0/2.3 MB 432.6 kB/s eta 0:00:03\n",
|
||
" ------------------ --------------------- 1.0/2.3 MB 432.6 kB/s eta 0:00:03\n",
|
||
" ------------------ --------------------- 1.0/2.3 MB 432.6 kB/s eta 0:00:03\n",
|
||
" ---------------------- ----------------- 1.3/2.3 MB 436.2 kB/s eta 0:00:03\n",
|
||
" ---------------------- ----------------- 1.3/2.3 MB 436.2 kB/s eta 0:00:03\n",
|
||
" ---------------------- ----------------- 1.3/2.3 MB 436.2 kB/s eta 0:00:03\n",
|
||
" --------------------------- ------------ 1.6/2.3 MB 431.0 kB/s eta 0:00:02\n",
|
||
" --------------------------- ------------ 1.6/2.3 MB 431.0 kB/s eta 0:00:02\n",
|
||
" ------------------------------- -------- 1.8/2.3 MB 447.5 kB/s eta 0:00:02\n",
|
||
" ------------------------------- -------- 1.8/2.3 MB 447.5 kB/s eta 0:00:02\n",
|
||
" ------------------------------- -------- 1.8/2.3 MB 447.5 kB/s eta 0:00:02\n",
|
||
" ------------------------------- -------- 1.8/2.3 MB 447.5 kB/s eta 0:00:02\n",
|
||
" ------------------------------------ --- 2.1/2.3 MB 421.3 kB/s eta 0:00:01\n",
|
||
" ------------------------------------ --- 2.1/2.3 MB 421.3 kB/s eta 0:00:01\n",
|
||
" ------------------------------------ --- 2.1/2.3 MB 421.3 kB/s eta 0:00:01\n",
|
||
" ---------------------------------------- 2.3/2.3 MB 421.1 kB/s 0:00:05\n",
|
||
"Installing collected packages: pyparsing, fonttools, ezdxf\n",
|
||
"\n",
|
||
" ------------- -------------------------- 1/3 [fonttools]\n",
|
||
" ------------- -------------------------- 1/3 [fonttools]\n",
|
||
" ------------- -------------------------- 1/3 [fonttools]\n",
|
||
" ------------- -------------------------- 1/3 [fonttools]\n",
|
||
" ------------- -------------------------- 1/3 [fonttools]\n",
|
||
" ------------- -------------------------- 1/3 [fonttools]\n",
|
||
" -------------------------- ------------- 2/3 [ezdxf]\n",
|
||
" -------------------------- ------------- 2/3 [ezdxf]\n",
|
||
" -------------------------- ------------- 2/3 [ezdxf]\n",
|
||
" -------------------------- ------------- 2/3 [ezdxf]\n",
|
||
" -------------------------- ------------- 2/3 [ezdxf]\n",
|
||
" -------------------------- ------------- 2/3 [ezdxf]\n",
|
||
" -------------------------- ------------- 2/3 [ezdxf]\n",
|
||
" ---------------------------------------- 3/3 [ezdxf]\n",
|
||
"\n",
|
||
"Successfully installed ezdxf-1.4.3 fonttools-4.61.1 pyparsing-3.3.2\n",
|
||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||
]
|
||
},
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
" WARNING: The scripts fonttools.exe, pyftmerge.exe, pyftsubset.exe and ttx.exe are installed in 'C:\\Users\\Lenovo\\AppData\\Local\\Python\\pythoncore-3.14-64\\Scripts' which is not on PATH.\n",
|
||
" Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n",
|
||
" WARNING: The script ezdxf.exe is installed in 'C:\\Users\\Lenovo\\AppData\\Local\\Python\\pythoncore-3.14-64\\Scripts' which is not on PATH.\n",
|
||
" Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n",
|
||
"\n",
|
||
"[notice] A new release of pip is available: 25.3 -> 26.0.1\n",
|
||
"[notice] To update, run: C:\\Users\\Lenovo\\AppData\\Local\\Python\\pythoncore-3.14-64\\python.exe -m pip install --upgrade pip\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"pip install ezdxf"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"id": "d84b7e1a",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"### Сохраняет файлы в папку с именем района, которая создается автоматически по трем первым буквам шейп-файла\n",
|
||
"import ezdxf\n",
|
||
"import os\n",
|
||
"import zipfile\n",
|
||
"import fiona\n",
|
||
"\n",
|
||
"# Функция для создания архива шейпа в той же папке\n",
|
||
"# filepath - путь к файлу, outfolder - папка для сохранения\n",
|
||
"def zip_shp(filepath, outfolder):\n",
|
||
" filename = os.path.splitext(os.path.basename(filepath))[0]\n",
|
||
" folder = os.path.dirname(filepath)\n",
|
||
" with zipfile.ZipFile(outfolder + \"//\" + f'{filename}.zip', 'w') as zip_file:\n",
|
||
" # Ищем файлы с одинаковым именем, но с разным расширением\n",
|
||
" for file in os.listdir(folder):\n",
|
||
" if os.path.splitext(file)[0] == filename:\n",
|
||
" # Добавляем файл в архив\n",
|
||
" zip_file.write(os.path.join(folder, file), file) \n",
|
||
" # Удаляет файл\n",
|
||
" os.remove(os.path.join(folder, file))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"id": "f8000661-5fda-4f3a-b112-7248b1d2d8e4",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Processing c:\\гис-проекты\\fiona-1.10.1-cp314-cp314-win_amd64.whl\n",
|
||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||
]
|
||
},
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"WARNING: Requirement 'fiona-1.10.1-cp314-cp314-win_amd64.whl' looks like a filename, but the file does not exist\n",
|
||
"ERROR: Could not install packages due to an OSError: [Errno 2] No such file or directory: 'C:\\\\ГИС-проекты\\\\fiona-1.10.1-cp314-cp314-win_amd64.whl'\n",
|
||
"\n",
|
||
"\n",
|
||
"[notice] A new release of pip is available: 25.3 -> 26.0.1\n",
|
||
"[notice] To update, run: C:\\Users\\Lenovo\\AppData\\Local\\Python\\pythoncore-3.14-64\\python.exe -m pip install --upgrade pip\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"pip install GDAL-3.9.1-cp314-cp314-win_amd64.whl\n",
|
||
"pip install fiona-1.10.1-cp314-cp314-win_amd64.whl"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"id": "b0cbd752",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"C:\\Users\\Lenovo\\AppData\\Local\\Temp\\ipykernel_14212\\3067829712.py:25: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n",
|
||
"\n",
|
||
" if gdf.geometry.centroid.intersects(msk23_1_boundary).any():\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"# Временная папка\n",
|
||
"temp = 'temp'\n",
|
||
"os.makedirs(temp, exist_ok=True)\n",
|
||
" \n",
|
||
"# Преобразуем все файлы в проекцию WGS84 и сохраняем в формате shape и DVG\n",
|
||
"for shp in shp_lst:\n",
|
||
" gdf = gpd.read_file(shp)\n",
|
||
" # Создать папку для района\n",
|
||
" outfolder = rayon_dic[os.path.basename(shp)[:3]] # берет первый три буквы названия файла и достает из словаря полное название района\n",
|
||
" os.makedirs(outfolder, exist_ok=True)\n",
|
||
" \n",
|
||
" ### WGS84\n",
|
||
" gdf = gdf.to_crs(4326)\n",
|
||
" filepath = os.path.join(temp, os.path.splitext(os.path.basename(shp))[0]) + '_WGS84' + '.shp'\n",
|
||
" gdf.to_file(filename=filepath, driver='ESRI Shapefile')\n",
|
||
" zip_shp(filepath, outfolder)\n",
|
||
" # DXF\n",
|
||
" filepath = os.path.join(outfolder, os.path.splitext(os.path.basename(shp))[0]) + '_WGS84' + '.dxf'\n",
|
||
" #gdf.geometry.to_file(filepath, driver=\"DXF\")\n",
|
||
" gdf.geometry.to_file(filepath, driver=\"DXF\", engine='fiona')\n",
|
||
" \n",
|
||
" # Раздел с МСК23 (распределение по зонам)\n",
|
||
" # Для определения делаем центроид полигона, если он внутри зоны МСК1, то это зона 1, если нет, то зона 2 (предварительно пришлось преобразовать WGS84 в Меркатор - не работало)\n",
|
||
" # if gdf.to_crs(3857).geometry.centroid.intersects(msk23_1_boundary).any():\n",
|
||
" if gdf.geometry.centroid.intersects(msk23_1_boundary).any():\n",
|
||
" gdf = gdf.to_crs(msk23_1)\n",
|
||
" filepath = os.path.join(temp, os.path.splitext(os.path.basename(shp))[0]) + '_MSK23_1' + '.shp'\n",
|
||
" gdf.to_file(filename=filepath, driver='ESRI Shapefile')\n",
|
||
" zip_shp(filepath, outfolder)\n",
|
||
" # DXF\n",
|
||
" filepath = os.path.join(outfolder, os.path.splitext(os.path.basename(shp))[0]) + '_MSK23_1' + '.dxf'\n",
|
||
" gdf.geometry.to_file(filepath, driver=\"DXF\")\n",
|
||
" else:\n",
|
||
" gdf = gdf.to_crs(msk23_2)\n",
|
||
" filepath = os.path.join(temp, os.path.splitext(os.path.basename(shp))[0]) + '_MSK23_2' + '.shp'\n",
|
||
" gdf.to_file(filename=filepath, driver='ESRI Shapefile')\n",
|
||
" zip_shp(filepath, outfolder)\n",
|
||
" # DXF\n",
|
||
" filepath = os.path.join(outfolder, os.path.splitext(os.path.basename(shp))[0]) + '_MSK23_2' + '.dxf'\n",
|
||
" gdf.geometry.to_file(filepath, driver=\"DXF\")\n",
|
||
"\n",
|
||
"\n",
|
||
" \n",
|
||
"# with tempfile.TemporaryDirectory() as temp_dir:\n",
|
||
"# temp_dir = Path(temp_dir)\n",
|
||
"# localFile = 'myshapefile'\n",
|
||
"\n",
|
||
"# gdf.to_file(filename=temp_dir, driver='ESRI Shapefile')\n",
|
||
"\n",
|
||
"# archiveFile = shutil.make_archive(localFile, 'zip', temp_dir)\n",
|
||
"# shutil.rmtree(temp_dir)\n",
|
||
" \n",
|
||
"# # Преобразуем данные в формат DWG-DXF\n",
|
||
"# filepath = os.path.join(outfolder, os.path.splitext(os.path.basename(shp))[0]) + '.dxf'\n",
|
||
" \n",
|
||
"# # Create a new DXF document\n",
|
||
"# doc = ezdxf.new(dxfversion='R2010')\n",
|
||
"# # Add a new layer to the DXF document\n",
|
||
"# msp = doc.modelspace()\n",
|
||
"\n",
|
||
"# # Iterate through the GeoDataFrame and add geometries to the DXF\n",
|
||
"# for _, row in gdf.iterrows():\n",
|
||
"# if row.geometry.type == 'Point':\n",
|
||
"# msp.add_point((row.geometry.x, row.geometry.y))\n",
|
||
"# elif row.geometry.type in ['LineString', 'MultiLineString']:\n",
|
||
"# for line in row.geometry:\n",
|
||
"# msp.add_lwpolyline(line.coords)\n",
|
||
"# elif row.geometry.type in ['Polygon', 'MultiPolygon']:\n",
|
||
"# for poly in row.geometry:\n",
|
||
"# coords = list(poly.exterior.coords)\n",
|
||
"# coords.append(coords[0]) # добавляем последнюю точку координат к началу списка координат\n",
|
||
"# msp.add_lwpolyline(coords)\n",
|
||
"\n",
|
||
"# # Save the DXF file\n",
|
||
"# doc.saveas(filepath)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0dff4cdd",
|
||
"metadata": {},
|
||
"source": [
|
||
"##### Преобразование файлов в DXF"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 87,
|
||
"id": "a33bf66c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"for shp in shp_lst:\n",
|
||
" gdf = gpd.read_file(shp)\n",
|
||
" # Создать папку для района\n",
|
||
" outfolder = rayon_dic[os.path.basename(shp)[:3]] # берет первый три буквы названия файла и достает из словаря полное название района\n",
|
||
" os.makedirs(outfolder, exist_ok=True)\n",
|
||
" \n",
|
||
" # DXF\n",
|
||
" filepath = os.path.join(outfolder, os.path.splitext(os.path.basename(shp))[0]) + '.dxf'\n",
|
||
" gdf.geometry.to_file(filepath, driver=\"DXF\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "8f6d5884",
|
||
"metadata": {},
|
||
"source": [
|
||
"!!!!! ДАЛЕЕ НУЖНО РАЗБИРАТЬСЯ\n",
|
||
"https://mapscaping.com/shapefile-to-dxf/"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 90,
|
||
"id": "2a16cebd",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"ename": "DataSourceError",
|
||
"evalue": "input.shp: No such file or directory",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[1;31mDataSourceError\u001b[0m Traceback (most recent call last)",
|
||
"Cell \u001b[1;32mIn[90], line 5\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mezdxf\u001b[39;00m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;66;03m# Load the Shapefile\u001b[39;00m\n\u001b[1;32m----> 5\u001b[0m gdf \u001b[38;5;241m=\u001b[39m \u001b[43mgpd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread_file\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43minput.shp\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 7\u001b[0m \u001b[38;5;66;03m# Create a new DXF document\u001b[39;00m\n\u001b[0;32m 8\u001b[0m doc \u001b[38;5;241m=\u001b[39m ezdxf\u001b[38;5;241m.\u001b[39mnew(dxfversion\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mR2010\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\geopandas\\io\\file.py:299\u001b[0m, in \u001b[0;36m_read_file\u001b[1;34m(filename, bbox, mask, columns, rows, engine, **kwargs)\u001b[0m\n\u001b[0;32m 296\u001b[0m from_bytes \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[0;32m 298\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m engine \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpyogrio\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m--> 299\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _read_file_pyogrio(\n\u001b[0;32m 300\u001b[0m filename, bbox\u001b[38;5;241m=\u001b[39mbbox, mask\u001b[38;5;241m=\u001b[39mmask, columns\u001b[38;5;241m=\u001b[39mcolumns, rows\u001b[38;5;241m=\u001b[39mrows, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[0;32m 301\u001b[0m )\n\u001b[0;32m 303\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m engine \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfiona\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[0;32m 304\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m pd\u001b[38;5;241m.\u001b[39mapi\u001b[38;5;241m.\u001b[39mtypes\u001b[38;5;241m.\u001b[39mis_file_like(filename):\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\geopandas\\io\\file.py:549\u001b[0m, in \u001b[0;36m_read_file_pyogrio\u001b[1;34m(path_or_bytes, bbox, mask, rows, **kwargs)\u001b[0m\n\u001b[0;32m 540\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[0;32m 541\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124minclude_fields\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mignore_fields\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m keywords are deprecated, and \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 542\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwill be removed in a future release. You can use the \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcolumns\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m keyword \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 545\u001b[0m stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m3\u001b[39m,\n\u001b[0;32m 546\u001b[0m )\n\u001b[0;32m 547\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcolumns\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m kwargs\u001b[38;5;241m.\u001b[39mpop(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minclude_fields\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m--> 549\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m pyogrio\u001b[38;5;241m.\u001b[39mread_dataframe(path_or_bytes, bbox\u001b[38;5;241m=\u001b[39mbbox, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\pyogrio\\geopandas.py:265\u001b[0m, in \u001b[0;36mread_dataframe\u001b[1;34m(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, fid_as_index, use_arrow, on_invalid, arrow_to_pandas_kwargs, **kwargs)\u001b[0m\n\u001b[0;32m 260\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_arrow:\n\u001b[0;32m 261\u001b[0m \u001b[38;5;66;03m# For arrow, datetimes are read as is.\u001b[39;00m\n\u001b[0;32m 262\u001b[0m \u001b[38;5;66;03m# For numpy IO, datetimes are read as string values to preserve timezone info\u001b[39;00m\n\u001b[0;32m 263\u001b[0m \u001b[38;5;66;03m# as numpy does not directly support timezones.\u001b[39;00m\n\u001b[0;32m 264\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdatetime_as_string\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m--> 265\u001b[0m result \u001b[38;5;241m=\u001b[39m read_func(\n\u001b[0;32m 266\u001b[0m path_or_buffer,\n\u001b[0;32m 267\u001b[0m layer\u001b[38;5;241m=\u001b[39mlayer,\n\u001b[0;32m 268\u001b[0m encoding\u001b[38;5;241m=\u001b[39mencoding,\n\u001b[0;32m 269\u001b[0m columns\u001b[38;5;241m=\u001b[39mcolumns,\n\u001b[0;32m 270\u001b[0m read_geometry\u001b[38;5;241m=\u001b[39mread_geometry,\n\u001b[0;32m 271\u001b[0m force_2d\u001b[38;5;241m=\u001b[39mgdal_force_2d,\n\u001b[0;32m 272\u001b[0m skip_features\u001b[38;5;241m=\u001b[39mskip_features,\n\u001b[0;32m 273\u001b[0m max_features\u001b[38;5;241m=\u001b[39mmax_features,\n\u001b[0;32m 274\u001b[0m where\u001b[38;5;241m=\u001b[39mwhere,\n\u001b[0;32m 275\u001b[0m bbox\u001b[38;5;241m=\u001b[39mbbox,\n\u001b[0;32m 276\u001b[0m mask\u001b[38;5;241m=\u001b[39mmask,\n\u001b[0;32m 277\u001b[0m fids\u001b[38;5;241m=\u001b[39mfids,\n\u001b[0;32m 278\u001b[0m sql\u001b[38;5;241m=\u001b[39msql,\n\u001b[0;32m 279\u001b[0m sql_dialect\u001b[38;5;241m=\u001b[39msql_dialect,\n\u001b[0;32m 280\u001b[0m return_fids\u001b[38;5;241m=\u001b[39mfid_as_index,\n\u001b[0;32m 281\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m 282\u001b[0m )\n\u001b[0;32m 284\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m use_arrow:\n\u001b[0;32m 285\u001b[0m meta, table \u001b[38;5;241m=\u001b[39m result\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\pyogrio\\raw.py:198\u001b[0m, in \u001b[0;36mread\u001b[1;34m(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, return_fids, datetime_as_string, **kwargs)\u001b[0m\n\u001b[0;32m 59\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Read OGR data source into numpy arrays.\u001b[39;00m\n\u001b[0;32m 60\u001b[0m \n\u001b[0;32m 61\u001b[0m \u001b[38;5;124;03mIMPORTANT: non-linear geometry types (e.g., MultiSurface) are converted\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 194\u001b[0m \n\u001b[0;32m 195\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 196\u001b[0m dataset_kwargs \u001b[38;5;241m=\u001b[39m _preprocess_options_key_value(kwargs) \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;28;01melse\u001b[39;00m {}\n\u001b[1;32m--> 198\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mogr_read\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 199\u001b[0m \u001b[43m \u001b[49m\u001b[43mget_vsi_path_or_buffer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath_or_buffer\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 200\u001b[0m \u001b[43m \u001b[49m\u001b[43mlayer\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlayer\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 201\u001b[0m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mencoding\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 202\u001b[0m \u001b[43m \u001b[49m\u001b[43mcolumns\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcolumns\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 203\u001b[0m \u001b[43m \u001b[49m\u001b[43mread_geometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mread_geometry\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 204\u001b[0m \u001b[43m \u001b[49m\u001b[43mforce_2d\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mforce_2d\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 205\u001b[0m \u001b[43m \u001b[49m\u001b[43mskip_features\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mskip_features\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 206\u001b[0m \u001b[43m \u001b[49m\u001b[43mmax_features\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmax_features\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 207\u001b[0m \u001b[43m \u001b[49m\u001b[43mwhere\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mwhere\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 208\u001b[0m \u001b[43m \u001b[49m\u001b[43mbbox\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbbox\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 209\u001b[0m \u001b[43m \u001b[49m\u001b[43mmask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_mask_to_wkb\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmask\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 210\u001b[0m \u001b[43m \u001b[49m\u001b[43mfids\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfids\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 211\u001b[0m \u001b[43m \u001b[49m\u001b[43msql\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msql\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 212\u001b[0m \u001b[43m \u001b[49m\u001b[43msql_dialect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msql_dialect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 213\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_fids\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_fids\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 214\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_kwargs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 215\u001b[0m \u001b[43m \u001b[49m\u001b[43mdatetime_as_string\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdatetime_as_string\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 216\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"File \u001b[1;32mpyogrio\\\\_io.pyx:1240\u001b[0m, in \u001b[0;36mpyogrio._io.ogr_read\u001b[1;34m()\u001b[0m\n",
|
||
"File \u001b[1;32mpyogrio\\\\_io.pyx:220\u001b[0m, in \u001b[0;36mpyogrio._io.ogr_open\u001b[1;34m()\u001b[0m\n",
|
||
"\u001b[1;31mDataSourceError\u001b[0m: input.shp: No such file or directory"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import geopandas as gpd\n",
|
||
"import ezdxf\n",
|
||
"\n",
|
||
"# Load the Shapefile\n",
|
||
"gdf = gpd.read_file('input.shp')\n",
|
||
"\n",
|
||
"# Create a new DXF document\n",
|
||
"doc = ezdxf.new(dxfversion='R2010')\n",
|
||
"\n",
|
||
"# Add a new layer to the DXF document\n",
|
||
"msp = doc.modelspace()\n",
|
||
"\n",
|
||
"# Iterate through the GeoDataFrame and add geometries to the DXF\n",
|
||
"for _, row in gdf.iterrows():\n",
|
||
" if row.geometry.type == 'Point':\n",
|
||
" msp.add_point((row.geometry.x, row.geometry.y))\n",
|
||
" elif row.geometry.type in ['LineString', 'MultiLineString']:\n",
|
||
" for line in row.geometry:\n",
|
||
" msp.add_lwpolyline(line.coords)\n",
|
||
" elif row.geometry.type in ['Polygon', 'MultiPolygon']:\n",
|
||
" for poly in row.geometry:\n",
|
||
" msp.add_lwpolyline(poly.exterior.coords, is_closed=True)\n",
|
||
"\n",
|
||
"# Save the DXF file\n",
|
||
"doc.saveas('output.dxf')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3b2d17c5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Для проекции в МСК \n",
|
||
"# В начале определяем зону по файлу с районами, далее преобразуем в эту зону\n",
|
||
"# НЕ ДОДЕЛАН!!!!\n",
|
||
"\n",
|
||
"for shp in shp_lst[:3]:\n",
|
||
" gdf = gpd.read_file(shp).union_all\n",
|
||
" centroid = gdf.centroid\n",
|
||
" centroid_gdf = gpd.GeoDataFrame(geometry=gpd.points_from_xy(centroid.x, centroid.y)).set_crs(3857)\n",
|
||
" gdf_joined = gpd.sjoin(\n",
|
||
" \n",
|
||
" \n",
|
||
" gdf = gdf.to_crs(msk23_1)\n",
|
||
" \n",
|
||
" filepath = os.path.join(outfolder, os.path.basename(shp))\n",
|
||
" gdf.to_file(filepath)\n",
|
||
"\n",
|
||
" \n",
|
||
"# Преобразуем данные в формат DWG-DXF\n",
|
||
"import osgeo import ogr\n",
|
||
"driver = ogr.GetDriverByName('DXF')\n",
|
||
"ds = driver.CreateCopy('output.dxf', gdf)\n",
|
||
"ds = None\n",
|
||
"\n",
|
||
"import pydxf\n",
|
||
"dxf = pydxf.DxfFile('input.dxf')\n",
|
||
"# Преобразуем DXF в DWG\n",
|
||
"dwg = pydxf.DwfFile('output.dwg')\n",
|
||
"dwg.write(dxf)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "84e4e74e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import pyproj\n",
|
||
"x, y = gdf.centroid.x, gdf.centroid.y\n",
|
||
"lon, lat = pyproj.transform(pyproj.Proj('epsg:3857'), pyproj.Proj('epsg:4326'), x, y)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "d696791f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Определите зону MSK\n",
|
||
"if central_meridian >= 45 and central_meridian < 48:\n",
|
||
" print(\"Проекция: MSK-23.1\")\n",
|
||
"elif central_meridian >= 48 and central_meridian <= 51:\n",
|
||
" print(\"Проекция: MSK-23.2\")\n",
|
||
"else:\n",
|
||
" print(\"Проекция: MSK, но зона не определена\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "aedd1949",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"centroid = gdf.centroid\n",
|
||
"gdf_joined = gpd.sjoin(centroid, gdf, how='inner', op='within').explore()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"id": "7efffd0c",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "NameError",
|
||
"evalue": "name 'gpd' is not defined",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
|
||
"Cell \u001b[1;32mIn[1], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m centroid_gdf \u001b[38;5;241m=\u001b[39m \u001b[43mgpd\u001b[49m\u001b[38;5;241m.\u001b[39mGeoDataFrame(geometry\u001b[38;5;241m=\u001b[39mgpd\u001b[38;5;241m.\u001b[39mpoints_from_xy(centroid\u001b[38;5;241m.\u001b[39mx, centroid\u001b[38;5;241m.\u001b[39my))\u001b[38;5;241m.\u001b[39mset_crs(msk23_1)\n",
|
||
"\u001b[1;31mNameError\u001b[0m: name 'gpd' is not defined"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"centroid_gdf = gpd.GeoDataFrame(geometry=gpd.points_from_xy(centroid.x, centroid.y)).set_crs(msk23_1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "3b530859",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 2. Создание таблицы с координатами (поворотные точки) ТОЛЬКО МСК23"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"id": "70de8c1d",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"ename": "DataSourceError",
|
||
"evalue": "11111\\sch-aibga-grushevn_pp_orz-new_MSK23_2.shp: No such file or directory",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[1;31mDataSourceError\u001b[0m Traceback (most recent call last)",
|
||
"Cell \u001b[1;32mIn[9], line 4\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;66;03m# Извлекаем имя файла\u001b[39;00m\n\u001b[0;32m 3\u001b[0m shp_name \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39msplitext(os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mbasename(shp))[\u001b[38;5;241m0\u001b[39m]\n\u001b[1;32m----> 4\u001b[0m gdf \u001b[38;5;241m=\u001b[39m \u001b[43mgpd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread_file\u001b[49m\u001b[43m(\u001b[49m\u001b[43mshp\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 6\u001b[0m \u001b[38;5;66;03m# Извлекаем координаты вертексов полигона (формат X, Y в текущей координатной системе)\u001b[39;00m\n\u001b[0;32m 7\u001b[0m df \u001b[38;5;241m=\u001b[39m gdf\u001b[38;5;241m.\u001b[39mget_coordinates()\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\geopandas\\io\\file.py:299\u001b[0m, in \u001b[0;36m_read_file\u001b[1;34m(filename, bbox, mask, columns, rows, engine, **kwargs)\u001b[0m\n\u001b[0;32m 296\u001b[0m from_bytes \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[0;32m 298\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m engine \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpyogrio\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m--> 299\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _read_file_pyogrio(\n\u001b[0;32m 300\u001b[0m filename, bbox\u001b[38;5;241m=\u001b[39mbbox, mask\u001b[38;5;241m=\u001b[39mmask, columns\u001b[38;5;241m=\u001b[39mcolumns, rows\u001b[38;5;241m=\u001b[39mrows, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[0;32m 301\u001b[0m )\n\u001b[0;32m 303\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m engine \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfiona\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[0;32m 304\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m pd\u001b[38;5;241m.\u001b[39mapi\u001b[38;5;241m.\u001b[39mtypes\u001b[38;5;241m.\u001b[39mis_file_like(filename):\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\geopandas\\io\\file.py:549\u001b[0m, in \u001b[0;36m_read_file_pyogrio\u001b[1;34m(path_or_bytes, bbox, mask, rows, **kwargs)\u001b[0m\n\u001b[0;32m 540\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[0;32m 541\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124minclude_fields\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mignore_fields\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m keywords are deprecated, and \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 542\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwill be removed in a future release. You can use the \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcolumns\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m keyword \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 545\u001b[0m stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m3\u001b[39m,\n\u001b[0;32m 546\u001b[0m )\n\u001b[0;32m 547\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcolumns\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m kwargs\u001b[38;5;241m.\u001b[39mpop(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minclude_fields\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m--> 549\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m pyogrio\u001b[38;5;241m.\u001b[39mread_dataframe(path_or_bytes, bbox\u001b[38;5;241m=\u001b[39mbbox, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\pyogrio\\geopandas.py:265\u001b[0m, in \u001b[0;36mread_dataframe\u001b[1;34m(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, fid_as_index, use_arrow, on_invalid, arrow_to_pandas_kwargs, **kwargs)\u001b[0m\n\u001b[0;32m 260\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_arrow:\n\u001b[0;32m 261\u001b[0m \u001b[38;5;66;03m# For arrow, datetimes are read as is.\u001b[39;00m\n\u001b[0;32m 262\u001b[0m \u001b[38;5;66;03m# For numpy IO, datetimes are read as string values to preserve timezone info\u001b[39;00m\n\u001b[0;32m 263\u001b[0m \u001b[38;5;66;03m# as numpy does not directly support timezones.\u001b[39;00m\n\u001b[0;32m 264\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdatetime_as_string\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m--> 265\u001b[0m result \u001b[38;5;241m=\u001b[39m read_func(\n\u001b[0;32m 266\u001b[0m path_or_buffer,\n\u001b[0;32m 267\u001b[0m layer\u001b[38;5;241m=\u001b[39mlayer,\n\u001b[0;32m 268\u001b[0m encoding\u001b[38;5;241m=\u001b[39mencoding,\n\u001b[0;32m 269\u001b[0m columns\u001b[38;5;241m=\u001b[39mcolumns,\n\u001b[0;32m 270\u001b[0m read_geometry\u001b[38;5;241m=\u001b[39mread_geometry,\n\u001b[0;32m 271\u001b[0m force_2d\u001b[38;5;241m=\u001b[39mgdal_force_2d,\n\u001b[0;32m 272\u001b[0m skip_features\u001b[38;5;241m=\u001b[39mskip_features,\n\u001b[0;32m 273\u001b[0m max_features\u001b[38;5;241m=\u001b[39mmax_features,\n\u001b[0;32m 274\u001b[0m where\u001b[38;5;241m=\u001b[39mwhere,\n\u001b[0;32m 275\u001b[0m bbox\u001b[38;5;241m=\u001b[39mbbox,\n\u001b[0;32m 276\u001b[0m mask\u001b[38;5;241m=\u001b[39mmask,\n\u001b[0;32m 277\u001b[0m fids\u001b[38;5;241m=\u001b[39mfids,\n\u001b[0;32m 278\u001b[0m sql\u001b[38;5;241m=\u001b[39msql,\n\u001b[0;32m 279\u001b[0m sql_dialect\u001b[38;5;241m=\u001b[39msql_dialect,\n\u001b[0;32m 280\u001b[0m return_fids\u001b[38;5;241m=\u001b[39mfid_as_index,\n\u001b[0;32m 281\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m 282\u001b[0m )\n\u001b[0;32m 284\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m use_arrow:\n\u001b[0;32m 285\u001b[0m meta, table \u001b[38;5;241m=\u001b[39m result\n",
|
||
"File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\pyogrio\\raw.py:198\u001b[0m, in \u001b[0;36mread\u001b[1;34m(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, return_fids, datetime_as_string, **kwargs)\u001b[0m\n\u001b[0;32m 59\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Read OGR data source into numpy arrays.\u001b[39;00m\n\u001b[0;32m 60\u001b[0m \n\u001b[0;32m 61\u001b[0m \u001b[38;5;124;03mIMPORTANT: non-linear geometry types (e.g., MultiSurface) are converted\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 194\u001b[0m \n\u001b[0;32m 195\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 196\u001b[0m dataset_kwargs \u001b[38;5;241m=\u001b[39m _preprocess_options_key_value(kwargs) \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;28;01melse\u001b[39;00m {}\n\u001b[1;32m--> 198\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mogr_read\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 199\u001b[0m \u001b[43m \u001b[49m\u001b[43mget_vsi_path_or_buffer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath_or_buffer\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 200\u001b[0m \u001b[43m \u001b[49m\u001b[43mlayer\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlayer\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 201\u001b[0m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mencoding\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 202\u001b[0m \u001b[43m \u001b[49m\u001b[43mcolumns\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcolumns\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 203\u001b[0m \u001b[43m \u001b[49m\u001b[43mread_geometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mread_geometry\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 204\u001b[0m \u001b[43m \u001b[49m\u001b[43mforce_2d\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mforce_2d\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 205\u001b[0m \u001b[43m \u001b[49m\u001b[43mskip_features\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mskip_features\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 206\u001b[0m \u001b[43m \u001b[49m\u001b[43mmax_features\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmax_features\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 207\u001b[0m \u001b[43m \u001b[49m\u001b[43mwhere\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mwhere\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 208\u001b[0m \u001b[43m \u001b[49m\u001b[43mbbox\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbbox\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 209\u001b[0m \u001b[43m \u001b[49m\u001b[43mmask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_mask_to_wkb\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmask\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 210\u001b[0m \u001b[43m \u001b[49m\u001b[43mfids\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfids\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 211\u001b[0m \u001b[43m \u001b[49m\u001b[43msql\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msql\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 212\u001b[0m \u001b[43m \u001b[49m\u001b[43msql_dialect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msql_dialect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 213\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_fids\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_fids\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 214\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_kwargs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 215\u001b[0m \u001b[43m \u001b[49m\u001b[43mdatetime_as_string\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdatetime_as_string\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 216\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"File \u001b[1;32mpyogrio\\\\_io.pyx:1240\u001b[0m, in \u001b[0;36mpyogrio._io.ogr_read\u001b[1;34m()\u001b[0m\n",
|
||
"File \u001b[1;32mpyogrio\\\\_io.pyx:220\u001b[0m, in \u001b[0;36mpyogrio._io.ogr_open\u001b[1;34m()\u001b[0m\n",
|
||
"\u001b[1;31mDataSourceError\u001b[0m: 11111\\sch-aibga-grushevn_pp_orz-new_MSK23_2.shp: No such file or directory"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"shp = '11111\\\\sch-aibga-grushevn_pp_orz-new_MSK23_2.shp'\n",
|
||
"# Извлекаем имя файла\n",
|
||
"shp_name = os.path.splitext(os.path.basename(shp))[0]\n",
|
||
"gdf = gpd.read_file(shp)\n",
|
||
"\n",
|
||
"# Извлекаем координаты вертексов полигона (формат X, Y в текущей координатной системе)\n",
|
||
"df = gdf.get_coordinates()\n",
|
||
"# Добавляем индекс к таблице\n",
|
||
"df.reset_index(inplace = True, drop = True)\n",
|
||
"# Первая строка с 1\n",
|
||
"df.index += 1\n",
|
||
"df = df.reset_index()\n",
|
||
"# Округляем\n",
|
||
"df = round(df)\n",
|
||
"# Переименовываем столбцы\n",
|
||
"df.columns = ['N', 'X_MSK23', 'Y_MSK23']\n",
|
||
"# Добавляет первую строку в конец таблицы\n",
|
||
"df = df.take(list(range(len(df) - 1)) + [0])\n",
|
||
"df.to_excel(shp_name + '.xlsx', index=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "7c473b4b",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 3. Поворотные точки градусы, минуты, секунды в ГСК 2011 (для проверки по ГЕОЛОГИИ)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"id": "1e5a4710",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import geopandas as gpd\n",
|
||
"import pandas as pd\n",
|
||
"from os.path import splitext\n",
|
||
"import os"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "198e699a",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Функции"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "2e3cf25c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Функция создания списка шейпфайлов для обработки\n",
|
||
"def shp_lst(folder):\n",
|
||
" lst = []\n",
|
||
" for file in os.listdir(folder):\n",
|
||
" if file.endswith(\".shp\"):\n",
|
||
" lst.append(os.path.join(folder, file))\n",
|
||
" print(lst[:2], '\\n', f'Всего: {len(lst)} файл(-а, -ов)')\n",
|
||
" return lst"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"id": "52edaf9c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Создает таблицу с координатами градусы-минуты-секунды для полигона в GeoDataFrame (должен быть один объект)\n",
|
||
"def coordinates(gdf):\n",
|
||
" df = gdf.get_coordinates()\n",
|
||
" # Добавляем индекс к таблице\n",
|
||
" df.reset_index(inplace = True, drop = True)\n",
|
||
" # Первая строка с 1\n",
|
||
" df.index += 1\n",
|
||
" df = df.reset_index()\n",
|
||
" \n",
|
||
" df['latitude_deg'] = df['y'].astype(int)\n",
|
||
" df['latitude_min_full'] = ((df['y'] - df['latitude_deg']) * 60).abs()\n",
|
||
" df['latitude_min'] = df['latitude_min_full'].astype(int)\n",
|
||
" df['latitude_sec'] = round((df['latitude_min_full'] - df['latitude_min']) * 60, 3)\n",
|
||
"\n",
|
||
" df['longitude_deg'] = df['x'].astype(int)\n",
|
||
" df['longitude_min_full'] = ((df['x'] - df['longitude_deg']) * 60).abs()\n",
|
||
" df['longitude_min'] = df['longitude_min_full'].astype(int)\n",
|
||
" df['longitude_sec'] = round((df['longitude_min_full'] - df['longitude_min']) * 60, 3)\n",
|
||
"\n",
|
||
" df.drop(['x', 'y', 'latitude_min_full', 'longitude_min_full'], axis=1, inplace=True)\n",
|
||
" df = df.rename(columns={'index': 'N'})\n",
|
||
"\n",
|
||
" # Добавляем в конец дубликат первой строки\n",
|
||
" df = df.take(list(range(len(df) - 1)) + [0])\n",
|
||
" return df"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"id": "23bd2b42",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"##### Функция шаблона Excel c шапкой для координат ГСК-2011\n",
|
||
"\n",
|
||
"from openpyxl import Workbook\n",
|
||
"from openpyxl.styles import Alignment, Font, Border, Side\n",
|
||
"\n",
|
||
"def template_gc(output_file):\n",
|
||
" wb = Workbook()\n",
|
||
" ws = wb.active\n",
|
||
"\n",
|
||
" # --- Первая строка: заголовок \"ГСК-2011\", объединённый над всеми столбцами ---\n",
|
||
" max_col = 7 # например, у вас 7 столбцов в шапке ниже\n",
|
||
"\n",
|
||
" ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=max_col)\n",
|
||
" header_cell = ws.cell(row=1, column=1, value='ГСК-2011')\n",
|
||
" header_cell.font = Font(bold=False) # простой шрифт (без жирности)\n",
|
||
" header_cell.alignment = Alignment(horizontal='center', vertical='center')\n",
|
||
" \n",
|
||
" # --- Вторая и третья строки: многоуровневая шапка ---\n",
|
||
" # Вторая строка — первый уровень шапки\n",
|
||
" ws['A3'] = \"№ точки\"\n",
|
||
" ws['B3'] = \"Широта [-90:90]\\n(С.Ш. - положительные\\nЮ.Ш. - отрицательные)\"\n",
|
||
" ws['E3'] = \"Долгота [-180:180]\\n(В.Д. - положительные\\nЗ.Д. - отрицательные)\"\n",
|
||
"\n",
|
||
" # Объединение ячеек для первого уровня заголовков\n",
|
||
" ws.merge_cells('A3:A4') # \"№ точки\" занимает две строки вертикально\n",
|
||
" ws.merge_cells('B3:D3') # \"Широта ...\" над 3 колонками\n",
|
||
" ws.merge_cells('E3:G3') # \"Долгота ...\" над 3 колонками\n",
|
||
"\n",
|
||
" # Третья строка — второй уровень (подзаголовки) с обычным шрифтом\n",
|
||
" sub_headers = [\n",
|
||
" 'Градусы, \\nцелое',\n",
|
||
" 'Минуты, \\nцелое',\n",
|
||
" 'Секунды,\\nдробь до \\n3 знаков'\n",
|
||
" ]\n",
|
||
"\n",
|
||
" cols_lat = ['B', 'C', 'D']\n",
|
||
" cols_lon = ['E', 'F', 'G']\n",
|
||
"\n",
|
||
" for col, text in zip(cols_lat, sub_headers):\n",
|
||
" c = ws[f\"{col}4\"]\n",
|
||
" c.value = text\n",
|
||
" c.font = Font(bold=False) # простой шрифт\n",
|
||
" c.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)\n",
|
||
"\n",
|
||
" for col, text in zip(cols_lon, sub_headers):\n",
|
||
" c = ws[f\"{col}4\"]\n",
|
||
" c.value = text\n",
|
||
" c.font = Font(bold=False)\n",
|
||
" c.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)\n",
|
||
"\n",
|
||
" # Выравнивание и жирность для второго уровня заголовка (строка 2)\n",
|
||
" for cell in ['A3', 'B3', 'E3']:\n",
|
||
" c = ws[cell]\n",
|
||
" c.font = Font(bold=True)\n",
|
||
" c.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)\n",
|
||
"\n",
|
||
" # Установим высоту строк для переносов текста\n",
|
||
" ws.row_dimensions[1].height = 20\n",
|
||
" ws.row_dimensions[2].height = 8\n",
|
||
" ws.row_dimensions[3].height = 48\n",
|
||
" ws.row_dimensions[4].height = 40\n",
|
||
"\n",
|
||
" # Подгонка ширины столбцов\n",
|
||
" col_widths = [10, 15, 15, 20, 15, 15, 20]\n",
|
||
" for i, width in enumerate(col_widths, 1):\n",
|
||
" ws.column_dimensions[chr(64 + i)].width = width\n",
|
||
"\n",
|
||
" # Добавление рамки по всей области шапки (с 1 по 3 строку, с A по G)\n",
|
||
" thin_side = Side(border_style=\"thin\", color=\"000000\")\n",
|
||
" border = Border(left=thin_side, right=thin_side, top=thin_side, bottom=thin_side)\n",
|
||
" for row in ws.iter_rows(min_row=3, max_row=4, min_col=1, max_col=max_col):\n",
|
||
" for cell in row:\n",
|
||
" # Центрируем все ячейки по горизонтали и вертикали, если текст в ячейке есть\n",
|
||
" if cell.value is not None:\n",
|
||
" cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)\n",
|
||
" # Устанавливаем рамку\n",
|
||
" cell.border = border\n",
|
||
"\n",
|
||
" # Сохраняем файл\n",
|
||
" wb.save(output_file)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"id": "4188dffe",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Функция форматирования файла Excel, выравнивание всех ячеек по центру и добавления первой строки с номером участка\n",
|
||
"from openpyxl import load_workbook\n",
|
||
"from openpyxl.styles import Alignment, Font, Border, Side\n",
|
||
"\n",
|
||
"def format_xlsx(xlsx, counter): # counter - текущий номер участка\n",
|
||
" # Открываем существующий файл\n",
|
||
" wb = load_workbook(xlsx)\n",
|
||
" ws = wb.active # или wb['SheetName']\n",
|
||
"\n",
|
||
" # Определяем размер текущей таблицы\n",
|
||
" min_row, max_row = ws.min_row, ws.max_row\n",
|
||
" min_col, max_col = ws.min_column, ws.max_column\n",
|
||
"\n",
|
||
"# УБРАЛ БЛОК ДОБАВЛЕНИЯ ПЕРВОЙ СТРОКИ С НОМЕРОМ УЧАСТКА, ТАК КАК В СИСТЕМУ МОЖНО ЗАГРУЖАТЬ ТОЛЬКО ПО ОДНОМУ УЧАСТКУ\n",
|
||
"# # Вставляем пустую первую строку\n",
|
||
"# ws.insert_rows(1)\n",
|
||
"# max_row += 1 # сдвигаем нижнюю границу таблицы вниз на 1, т.к. вставили строку\n",
|
||
"\n",
|
||
"# # Объединяем все ячейки первой строки в одну ячейку\n",
|
||
"# merge_range = f\"{ws.cell(row=1, column=min_col).coordinate}:\" \\\n",
|
||
"# f\"{ws.cell(row=1, column=max_col).coordinate}\"\n",
|
||
"# ws.merge_cells(merge_range)\n",
|
||
"\n",
|
||
"# header_cell = ws.cell(row=1, column=min_col)\n",
|
||
"# header_cell.value = \"Участок \" + str(counter)\n",
|
||
"# header_cell.font = Font(bold=True, size=11)\n",
|
||
"# header_cell.alignment = Alignment(horizontal='center', vertical='center')\n",
|
||
"\n",
|
||
"# # Устанавливаем высоту первой строки для читаемости\n",
|
||
"# ws.row_dimensions[1].height = 20\n",
|
||
"\n",
|
||
" # Создаем стиль тонкой рамки\n",
|
||
" thin_side = Side(border_style=\"thin\", color=\"000000\")\n",
|
||
" thin_border = Border(left=thin_side, right=thin_side, top=thin_side, bottom=thin_side)\n",
|
||
"\n",
|
||
" # Проходим по всем ячейкам таблицы (включая новую первую строку)\n",
|
||
" for row in ws.iter_rows(min_row=0, max_row=max_row, min_col=min_col, max_col=max_col):\n",
|
||
" for cell in row:\n",
|
||
" # Центрируем содержимое ячеек\n",
|
||
" if cell.value is not None:\n",
|
||
" cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)\n",
|
||
" # Устанавливаем тонкую рамку в каждую ячейку\n",
|
||
" cell.border = thin_border\n",
|
||
"\n",
|
||
" # Сохраняем в тот же файл\n",
|
||
" wb.save(xlsx)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"id": "7c5eb821",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Функция объединения 2+ файлов-участков от одного ООПТ \n",
|
||
"from openpyxl import load_workbook, Workbook\n",
|
||
"from openpyxl.styles import Font, PatternFill, Border, Alignment, Protection\n",
|
||
"\n",
|
||
"def copy_cell_style(src_cell, tgt_cell):\n",
|
||
" if src_cell.has_style:\n",
|
||
" tgt_cell.font = src_cell.font.copy()\n",
|
||
" tgt_cell.border = src_cell.border.copy()\n",
|
||
" tgt_cell.fill = src_cell.fill.copy()\n",
|
||
" tgt_cell.number_format = src_cell.number_format\n",
|
||
" tgt_cell.protection = src_cell.protection.copy()\n",
|
||
" tgt_cell.alignment = src_cell.alignment.copy()\n",
|
||
"\n",
|
||
"def concat_xlsx_with_style(files, output_file):\n",
|
||
" wb_new = Workbook()\n",
|
||
" ws_new = wb_new.active\n",
|
||
" ws_new.title = \"Угловые точки DD⁰MM'SS.SS\"\n",
|
||
" \n",
|
||
" current_row = 1\n",
|
||
" for idx, file in enumerate(files):\n",
|
||
" wb_src = load_workbook(file)\n",
|
||
" ws_src = wb_src.active\n",
|
||
" \n",
|
||
" min_row = 1 # Можно поменять на 2 для пропуска заголовков во 2-м и последующих файлах\n",
|
||
" \n",
|
||
" # Копируем значения и стили по строкам\n",
|
||
" for r in range(min_row, ws_src.max_row + 1):\n",
|
||
" for c in range(1, ws_src.max_column + 1):\n",
|
||
" src_cell = ws_src.cell(row=r, column=c)\n",
|
||
" tgt_cell = ws_new.cell(row=current_row, column=c)\n",
|
||
" tgt_cell.value = src_cell.value\n",
|
||
" copy_cell_style(src_cell, tgt_cell)\n",
|
||
" current_row += 1\n",
|
||
"\n",
|
||
" # Копируем объединённые ячейки (merged cells) с учётом сдвига строк\n",
|
||
" row_offset = current_row - (ws_src.max_row + 1)\n",
|
||
" for merged_range in ws_src.merged_cells.ranges:\n",
|
||
" start_row = merged_range.min_row + row_offset\n",
|
||
" end_row = merged_range.max_row + row_offset\n",
|
||
" start_col = merged_range.min_col\n",
|
||
" end_col = merged_range.max_col\n",
|
||
" \n",
|
||
" new_range = f\"{ws_src.cell(row=start_row, column=start_col).coordinate}:\" \\\n",
|
||
" f\"{ws_src.cell(row=end_row, column=end_col).coordinate}\"\n",
|
||
" try:\n",
|
||
" ws_new.merge_cells(new_range)\n",
|
||
" except Exception as e:\n",
|
||
" print(f\"Ошибка объединения: {new_range} - {e}\")\n",
|
||
"\n",
|
||
" # Копирование высоты строк с учётом сдвига\n",
|
||
" for r in range(min_row, ws_src.max_row + 1):\n",
|
||
" height = ws_src.row_dimensions[r].height\n",
|
||
" if height is not None:\n",
|
||
" ws_new.row_dimensions[r + row_offset].height = height\n",
|
||
"\n",
|
||
" wb_new.save(output_file)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"id": "41cb9036",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Функция добавления листа с координатной системой СК-2011 для добавления на сайт с геологической информацией https://efgi.ru/\n",
|
||
"from openpyxl import load_workbook\n",
|
||
"from openpyxl.utils import get_column_letter\n",
|
||
"\n",
|
||
"def add_cs(excel_path):\n",
|
||
" # Данные для записи\n",
|
||
" headers = [\"СК\", \"EPSG\", \"Код в Proj4\"]\n",
|
||
" values = [\n",
|
||
" \"ГСК-2011\",\n",
|
||
" 7683,\n",
|
||
" \"+proj=longlat +a=6378136.5 +rf=298.2564151 \"\n",
|
||
" \"+towgs84=0.013,-0.092,-0.03,-0.001738,0.003559,-0.004263,0.0074 +no_defs\"\n",
|
||
" ]\n",
|
||
"\n",
|
||
" # Загружаем книгу\n",
|
||
" wb = load_workbook(excel_path)\n",
|
||
" \n",
|
||
" # Если лист с именем \"СК\" существует - удаляем его (чтобы заменить)\n",
|
||
" if \"СК\" in wb.sheetnames:\n",
|
||
" del wb[\"СК\"]\n",
|
||
"\n",
|
||
" # Создаём новый лист \"СК\"\n",
|
||
" ws = wb.create_sheet(\"СК\")\n",
|
||
"\n",
|
||
" # Записываем заголовки в первую строку\n",
|
||
" for col_num, header in enumerate(headers, start=1):\n",
|
||
" cell = ws.cell(row=1, column=col_num, value=header)\n",
|
||
"\n",
|
||
" # Записываем данные во вторую строку\n",
|
||
" for col_num, value in enumerate(values, start=1):\n",
|
||
" ws.cell(row=2, column=col_num, value=value)\n",
|
||
" \n",
|
||
" # Сохраняем файл\n",
|
||
" wb.save(excel_path)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"id": "8d0cdc89",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Словарь с названиями районов и ООПТ\n",
|
||
"dic_oopt = {\n",
|
||
"'anp-anap-soch-skal_pp_orz-new_WGS84': 'Анапа_Анапские сочащиеся скалы',\n",
|
||
"'anp-stepi-balki-zozulina_pp_orz-new_WGS84': 'Анапа_Степи балки Зозулина',\n",
|
||
"'anp-bujor-kodzor-les_orz-new_WGS84': 'Анапа_ПП Бужоро-Кодзорский лес',\n",
|
||
"'anp-krasnogor-les_pp_orz-new_WGS84': 'Анапа_ПП Красногорский лес',\n",
|
||
"'anp-kumatyr-hrebet_zak_orz_WGS84': 'Анапа_ПП Куматырский лес',\n",
|
||
"'anp-shkurat-les_orz-new_WGS84': 'Анапа_ПП Шкуратский лес',\n",
|
||
"'anp-yug-gostag-les_orz-new_WGS84': 'Анапа_ПП Южно-Гостагаевскй лес',\n",
|
||
"'anp-kurb-bugor_pp_orz-new_WGS84': 'Анапа_ПП Курбацкие бугры',\n",
|
||
"'anp-chekon-redkoles_orz-new_WGS84': 'Анапа_ПП Чеконское редколесье',\n",
|
||
"'brh-vys-bereg-beysug_pp_orz-new_WGS84': 'Брюховецкий_район_ПП_Высокий берег реки Бейсуг',\n",
|
||
"'glj-gebeus-gorn-mass_zak_orz-new_WGS84': 'Геленджик_ПП_Гебеусский горный массив',\n",
|
||
"'glj-mojj-redkles-gor-neksis_pp_orz-new_WGS84': 'Геленджик_ПП_Можжевеловые редколесья хребта Нексис',\n",
|
||
"'esk-voronts-step_pp_orz-new_WGS84': 'Ейский район_Воронцовская степь',\n",
|
||
"'esk-kruglaya-pad_pp_orz-new_WGS84': 'Ейский район_Круглая падь',\n",
|
||
"'esk-hans-yasen_zak_orz-new_WGS84': 'Ейский район_Ханско-Ясенский заказник',\n",
|
||
"'esk-yasnopol-step_pp_orz-new_WGS84': 'Ейский район_Яснопольская_степь',\n",
|
||
"'kvk-obrivistiy-bereg-reki-kuban_pp_orz-new_WGS84': 'Кавказский и Тбилисск район_Обрывистый берег реки Кубань',\n",
|
||
"'kvk-temijbek-vysok-bereg_pp_orz-new_WGS84': 'Кавказский_район_ПП_Темижбекский высокий берег',\n",
|
||
"'knv-bolot-albashi_lpk_orz-new_WGS84': 'Каневской_район_ ЛПК Болото Албаши',\n",
|
||
"'knv-chelbas-plavn_lpk_orz-new_WGS84': 'Каневской_район_ЛПК Челбасские плавни',\n",
|
||
"'knv-nijn-beisug-plavn_lpk_orz-new_WGS84': 'Каневской_район_ЛПК Нижнебейсугские плавни',\n",
|
||
"'kln-ponur-les_pp-orz-new_WGS84': 'Калининский_район_ПП Понурский лес',\n",
|
||
"'kln-ponura-liman_lpk_orz-new_WGS84': 'Калининский_район_ЛПК Понурский лиман',\n",
|
||
"'krl-balk-irinovka+_pp_orz-new_WGS84': 'Крыловский_район_ПП_Балка Ириновка',\n",
|
||
"'krl-balk-krutaya_pp_orz-new_WGS84': 'Крыловский район_Балка Крутая в долине реки Ея',\n",
|
||
"'krl-gryadin-plavn-rek-eya_pp_orz-new_WGS84': 'Крыловский_район_ПП_Грядинские плавни реки Ея',\n",
|
||
"'krl-balk-irinovka+_pp_orz-new_WGS84': 'Крыловский_район_ПП_Балка Ириновка',\n",
|
||
"'krm-uroch_kovalenkova_baga_pp_orz-new_WGS84': 'Крымский район_Коваленкова бага',\n",
|
||
"'ksh-poltavskiy-ostanec_pp_orz-new_WGS84': 'Кущевский район_Полтавский останец степи в долине реки Эльбузд',\n",
|
||
"'ksh-uroch-alekseevskoe_pp_orz-new_WGS84': 'Кущевский район_Урочище Алексеевское',\n",
|
||
"'ksh-shalfey-step-rek-elbuzd_pp_orz-new_WGS84': 'Кущевский_район_ПП_Шалфеевая_степь',\n",
|
||
"'mst-besleneev-pesheri_pp_orz-new_WGS84': 'Мостовской_р-н_ПП_Пещера Бесленеевская',\n",
|
||
"'nvk-kutanskaya-step_pp_orz-new_WGS84': 'Успенск_Новокуб_Армавир_р-н_ПП_Кутанская степь',\n",
|
||
"'nvp-fedorenk-bugr_pp_orz-new_WGS84': 'Новопокровский_район_ПП_Федоренковы бугры',\n",
|
||
"'nvk-fortshtadt-nagorn-step_pp_orz-new_WGS84': 'Армавир_Новокубанск_р-н_ПП_Фортштадская степь',\n",
|
||
"'nvr-abrau_zak+_orz-new_WGS84': 'Новороссийск_Абраусский заказник',\n",
|
||
"'nvr-abrau_zak_orz-IZMENENIE_WGS84': 'Новороссийск_Абраусский заказник_расширение Щурова',\n",
|
||
"'nvr-atakay-markoth_zak_orz-new_WGS84': 'Новороссийск_Атакайско-Маркотхский',\n",
|
||
"'nvr-kovilskaya-step_pp_orz-new_WGS84': 'Новороссийск_Ковыльская_степь_хребта_Сенетх',\n",
|
||
"'nvr-petrof-step-hr-seneth_pp_orz-new_WGS84': 'Новороссийск_Петрофитные_степи_Гора Самбурова',\n",
|
||
"'otr-dzheltmesskie-vysoty_zak_orz-new_WGS84': 'Отрадненский район_Джельтмесские Высоты',\n",
|
||
"'otr-chehrak+_zak_orz-new_WGS84': 'Отрадненский район_заказник Чехрак',\n",
|
||
"'otr-chehrak+_zak_orz-IZMENENIE_WGS84': 'Отрадненский район_заказник Чехрак_изменения ООПТ',\n",
|
||
"'pvl-urch-mugan_pp_orz-new_WGS84': 'Павловский_район_ПП_Урочище Муган',\n",
|
||
"'svr-hrebet-dlinn-gor_prz_orz-new_WGS84': 'Cеверский_район_ПРЗ Хребет Длинная гора',\n",
|
||
"'sch-aibga-grushevn_pp_orz-new_WGS84': 'Сочи_ПП_Аибгинский грушевник',\n",
|
||
"'sch-mamay-lesopark_zak_orz-new_WGS84': 'Сочи_Мамайский лесопарк',\n",
|
||
"'sch-urch-dzhegosh_pp_orz-new_WGS84': 'Сочи_ПП_Урочище Джегош',\n",
|
||
"'tmr-urochische-strelka-yuzhnaya_pp_orz-new_WGS84': 'Темрюкский район_Урочище Стрелка Южная',\n",
|
||
"'tbl-tbiliss_visokiy_bereg_pp_orz-new_WGS84': 'Тбилисский_р-н_ПП_Тбилисский высокий берег',\n",
|
||
"'tbl-savk-kruch_pp_orz-new_WGS84': 'Тбилисский_р-н_ПП_Савкины кручи',\n",
|
||
"'tps-gebeus-gorn-mass_zak_orz-new_WGS84': 'Туапсинский район_ПП_Гебеусский горный массив',\n",
|
||
"'usp-stepnoy_zak++_orz-new_WGS84': 'Успенский_р-н_заказник Степной',\n",
|
||
"'usp-uspen-poim-les_zak_orz-new_WGS84': 'Успенский_Отрадн_р-н_ПП_Успенские пойменные леса',\n",
|
||
"'ulb-uch-lesostep-rek-2-zelench_pp_orz-new_WGS84': 'Усть-Лаб_р-н_ПП_Участки лесостепи на р. Зеленчук',\n",
|
||
"'ulb-urochische-ladozhskoe_pp_orz-new_WGS84': 'Усть-Лабинский район_Урочище Ладожское',\n",
|
||
"'ulb-urochische-pyatihatskoe_pp_orz-new_WGS84': 'Усть-Лабинский район_Урочище Пятихатское',\n",
|
||
"'shr-eisk-plavn_lpk_orz-new_WGS84': 'Щербиновский район_ЛПК Ейские плавни',\n",
|
||
"'shr-uroch-tureckaya-krepost_ppk_orz-new_WGS84': 'Щербиновский район_ППК Турецкая крепость',\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "39a10e18",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Начало обработки"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"id": "9730503b",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"['Input_processing\\\\tbl-tbiliss_visokiy_bereg_pp_orz-new_WGS84.shp', 'Input_processing\\\\Орнитологический Границы тропы.shp'] \n",
|
||
" Всего: 2 файл(-а, -ов)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"## Список файлов\n",
|
||
"folder = 'Input_processing' # папка для обработки\n",
|
||
"\n",
|
||
"lst = shp_lst(folder)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"id": "cfbad0f3",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:7: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.font = src_cell.font.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:8: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.border = src_cell.border.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:9: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.fill = src_cell.fill.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:11: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.protection = src_cell.protection.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:12: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.alignment = src_cell.alignment.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:7: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.font = src_cell.font.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:8: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.border = src_cell.border.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:9: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.fill = src_cell.fill.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:11: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.protection = src_cell.protection.copy()\n",
|
||
"C:\\Users\\Evgenii\\AppData\\Local\\Temp\\ipykernel_43168\\1470149036.py:12: DeprecationWarning: Call to deprecated function copy (Use copy(obj) or cell.obj = cell.obj + other).\n",
|
||
" tgt_cell.alignment = src_cell.alignment.copy()\n"
|
||
]
|
||
},
|
||
{
|
||
"ename": "KeyError",
|
||
"evalue": "'Орнитологический Границы тропы'",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
|
||
"Cell \u001b[1;32mIn[10], line 40\u001b[0m\n\u001b[0;32m 37\u001b[0m merge_lst\u001b[38;5;241m.\u001b[39minsert(\u001b[38;5;241m0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtemplate_gc.xlsx\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m 39\u001b[0m \u001b[38;5;66;03m# Имя из словаря со списком район+ООПТ по имени shape-файла\u001b[39;00m\n\u001b[1;32m---> 40\u001b[0m final_name \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mКоординаты_\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;241m+\u001b[39m \u001b[43mdic_oopt\u001b[49m\u001b[43m[\u001b[49m\u001b[43mshp_name\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_Участок_\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(counter) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.xlsx\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[0;32m 42\u001b[0m \u001b[38;5;66;03m# Объединяем все файлы из списка с сохранением исходного форматирования (функция)\u001b[39;00m\n\u001b[0;32m 43\u001b[0m concat_xlsx_with_style(merge_lst, final_name)\n",
|
||
"\u001b[1;31mKeyError\u001b[0m: 'Орнитологический Границы тропы'"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"# Пакетная обработка\n",
|
||
"for shp in lst:\n",
|
||
" # Считываем файл\n",
|
||
" gdf = gpd.read_file(shp) \n",
|
||
" gdf = gdf.to_crs(7683) # Переводим в ГСК-2011\n",
|
||
" # Извлекаем имя файла\n",
|
||
" shp_name = os.path.basename(shp).split('.')[0]\n",
|
||
" # Счетчик для сохранения разных участков одной ООПТ\n",
|
||
" counter = 0\n",
|
||
" \n",
|
||
" # Превращаем возможных мултисоставной объект (multipart) в односоставной (singlepart)\n",
|
||
" gdf = gdf.explode(index_parts=False).reset_index(drop=True)\n",
|
||
" \n",
|
||
" # Создает список фреймов из каждой объекта (если многосоставной) \n",
|
||
" list_of_single_row_gdfs = [gdf.iloc[[i]] for i in range(len(gdf))]\n",
|
||
"\n",
|
||
" \n",
|
||
" for el in list_of_single_row_gdfs:\n",
|
||
" # Счетчик для номера участка внутри одного шейпа\n",
|
||
" counter += 1\n",
|
||
" merge_lst = []\n",
|
||
" # Вызов функции для расчета и форматирования координат\n",
|
||
" df = coordinates(el)\n",
|
||
" \n",
|
||
" name_xlsx = shp_name + '.xlsx'\n",
|
||
" df.to_excel(name_xlsx, header=False, index=False)\n",
|
||
" \n",
|
||
" # Форматируем файл через функцию\n",
|
||
" format_xlsx(name_xlsx, counter) \n",
|
||
" merge_lst.append(name_xlsx)\n",
|
||
" \n",
|
||
" # Создаем шапку для таблицы (функция), если файл не существует\n",
|
||
" if not os.path.exists('template_gc.xlsx'):\n",
|
||
" template_gc('template_gc.xlsx') \n",
|
||
" \n",
|
||
" # Добавлеем шапку таблицы в список файлов для обработки под номером 0\n",
|
||
" merge_lst.insert(0, 'template_gc.xlsx')\n",
|
||
" \n",
|
||
" # Имя из словаря со списком район+ООПТ по имени shape-файла\n",
|
||
" final_name = str('Координаты_') + dic_oopt[shp_name] + \"_Участок_\" + str(counter) + '.xlsx'\n",
|
||
" \n",
|
||
" # Объединяем все файлы из списка с сохранением исходного форматирования (функция)\n",
|
||
" concat_xlsx_with_style(merge_lst, final_name)\n",
|
||
" \n",
|
||
" # Добавляем второй лист с параметрами преобразования координат для геологического сервиса\n",
|
||
" add_cs(final_name)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "41efeb91",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 4. Поворотные точки с 3 координатными системами (WGS84, МСК23, ГСК2011) - АНАПСКАЯ ПЕРЕСЫПЬ"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 56,
|
||
"id": "1393e5ee",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import geopandas as gpd\n",
|
||
"import pandas as pd\n",
|
||
"from os.path import splitext\n",
|
||
"import os"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 57,
|
||
"id": "c264ba85",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Функция создания списка шейпфайлов для обработки\n",
|
||
"def shp_lst(folder):\n",
|
||
" lst = []\n",
|
||
" for file in os.listdir(folder):\n",
|
||
" if file.endswith(\".shp\"):\n",
|
||
" lst.append(os.path.join(folder, file))\n",
|
||
" print(lst[:2], '\\n', f'Всего: {len(lst)} файл(-а, -ов)')\n",
|
||
" return lst\n",
|
||
"\n",
|
||
"### Функция создания таблицы с коодинатными системами\n",
|
||
"# Извлекаем имя файла\n",
|
||
"def coord_crs(shp):\n",
|
||
" shp_name = os.path.splitext(os.path.basename(shp))[0]\n",
|
||
" gdf = gpd.read_file(shp)\n",
|
||
" \n",
|
||
" # WGS84\n",
|
||
" gdf1 = gdf.to_crs(4326)\n",
|
||
" # Извлекаем координаты вертексов полигона (формат X, Y в текущей координатной системе)\n",
|
||
" df1 = gdf1.get_coordinates()\n",
|
||
" # Добавляем индекс к таблице\n",
|
||
" df1.reset_index(inplace = True, drop = True)\n",
|
||
" # Первая строка с 1\n",
|
||
" df1.index += 1\n",
|
||
" df1 = df1.reset_index()\n",
|
||
" df1 = round(df1,6)\n",
|
||
" df1.columns = ['N', 'Dolgota_X_WGS84', 'Shirota_Y_WGS84', ]\n",
|
||
" df1 = df1[['N', 'Shirota_Y_WGS84', 'Dolgota_X_WGS84']]\n",
|
||
"\n",
|
||
" #MSK23\n",
|
||
" gdf2 = gdf.to_crs(msk23_1)\n",
|
||
" df2 = gdf2.get_coordinates()\n",
|
||
" # Добавляем индекс к таблице\n",
|
||
" df2.reset_index(inplace = True, drop = True)\n",
|
||
" # Первая строка с 1\n",
|
||
" df2.index += 1\n",
|
||
" df2 = df2.reset_index()\n",
|
||
" # Округляем\n",
|
||
" df2 = round(df2)\n",
|
||
" df2.columns = ['N', 'Dolgota_X_MSK23', 'Shirota_Y_MSK23', ]\n",
|
||
" df2 = df2[['N', 'Shirota_Y_MSK23', 'Dolgota_X_MSK23']]\n",
|
||
"\n",
|
||
" #GSK2011\n",
|
||
" gdf3 = gdf.to_crs(7683)\n",
|
||
" df3 = gdf3.get_coordinates()\n",
|
||
" # Добавляем индекс к таблице\n",
|
||
" df3.reset_index(inplace = True, drop = True)\n",
|
||
" # Первая строка с 1\n",
|
||
" df3.index += 1\n",
|
||
" df3 = df3.reset_index()\n",
|
||
" df3 = round(df3,6)\n",
|
||
" df3.columns = ['N', 'Dolgota_X_GSK2011', 'Shirota_Y_GSK2011',]\n",
|
||
" df3 = df3[['N', 'Shirota_Y_GSK2011','Dolgota_X_GSK2011']]\n",
|
||
"\n",
|
||
" # Объединение таблиц с координатами (df1 и df2)\n",
|
||
" df1 = df1.merge(df2,left_on='N', right_on='N')\n",
|
||
" df1 = df1.merge(df3,left_on='N', right_on='N')\n",
|
||
" # Добавляем в конец дубликат первой строки\n",
|
||
" df1 = df1.take(list(range(len(df1) - 1)) + [0])\n",
|
||
" # Файлы Excel помещаются в папку скрипта с именем исходном файла\n",
|
||
" df1.to_excel(shp_name + '.xlsx', index=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 58,
|
||
"id": "5ba0c820",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Считываем проекцию в формате WKT и сохраняем ее в переменной\n",
|
||
"from pyproj import CRS\n",
|
||
"with open(r'F:\\PROJECT-Colormap\\Преобразования географических проекций (СК, ГСК-2011, МСК)\\МСК23 проекции Краснодар\\MCK-23_Zone_1N.prj', 'r') as f:\n",
|
||
" #wkt = f.read()\n",
|
||
" msk23_1 = f.read()\n",
|
||
"# crs = CRS.from_wkt(wkt)\n",
|
||
"\n",
|
||
"with open(r'F:\\PROJECT-Colormap\\Преобразования географических проекций (СК, ГСК-2011, МСК)\\МСК23 проекции Краснодар\\MCK-23_Zone_2N.prj', 'r') as f:\n",
|
||
" msk23_2 = f.read()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 59,
|
||
"id": "b2077b77",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"['Input_processing\\\\Орнитологический Границы тропы.shp'] \n",
|
||
" Всего: 1 файл(-а, -ов)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"## Список файлов\n",
|
||
"folder = 'Input_processing' # папка для обработки\n",
|
||
"\n",
|
||
"lst = shp_lst(folder)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 60,
|
||
"id": "f97e8123",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Обработка \n",
|
||
"for shp in lst:\n",
|
||
" coord_crs(shp)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "e5e45902",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Тоже, что и выше, но создают для каждого элемента в шейпе отдельный файл Excel и название файла по номеру кад. участка (делал через Perplexity)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 55,
|
||
"id": "1627e21e",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"['Input_processing\\\\selected_cad_numbers.shp'] \n",
|
||
" Всего: 1 файл(-а, -ов)\n",
|
||
"Готово: selected_cad_numbers -> Output_excel\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"\n",
|
||
"\n",
|
||
"import geopandas as gpd\n",
|
||
"import pandas as pd\n",
|
||
"from os.path import splitext, basename, join\n",
|
||
"import os\n",
|
||
"from pyproj import CRS\n",
|
||
"\n",
|
||
"# ---------- Настройки ----------\n",
|
||
"INPUT_FOLDER = 'Input_processing' # папка для обработки\n",
|
||
"OUTPUT_FOLDER = 'Output_excel' # куда сохранять Excel\n",
|
||
"CAD_FIELD = 'cad_number' # имя столбца с кадастровым номером\n",
|
||
"MSK23_WKT_FILE = r'F:\\PROJECT-Colormap\\Преобразования географических проекций (СК, ГСК-2011, МСК)\\МСК23 проекции Краснодар\\MCK-23_Zone_1N.prj'\n",
|
||
"\n",
|
||
"# ---------- Вспомогательные ----------\n",
|
||
"def ensure_dir(path):\n",
|
||
" os.makedirs(path, exist_ok=True)\n",
|
||
"\n",
|
||
"def shp_lst(folder):\n",
|
||
" lst = [os.path.join(folder, f) for f in os.listdir(folder) if f.lower().endswith(\".shp\")]\n",
|
||
" print(lst[:2], '\\n', f'Всего: {len(lst)} файл(-а, -ов)')\n",
|
||
" return lst\n",
|
||
"\n",
|
||
"def load_wkt(path):\n",
|
||
" with open(path, 'r', encoding='utf-8') as f:\n",
|
||
" return f.read()\n",
|
||
"\n",
|
||
"# ---------- Основная функция ----------\n",
|
||
"def export_features_to_excels(shp, msk23_wkt, output_dir=OUTPUT_FOLDER, cad_field=CAD_FIELD):\n",
|
||
" ensure_dir(output_dir)\n",
|
||
" shp_name = os.path.splitext(os.path.basename(shp))[0]\n",
|
||
" gdf = gpd.read_file(shp)\n",
|
||
"\n",
|
||
" if cad_field not in gdf.columns:\n",
|
||
" print(f'WARNING: {cad_field} не найден в {shp_name}. Будут использованы имена по индексу.')\n",
|
||
"\n",
|
||
" # Преобразования систем координат заранее\n",
|
||
" gdf_wgs = gdf.to_crs(4326) # WGS84\n",
|
||
" gdf_msk = gdf.to_crs(msk23_wkt) # MSK23 WKT\n",
|
||
" gdf_gsk = gdf.to_crs(7683) # GSK2011 / EPSG:7683\n",
|
||
"\n",
|
||
" # Проходим по каждому объекту\n",
|
||
" for i, (wgs_geom, msk_geom, gsk_geom, row) in enumerate(zip(gdf_wgs.geometry, gdf_msk.geometry, gdf_gsk.geometry, gdf.itertuples(index=False))):\n",
|
||
" # Имя файла\n",
|
||
" base_name = getattr(row, cad_field) if cad_field in gdf.columns else f'{shp_name}_feat_{i+1}'\n",
|
||
" base_name = str(base_name).replace(':', '_')\n",
|
||
"\n",
|
||
" # Собираем координаты вершин полигона/мультиполигона\n",
|
||
" def coords_as_df(geom, x_name, y_name, round_ndigits=None, round0=False):\n",
|
||
" # Разворачиваем в список колец\n",
|
||
" def extract_rings(g):\n",
|
||
" if g is None or g.is_empty:\n",
|
||
" return []\n",
|
||
" if g.geom_type == 'Polygon':\n",
|
||
" return [g.exterior] + list(g.interiors)\n",
|
||
" if g.geom_type == 'MultiPolygon':\n",
|
||
" rings = []\n",
|
||
" for p in g.geoms:\n",
|
||
" rings.append(p.exterior)\n",
|
||
" rings.extend(list(p.interiors))\n",
|
||
" return rings\n",
|
||
" # Для LineString/Point fallback\n",
|
||
" return [g]\n",
|
||
" pts = []\n",
|
||
" for ring in extract_rings(geom):\n",
|
||
" for x, y in ring.coords:\n",
|
||
" pts.append((y, x)) # хотим сначала Y, потом X\n",
|
||
" df = pd.DataFrame(pts, columns=[y_name, x_name]).reset_index(drop=True)\n",
|
||
" df.index += 1\n",
|
||
" df.insert(0, 'N', df.index)\n",
|
||
" if round0:\n",
|
||
" df[[y_name, x_name]] = df[[y_name, x_name]].round(0)\n",
|
||
" elif round_ndigits is not None:\n",
|
||
" df[[y_name, x_name]] = df[[y_name, x_name]].round(round_ndigits)\n",
|
||
" # Добавляем дубликат первой строки в конец\n",
|
||
" if len(df) > 0:\n",
|
||
" first_row = df.iloc[[0]].copy()\n",
|
||
" df = pd.concat([df.iloc[:-1], first_row], ignore_index=True)\n",
|
||
" df.index += 1\n",
|
||
" df['N'] = df.index\n",
|
||
" return df\n",
|
||
"\n",
|
||
" df_wgs = coords_as_df(wgs_geom, 'Dolgota_X_WGS84', 'Shirota_Y_WGS84', round_ndigits=6)\n",
|
||
" df_msk = coords_as_df(msk_geom, 'Dolgota_X_MSK23', 'Shirota_Y_MSK23', round0=True)\n",
|
||
" df_gsk = coords_as_df(gsk_geom, 'Dolgota_X_GSK2011', 'Shirota_Y_GSK2011', round_ndigits=6)\n",
|
||
"\n",
|
||
" # Объединяем по N\n",
|
||
" df = df_wgs.merge(df_msk, on='N', how='outer').merge(df_gsk, on='N', how='outer')\n",
|
||
"\n",
|
||
" # Сохраняем в Excel\n",
|
||
" out_path = os.path.join(output_dir, f'{base_name}.xlsx')\n",
|
||
" df.to_excel(out_path, index=False)\n",
|
||
"\n",
|
||
" print(f'Готово: {shp_name} -> {output_dir}')\n",
|
||
"\n",
|
||
"# ---------- Инициализация ----------\n",
|
||
"msk23_wkt = load_wkt(MSK23_WKT_FILE)\n",
|
||
"\n",
|
||
"# ---------- Запуск ----------\n",
|
||
"for shp in shp_lst(INPUT_FOLDER):\n",
|
||
" export_features_to_excels(shp, msk23_wkt)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "90e191f7",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 5. Преобразование в MapInfo"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "afff19d6",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import geopandas as gpd\n",
|
||
"import pandas as pd\n",
|
||
"from os.path import splitext\n",
|
||
"import os\n",
|
||
"\n",
|
||
"# Функция создания списка шейпфайлов для обработки\n",
|
||
"def shp_lst(folder):\n",
|
||
" lst = []\n",
|
||
" for file in os.listdir(folder):\n",
|
||
" if file.endswith(\".shp\"):\n",
|
||
" lst.append(os.path.join(folder, file))\n",
|
||
" print(lst[:2], '\\n', f'Всего: {len(lst)} файл(-а, -ов)')\n",
|
||
" return lst\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 48,
|
||
"id": "76cbf432",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"### Перевод в MapInfo\n",
|
||
"folder = 'Output'\n",
|
||
"for shp in lst:\n",
|
||
" shp_name = os.path.splitext(os.path.basename(shp))[0]\n",
|
||
" gdf = gpd.read_file(shp)\n",
|
||
" gdf.to_file(folder + '\\\\' + shp_name, driver='MapInfo File')"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.14.3"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|