-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshp2csv_points_add_proj.py
executable file
·94 lines (71 loc) · 3.22 KB
/
shp2csv_points_add_proj.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/python3
"""
@brief:
Convertir un fichier shp (de type POINT) en un fichier CSV
X, Y, ...fields...
"""
#TODO: avec et sans Z? force...
import csv
import fiona
import sys
from shapely.geometry import Point, MultiPoint, LineString
import shapely.affinity as aff
from common.arg_command_line import myargparse
parser = myargparse(description=__doc__, add_args=['force'])
parser.add_argument("inname", help="fichier d'entrée shp (semis de points avec ou sans Z)")
parser.add_argument("outname", help="fichier de sortie csv (X, Y, Z, ...fields...)")
parser.add_argument("--digits", type=int, help="nombre de chiffres significatifs des flottants", default=4)
parser.add_argument("--sep", help="séparateur de colonnes", default=';')
parser.add_argument("--shift", type=float, nargs=2, help="décalage en X et Y (en mètre)")
parser.add_argument("--add_proj", help="fichier shp avec une polyligne")
args = parser.parse_args()
FIELD = 'Absc_proj'
if args.add_proj is not None:
with fiona.open(args.add_proj, 'r') as filein:
for i, elem in enumerate(filein):
profil_long = LineString(elem['geometry']['coordinates'])
if i != 0:
raise NotImplementedError("Une seule polyligne pour add_proj est attendue !")
with fiona.open(args.inname, 'r') as filein:
with open(args.outname, 'w', newline='') as csvfile:
csvwriter = csv.writer(csvfile, delimiter=args.sep)
def write_single_point(coords, properties):
"""Write a single point (dict from fiona)"""
global first
geom_point = Point(coords)
if args.add_proj is not None:
absc_proj = profil_long.project(geom_point)
if absc_proj<= 0 or absc_proj >= profil_long.length:
absc_proj = -1. # HARDCODED default value (NaN?)
if first:
# Write header
fields = ['X', 'Y']
if len(coords) == 3:
fields.append('Z')
fields = fields + [key for key, value in properties.items()]
if args.add_proj is not None:
fields.append(FIELD)
csvwriter.writerow(fields)
first = False
if args.shift is not None:
geom_point = aff.translate(geom_point, xoff=args.shift[0], yoff=args.shift[1])
row = [round(x, args.digits) for x in list(geom_point.coords)[0]] + [value for key, value in properties.items()]
if args.add_proj is not None:
row.append(absc_proj)
csvwriter.writerow(row)
first = True
for point in filein:
geom = point['geometry']
properties = point['properties']
if geom is None:
sys.exit("Object is a None type")
else:
type = geom['type']
coords = geom['coordinates']
if type == 'Point':
write_single_point(coords, properties)
elif type == 'MultiPoint':
for coord in coords:
write_single_point(coords, properties)
else:
sys.exit("ERREUR: L'objet '{}' n'est un semis de point".format(type))