/
Rpg.py
160 lines (128 loc) · 6.49 KB
/
Rpg.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of PHYMOBAT 1.2.
# Copyright 2016 Sylvio Laventure (IRSTEA - UMR TETIS)
#
# PHYMOBAT 1.2 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PHYMOBAT 1.2 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PHYMOBAT 1.2. If not, see <http://www.gnu.org/licenses/>.
import sys, os
import numpy as np
from Vector import Vector
try :
import ogr
except :
from osgeo import ogr
from collections import *
class Rpg(Vector):
"""
Vector class inherits the super vector class properties. This class create a new RPG shapefile
with mono-crops. It needs a basic RPG shapefile and a basic RPG CSV file *(...-GROUPES-CULTURE...)* in :func:`mono_rpg`.
:param vector_used: Input/Output shapefile to clip (path)
:type vector_used: str
:param vector_cut: Area shapefile (path)
:type vector_cut: str
:param rm_dupli: Rpg table with no duplicated crops group
:type rm_dupli: dict
:param head_in_read: List of rgp header
:type head_in_read: list of str
:param min_size: Minimum size to extract a rpg polygons
:type min_size: float
"""
def __init__(self, used, cut):
"""Create a new 'Rpg' instance
"""
Vector.__init__(self, used, cut)
self.rm_dupli = defaultdict(list)
self.head_in_read = []
self.min_size = 1
def create_new_rpg_files(self):
"""
Function to create new rpg shapefile with **rm_dpli** variable. The output shapefile
will be create in the same folder than the input shapefile with prefix *MONO_*.
"""
## The output shapefile if it exists
self.vector_used = os.path.split(self.vector_used)[0] + '/' + 'MONO_' + os.path.split(self.vector_used)[1].split('-')[2]
if not os.path.exists(self.vector_used):
shp_ogr = self.data_source.GetLayer()
# Projection
# Import input shapefile projection
srsObj = shp_ogr.GetSpatialRef()
# Conversion to syntax ESRI
srsObj.MorphToESRI()
# Create output file
out_ds = self.data_source.GetDriver().CreateDataSource(self.vector_used)
if out_ds is None:
print('Could not create file')
sys.exit(1)
# Specific output layer
out_layer = out_ds.CreateLayer(str(self.vector_used), srsObj, geom_type=ogr.wkbMultiPolygon)
# Add existing fields
for i in range(0, len(self.head_in_read)):
fieldDefn = ogr.FieldDefn(self.head_in_read[i], ogr.OFTString)
out_layer.CreateField(fieldDefn)
# Feature for the ouput shapefile
featureDefn = out_layer.GetLayerDefn()
in_feature = shp_ogr.SetNextByIndex(0) # Polygons initialisation
in_feature = shp_ogr.GetNextFeature()
# Loop on input polygons to create a output polygons
while in_feature:
id_rpg = str(in_feature.GetField(self.field_names[0]))
# Create a existing polygons in modified rpg list
# with minimum size greater than or equal to 1 ha
try:
if self.rm_dupli[id_rpg] and float(self.rm_dupli[id_rpg][2].replace(',','.')) >= self.min_size:
# Add .replace(',','.') if the input RPG contains comma instead of point
geom = in_feature.GetGeometryRef() # Extract input geometry
# Create a new polygon
out_feature = ogr.Feature(featureDefn)
# Set the polygon geometry and attribute
out_feature.SetGeometry(geom)
for i in range(0, len(self.head_in_read)):
out_feature.SetField(self.head_in_read[i], self.rm_dupli[id_rpg][i])
# Append polygon to the output shapefile
out_layer.CreateFeature(out_feature)
# Destroy polygons
out_feature.Destroy()
in_feature.Destroy()
except:
pass
# Next polygon
in_feature = shp_ogr.GetNextFeature()
# Close data
out_ds.Destroy()
def mono_rpg(self):
"""
Function to extract no duplicated crops.
"""
# Table from the RPG input shapefile name
file_tab = os.path.split(self.vector_used)[1].split('-')[len(os.path.split(self.vector_used)[1].split('-'))-1].split('_')
# Define the input csv file from RPG input shapefile
myfile = os.path.split(self.vector_used)[0] + '/' + file_tab[0] + '-' + file_tab[1] + '-GROUPES-CULTURE_' + file_tab[2] +\
'_' + file_tab[3][:-3] + 'csv'
my_file = open(myfile, "r")
in_read = []
for l in my_file.readlines():
in_read.append(l.split("\n")[0].split(";"))
# Fields name
for y in in_read[0]:
if len(y) < 11: # Field names shapefile has to be < 10 charaters
self.head_in_read.append(y)
else:
self.head_in_read.append(y[:10])
body_in_read = map(list, zip(*in_read[1:])) # Transpose table [[e,e,e],[a,a,a]] -> [[e,a],[e,a],[e,a]]
# self.rm_dupli = [[x, body_in_read[1][body_in_read[0].index(x)], body_in_read[2][body_in_read[0].index(x)]] \
# for x in body_in_read[0] if body_in_read[0].count(x) == 1]
for x in body_in_read[0]:
if body_in_read[0].count(x) == 1:
self.rm_dupli[x] = [x, body_in_read[1][body_in_read[0].index(x)], body_in_read[2][body_in_read[0].index(x)]]