def getDirections(routeParams): origin = routeParams["departureCoord"] destination = routeParams["destinationCoord"] #TODO add mode (defaults to driving) #TODO add waypoints/vias https://developers.google.com/maps/documentation/directions/#Waypoints # waypoints=optimize:false|Charlestown,MA|via:Lexington,MA #TODO add language - en-GB #TODO add units - metric #TODO add region=nl ?? url = "http://maps.googleapis.com/maps/api/directions/json?" +\ "origin=" + origin +\ "&destination=" + destination +\ "&alternatives=true" +\ "&sensor=false" logger.dbg("Sending HTTP request for url='" + url + "'") response = urllib.urlopen(url) jsonResponse = json.loads(response.read()) #logger.dbg(str(json.dumps(jsonResponse, sort_keys=True, indent=4, separators=(',', ': ')))) status = jsonResponse.get("status", "UNKNOWN_ERROR") routes = jsonResponse.get("routes", []) if status != "OK" or len(routes) == 0: logger.error("Request failed. status='%s', len(routes)=%d" % (status, len(routes))) return "Error" else: logger.dbg("status=OK, nofRoutes=%d" % len(routes)) return routes
def get_state(self): if isinstance(self.handler_state, statemachine.State): return self.handler_state else: if self.ctor_parameters is not None: try: logger.log('Next state : {}{}'.format( self.handler_state.__name__, self.ctor_parameters)) return self.handler_state(*self.ctor_parameters) except Exception as e: logger.dbg( "Exception while calling constructor for {} with parameters" .format(self.handler_state, self.ctor_parameters)) logger.log_exception(e) raise else: try: logger.log('Next state : {}()'.format( self.handler_state.__name__)) return self.handler_state() except Exception as e: logger.dbg( "Exception while calling constructor for {}".format( self.handler_state)) logger.log_exception(e) raise
def write(filename=None): try: if filename is None: filename=logger.filepath.replace(".py",".json") logger.dbg("Writing metrics to {}".format(filename)) scales.dumpStatsTo(filename) except Exception as e: logger.dbg("Exception in stats writing") logger.log_exception(e)
def extractInfoFromKmlFile(kmlFileName): logger.info("Processing file '" + kmlFileName + "'") xmldoc = minidom.parse(kmlFileName) placemarks = xmldoc.getElementsByTagName("Placemark") if len(placemarks) < 3: logger.error("Invalid kml file '" + kmlFileName + "'" + " - len(placemarks)=%d" % len(placemarks)) return "Error" # get departure coord temp = placemarks[0].getElementsByTagName("name")[0].childNodes[0].data routeName = temp.split()[0] logger.dbg("routeName='" + routeName + "'") assert temp.split()[1] == "(origin)" temp = placemarks[0].getElementsByTagName("description")[0].childNodes[0].data assert temp == "#start" departureCoord = placemarks[0].getElementsByTagName("Point")[0]\ .getElementsByTagName("coordinates")[0]\ .childNodes[0].data.strip().replace(" ", "") departureCoord = swapCoordinates(departureCoord) logger.dbg("departureCoord='" + departureCoord + "'") # get departure coord # TODO fix ProcessQueries: #destination is stored inside styleUrl """temp = placemarks[1].getElementsByTagName("description")[0]\ .childNodes[0].data assert temp == "#destination" """ destinationCoord = placemarks[1].getElementsByTagName("Point")[0]\ .getElementsByTagName("coordinates")[0]\ .childNodes[0].data.strip().replace(" ", "") destinationCoord = swapCoordinates(destinationCoord) logger.dbg("destinationCoord='" + destinationCoord + "'") # get route nodes and intermediates route = xmldoc.getElementsByTagName("Folder")[0]\ .getElementsByTagName("Placemark")[0]\ .getElementsByTagName("LineString")[0]\ .getElementsByTagName("coordinates")[0]\ .childNodes[0].data.strip() nodes = [swapCoordinates(node.replace(" ", "")) for node in route.split()] logger.dbg("Route has %d nodes/intermediates" % len(nodes)) #logger.dbg(str(nodes)) results = {"routeName": routeName, "departureCoord": departureCoord, "destinationCoord": destinationCoord, "nodes": nodes} return results
def _fmtEncode(fmt): ''' 获得具有EC位的15位 [格式信息], Encode the 15-bit format code using BCH code. ''' logger.dbg("format-info=%r", fmt) g = 0x537 code = fmt << 10 for i in range(4, -1, -1): if code & (1 << (i + 10)): code ^= g << i # # 计算得出十位BCH容错码接在格式信息之后, # 还要与掩码101010000010010进行异或, 作用同QR掩码; # return ((fmt << 10) ^ code) ^ 0b101010000010010
def get_state(self): if isinstance(self.handler_state, statemachine.State): return self.handler_state else : if self.ctor_parameters is not None: try : logger.log('Next state : {}{}'.format(self.handler_state.__name__, self.ctor_parameters)) return self.handler_state(*self.ctor_parameters) except Exception as e : logger.dbg("Exception while calling constructor for {} with parameters".format(self.handler_state, self.ctor_parameters)) logger.log_exception(e) raise else: try : logger.log('Next state : {}()'.format(self.handler_state.__name__)) return self.handler_state() except Exception as e : logger.dbg("Exception while calling constructor for {}".format(self.handler_state)) logger.log_exception(e) raise
def _rsEncode(bitstring, nsym): ''' 添加 里德-所罗门码(Reed-Solomon) 里德-所罗门码是定长码: 也就是一个固定长度输入的数据, 将被处理成一个固定长度的输出数据, 在最常用的(255,223)里所码中, 223个里德-所罗门输入符号(每个符号有8个位元)被编码成255个输出符号; Encode bitstring with nsym EC bits using RS algorithm. ''' gen = _rsGenPoly(nsym) res = [0] * (len(bitstring) + len(gen) - 1) res[:len(bitstring)] = bitstring for i in range(len(bitstring)): coef = res[i] if coef != 0: for j in range(1, len(gen)): res[i + j] ^= _gfMul(gen[j], coef) res[:len(bitstring)] = bitstring logger.dbg("encode+rscode, len:%r, data=\n\t%r\n", len(res), res) return res
def _mask(mat): ''' 为 矩阵数据 应用掩码, 返回 结果矩阵 和 掩码ID; Mask the data QR code matrix with all 8 masks, call _penalty to calculate penalty scores for each and select the best mask. Return tuple(selected masked matrix, number of selected mask). ''' #logger.dbg("data-len=%r, data=%r", len(mat), mat) maskeds = [_matXor(mat, dataMask) for dataMask in _dataMasks] #logger.dbg("Mask-len=%r, data=%r", len(maskeds), maskeds) penalty = [0] * 8 for i, masked in enumerate(maskeds): penalty[i] = _penalty(masked) logger.dbg("penalty-len=%r, data=%r", len(penalty), penalty) # Find the id of the best mask. index = penalty.index(min(penalty)) return maskeds[index], index
def _genImage(bitmapMat, qrcodesize, filename): ''' 创建 二维码 以矩阵的左上角为原点, 原点坐标定义为(0, 0), x 轴向右,坐标 x 对应列, y 轴向下, 坐标 y 对应行; 于是对于图像中的像素(x, y), 有矩阵元素 mat [ y ] [ x ] 与之对应。 --------> X | | | v Y Generate image corresponding to the input bitmapMat with specified qrcodesize and filename. ''' logger.dbg() width = qrcodesize height = qrcodesize # New image in black-white mode initialized with white. img = Image.new('1', (width, height), 'white') drw = ImageDraw.Draw(img) # Normalized pixel width. logger.dbg("block:%rx%r", len(bitmapMat), len(bitmapMat)) #用图像宽度 除以 矩阵维度得到 QR码中一个单位对应的像素数 a_unit_size = qrcodesize / len(bitmapMat) logger.dbg("a-rectangle-size=%r", a_unit_size) for y in range(height): # Normalized y coordinate in bitmapMat normaly = y / a_unit_size for x in range(width): # Normalized x coordinate in bitmapMat normalx = x / a_unit_size if normaly < len(bitmapMat) and normalx < len(bitmapMat): # # 在 ImageDraw里, 0(False)是黑色,1(True)是白色; # if DARK_IS_1: drow_color = not bitmapMat[normaly][normalx] else: drow_color = bitmapMat[normaly][normalx] # Draw pixel. drw.point((x, y), fill=drow_color) img.save(filename)
def dbg(self, msg): logger.dbg(self.name + ": " + msg)
def _encode(data): ''' 编码 输入数据, 返回 一维 整数矩阵 [ 模式指示符 + 字数指示符 + 数据内容 + 终止符 + 容错码 ] Encode the input data stream. Add mode prefix, encode data using ISO-8859-1, group data, add padding suffix, and call RS encoding method. ''' logger.dbg("input-data, len=%r, [%r]", len(data), data) # # 检测输入的数据是否超过V1-L byte mode 的最大编码长度17, # 如果超过就抛出异常 # if len(data) > 17: raise CapacityOverflowException( 'Error: Version 1 QR code[binary mode] encodes no more than 17 characters.' ) # # 1. 添加 模式指示符; # Byte mode prefix 0100. # bitstring = '0100' logger.dbg("byte mode=\n\t%r\n", bitstring) # # 2. 添加 字符数指示符; # Character count in 8 binary bits. # bitstring += '{:08b}'.format(len(data)) logger.dbg("byte mode + char cnt=\n\t%r\n", bitstring) # # 3. 把每一个字符 用 ISO/IEC 8859-1 标准编码, 然后 转换为 八位的二进制; # ISO-8859-1编码是单字节编码,向下兼容ASCII; # # Encode every character in ISO-8859-1 in 8 binary bits. # for c in data: bitstring += '{:08b}'.format(ord(c.encode('iso-8859-1'))) logger.dbg("byte mode + char cnt + data=\n\t%r\n", bitstring) # # 4. 添加终止符, # 如果尾部数据不足8bit,则在尾部 填充0 # # Terminator 0000. # tmpstr = bitstring convert_str_to_8_bit_array = '' last_str = '' while tmpstr: convert_str_to_8_bit_array += tmpstr[:8] last_str = tmpstr[:8] convert_str_to_8_bit_array += ', ' tmpstr = tmpstr[8:] #logger.dbg("8 bit to arry=\n\t%r\n", convert_str_to_8_bit_array) logger.dbg("last-str, len=%r, data=%r, append-0=%r", len(last_str), last_str, last_str + '0' * (8 - len(last_str))) bitstring += '0' * (8 - len(last_str)) logger.dbg("byte mode + char cnt + data + terminater=\n\t%r\n", bitstring) res = list() # # 5. 把 每8位 二进制数据 转换为 整数; # Convert string to byte numbers. # while bitstring: res.append(int(bitstring[:8], 2)) bitstring = bitstring[8:] logger.dbg("convert byte to int=\n\t%r\n", res) # # 6. 如果编码后的数据不足版本及纠错级别的最大容量, # 则在尾部补充 "11101100" 和 "00010001" # # Add padding pattern. # while len(res) < 19: #zgj, 这个19是如何计算的; res.append(int('11101100', 2)) res.append(int('00010001', 2)) # # 7. 截取 前19个字符 # Slice to 19 bytes for V1-L. # res = res[:19] logger.dbg("value:1~19, data=\n\t%r\n", res) # # 8. 添加 RS容错码; # return _rsEncode(res, 7) #zgj, 为什么是7个;
def _fillFormatInfo(arg): ''' 填充格式信息 Fill the encoded format code into the masked QR code matrix. arg: (masked QR code matrix, mask number). ''' mat, mask = arg logger.dbg("mask-id=%r", mask) # # 1. 计算 15位 格式信息 # # 01 is the format code for L error control level, # concatenated with mask id and passed into _fmtEncode # to get the 15 bits format code with EC bits. fmt = _fmtEncode(int('01' + '{:03b}'.format(mask), 2)) logger.dbg("fmt=%r", fmt) # # 2. 把 格式信息 转换为 15bit的二进制 # if DARK_IS_1: fmtarr = [[int(c)] for c in '{:015b}'.format(fmt)] else: fmtarr = [[not int(c)] for c in '{:015b}'.format(fmt)] logger.dbg("fmtInfo-len=%r, data=%r", len(fmtarr), fmtarr) # # 格式信息, 水平方向 从左向右 一共15个数字, 如下: # 14, 13, 12, 11, 10, 9, 空格, 8, 空格..., 7, 6, 5, 4, 3, 2, 1, 0 # # 3.1. 填充 水平的 0~7, 共 8个数字: horizontal_0_7 = _transpose(fmtarr[7:]) #截取 bit7 ~ bit14 logger.dbg("01, fmt-len=%r, data=%r", len(horizontal_0_7), horizontal_0_7) mat = _matCp(horizontal_0_7, mat, 8, 13) # 3.2. 填充 水平的 8, 共 1个数字: mat = _matCp([fmtarr[6]], mat, 8, 7) #获取bit6 # 3.3. 填充 水平的 9~14, 共 6个数字: mat = _matCp(_transpose(fmtarr[:6]), mat, 8, 0) #截取 bit0 ~ bit5 # # 格式信息, 垂直方向 从下向上 一共15个数字, 如下: # 14, 13, 12, 11, 10, 9, 8, 空格..., 7, 6, 空格, 5, 4, 3, 2, 1, 0 # # 3.4. 填充 垂直的 0~5, 共 6个数字: vertical_0_5 = fmtarr[9:][::-1] #截取 bit9 ~ bit14, 然后反向 #logger.dbg("02, fmt-len=%r, data=%r", len(vertical_0_5), vertical_0_5) mat = _matCp(vertical_0_5, mat, 0, 8) # 3.5. 填充 垂直的 6~7, 共 2个数字: mat = _matCp(fmtarr[7:9][::-1], mat, 7, 8) #截取 bit7 ~ bit9, 然后反向 # 3.6. 填充 垂直的 8~14, 共 7个数字: mat = _matCp(fmtarr[:7][::-1], mat, 14, 8) #截取 bit0 ~ bit6, 然后反向 return mat
1:对应黑色, 0:对应白色 ''' DARK_IS_1 = True if vars().has_key('DARK_IS_1') and DARK_IS_1: pass else: DARK_IS_1 = False if DARK_IS_1: _DARK = 1 _LIGHT = 0 else: _DARK = 0 _LIGHT = 1 logger.dbg("dark:%r", _DARK) def _transpose(mat): ''' 转换矩阵, 例如: 1x5 --> 5x1 Transpose a matrix ''' res = [[mat[j][i] for j in range(len(mat))] for i in range(len(mat[0]))] return res def _timSeq(time_len, vertical=False): ''' 创建 定位图形 矩阵