# -*- coding: utf-8 -*-
import geopandas as gpd
from shapely.geometry import Point, Polygon
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QComboBox, QFileDialog, QMessageBox, QLineEdit
class ShpConverter(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.shp_file_path = ""
self.fields = []
def initUI(self):
# 创建布局
main_layout = QVBoxLayout()
# 选择 SHP 文件部分
select_file_layout = QHBoxLayout()
self.select_file_button = QPushButton('选择 SHP 文件')
self.select_file_button.clicked.connect(self.select_shp_file)
self.file_path_textbox = QLineEdit()
self.file_path_textbox.setReadOnly(True)
self.file_path_textbox.setFixedWidth(300) # 固定文本框宽度为 300 像素
select_file_layout.addWidget(self.select_file_button)
select_file_layout.addWidget(self.file_path_textbox)
main_layout.addLayout(select_file_layout)
# 字段选择部分
fields = ['面积字段', '地块名称字段', '工业区名称字段', '图幅号字段', '地块用途字段', '地类编码字段']
self.field_vars = []
for field in fields:
field_layout = QHBoxLayout()
field_label = QLabel(field)
field_combo = QComboBox()
self.field_vars.append(field_combo)
field_layout.addWidget(field_label)
field_layout.addWidget(field_combo)
main_layout.addLayout(field_layout)
# 转换按钮
self.convert_button = QPushButton('转换')
self.convert_button.clicked.connect(self.convert_shp)
self.convert_button.setEnabled(False)
main_layout.addWidget(self.convert_button)
self.setLayout(main_layout)
self.setWindowTitle('SHP 转换工具')
self.show()
def select_shp_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, '选择 SHP 文件', '', 'Shapefile (*.shp)')
if file_path:
self.shp_file_path = file_path
self.file_path_textbox.setText(f'选择的 SHP 文件路径: {file_path}')
try:
gdf = gpd.read_file(file_path)
self.fields = list(gdf.columns)
for combo in self.field_vars:
combo.clear()
combo.addItems(self.fields)
self.convert_button.setEnabled(True)
except Exception as e:
QMessageBox.critical(self, '错误', f'读取 SHP 文件时出错: {e}')
def convert_shp(self):
if not self.shp_file_path:
QMessageBox.critical(self, '错误', '请选择 SHP 文件')
return
area_field = self.field_vars[0].currentText()
project_id_field = self.field_vars[1].currentText()
project_mc_field = self.field_vars[2].currentText()
project_tf_field = self.field_vars[3].currentText()
project_yt_field = self.field_vars[4].currentText()
project_bm_field = self.field_vars[5].currentText()
if not all([area_field, project_id_field, project_mc_field, project_tf_field, project_yt_field, project_bm_field]):
QMessageBox.critical(self, '错误', '请选择所有必要的字段')
return
try:
# 读取 SHP 文件
gdf = gpd.read_file(self.shp_file_path)
# 准备输出内容
output_lines = []
# 添加属性描述部分
attributes = {
"格式版本号": "1.01 版本",
"数据产生单位": "自然资源部",
"数据产生日期": "2024-4-9",
"坐标系": "2000 国家大地坐标系",
"几度分带": "3",
"投影类型": "高斯克吕格",
"计量单位": "米",
"带号": "40",
"精度": "0.0001",
"转换参数": "0,0,0,0,0,0,0",
}
output_lines.append("[属性描述]")
for key, value in attributes.items():
output_lines.append(f"{key}={value}")
# 添加地块坐标部分
output_lines.append("[地块坐标]")
for _, row in gdf.iterrows():
polygon = row.geometry
coordinates = list(row.geometry.exterior.coords) # 获取多边形的外部坐标
interior_coords = [list(interior.coords) for interior in polygon.interiors]
wb = 0
for j in interior_coords:
wb += len(j)
area = row[area_field]
project_id = row[project_id_field]
project_mc = row[project_mc_field]
project_tf = row[project_tf_field]
project_yt = row[project_yt_field]
project_bm = row[project_bm_field]
output_lines.append(f"{len(coordinates) + wb},{area},{project_id},{project_mc},面,{project_tf},{project_yt},{project_bm},@")
for i, (x, y) in enumerate(coordinates):
if i == 0:
output_lines.append(f"{{{i + 1},1,{y:.4f},{x:.4f}")
else:
output_lines.append(f"{i + 1},1,{y:.4f},{x:.4f}")
output_lines.append(f"{1},1,{coordinates[0][1]:.4f},{coordinates[0][0]:.4f}}}")
if len(interior_coords) != 0:
n = 2
for m in interior_coords:
for i, (x, y) in enumerate(m):
if i == 0:
output_lines.append(f"{{{i + 1},{n},{y:.4f},{x:.4f}")
else:
output_lines.append(f"{i + 1},{n},{y:.4f},{x:.4f}")
output_lines.append(f"{1},{n},{coordinates[0][1]:.4f},{coordinates[0][0]:.4f}}}")
n += 1
# 写入 TXT 文件
output_file = "界址点坐标文件.txt"
with open(output_file, "w") as f:
for line in output_lines:
f.write(line + "\n")
QMessageBox.information(self, '完成', f'转换完成,结果保存在 {output_file}')
except Exception as e:
QMessageBox.critical(self, '错误', f'转换过程中出错: {e}')
if __name__ == '__main__':
app = QApplication(sys.argv)
converter = ShpConverter()
sys.exit(app.exec_())
通过以上代码可以生成标准格式的txt文件。