def main(action=None): debug = False # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Reads config file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print '\n\nInterpreting command line options\n' + '~' * 72 + '\n' parser = ArgumentParser(\ formatter_class=RawDescriptionHelpFormatter, description=('''\n Tools for handling KENUE files and related in python ''')) parser.add_argument("args", nargs='*') # valid for i2s / i3s parser.add_argument(\ "--replace",action="store_true",dest="freplace",default=False, help="if present, the output file will eventualy replace the input file" ) parser.add_argument(\ "--duplicates",action="store_true",dest="fduplicates",default=False, help="if present, remove duplicate points" ) parser.add_argument(\ "--duplangles",action="store_true",dest="fduplangles",default=False, help="if present, remove return angles" ) parser.add_argument(\ "--subdivise",dest="fsubdivise",default=None, help="if present, use the subdivise method (first)" ) parser.add_argument(\ "--subsample",dest="fsubsample",default=None, help="if present, use the subsample method (distance=..;angle=.." ) parser.add_argument(\ "--clockwise",action="store_true",dest="fclock",default=False, help="if present, anticlockwise polylines will be converted clockwise" ) parser.add_argument(\ "--aclockwise",action="store_true",dest="faclock",default=False, help="if present, clockwise polylines will be converted anticlockwise" ) parser.add_argument(\ "--sph2ll",dest="sph2ll",default=None, help="convert from spherical to longitude-latitude" ) parser.add_argument(\ "--ll2sph",dest="ll2sph",default=None, help="convert from longitude-latitude to spherical" ) options = parser.parse_args() if not action is None: options.args.insert(0, action) if len(options.args) < 1: print '\nThe name of one file at least is required\n' parser.print_help() sys.exit(1) # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Reads code name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ codeName = options.args[0] # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Case of I2S / I3S ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if codeName in ['i2s', 'i3s']: if not options.freplace: if len(options.args) != 3: print '\nThe code ', codeName, ' (without --replace) uses a minimum of 2 argumensts, aside from the options\n' parser.print_help() sys.exit(1) insFiles = [options.args[1]] outFile = options.args[2] else: insFiles = options.args[1:] outFile = "smooth-tmp.i2s" for insFile in insFiles: insFile = path.realpath( insFile ) #/!\ to do: possible use of os.path.relpath() and comparison with os.getcwd() print '\n\nProcessing ' + path.basename( insFile) + ' within ' + path.dirname( insFile) + '\n' + '~' * 72 + '\n' ins = InS(insFile) if options.sph2ll != None: ins.sph2ll(options.sph2ll.split(":")) if options.ll2sph != None: ins.ll2sph(options.ll2sph.split(":")) if options.fclock: print '\nMake closed loops clockwise' ins.makeClockwise() if options.faclock: print '\nMake closed loops anti-clockwise' ins.makeAntiClockwise() #if options.fduplicates: # print '\nRemove duplicates' # ins.removeDuplicates() #if options.fduplangles: # print '\nRemove return angles' # ins.removeDuplangles() if options.fsubdivise != None: print '\nSubdivise and average' ins.smoothSubdivise(float(options.fsubdivise)) if options.fsubsample != None: distance = '' angle = '' for dw in options.fsubsample.split(';'): if "dist" in dw.split('=')[0]: distance = dw.split('=')[1] if "angl" in dw.split('=')[0]: angle = dw.split('=')[1] if distance != '': print '\nSubsample based on proximity' ins.smoothSubsampleDistance(float(distance)) if angle != '': print '\nSubsample based on flatness' ins.smoothSubsampleAngle(float(angle)) ins.putContent(outFile) if options.freplace: moveFile(outFile, insFile) # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Case of UNKNOWN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else: print '\nDo not know what to do with this code name: ', codeName sys.exit(1) # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Jenkins' success message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print '\n\nMy work is done\n\n' sys.exit(0)
print '\nSubdivise and average' ins.smoothSubdivise(float(options.fsubdivise)) if options.fsubsample != None: distance = '' angle = '' for dw in options.fsubsample.split(';'): if "dist" in dw.split('=')[0]: distance = dw.split('=')[1] if "angl" in dw.split('=')[0]: angle = dw.split('=')[1] if distance != '': print '\nSubsample based on proximity' ins.smoothSubsampleDistance(float(distance)) if angle != '': print '\nSubsample based on flatness' ins.smoothSubsampleAngle(float(angle)) ins.putContent(outFile) if options.freplace: moveFile(outFile, slfFile) # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Case of UNKNOWN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else: print '\nDo not know what to do with this code name: ', codeName sys.exit() # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Jenkins' success message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print '\n\nMy work is done\n\n' sys.exit()
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: print '\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.' sys.exit(1) janFile = options.args[0] head,tail = path.splitext(janFile) insel = INSEL(janFile) ins = InS('') if insel.fileType: ins.fileType = 'i3s' else: ins.fileType = 'i2s' kenFile = head+'.'+ins.fileType insel.toi2s(ins) ins.putContent(kenFile) # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # ~~~~ Jenkins' success message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print '\n\nMy work is done\n\n' sys.exit(0)
class Polygons: def __init__(self): self.object = None self.coordinates = { 'type': None } # important for coordinate conversions and distance calculations # self.poly = [] # list of several polygons, each being defined as a pairs of x,y # self.vals = [] # list of several polygons, each being defined as the values for the corresponding nodes # self.type = [] # 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.atrbut = [] # a list of attributs for each polygon, common to all nodes on the polygon self.npoly = 0 self.npoin = 0 # /!\ the poly does not duplicate the first and last node for closed contours def parseContent(self, fileName): # file parsing is based on the name of the extension _, tail = path.splitext(fileName) # ~~> Case of a Kenue type i2s/i3s file if tail in ['.i2s', '.i3s']: self.object = InS(fileName) 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.fileName) # ~~> Sort out the poly types for ip in range(self.object.npoly): if self.object.type[ip] > 0: if isClockwise(self.object.poly[ip]): self.object.type[ip] = 1 else: self.object.type[ip] = 2 return self.object.head def putContent(self, fileName, head=[]): # ~~> all object should have a putContent method self.object.putContent(fileName, head) def getAreas(self, select=[]): if select == []: select = range(self.npoly) # TODO: take sperical coordinate into account areas = np.zeros(len(select), dtype=np.float) for ip, i in zip(select, range(len(select))): # ~~> compute the area only for closed polygons if self.object.type[ip] in [1, 2]: areas[i] = getArea(self.object.poly[ip]) return areas def getLengths(self, select=[]): # TODO return np.zeros(len(select), dtype=float) def sortByAreas(self): s = np.sort(np.array(zip( np.argsort(self.getAreas())[::-1], np.arange(self.npoly)), dtype=[('s', int), ('i', int)]), order='s') for i in range(len(s)): if s['s'][i] > s['i'][i]: self.object.poly.insert(s['i'][i], self.object.poly.pop(s['s'][i])) self.object.type.insert(s['i'][i], self.object.type.pop(s['s'][i])) self.object.vals.insert(s['i'][i], self.object.vals.pop(s['s'][i])) def makeAntiClockwise(self, select=[]): if select == []: select = range(self.npoly) for ip in select: # ~~> make anti-clockwise only closed clockwise polygons if self.object.type[ip] in [1, 2]: self.object.poly[ip], self.object.vals[ip] = makeAntiClockwise( self.object.poly[ip], self.object.vals[ip]) self.object.type[ip] = 2 def makeClockwise(self, select=[]): if select == []: select = range(self.npoly) for ip in select: # ~~> make clockwise only closed anti-clockwise polygons if self.object.type[ip] in [1, 2]: self.object.poly[ip], self.object.vals[ip] = makeClockwise( self.object.poly[ip], self.object.vals[ip]) self.object.type[ip] = 1 def smoothSubdivise(self, select=[], weigth=0.5): if select == []: select = range(self.npoly) for ip in select: # ~~> make clockwise only closed anti-clockwise polygons self.object.poly[ip], self.object.vals[ip], _ = smoothSubdivise( self.object.poly[ip], self.object.vals[ip], self.object.type[ip], weigth) def subsampleDistance(self, select=[], distance=1000.0): if select == []: select = range(self.npoly) for ip in select: # ~~> make clockwise only closed anti-clockwise polygons self.object.poly[ip], self.object.vals[ip], _ = subsampleDistance( self.object.poly[ip], self.object.vals[ip], self.object.type[ip], distance) def subsampleAngle(self, select=[], angle=15.0): if select == []: select = range(self.npoly) for ip in select: # ~~> make clockwise only closed anti-clockwise polygons self.object.poly[ip], self.object.vals[ip], _ = subsampleAngle( self.object.poly[ip], self.object.vals[ip], self.object.type[ip], angle) def sph2ll(self, (long0, lat0)): 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 ip in range(len(poly)): poly[ip][0] = np.rad2deg(poly[ip][0] / radius + long0) poly[ip][1] = np.rad2deg( 2. * np.arctan(const * np.exp(poly[ip][1] / radius)) - np.pi / 2.)