之前想用GEE做机器学习地物分类,具体是根据矢量样本点位置下的光谱值进行分类,但是发现类别标签是中文,GEE不支持,所以需要做中-英文映射。
ArcMap和GEE Javascript不好用,还是python习惯点:
import os
import shapefile
import pandas as pd
import pyproj
## 适用于点数据字段名替换的python文件
# 脚本路径
this_path = os.path.dirname(__file__)
print(this_path) # E:\files\PyProjects\gis\samples\new
# 原有shp文件路径
sample_dir = os.path.join(this_path, '目视样本_1', "目视样本", '目视样本.shp')
# 新写入shp文件路径
new_shp_dir = os.path.join(this_path, 'view_sample', 'new_samples.shp')
# 读shp,检查
file = shapefile.Reader(sample_dir)
print(str(file.shapeType)) # 输出shp类型
print(file.encoding) # 输出shp文件编码
print(file.bbox) # 输出shp的文件范围(外包矩形)
print(file.numRecords) # 输出shp文件的要素数据
print(file.fields) # 输出所有字段信息
reasonable_bbox = [file.bbox[0], file.bbox[1], file.bbox[2], file.bbox[3]]
# 定义中英文映射
# mapping = {
# '0060':'0060',
# '旱柳':'drought_willow',
# '杞柳':'basket_willow',
# '柽柳': 'tamarisk',
# '盐地碱蓬': 'nitraria',
# '碱蓬': 'alkali_seepweed',
# '芦苇': 'reed',
# '芦苇、盐地碱蓬、柽柳群落': 'reed_nitraria_tamarisk',
# '芦苇、盐地碱蓬群落': 'reed_nitraria',
# '荻': 'wild_rice_stem',
# }
# 定义中文-数字映射
mapping = {
'0060':0,
'旱柳':1,
'杞柳':2,
'柽柳':3,
'盐地碱蓬':4,
'碱蓬':5,
'芦苇': 6,
'芦苇、盐地碱蓬、柽柳群落': 7,
'芦苇、盐地碱蓬群落':8,
'荻':9,
}
# 选择映射字段名
field_name = 'class'
# 转换
new_records = []
# for record in file.records():
# class_cn = record[field_name]
# # print(class_cn, '\t', mapping[class_cn])
# if class_cn in mapping:
# record[field_name] = mapping[class_cn]
# # print(record[field_name])
# new_records.append(record)
new_shapes = []
def is_point_within_bbox(point, bbox):
x, y = point
return bbox[0] <= x <= bbox[2] and bbox[1] <= y <= bbox[3]
for record, shape in zip(file.records(), file.shapes()):
class_cn = record['class']
if class_cn in mapping:
record['class'] = mapping[class_cn]
new_points = [point for point in shape.points if is_point_within_bbox(point, reasonable_bbox)]
if new_points:
new_shape = shapefile.Shape(shapeType=shape.shapeType)
new_shape.points = new_points
new_shapes.append(new_shape)
new_records.append(record)
new_file = shapefile.Writer(new_shp_dir)
new_file.fields = file.fields[1:] # 跳过删除字段 'DeletionFlag'
# 设置新的shapefile的范围(bbox)
# new_file.bbox = file.bbox
# 添加更新后的记录
for record in new_records:
new_file.record(*record)
# 复制原来的shapes
for shape in new_shapes:
new_file.shape(shape)
# 读取空间参考
prj_file = sample_dir.replace('.shp', '.prj')
with open(prj_file, 'r') as prj:
spatial_ref = prj.read()
with open(new_shp_dir.replace('.shp', '.prj'), 'w') as new_prj:
new_prj.write(spatial_ref)
new_file.close()
# 检验
new = shapefile.Reader(new_shp_dir)
print(new.bbox)
print(file.bbox)
重点还是在保留空间参考上,费了好大功夫