def getGridIntersection(self, fPoint, tPoint, fromGid, toGid, direction): """ 计算交叉点,所有点格式均为 [lng, lat] :param self: :param fPoint: 来源�? :param tPoint: 到达�? :param fromGid: 来源 gid :param toGid: 到达 gid :param direction: 方向 """ fGIPoint, tGIPoint = [], [] fromLat = float(fPoint[1]) fromLng = float(fPoint[0]) toLat = float(tPoint[1]) toLng = float(tPoint[0]) # 处理 from/to toDirection = { 'n': 's', 's': 'n', 'w': 'e', 'e': 'w' } pfRes = parseFormatGID(fromGid, direction, self.LngSPLIT, self.LatSPLIT, self.locs) ptRes = parseFormatGID(toGid, toDirection[direction], self.LngSPLIT, self.LatSPLIT, self.locs) fGidLine = pfRes['dlinePoint'] tGidLine = ptRes['dlinePoint'] fLng = pfRes['lng'] fLat = pfRes['lat'] tLng = ptRes['lng'] tLat = ptRes['lat'] # 计算网格方边交点 if direction in ['n', 's']: # 与纬度线相交 k = (toLng - fromLng) / (toLat - fromLat) b1, b2 = fLng, tLng fIlng = b1 + (fGidLine - fromLat) * k fGIPoint = [fIlng, fGidLine] tIlng = b2 + (tGidLine - fromLat) * k tGIPoint = [tIlng, tGidLine] else: # 与经度线相交 k = (toLat - fromLat) / (toLng - fromLng) b1, b2 = fLat, tLat fIlat = b1 + (fGidLine - fromLng) * k fGIPoint = [fGidLine, fIlat] tIlat = b2 + (tGidLine - fromLng) * k tGIPoint = [tGidLine,tIlat] return fGIPoint, tGIPoint
def iterateResByDirection(self): # 四个方向分别聚类 for x in xrange(0, self.typeNum): currentDir = -1 for line in self.resByDir[x]: linelist = line.split(',') lng = float(linelist[0]) lat = float(linelist[1]) gid = int(linelist[2]) gdirStr = linelist[3] speed = linelist[4] direction = linelist[5] gidInfo = parseFormatGID(gid, 'e', self.LngSPLIT, self.LatSPLIT, self.locs) gLat = gidInfo['lat'] gLng = gidInfo['lng'] if currentDir == -1: currentDir = direction self.dbInput[x].append([lng, lat]) subprops = "%s,%s,%s" % (gdirStr, speed, direction) self.subInfo[x].append([gid, gLng, gLat, subprops]) print "Direction: %s - process completed. Total %d records." % ( currentDir, len(self.resByDir[x]))
def iterateRes(self): cateKeys = {0: 'from', 1: 'to'} for x in xrange(0, self.typeNum): accumulator = 0 totalNum, noiseNum = 0, 0 for gid, tripsArray in self.resByAng[cateKeys[x]].iteritems(): tripsLen = len(tripsArray) totalNum += tripsLen tmpLngLat, tmpAngle, tmpSubInfo = [], [], [] for index in xrange(0, tripsLen): linelist = tripsArray[index].split(',') # lng = float(linelist[0]) # lat = float(linelist[1]) gid = int(linelist[2]) gdirStr = linelist[3] speed = linelist[4] direction = linelist[5] angle = int(float(linelist[6])) gidInfo = parseFormatGID(gid, 'e') gLat = gidInfo['lat'] gLng = gidInfo['lng'] strength = float(linelist[7]) tmpLngLat.append(linelist[0] + ',' + linelist[1]) tmpAngle.append([angle, strength]) subprops = "%s,%s,%s" % (gdirStr, speed, direction) tmpSubInfo.append("%d,%.6f,%.6f,%s" % (gid, gLng, gLat, subprops)) # DBScan result dbres = self.lineCLusterCalculation(tmpAngle) if not dbres: continue noiseNum += dbres['noiseNum'] self.dbLabel[x] += dbres['labels'] self.dbInput[x] += tmpLngLat self.subInfo[x] += tmpSubInfo accumulator += 1 noiseRate = float(noiseNum) / totalNum print ''' === Angle Cluster Info === Number of dbscan clusters in all: %d Grid ID number: %d Records(total): %d Noise Rate: %f === Angle Cluster Info === ''' % (self.dbscanBaseNum, accumulator, totalNum, noiseRate) return noiseRate
def iterateResByCategory(self): # 暂时只拿 from 的数据进行聚类,所以所有结果存在 index=0 的元素中 # noiseRate 只会返回最后一个计算的结果,如果 from/to 均计算过,只有一个结果被保留 noiseRate = 0 cateKeys = {0: 'from', 1: 'to'} for x in xrange(0, self.typeNum): accumulator = 0 totalNum, noiseNum = 0, 0 for gid, tripsArray in self.resByCate[cateKeys[x]].iteritems(): tripsLen = len(tripsArray) totalNum += tripsLen tmpInput, tmpSubInfo = [], [] for index in xrange(0, tripsLen): linelist = tripsArray[index].split(',') lng = float(linelist[0]) lat = float(linelist[1]) gid = int(linelist[2]) gdirStr = linelist[3] speed = linelist[4] direction = linelist[5] gidInfo = parseFormatGID(gid, 'e', self.LngSPLIT, self.LatSPLIT, self.locs) gLat = gidInfo['lat'] gLng = gidInfo['lng'] tmpInput.append([lng, lat]) subprops = "%s,%s,%s" % (gdirStr, speed, direction) tmpSubInfo.append([gid, gLng, gLat, subprops]) self.dbInput[x] += tmpInput self.subInfo[x] += tmpSubInfo # DBScan result dbres = self.dbscanCalByCategory(tmpInput) noiseNum += dbres['noiseNum'] self.dbLabel[x] += dbres['labels'] accumulator += 1 noiseRate = float(noiseNum) / totalNum print ''' === DBScan Info === Number of dbscan clusters in all: %d Grid ID number: %d Records(total): %d Noise Rate: %f === DBScan Info === ''' % (self.dbscanBaseNum, accumulator, totalNum, noiseRate) return noiseRate
def iterateResWithoutFromTo(self): cateKeys = {0: 'from', 1: 'to'} self.resByAng['all'] = {} # merge from and to if 'from' in self.resByAng.keys(): for gid, tripsArray in self.resByAng['from'].iteritems(): self.resByAng['all'][gid] = tripsArray if 'to' in self.resByAng.keys(): for gid, tripsArray in self.resByAng['to'].iteritems(): if self.resByAng['all'].has_key(gid): self.resByAng['all'][gid].extend(tripsArray) else: self.resByAng['all'][gid] = tripsArray accumulator, clusterNum = 0, 0 totalNum, noiseNum = 0, 0 for gid, tripsArray in self.resByAng['all'].iteritems(): tripsLen = len(tripsArray) totalNum += tripsLen tmpLngLat, tmpSubInfo, tmpLngLatAngle, labels = [], [], [], [] mapLngLatAngle = {} for index in xrange(0, tripsLen): linelist = tripsArray[index].split(',') startLng = float(linelist[0]) startLat = float(linelist[1]) gid = int(linelist[2]) gdirStr = linelist[3] speed = linelist[4] direction = linelist[5] angle = float(linelist[6]) gidInfo = parseFormatGID(gid, 'e', self.LngSPLIT, self.LatSPLIT, self.locs) gLat = gidInfo['lat'] gLng = gidInfo['lng'] tmpLngLat.append("%.6f,%.6f" % (startLng, startLat)) subprops = "%s,%s,%s,%.1f" % (gdirStr, speed, direction, angle) tmpSubInfo.append("%d,%.6f,%.6f,%s" % (gid, gLng, gLat, subprops)) clusterKey = "%.6f,%.6f,%.1f" % (startLng, startLat, angle) tmpLngLatAngle.append(clusterKey) if clusterKey in mapLngLatAngle.keys(): mapLngLatAngle[clusterKey] = mapLngLatAngle[clusterKey] + 1 else: mapLngLatAngle[clusterKey] = 1 # Aggregation by tmpLngLatAngle clusterIndex = 0 clusterMap = {} for clusterKey in mapLngLatAngle.keys(): if mapLngLatAngle[clusterKey] >= self.min_samples: clusterMap[clusterKey] = clusterIndex clusterIndex = clusterIndex + 1 clusterNum = clusterNum + 1 else: clusterMap[clusterKey] = -1 noiseNum += mapLngLatAngle[clusterKey] for index in xrange(0, tripsLen): labels.append(clusterMap[tmpLngLatAngle[index]]) self.dbLabel[0] += labels self.dbInput[0] += tmpLngLat self.subInfo[0] += tmpSubInfo accumulator += 1 noiseRate = float(noiseNum) / totalNum print ''' === Angle Cluster Info === Number of clusters in total: %d Grid ID number: %d Records(total): %d Noise Rate: %f === Angle Cluster Info === ''' % (clusterNum, accumulator, totalNum, noiseRate) return noiseRate
lng = linelist[4] gid = getFormatGID([lng, lat])['gid'] devId = int(linelist[1]) if devIdDict.has_key(gid): if devId not in devIdDict[gid]: devIdDict[gid].append(devId) res[gid] += 1 else: devIdDict[gid] = [devId] res[gid] += 1 #res[gid] += 1 f.close() # 写入文件 preline=[[] for j in xrange(len(res))]; ofile = os.path.join(OUTPUT_PATH, ofilename) with open(ofile, 'wb') as output: for index in xrange(len(res)): dirDict = parseFormatGID(index); preline[index].append(int(index)); preline[index].append(float(dirDict['lng'])); preline[index].append(float(dirDict['lat'])); preline[index].append(int(res[index])); output.write(str(index)+","+str(dirDict['lng'])+","+str(dirDict['lat'])+","+str(res[index])+"\n"); output.close() ojsonFile = os.path.join(OUTPUT_PATH, ofilename+".json") with open(ojsonFile, 'wb') as foutput: foutput.write(json.dumps(preline)); foutput.close()
def getNextGIDs(self, point, direction): """ 获取方向后续的前 N 个交点 :param self: :param point: [lng, lat, gid] :param direction: """ res = [] [x, y] = direction fromLat = point[1] fromLng = point[0] fromGID = point[2] parsedObj = parseFormatGID(fromGID) baseLatCenter = parsedObj['lat'] baseLngCenter = parsedObj['lng'] latDir = 1 if y > 0 else -1 lngDir = 1 if x > 0 else -1 # 存储所有交点数据 jumpPoints = [] # 计算网格方边交点 if y != 0: # 与平行纬度线相交 k = x / y for i in xrange(0, self.custom_params['jump_length']): incrementLat = baseLatCenter + self.custom_params[ 'LatSPLIT'] * (0.5 + i) * latDir - fromLat iLng = fromLng + incrementLat * k iLat = incrementLat + fromLat # key = '0,%d' % (i) jumpPoints.append([iLng, iLat, 0, i]) if x != 0: # 与平行经度线相交 k = y / x for i in xrange(0, self.custom_params['jump_length']): incrementLng = baseLngCenter + self.custom_params[ 'LngSPLIT'] * (0.5 + i) * lngDir - fromLng iLat = fromLat + incrementLng * k iLng = incrementLng + fromLng # key = '%d,0' % (i) jumpPoints.append([iLng, iLat, i, 0]) if x != 0 and y != 0: # 根据纬度从小到大排前三 for i in xrange(self.custom_params['jump_length'], self.custom_params['jump_length'] * 2): currentIndex = -1 currentMax = jumpPoints[i][0] for jumpIndex in xrange(0, self.custom_params['jump_length']): if (jumpPoints[jumpIndex][0] * lngDir) > (currentMax * lngDir): currentIndex = jumpIndex currentMax = jumpPoints[jumpIndex][0] if currentIndex != -1: jumpPoints[currentIndex] = jumpPoints[i][:] # 确定该方向离圆心最小的交点 minLng = jumpPoints[0][0] minLat = jumpPoints[0][1] originGid = 0 if x != 0 and y != 0: for i in xrange(1, self.custom_params['jump_length']): if minLng * lngDir > jumpPoints[i][0] * lngDir: minLng = jumpPoints[i][0] minLat = jumpPoints[i][1] # 只取三个交点 updateOriginGid = False for i in xrange(0, self.custom_params['jump_length']): ilng = jumpPoints[i][0] ilat = jumpPoints[i][1] # if ilng == minLng and ilat == minLat: # updateOriginGid = True if jumpPoints[i][2] == 0: ilat += 0.002 * latDir # 0.002 为一小点偏量,使交点在对应网格内而不至于只卡在边界上 else: ilng += 0.002 * lngDir point = getFormatGID([ilng, ilat]) gid = point['gid'] # if updateOriginGid: # updateOriginGid = False # originGid = gid res.append([ilng, ilat, gid]) return { 'res': res, 'endPoints': [minLng, minLat] # 'originGid': originGid }