def __init__(self, file_name): # ~~> possibly empty i2s InS.__init__(self, file_name) # TODO: You may need to account for the fact that more than one polygon # is an outside domain boundary # ~~> sort out by the area to build the order map self.sort_by_areas() # ~~> make the first / larger polygon anti-clockwise self.make_anti_clockwise(select=[0]) # ~~> make the other polygons clockwise self.make_clockwise(select=range(len(self.poly))[1:]) # ~~> initialisasing counters self.ipoin = [0] self.iline = [0] self.iloop = [0] self.isurf = [0]
def parse_content(self, file_name): # file parsing is based on the name of the extension _, tail = path.splitext(file_name) # ~~> Case of a Kenue type i2s/i3s file if tail in ['.i2s', '.i3s']: self.object = InS(file_name) self.npoly = self.object.npoly # ~~> Case of a Arc-GIS type shap file (which comes with additional # related files) #elif tail == '.shp': # head, fileType, self.npoin, self.poly, self.vals, self.type, \ # self.atrbut = getShp(self.file_name) # ~~> Sort out the poly types for ipoly in range(self.object.npoly): if self.object.type[ipoly] > 0: if is_clockwise(self.object.poly[ipoly]): self.object.type[ipoly] = 1 else: self.object.type[ipoly] = 2 return self.object.head
def main(): """ Main function of parserJanet """ print('\n\nInterpreting command line options\n' + '~' * 72 + '\n') parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter, description=('''\n Tools for handling Janet native files in python. Janet and its related software (..., ) are property of Smile Consulting ''')) parser.add_argument("args", nargs='*') options = parser.parse_args() if len(options.args) != 1: raise TelemacException( '\nThis program takes only one Insel type file ' 'as a time as input.\n' ' ... an i2s or i3s file of the same name ' 'will be created depending on the Insel content.') jan_file = options.args[0] head, _ = path.splitext(jan_file) insel = Insel(jan_file) ins = InS('') if insel.file_type: ins.file_type = 'i3s' else: ins.file_type = 'i2s' ken_file = head + '.' + ins.file_type insel.toi2s(ins) ins.put_content(ken_file) # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Jenkins' success message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print('\n\nMy work is done\n\n') sys.exit(0)
class Polygons(object): """ Polygons is a lightweight structure to hold polygon information, whether to support i2s/i3s or shape or other file types. Polygons repalces the previous object InS Note that the derived class of Polygons have to implement the methods parse_content and put_content """ def __init__(self): self.object = None # important for coordinate conversions and distance calculations self.coordinates = {'type': None} # list of several polygons, each being defined as a pairs of x,y # self.poly = [] # list of several polygons, each being defined as the values for the # corresponding nodes # self.vals = [] # an tuples of integers for each polygon, where for the # first value: 0 = open; 1 = closed clockwise; # 2 = closed anti-clockwise; 3 = ... # second value: 0 = soft line; 1 = hard line; 2 = ... # self.type = [] # a list of attributs for each polygon, common to all nodes on the # polygon # self.atrbut = [] self.npoly = 0 # /!\ the poly does not duplicate the first and last node for closed # contours self.npoin = 0 def parse_content(self, file_name): # file parsing is based on the name of the extension _, tail = path.splitext(file_name) # ~~> Case of a Kenue type i2s/i3s file if tail in ['.i2s', '.i3s']: self.object = InS(file_name) self.npoly = self.object.npoly # ~~> Case of a Arc-GIS type shap file (which comes with additional # related files) #elif tail == '.shp': # head, fileType, self.npoin, self.poly, self.vals, self.type, \ # self.atrbut = getShp(self.file_name) # ~~> Sort out the poly types for ipoly in range(self.object.npoly): if self.object.type[ipoly] > 0: if is_clockwise(self.object.poly[ipoly]): self.object.type[ipoly] = 1 else: self.object.type[ipoly] = 2 return self.object.head def put_content(self, file_name, head=None): # ~~> all object should have a put_content method self.object.put_content(file_name, head) def get_areas(self, select=None): if select == None: select = range(self.npoly) # TODO: take sperical coordinate into account areas = np.zeros(len(select), dtype=np.float) for i, ipoly in enumerate(select): # ~~> compute the area only for closed polygons if self.object.type[ipoly] in [1, 2]: areas[i] = get_area(self.object.poly[ipoly]) return areas def get_lenghts(self, select=None): if select == None: select = range(self.npoly) return np.zeros(len(select), dtype=float) def sort_by_areas(self): srt = np.sort(np.array(zip( np.argsort(self.get_areas())[::-1], np.arange(self.npoly)), dtype=[('s', int), ('i', int)]), order='s') for i in range(len(srt)): if srt['s'][i] > srt['i'][i]: self.object.poly.insert(srt['i'][i], self.object.poly.pop(srt['s'][i])) self.object.type.insert(srt['i'][i], self.object.type.pop(srt['s'][i])) self.object.vals.insert(srt['i'][i], self.object.vals.pop(srt['s'][i])) def make_anti_clockwise(self, select=None): if select is None: select = range(self.npoly) for ipoly in select: # ~~> make anti-clockwise only closed clockwise polygons if self.object.type[ipoly] in [1, 2]: self.object.poly[ipoly], self.object.vals[ipoly] = \ make_anti_clockwise(self.object.poly[ipoly], self.object.vals[ipoly]) self.object.type[ipoly] = 2 def make_clockwise(self, select=None): if select is None: select = range(self.npoly) for ipoly in select: # ~~> make clockwise only closed anti-clockwise polygons if self.object.type[ipoly] in [1, 2]: self.object.poly[ipoly], self.object.vals[ipoly] = \ make_clockwise(self.object.poly[ipoly], self.object.vals[ipoly]) self.object.type[ipoly] = 1 def smooth_subdivise(self, select=None, weigth=0.5): if select is None: select = range(self.npoly) for ipoly in select: # ~~> make clockwise only closed anti-clockwise polygons self.object.poly[ipoly], self.object.vals[ipoly], _ = \ smooth_subdivise(self.object.poly[ipoly], self.object.vals[ipoly], self.object.type[ipoly], weigth) def subsample_distance(self, select=None, distance=1000.0): if select is None: select = range(self.npoly) for ipoly in select: # ~~> make clockwise only closed anti-clockwise polygons self.object.poly[ipoly], self.object.vals[ipoly], _ = \ subsample_distance(self.object.poly[ipoly], self.object.vals[ipoly], self.object.type[ipoly], distance) def subsample_angle(self, select=None, angle=15.0): if select is None: select = range(self.npoly) for ipoly in select: # ~~> make clockwise only closed anti-clockwise polygons self.object.poly[ipoly], self.object.vals[ipoly], _ = \ subsample_angle(self.object.poly[ipoly], self.object.vals[ipoly], self.object.type[ipoly], angle) def sph2ll(self, t1): (long0, lat0) = t1 radius = 6371000. long0 = np.deg2rad(float(long0)) lat0 = np.deg2rad(float(lat0)) const = np.tan(lat0 / 2. + np.pi / 4.) for poly in self.object.poly: for ipoly in range(len(poly)): poly[ipoly][0] = np.rad2deg(poly[ipoly][0] / radius + long0) poly[ipoly][1] = np.rad2deg\ (2.*np.arctan(const*np.exp(poly[ipoly][1]/radius)) \ - np.pi/2.) def ll2sph(self, t1): (long0, lat0) = t1 radius = 6371000. long0 = np.deg2rad(float(long0)) lat0 = np.deg2rad(float(lat0)) const = np.tan(lat0 / 2. + np.pi / 4.) for poly in self.object.poly: for ipoly in range(len(poly)): poly[ipoly][0] = radius * (np.deg2rad(poly[ipoly][0]) - long0) poly[ipoly][1] = radius * (np.log(\ np.tan(np.deg2rad(poly[ipoly][1])/2. + np.pi/4.)) \ - np.log(const)) def get_bbox(self): if len(self.object.poly) == 0: return 0., 0., 0., 0. xmin = xmax = self.object.poly[0][0][0] ymin = ymax = self.object.poly[0][0][1] for poly in self.object.poly: x_p, y_p = poly.T xmin = min(xmin, min(x_p)) xmax = max(xmax, max(x_p)) ymin = min(ymin, min(y_p)) ymax = max(ymax, max(y_p)) return xmin, ymin, xmax, ymax
def tesselate(options): """ Generate a mesh from a polygon """ if not options.freplace: if len(options.args) != 2: raise TelemacException(\ '\nThe code "tessellate" here ' 'requires one i2s/i3s file and ' 'one output slf file\n') i3s_file = options.args[0] out_file = options.args[1] else: if len(options.args) != 1: raise TelemacException(\ '\nThe code "tessellate" here ' 'requires one i2s/i3s file\n') i3s_file = options.args[0] head, _ = path.splitext(i3s_file) out_file = head+'.slf' i3s_file = path.realpath(i3s_file) if not path.exists(i3s_file): raise TelemacException(\ '\nCould not find ' 'the file named: {}'.format(i3s_file)) print('\n\nTessellating ' + path.basename(i3s_file) + ' within ' + \ path.dirname(i3s_file) + '\n'+'~'*72+'\n') i2s = InS(i3s_file) ikle2, ipob2, meshx, meshy = tessellate_poly(i2s, debug=True) print('\n\nWriting down the Selafin file ' + \ path.basename(out_file) + '\n'+'~'*72+'\n') slf = Selafin('') slf.title = '' slf.nplan = 1 slf.ndp2 = 3 slf.ndp3 = 3 slf.nbv1 = 1 slf.nvar = 1 slf.varindex = 1 slf.varnames = ['BOTTOM '] slf.varunits = ['M '] slf.ikle2 = ikle2 slf.ikle3 = slf.ikle2 slf.meshx = meshx slf.meshy = meshy slf.npoin2 = i2s.npoin slf.npoin3 = slf.npoin2 slf.nelem2 = len(slf.ikle2)/slf.ndp3 slf.nelem3 = slf.nelem2 slf.iparam = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0] slf.ipob2 = ipob2 slf.ipob3 = slf.ipob2 slf.fole = {'hook':open(out_file, 'wb'), 'endian':">", 'float':('f', 4), 'name':out_file} slf.tags['times'] = [1] if options.sph2ll != None: radius = 6371000. long0, lat0 = options.sph2ll.split(":") long0 = np.deg2rad(float(long0)) lat0 = np.deg2rad(float(lat0)) const = np.tan(lat0/2. + np.pi/4.) slf.meshx = np.rad2deg(slf.meshx/radius + long0) slf.meshy = np.rad2deg(2.*np.arctan(const*np.exp(slf.meshy/radius)) \ - np.pi/2.) if options.ll2sph != None: radius = 6371000. long0, lat0 = options.ll2sph.split(":") long0 = np.deg2rad(float(long0)) lat0 = np.deg2rad(float(lat0)) slf.meshx = radius * (np.deg2rad(slf.meshx) - long0) slf.meshy = radius * \ (np.log(np.tan(np.deg2rad(slf.meshy)/2. + np.pi/4.)) \ - np.log(np.tan(lat0/2. + np.pi/4.))) if options.ll2utm != None: zone = int(options.ll2utm) slf.meshx, slf.meshy, zone = utm.from_lat_long(slf.meshx, slf.meshy, zone) if options.utm2ll != None: zone = int(options.utm2ll) slf.meshx, slf.meshy = utm.to_lat_long(slf.meshx, slf.meshy, zone) slf.append_header_slf() slf.append_core_time_slf(0) slf.append_core_vars_slf([np.zeros(slf.npoin2)]) slf.fole['hook'].close()
def __init__(self, file_name): InS.__init__(self, file_name)