def uploadStationExcel(): """ 批量上传站点excel """ res = ResMsg() aiBusModel=AiBusModel() userInfo = session.get("userInfo") #获取excel文件 data=request.get_json() #循环判断数据类型 insertVals = [] for item in data["items"]: if item["siteName"] =="" or item["siteName"] is None or\ item["siteProperty"] =="" or item["siteProperty"] is None or\ item["longitude"] =="" or item["longitude"] is None or \ item["latitude"] =="" or item["latitude"] is None: res.update(code=ResponseCode.Fail,msg="名称经纬度站点属性字段不能为空!") return res.data else: siteProperty=1 if item["siteProperty"]=="固定" else 0 #geojson = { "type": "Point", "coordinates": [float(item["longitude"]),float(item["latitude"])]} #geojson = '{ "type": "Point", "coordinates": [%s, %s]}'%(float(item["longitude"]),float(item["latitude"])) insertVals.append((item["province"],item["city"],item["region"],item["siteName"],siteProperty,item["direction"],\ float(item["longitude"]),float(item["latitude"]),item["road"],userInfo["citycode"],userInfo["userName"],userInfo["userName"])) row=aiBusModel.batchStation(tuple(insertVals)) if row>0: res.update(code=ResponseCode.Success, msg="成功插入{}条记录!".format(row)) return res.data else: res.update(code=ResponseCode.Fail, msg="插入失败!") return res.data
def exportClusterPoints(): """ 根据网点文件id导出网点和聚类信息 """ res = ResMsg() try: aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() fileId = data["fileId"] # print(fileId) #sitefileList=aiBusModel.searchSiteListByFileId(fileId) # 聚类文件导出 #1)先查询聚类参数 clusterParams = aiBusModel.selectClusterParams((fileId)) if not clusterParams: clusterParams = aiBusModel.selectClusterParamsBySiteFileId( (fileId)) if not clusterParams: res.update(code=ResponseCode.Success, data={"clusterResult": []}) return res.data fileId = clusterParams["id"] clusterInfo = aiBusModel.searchClusterResult(fileId) if None == clusterInfo: clusterInfo = [] res.update(code=ResponseCode.Success, data={"clusterResult": clusterInfo}) return res.data except Exception as e: res.update(code=ResponseCode.Fail) return res.data
def identify(self, auth_header): """ 用户鉴权 :return: list """ aiBusModel=AiBusModel() if auth_header: payload = self.decode_auth_token(auth_header) if payload is None: return False if "data" in payload and "flag" in payload: if payload["flag"] == 0: #获取用户所有下级 userInfo=payload["data"] subUsers=aiBusModel.selectSubUserByUserName(userInfo["userName"],userInfo["citycode"]) userNames=[] for user in subUsers: userNames.append(user["userName"]) userNames.append(userInfo["userName"]) return {"userName":userInfo["userName"],"userNames":userNames,"citycode":userInfo["citycode"]} else: # 其他状态暂不允许 return False else: return False else: return False
def authenticate(self,userName,password,citycode): """ 用户登录认证,登录成功返回token,登录失败返回失败原因 """ res = ResMsg() aiBusModel=AiBusModel() matchUser=aiBusModel.selectUserByUserInfo(userName,password) #print(matchUser) if not matchUser: res.update(code=ResponseCode.AccountOrPassWordErr) return res.data else: token=self.encode_auth_token(userName,citycode) res.update(code=ResponseCode.Success,data={"token":token,"citycode":citycode}) return res.data
def fuzzyQueryStationName(): """ 根据站点名称模糊查询站点 """ res = ResMsg() try: aiBusModel=AiBusModel() userInfo = session.get("userInfo") data=request.get_json() queryText=data['queryText'] row=aiBusModel.selectStationNameByText(queryText,userInfo["citycode"],userInfo["userNames"]) res.update(code=ResponseCode.Success, data=row) return res.data except Exception as e: res.update(code=ResponseCode.Fail,msg="站点名称模糊查询报错!") return res.data
def queryRoutePlanFileList(): """ 根据用户权限查询文件列表 """ res = ResMsg() try: aiBusModel = AiBusModel() data = request.get_json() clusterStatus = int(data["clusterStatus"]) userInfo = session.get("userInfo") clusterFileList = aiBusModel.selectFileListByClusterStatus( clusterStatus, userInfo["citycode"], userInfo["userNames"]) res.update(code=ResponseCode.Success, data=clusterFileList) return res.data except Exception as e: res.update(code=ResponseCode.Fail, msg="查询聚类文件报错!") return res.data
def removeClusterPoints(): """ 批量失效聚类点 """ res = ResMsg() try: logger.info("begin removeClusterPoints!") aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() ids = data["ids"] row = aiBusModel.invalidClusterSitesById((userInfo["userName"]), ids) res.update(code=ResponseCode.Success, msg="成功删除{}条记录!".format(row)) return res.data except Exception as e: logger.error("removeClusterPoints exception:{}".format(str(e))) res.update(code=ResponseCode.Fail) return res.data
def queryStationList(): res = ResMsg() try: aiBusModel=AiBusModel() userInfo = session.get("userInfo") data=request.get_json() province=data['province'] city=data['city'] siteName=data['siteName'] road=data['road'] siteStatus=data['siteStatus'] pageSize=int(data['pageSize']) pageNum=int(data['pageNum'])-1 count,row=aiBusModel.selectStationList(province,city,siteName,road,siteStatus,pageSize,pageNum,userInfo["citycode"],userInfo["userNames"]) res.update(code=ResponseCode.Success, data={"count":count,"stationList":row}) return res.data except Exception as e: res.update(code=ResponseCode.Fail,msg="查询站点列表报错!") return res.data
def queryClusterPointInfo(): """ 根据聚类点id查询聚类点信息:id、客户名称、人数、站点名称、经纬度 """ res = ResMsg() try: logger.info("begin queryClusterPointInfo!") aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() clusterId = data["id"] clusterPoint = aiBusModel.selectClusterPointById(clusterId) siteIdList = clusterPoint["siteSet"].split(",") siteInfo = aiBusModel.selectClientNameByIds(siteIdList) res.update(code=ResponseCode.Success, data=siteInfo) return res.data except Exception as e: logger.error("queryClusterPointInfo exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="查询聚类点信息报错!") return res.data
def multiThreadGetAmapInfo(): res = ResMsg() try: logger.info("begin multiThreadGetAmapInfo!") aiBusModel = AiBusModel() data = request.get_json() fileId = data["fileId"] siteList = aiBusModel.selectSiteGeoListByFileId(fileId) if not siteList: res.update(code=ResponseCode.Fail, msg="网点为空!") return res.data routeNodeList = [] sitePairs = list(itertools.permutations(siteList, 2)) for sitePair in sitePairs: key = str(sitePair[0]["id"]) + "-" + str(sitePair[1]["id"]) fromNode = str(round(sitePair[0]["lng"], 6)) + "," + str( round(sitePair[0]["lat"], 6)) toNode = str(round(sitePair[1]["lng"], 6)) + "," + str( round(sitePair[1]["lat"], 6)) routeNodeList.append({ "key": key, "origin": fromNode, "destination": toNode, "routeType": 1 }) result = build_process(routeNodeList) res.update(code=ResponseCode.Success, data={ "srcSize": len(sitePairs), "destSize": len(result.keys()), "result": result }) return res.data except Exception as e: logger.error("multiThreadGetAmapInfo exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="生成聚类点报错!") return res.data
def addNewClusterPoint(): res = ResMsg() try: logger.info("begin addNewClusterPoint!") aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() fileId = data["fileId"] siteName = data["siteName"] longitude = data["longitude"] latitude = data["latitude"] number = data["number"] siteProperty = data["siteProperty"] if siteProperty == "固定": relativeProperty = 1 elif siteProperty == "临时": relativeProperty = 0 else: relativeProperty = 2 row = aiBusModel.selectClusterPointId( (fileId, siteName, float(longitude), float(latitude))) if row: res.update(code=ResponseCode.Success, data={"id":row["id"],"siteName":siteName,\ "longitude":longitude,"latitude":latitude,"number":number,"siteProperty":siteProperty,"users":[]}) return res.data #插入 aiBusModel.insertClusterPoint( (fileId, ' ', relativeProperty, siteName, 1, 2, float(longitude), float(latitude), number, ' ', userInfo["userName"], userInfo["userName"])) #查找id row = aiBusModel.selectClusterPointId( (fileId, siteName, float(longitude), float(latitude))) res.update(code=ResponseCode.Success, data={"id":row["id"],"siteName":siteName,\ "longitude":longitude,"latitude":latitude,"number":number,"siteProperty":siteProperty,"users":[]}) return res.data except Exception as e: logger.error("addNewClusterPoint exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="新增聚类点报错!") return res.data
def generateClusterPointsOld(): """ 根据网点文件id生成聚类点 """ res = ResMsg() try: aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() fileId = data["fileId"] epsRadius = float(data["epsRadius"]) minSamples = data["minSamples"] #先判断网点文件是否有效 fileStatus = aiBusModel.selectSiteFileStatus(fileId) #if fileStatus["fileProperty"]==0: # res.update(code=ResponseCode.Fail,data="该网点文件还未确认导入!") # return res.data if fileStatus["fileStatus"] == 0: res.update(code=ResponseCode.Fail, msg="该网点文件已经失效!") return res.data #对聚类过的临时结果进行失效 aiBusModel.updateClusterResultByFileId( (0, userInfo["userName"], fileId), [2]) #根据网点文件查询网点list siteGeoList = aiBusModel.selectSiteGeoListByFileId(fileId) clusterInfo = clusterByDbscan(siteGeoList, epsRadius / 1000, minSamples) #将聚类结果保存至表中 insertVals = [] siteGeoDict = {} for site in siteGeoList: siteGeoDict[str(site["id"])] = site clusterOutPoints = [] clusterCorePoints = [] clusterAroundPoints = [] #1)处理异常点fileId,siteId,clusterName,clusterProperty,clusterStatus,longitude,latitude,number,siteSet for id in clusterInfo["noiseIds"]: relativeId = "site_" + str(id) site = siteGeoDict[str(id)] insertVals.append( (fileId, relativeId, site["siteName"], site["siteProperty"], 0, 2, site["lng"], site["lat"], site["number"], "", userInfo["userName"], userInfo["userName"])) #clusterOutPoints.append({"id":relativeId,"siteName":site["siteName"],"siteProperty":site["siteProperty"],"number":site["number"],"longitude":site["lng"],"latitude":site["lat"]}) #2)处理聚类点 for cluster in clusterInfo["clusterSet"]: #处理聚类核心点 clusterNumber = 0 clusterId = int(cluster["clusterCenterId"]) site = siteGeoDict[str(clusterId)] for id in cluster["clusterCoreIds"]: clusterNumber += siteGeoDict[str(id)]["number"] insertVals.append( (fileId, "site_" + str(clusterId), site["siteName"], site["siteProperty"], 1, 2, site["lng"], site["lat"], clusterNumber, ",".join(map(str, cluster["clusterCoreIds"])), userInfo["userName"], userInfo["userName"])) #clusterCorePoints.append({"id":"site_"+str(clusterId),"siteName":site["siteName"],"siteProperty":site["siteProperty"],"number":clusterNumber,"longitude":site["lng"],"latitude":site["lat"]}) #处理边界点 for id in cluster["clusterAroundIds"]: relativeId = "site_" + str(id) aroundSite = siteGeoDict[str(id)] insertVals.append( (fileId, relativeId, aroundSite["siteName"], aroundSite["siteProperty"], 2, 2, aroundSite["lng"], aroundSite["lat"], aroundSite["number"], "", userInfo["userName"], userInfo["userName"])) #clusterAroundPoints.append({"id":relativeId,"siteName":aroundSite["siteName"],"siteProperty":site["siteProperty"],"number":aroundSite["number"],"longitude":aroundSite["lng"],"latitude":aroundSite["lat"]}) #3)插入聚类点并返回 aiBusModel.batchClusterSites(insertVals) #4)返回聚类结果 clusterResut = aiBusModel.selectClusterResult((2, fileId)) for item in clusterResut: if item["relativeProperty"] == 1: siteProperty = "固定" elif item["relativeProperty"] == 0: siteProperty = "临时" else: siteProperty = "自定义" row={"id":item["id"],"siteName":item["clusterName"],"siteProperty":siteProperty,\ "longitude":item["longitude"],"latitude":item["latitude"],"number":item["number"]} if item["clusterProperty"] == 1: clusterCorePoints.append(row) elif item["clusterProperty"] == 2: clusterAroundPoints.append(row) else: clusterAroundPoints.append(row) res.update(code=ResponseCode.Success, data={ "clusterCorePoints": clusterCorePoints, "clusterAroundPoints": clusterAroundPoints, "clusterOutPoints": clusterOutPoints }) return res.data except Exception as e: res.update(code=ResponseCode.Fail, msg="生成聚类点报错!") return res.data
def exportClusterResult(): res = ResMsg() try: aiBusModel = AiBusModel() fileId = request.args.get("fileId") clusterPoints = [] sitePoints = [] #1)先查询聚类参数 siteParams = aiBusModel.selectClusterParams( (fileId)) ##根据网点文件fileId的查询网点文件 if not siteParams: siteResut = aiBusModel.exportCustomSiteInfo(fileId) siteItems = [ "区域", "经度", "纬度", "公交站", "公交站属性", "客户姓名", "客户属性", "年龄", "客户地址", "乘车人数", "年级" ] for item in siteResut: if item["siteProperty"] == 1: item["siteProperty"] = "固定" elif item["siteProperty"] == 0: item["siteProperty"] = "临时" else: item["siteProperty"] = "自定义" row = [ item["region"], item["longitude"], item["latitude"], item["siteName"], item["siteProperty"], item["clientName"], item["clientProperty"], item["age"], item["clientAddress"], item["number"], item["grade"] ] sitePoints.append(row) file_path = writeExcel(fileId, siteItems, sitePoints, "网点文件") clusterParams = aiBusModel.selectClusterParamsBySiteFileId( (fileId)) ##根据网点文件fileId查询聚类文件 if clusterParams: clusterId = clusterParams["id"] #2)查询聚类结果 clusterResut = aiBusModel.exportClusterResult((1, clusterId)) clusterItems = ["区域", "经度", "纬度", "公交站", "公交站属性", "乘车人数"] for item in clusterResut: if item["relativeProperty"] == 1: item["relativeProperty"] = "固定" elif item["relativeProperty"] == 0: item["relativeProperty"] = "临时" else: item["relativeProperty"] = "自定义" clusterrow = [ item["region"], item["longitude"], item["latitude"], item["clusterName"], item["relativeProperty"], item["number"] ] clusterPoints.append(clusterrow) file_path = writeExcel(fileId, clusterItems, clusterPoints, "聚类文件", removeLabel=False) if file_path is None: return to_json({'success': 0, 'message': '请输入参数'}) else: if file_path == '': return to_json({'success': 0, 'message': '请输入正确路径'}) else: if not os.path.isfile(file_path): return to_json({'success': 0, 'message': '文件路径不存在'}) else: filename = os.path.basename( file_path) #filename=routeplan_student.xls utf_filename = quote(filename.encode('utf-8')) # print(utf_filename) response = Response(file_iterator(file_path)) # response.headers['Content-Type'] = 'application/octet-stream' # response.headers["Content-Disposition"] = 'attachment;filename="{}"'.format(filename) response.headers[ "Content-Disposition"] = "attachment;filename*=UTF-8''{}".format( utf_filename) response.headers[ 'Content-Type'] = "application/octet-stream; charset=UTF-8" #print(response) return response except Exception as e: res.update(code=ResponseCode.Fail, msg="导出报错!") return res.data
def saveRouteNode(): """ 保存规划路线接口 """ res = ResMsg() try: logger.info("begin saveRouteNode!") aiBusModel = AiBusModel() data = request.get_json() fileId = data["fileId"] routeId = data["routeId"] roundStatus = data["roundStatus"] passengers = data["passengers"] vehicleType = int(data["vehicleType"]) routeNodeList = data["routeNodeList"] invalidNodeList = data["invalidNodeList"] if fileId is None or fileId == "": res.update(code=ResponseCode.Fail, msg="路线规划保存时,fileId不能为空!") return res.data #根据结点顺序获取对应信息 nodeIndex = 0 for node in invalidNodeList: aiBusModel.updateRouteDetail( (nodeIndex, 0, 0, 0, 1, roundStatus, node["nodeName"], node["lng"], node["lat"], routeId, node["id"])) #newInvalidNodeList.append({"id":node["id"],"nodeIndex":nodeIndex,"nodeName":node["nodeName"],\ # "lng":float(node["lng"]),"lat":float(node["lat"]),"number":node["number"]}) nodeIndex += 1 #失效所有的途经点 aiBusModel.invalidWayPoints((routeId)) nodeIndex = 0 dist = 0 time = 0 length = len(routeNodeList) for i in range(length - 1): fromNode = routeNodeList[i] toNode = routeNodeList[i + 1] fromLngLat = str(round(float(fromNode["lng"]), 6)) + "," + str( round(float(fromNode["lat"]), 6)) toLngLat = str(round(float(toNode["lng"]), 6)) + "," + str( round(float(toNode["lat"]), 6)) #手动生成id,批量查询 paramId = generate_md5_key(fromLngLat + "," + toLngLat) row = aiBusModel.selectRouteParams(vehicleType, [paramId]) if row is None or len(row) < 1 or row[0]["dist"] < 0.5: startPoint = str(fromNode["lng"]) + "," + str(fromNode["lat"]) endPoint = str(toNode["lng"]) + "," + str(toNode["lat"]) distTime = get_route_distance_time(startPoint, endPoint) dist += distTime["dist"] time += distTime["time"] else: dist += row[0]["dist"] time += row[0]["time"] if fromNode["nodeType"] == 0: #fileId,routeId,roundStatus,nodeIndex,nodeName,nodeStatus,nodeLng,nodeLat,number,nextDist,nextTime,nodeProperty,nodeType aiBusModel.insertRouteDetail((fileId,routeId,roundStatus,nodeIndex,fromNode["nodeName"],\ 1,fromNode["lng"],fromNode["lat"],0,dist,time,1,0)) else: #routeNumber+=fromNode["number"] #newRouteNodeList.append({"id":fromNode["id"],"nodeIndex":nodeIndex,"nodeName":fromNode["nodeName"],\ # "lng":float(fromNode["lng"]),"lat":float(fromNode["lat"]),"number":fromNode["number"],\ # "nextDist":row["dist"],"nextTime":row["time"]}) aiBusModel.updateRouteDetail( (nodeIndex, 1, dist, time, 1, roundStatus, fromNode["nodeName"], fromNode["lng"], fromNode["lat"], routeId, fromNode["id"])) dist = 0 time = 0 nodeIndex += 1 if i + 1 == length - 1: #newRouteNodeList.append({"id":toNode["id"],"nodeIndex":nodeIndex,"nodeName":toNode["nodeName"],\ # "lng":float(toNode["lng"]),"lat":float(toNode["lat"]),"number":toNode["number"],"nextDist":0,"nextTime":0}) aiBusModel.updateRouteDetail( (nodeIndex, 1, 0, 0, 1, roundStatus, toNode["nodeName"], toNode["lng"], toNode["lat"], routeId, toNode["id"])) #routeNumber+=toNode["number"] #更新routeInfo参数表,实现之前保存的参数,替换为当前的参数 if fileId != -1: aiBusModel.invalidRouteInfo((0, fileId)) aiBusModel.validRouteInfo((1, fileId, routeId)) res.update(code=ResponseCode.Success, msg="路线保存成功!") return res.data except Exception as e: logger.error("saveRouteNode exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="路线规划结点保存报错!") return res.data
def queryRouteInfo(): """ 根据fileId查询路线规矩信息 """ res = ResMsg() try: logger.info("begin queryRouteInfo!") data = request.get_json() aiBusModel = AiBusModel() fileId = data["fileId"] if fileId is None or fileId == '': res.update(code=ResponseCode.Fail, msg="fileId不能为空!") return res.data #1)查询routeInfo,处理返回路径的基本信息 routeParams = aiBusModel.selectRouteInfo((fileId)) if not routeParams: res.update(code=ResponseCode.Success) return res.data routeParams["destination"] = { "siteName": routeParams["destName"], "lng": routeParams["destLng"], "lat": routeParams["destLat"] } routeParams["waypoints"] = json.loads(routeParams["wayPoints"]) if routeParams["maxDistance"]: if routeParams["maxDistance"] != "" and routeParams[ "maxDistance"] >= 1000000.0: routeParams["maxDistance"] = "" elif routeParams["maxDistance"] < 1000000.0: routeParams["maxDistance"] = routeParams["maxDistance"] / 1000 else: routeParams["maxDistance"] = "" if routeParams["maxDuration"]: if routeParams["maxDuration"] != "" and routeParams[ "maxDuration"] >= 24 * 3600: routeParams["maxDuration"] = "" else: routeParams["maxDuration"] = "" del routeParams["destName"] del routeParams["destLng"] del routeParams["destLat"] del routeParams["wayPoints"] #2)查询路线规划信息 #获取网点人数 orderNumber = -1 fileInfo = aiBusModel.selectSiteFileStatus(fileId) if fileInfo: if fileInfo["clusterStatus"] == 1: siteInfo = aiBusModel.selectSiteFileStatus( fileInfo["siteFileId"]) if siteInfo: orderNumber = siteInfo["siteCount"] else: orderNumber = fileInfo["siteCount"] if orderNumber is None or orderNumber <= 0: orderNumber = routeParams["passengers"] routeList = [] #去程 routeNodeResult = aiBusModel.selectRouteDetail( (routeParams["routeId"], 1, 0, 1)) if routeNodeResult and len(routeNodeResult) > 0: routeTime = 0 routeDist = 0 routeNumber = 0 routeOccupancyRate = 0 for routeNode in routeNodeResult: routeTime += routeNode["nextTime"] routeDist += routeNode["nextDist"] routeNumber += routeNode["number"] routeOccupancyRate = float(routeNumber) / orderNumber * 100 invalidRouteNodeResult = aiBusModel.selectRouteDetail( (routeParams["routeId"], 1, 0, 0)) invalidNodeList = [] for routeNode in invalidRouteNodeResult: invalidNodeList.append({ "id": routeNode["id"], "lat": routeNode["lat"], "lng": routeNode["lng"], "nodeIndex": routeNode["nodeIndex"], "nodeName": routeNode["nodeName"], "number": routeNode["number"] }) routeList.append({"routeId":routeParams["routeId"],"routeDist":int(routeDist),\ "routeTime":routeTime,"routeNumber":routeNumber,"orderNumber":orderNumber,\ "routeOccupancyRate":routeOccupancyRate,"roundStatus":0,\ "routeNodeList":routeNodeResult,"invalidNodeList":invalidNodeList}) #返程 roundRouteNodeResult = aiBusModel.selectRouteDetail( (routeParams["routeId"], 1, 1, 1)) if roundRouteNodeResult and len(roundRouteNodeResult) > 0: routeTime = 0 routeDist = 0 routeNumber = 0 routeOccupancyRate = 0 for routeNode in roundRouteNodeResult: routeTime += routeNode["nextTime"] routeDist += routeNode["nextDist"] routeNumber += routeNode["number"] invalidRouteNodeResult = aiBusModel.selectRouteDetail( (routeParams["routeId"], 1, 1, 0)) invalidNodeList = [] for routeNode in invalidRouteNodeResult: invalidNodeList.append({ "id": routeNode["id"], "lat": routeNode["lat"], "lng": routeNode["lng"], "nodeIndex": routeNode["nodeIndex"], "nodeName": routeNode["nodeName"], "number": routeNode["number"] }) routeOccupancyRate = float(routeNumber) / orderNumber * 100 routeList.append({"routeId":routeParams["routeId"],"routeDist":int(routeDist),\ "routeTime":routeTime,"routeNumber":routeNumber,"orderNumber":orderNumber,\ "routeOccupancyRate":routeOccupancyRate,"roundStatus":1,\ "routeNodeList":roundRouteNodeResult,"invalidNodeList":invalidNodeList}) #未规划的点 invalidRouteNodeResult = aiBusModel.selectRouteDetail( (routeParams["routeId"], 1, 2, 0)) invalidNodeList = [] for routeNode in invalidRouteNodeResult: invalidNodeList.append({ "id": routeNode["id"], "lat": routeNode["lat"], "lng": routeNode["lng"], "nodeIndex": routeNode["nodeIndex"], "nodeName": routeNode["nodeName"], "number": routeNode["number"] }) del routeParams["routeId"] res.update(code=ResponseCode.Success, data={ "routeParams": routeParams, "routeList": routeList }) return res.data except Exception as e: logger.error("queryRouteInfo exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="查询路线规划信息报错!") return res.data
def upInsertStation(): """ 新增或者更新站点 """ res = ResMsg() try: aiBusModel=AiBusModel() userInfo = session.get("userInfo") data=request.get_json() province=data['province'] city=data['city'] region=data["region"] siteName=data['siteName'] siteProperty=data['siteProperty'] road=data['road'] siteStatus=data['siteStatus'] latitude=float(data["latitude"]) longitude=float(data["longitude"]) direction=data["direction"] unilateral=data["unilateral"] upInsertType=data["upInsertType"] if siteName=="" or \ siteProperty=="" or\ latitude=="" or \ longitude=="" or \ direction=="" or \ upInsertType=="": res.update(code=ResponseCode.Fail,msg="必填字段不可为空!") return res.data if siteProperty=="临时": siteProperty=0 else: siteProperty=1 if siteStatus=="停用": siteStatus=3 elif siteStatus=="无效": siteStatus=2 else: siteStatus=1 if unilateral=="是": unilateral=1 else: unilateral=0 #geojson = '{ "type": "Point", "coordinates": [%s, %s]}'% (longitude,latitude) if upInsertType=="I": #根据站点名称和地理方位保持唯一性 row=aiBusModel.selectStationByNameDirection((siteName,direction)) if row["num"]>0: res.update(code=ResponseCode.Fail,msg="该站点+地理方位己存在!") return res.data aiBusModel.insertStation((province,city,region,siteName,siteProperty,siteStatus,direction,longitude,latitude,road,unilateral,userInfo["citycode"],userInfo["userName"],userInfo["userName"])) else: id=data['id'] if id is None or id=="": res.update(code=ResponseCode.Fail,msg="更新站点id不能为null") return res.data row=aiBusModel.updateStation((province,city,region,siteName,siteProperty,siteStatus,direction,longitude,latitude,road,unilateral,userInfo["citycode"],userInfo["userName"],id)) res.update(code=ResponseCode.Success, msg="保存成功!") return res.data except Exception as e: res.update(code=ResponseCode.Fail,msg="站点新增/编辑报错!") return res.data
def removeClusterResult(): """ 根据网点文件id,失效网点文件、聚类问件,聚类结果和网点结果 """ res = ResMsg() try: logger.info("begin removeClusterResult!") aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() fileId = data["fileId"] aiBusModel.updateSiteFile((0, 0, userInfo["userName"], fileId)) aiBusModel.updateSiteStatusByfieldId( (0, userInfo["userName"], fileId, 1)) aiBusModel.updateClusterResultByFileId( (0, userInfo["userName"], fileId), [1, 2]) #失效fileId对应的聚类文件 siteParams = aiBusModel.selectClusterParamsBySiteFileId( (fileId)) ##根据网点文件fileId的查询网点文件 if siteParams: aiBusModel.updateClusterResultByFileId( (0, userInfo["userName"], siteParams["id"]), [1, 2]) aiBusModel.updateSiteFile( (0, 0, userInfo["userName"], siteParams["id"])) res.update(code=ResponseCode.Success, msg="成功删除网点聚类结果!") return res.data except Exception as e: logger.error("removeClusterResult exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="删除网点聚类结果报错!") return res.data
def queryClusterResult(): res = ResMsg() try: logger.info("begin queryClusterResult!") aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() fileId = data["fileId"] clusterOutPoints = [] clusterCorePoints = [] clusterAroundPoints = [] #1)先查询聚类参数 clusterParams = aiBusModel.selectClusterParams((fileId)) if not clusterParams: clusterParams = aiBusModel.selectClusterParamsBySiteFileId( (fileId)) if not clusterParams: res.update(code=ResponseCode.Success) return res.data fileId = clusterParams["id"] #2)查询聚类结果 clusterResut = aiBusModel.selectClusterResult((1, fileId)) for item in clusterResut: if item["relativeProperty"] == 1: siteProperty = "固定" elif item["relativeProperty"] == 0: siteProperty = "临时" else: siteProperty = "自定义" #根据site id查询网点信息 clientNames = [] users = [] if item["siteSet"] != '': users = item["siteSet"].split(",") siteInfo = aiBusModel.selectClientNameByIds(users) for site in siteInfo: clientNames.append(site["clientName"]) row={"id":item["id"],"siteName":item["clusterName"],"siteProperty":siteProperty,\ "longitude":item["longitude"],"latitude":item["latitude"],"number":item["number"],\ "users":users,"userNames":clientNames} if item["clusterProperty"] == 1: clusterCorePoints.append(row) elif item["clusterProperty"] == 2: clusterAroundPoints.append(row) else: clusterOutPoints.append(row) res.update(code=ResponseCode.Success, data={ "epsRadius": clusterParams["clusterRadius"], "minSamples": clusterParams["clusterMinSamples"], "clusterCorePoints": clusterCorePoints, "clusterAroundPoints": clusterAroundPoints, "clusterOutPoints": clusterOutPoints }) return res.data except Exception as e: logger.error("generateClusterPoints exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="查询聚类结果报错!") return res.data
def planSingleRoute(): """ 单路线规划 """ res = ResMsg() try: logger.info("begin planSingleRoute!") data = request.get_json() aiBusModel = AiBusModel() fileId = data["fileId"] destination = data["destination"] waypoints = data["waypoints"] passengers = data["passengers"] #座位上限 occupancyRate = int(data["occupancyRate"]) #改为上座下限 #初始化相关系数 odometerFactor = 100.0 maxDistance = 1000.0 * 1000 #m maxDuration = 24 * 3600 #分钟 if "odometerFactor" in data and data["odometerFactor"] != "": odometerFactor = float(data["odometerFactor"]) #非直线系数(非必选) if "maxDistance" in data and data["maxDistance"] != "": maxDistance = float( data["maxDistance"]) * 1000 #最大行程距离,data["maxDistance"](km) if "maxDuration" in data and data["maxDuration"] != "": maxDuration = float(data["maxDuration"]) * 60 #最大行程耗时 roundTrip = data["roundTrip"] #是否往返0, routeFactor = data["routeFactor"] #路线方案,0时间最短,1距离最短 vehicleType = int(data["vehicleType"]) #车辆类型0为小车方案,1为货车方案 MAXNODE = 20 MINNODE = 2 if not destination: res.update(code=ResponseCode.Fail, data=[], msg="目的地不能为空!") return res.data #1)先判断fileid是否为空 routeNode = [] indexList = [] index = 0 orderNumber = -1 #订单总数 if fileId is not None and fileId != '': #根据fileId查询文件信息,判断是聚类文件还网点文件 fileInfo = aiBusModel.selectSiteFileStatus(fileId) if fileInfo and fileInfo["clusterStatus"] == 1: clusterPoints = aiBusModel.selectClusterResult((1, fileId)) siteInfo = aiBusModel.selectSiteFileStatus( fileInfo["siteFileId"]) orderNumber = siteInfo["siteCount"] for point in clusterPoints: indexList.append(str(index)) routeNode.append({ "index": index, "nodeName": point["clusterName"], "lng": format(point["longitude"], '.6f'), "lat": format(point["latitude"], '.6f'), "number": point["number"] }) index += 1 else: orderNumber = fileInfo["siteCount"] sitePoints = aiBusModel.selectSiteInfoByFileId(fileId) for point in sitePoints: indexList.append(str(index)) routeNode.append({ "index": index, "nodeName": point["siteName"], "lng": format(point["longitude"], '.6f'), "lat": format(point["latitude"], '.6f'), "number": point["clientNumber"] }) index += 1 if orderNumber is None or orderNumber <= 0: orderNumber = passengers else: fileId = -1 orderNumber = passengers #添加途经点 for point in waypoints: indexList.append(str(index)) routeNode.append({ "index": index, "nodeName": point["siteName"], "lng": format(point["lng"], '.6f'), "lat": format(point["lat"], '.6f'), "number": point["number"] }) index += 1 #判断结点数量是否超过限制len(routeNode)>MAXNODE or if len(routeNode) < MINNODE: res.update(code=ResponseCode.Fail, data=[], msg="路线规划结点数量超过最大限制{}或者小于最小限度{}!".format( MAXNODE, MINNODE)) return res.data #判断参数是否冲突 if occupancyRate > passengers: res.update(code=ResponseCode.Fail, data=[], msg="路线规划上座下限必须小于座位上限!") return res.data """ if occupancyRate<=0 or occupancyRate>100: res.update(code=ResponseCode.Fail,data=[],msg="路线规划上座率下限必须大于{}或者小于{}!".format(0,100)) return res.data if passengers<int(orderNumber*occupancyRate/100): res.update(code=ResponseCode.Fail,data=[],msg="最低上座率人数超过座位上限!") return res.data """ #将目标点一起添加至末尾 routeNode.append({ "index": "dest", "nodeName": destination["siteName"], "lng": format(destination["lng"], '.6f'), "lat": format(destination["lat"], '.6f'), "number": 0 }) indexList.append("dest") #2)构建结点对,用于获取高德数据 nodePairDict = {} nodePairList = [] #用于多线程获取高德数据 pointNum = len(indexList) nodeCostDF = pd.DataFrame(np.zeros([pointNum, pointNum]), columns=indexList, index=indexList) routeNodePair = list(itertools.permutations(routeNode, 2)) paramIds = [] for nodePair in routeNodePair: fromNode = str(round(float(nodePair[0]["lng"]), 6)) + "," + str( round(float(nodePair[0]["lat"]), 6)) toNode = str(round(float(nodePair[1]["lng"]), 6)) + "," + str( round(float(nodePair[1]["lat"]), 6)) #手动生成id,批量查询 paramId = generate_md5_key(fromNode + "," + toNode) paramIds.append(paramId) #根据paramIds查询缓存的距离nodePairDistList nodePairParamsList = aiBusModel.selectRouteParams( vehicleType, paramIds) nodePairParamsDict = {} if nodePairParamsList: for item in nodePairParamsList: nodePairParamsDict[item["id"]] = item #获取nodePair的距离 for nodePair in routeNodePair: key = str(nodePair[0]["index"]) + "-" + str(nodePair[1]["index"]) fromNode = str(round(float(nodePair[0]["lng"]), 6)) + "," + str( round(float(nodePair[0]["lat"]), 6)) toNode = str(round(float(nodePair[1]["lng"]), 6)) + "," + str( round(float(nodePair[1]["lat"]), 6)) paramId = generate_md5_key(fromNode + "," + toNode) #先判断是否已经存在库中 if paramId in nodePairParamsDict.keys(): item = nodePairParamsDict[paramId] directDist = getGPSDistance(float(nodePair[0]["lng"]), float(nodePair[0]["lat"]), float(nodePair[1]["lng"]), float(nodePair[1]["lat"])) nodePairDict[key] = { "dist": float(item["dist"]), "time": item["time"], "directDist": directDist } #对df进行赋值 if routeFactor == 0: nodeCostDF.loc[str(nodePair[0]["index"]), str(nodePair[1]["index"])] = int( item["time"]) else: nodeCostDF.loc[str(nodePair[0]["index"]), str(nodePair[1]["index"])] = float( item["dist"]) else: nodePairList.append({ "key": key, "origin": fromNode, "destination": toNode, "routeType": vehicleType, "fromNode": nodePair[0], "toNode": nodePair[1], "paramId": paramId }) #从高德获取路径数据 if len(nodePairList) > 0: nodePairResult = build_process(nodePairList) for item in nodePairList: key = item["key"] nodeItem = nodePairResult[key] directDist = getGPSDistance(float(item["fromNode"]["lng"]), float(item["fromNode"]["lat"]), float(item["toNode"]["lng"]), float(item["toNode"]["lat"])) nodePairDict[key] = { "dist": nodeItem["dist"], "time": nodeItem["time"], "directDist": directDist } #对df进行赋值 if routeFactor == 0: nodeCostDF.loc[ str(item["fromNode"]["index"]), str(item["toNode"]["index"])] = nodeItem["time"] else: nodeCostDF.loc[ str(item["fromNode"]["index"]), str(item["toNode"]["index"])] = nodeItem["dist"] #存储获取的数据 if item["paramId"] not in nodePairParamsDict.keys(): #startGeo = '{ "type": "Point", "coordinates": [%s, %s]}'%(float(item["fromNode"]["lng"]),float(item["fromNode"]["lat"])) #endGeo = '{ "type": "Point", "coordinates": [%s, %s]}'%(float(item["toNode"]["lng"]),float(item["toNode"]["lat"])) aiBusModel.inserRouteParams((item["paramId"],float(item["fromNode"]["lng"]),float(item["fromNode"]["lat"]),\ float(item["toNode"]["lng"]),float(item["toNode"]["lat"]),nodeItem["dist"],nodeItem["time"],directDist,0.0)) else: aiBusModel.updateRouteParams( (nodeItem["dist"], nodeItem["time"], directDist, item["paramId"])) #3)进行路线规划 logger.info("start single route plan!") solution = singleRoutePlanByGreedyAlgorithm(routeNode, nodePairDict, nodeCostDF, passengers, occupancyRate, orderNumber, odometerFactor, maxDistance, maxDuration) if solution["routeNode"] is None: res.update(code=ResponseCode.Fail, data=[], msg="未找到满足条件的路线!") return res.data else: #用sa算法进行优化 routeInfo = { "nodePair": nodePairDict, "routeNode": solution["routeNode"], "routeFactor": routeFactor } reSolution = singleRoutePlanSolution(routeInfo) #print("re bestCost:",reSolution["bestRouteCost"]) if solution["bestRouteCost"] > reSolution["bestRouteCost"]: solution["routeNode"] = reSolution["routeNode"] #找出最后一段顺路点 if len(solution["routeNode"]) > 1: lastNode = solution["routeNode"][len(solution["routeNode"]) - 2] fromNode = str(round(float(lastNode["lng"]), 6)) + "," + str( round(float(lastNode["lat"]), 6)) toNode = str(round(float(destination["lng"]), 6)) + "," + str( round(float(destination["lat"]), 6)) polyline = get_driving_polyline(fromNode, toNode) solution = findOnwayRouteNode(solution, polyline) if solution["routeNumber"] < occupancyRate: res.update(code=ResponseCode.Fail, data=[], msg="未找到满足条件的路线!") return res.data logger.info("end single route plan!") #4)保存路线规划结果,获取最优路径的行程距离、行程时间、直线距离 routeList = [] ############往程################ nodeIndex = 0 routeDist = 0 routeTime = 0 routeNumber = 0 directDist = 0 routeNodeList = [] for i in range(len(solution["routeNode"]) - 1): fromNode = solution["routeNode"][i] toNode = solution["routeNode"][i + 1] key = str(fromNode["index"]) + "-" + str(toNode["index"]) routeDist += nodePairDict[key]["dist"] routeTime += nodePairDict[key]["time"] directDist += getGPSDistance(float(fromNode["lng"]), float(fromNode["lat"]), float(toNode["lng"]), float(toNode["lat"])) routeNumber += fromNode["number"] routeNodeList.append({"nodeIndex":nodeIndex,"nodeName":fromNode["nodeName"],\ "lng":float(fromNode["lng"]),"lat":float(fromNode["lat"]),"number":fromNode["number"],\ "nextDist":nodePairDict[key]["dist"],"nextTime":nodePairDict[key]["time"]}) nodeIndex += 1 #添加终点 routeNodeList.append({"nodeIndex":nodeIndex,"nodeName":destination["siteName"],\ "lng":float(destination["lng"]),"lat":float(destination["lat"]),"number":0,"nextDist":0,"nextTime":0}) #存储路线结点 routeUuid = uuid.uuid1().int aiBusModel.insertRouteInfo((fileId,routeUuid,destination["siteName"],\ destination["lng"],destination["lat"],passengers,occupancyRate,odometerFactor,\ routeFactor,roundTrip,json.dumps(waypoints),maxDistance,maxDuration,vehicleType,2)) for node in routeNodeList: aiBusModel.insertRouteDetail((fileId,routeUuid,0,node["nodeIndex"],node["nodeName"],2,\ node["lng"],node["lat"],node["number"],node["nextDist"],node["nextTime"],1,1)) for i, node in enumerate(solution["invalidRouteNode"]): aiBusModel.insertRouteDetail((fileId,routeUuid,0,i,node["nodeName"],2,\ node["lng"],node["lat"],node["number"],0,0,0,1)) #查询路线结点及未规划的结点 routeOccupancyRate = int(routeNumber / orderNumber * 100) routeNodeResult1 = aiBusModel.selectRouteDetail((routeUuid, 2, 0, 1)) invalidRouteNodeResult = aiBusModel.selectRouteDetail( (routeUuid, 2, 0, 0)) invalidNodeList = [] for routeNode in invalidRouteNodeResult: invalidNodeList.append({ "id": routeNode["id"], "lat": routeNode["lat"], "lng": routeNode["lng"], "nodeIndex": routeNode["nodeIndex"], "nodeName": routeNode["nodeName"], "number": routeNode["number"] }) routeList.append({"routeId":routeUuid,"routeDist":int(routeDist),\ "routeTime":routeTime,"routeNumber":routeNumber,"orderNumber":orderNumber,\ "routeOccupancyRate":routeOccupancyRate,"roundStatus":0,\ "routeNodeList":routeNodeResult1,"invalidNodeList":invalidNodeList}) #############返程################ if roundTrip == 1: roundRouteDist = 0 roundRouteTime = 0 roundDirectDist = 0 roundRouteNodeList = [] nodeIndex = 0 for i in range(len(solution["routeNode"]) - 1, 0, -1): fromNode = solution["routeNode"][i] toNode = solution["routeNode"][i - 1] key = str(fromNode["index"]) + "-" + str(toNode["index"]) roundRouteDist += nodePairDict[key]["dist"] roundRouteTime += nodePairDict[key]["time"] roundDirectDist += getGPSDistance(float(fromNode["lng"]), float(fromNode["lat"]), float(toNode["lng"]), float(toNode["lat"])) roundRouteNodeList.append({"nodeIndex":nodeIndex,"nodeName":fromNode["nodeName"],\ "lng":float(fromNode["lng"]),"lat":float(fromNode["lat"]),"number":fromNode["number"],\ "nextDist":nodePairDict[key]["dist"],"nextTime":nodePairDict[key]["time"]}) nodeIndex += 1 if i == 1: roundRouteNodeList.append({"nodeIndex":nodeIndex,"nodeName":toNode["nodeName"],\ "lng":float(toNode["lng"]),"lat":float(toNode["lat"]),"number":toNode["number"],\ "nextDist":0,"nextTime":0}) #存储结点 for node in roundRouteNodeList: aiBusModel.insertRouteDetail((fileId,routeUuid,1,node["nodeIndex"],node["nodeName"],2,\ node["lng"],node["lat"],node["number"],node["nextDist"],node["nextTime"],1,1)) for i, node in enumerate(solution["invalidRouteNode"]): aiBusModel.insertRouteDetail((fileId,routeUuid,1,i,node["nodeName"],2,\ node["lng"],node["lat"],node["number"],0,0,0,1)) #查询路线结点及未规划的结点 routeNodeResult2 = aiBusModel.selectRouteDetail( (routeUuid, 2, 1, 1)) invalidRouteNodeResult = aiBusModel.selectRouteDetail( (routeUuid, 2, 1, 0)) invalidNodeList = [] for routeNode in invalidRouteNodeResult: invalidNodeList.append({ "id": routeNode["id"], "lat": routeNode["lat"], "lng": routeNode["lng"], "nodeIndex": routeNode["nodeIndex"], "nodeName": routeNode["nodeName"], "number": routeNode["number"] }) routeList.append({"routeId":routeUuid,"routeDist":int(roundRouteDist),\ "routeTime":roundRouteTime,"routeNumber":routeNumber,"orderNumber":orderNumber,\ "routeOccupancyRate":routeOccupancyRate,"roundStatus":1,\ "routeNodeList":routeNodeResult2,"invalidNodeList":invalidNodeList}) res.update(code=ResponseCode.Success, data={ "destination": destination, "routeList": routeList }) return res.data except Exception as e: logger.error("planSingleRoute exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg=str(e)) return res.data
def generateClusterPoints(): """ 根据网点文件id生成聚类点 """ res = ResMsg() try: logger.info("begin generateClusterPoints!") aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() fileId = data["fileId"] epsRadius = float(data["epsRadius"]) minSamples = data["minSamples"] #先判断网点文件是否有效 fileProperty = aiBusModel.selectSiteFileStatus(fileId) if fileProperty["fileStatus"] == 0: res.update(code=ResponseCode.Fail, msg="该文件已经失效!") return res.data #根据网点文件查询网点list #先判断是该文件是聚类文件还是网点文件 if fileProperty["clusterStatus"] == 1: siteFileId = fileProperty["siteFileId"] else: siteFileId = fileId #对网点文件的临时聚类结果进行失效 aiBusModel.updateClusterResultByFileId( (0, userInfo["userName"], fileId), [2]) siteGeoList = aiBusModel.selectSiteGeoListByFileId(siteFileId) if not siteGeoList: res.update(code=ResponseCode.Fail, msg="网点为空!") return res.data #{"noiseList":[ids],"aroundList":[ids],"clusterDict":{"id":[ids],"id":[ids]}} clusterInfo = clusterByAdaptiveDbscan(siteGeoList, epsRadius, minSamples) #将聚类结果保存至表中 insertVals = [] siteGeoDict = {} for site in siteGeoList: siteGeoDict[str(site["id"])] = site clusterOutPoints = [] clusterCorePoints = [] clusterAroundPoints = [] #1)处理异常点fileId,siteId,clusterName,clusterProperty,clusterStatus,longitude,latitude,number,siteSet for id in clusterInfo["noiseList"]: relativeId = "site_" + str(id) site = siteGeoDict[str(id)] insertVals.append( (fileId, relativeId, site["siteName"], site["siteProperty"], 0, 2, site["lng"], site["lat"], site["number"], str(id), userInfo["userName"], userInfo["userName"])) #clusterOutPoints.append({"id":relativeId,"siteName":site["siteName"],"siteProperty":site["siteProperty"],"number":site["number"],"longitude":site["lng"],"latitude":site["lat"]}) #2)处理聚类点 for key in clusterInfo["clusterDict"].keys(): clusterSet = clusterInfo["clusterDict"][key] #处理聚类核心点 clusterNumber = 0 site = siteGeoDict[str(key)] for id in clusterSet: sitePoint = siteGeoDict[str(id)] clusterNumber += int(sitePoint["number"]) clusterIdStr = ",".join(map(str, clusterSet)) insertVals.append((fileId, "site_" + str(key), site["siteName"], site["siteProperty"], 1, 2, site["lng"], site["lat"], clusterNumber, clusterIdStr, userInfo["userName"], userInfo["userName"])) #处理边界点 for id in clusterInfo["aroundList"]: relativeId = "site_" + str(id) aroundSite = siteGeoDict[str(id)] insertVals.append( (fileId, relativeId, aroundSite["siteName"], aroundSite["siteProperty"], 2, 2, aroundSite["lng"], aroundSite["lat"], aroundSite["number"], str(id), userInfo["userName"], userInfo["userName"])) #3)插入聚类点并返回 aiBusModel.batchClusterSites(insertVals) #4)返回聚类结果 clusterResut = aiBusModel.selectClusterResult((2, fileId)) for item in clusterResut: if item["relativeProperty"] == 1: siteProperty = "固定" elif item["relativeProperty"] == 0: siteProperty = "临时" else: siteProperty = "自定义" #根据site id查询网点信息 siteInfo = aiBusModel.selectClientNameByIds( item["siteSet"].split(",")) clientNames = [] for site in siteInfo: clientNames.append(site["clientName"]) row={"id":item["id"],"siteName":item["clusterName"],"siteProperty":siteProperty,\ "longitude":item["longitude"],"latitude":item["latitude"],"number":item["number"],\ "users":item["siteSet"].split(","),"userNames":clientNames} if item["clusterProperty"] == 1: clusterCorePoints.append(row) elif item["clusterProperty"] == 2: clusterAroundPoints.append(row) else: clusterOutPoints.append(row) res.update(code=ResponseCode.Success, data={ "clusterCorePoints": clusterCorePoints, "clusterAroundPoints": clusterAroundPoints, "clusterOutPoints": clusterOutPoints }) return res.data except Exception as e: logger.error("generateClusterPoints exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg=str(e)) return res.data
def saveClusterResult(): """ 保存聚类接口 """ res = ResMsg() try: logger.info("begin saveClusterResult!") aiBusModel = AiBusModel() userInfo = session.get("userInfo") data = request.get_json() fileId = data["fileId"] epsRadius = data["epsRadius"] minSamples = data["minSamples"] clusterAroundPoints = data["clusterAroundPoints"] clusterCorePoints = data["clusterCorePoints"] clusterOutPoints = data["clusterOutPoints"] #1)先判断该文件是网点文件还是聚类结果文件,再更新文件表; fileProperty = aiBusModel.selectSiteFileStatus(fileId) if fileProperty["clusterStatus"] == 1: aiBusModel.updateClusterParams( (epsRadius, minSamples, userInfo["userName"], fileId)) else: #先判断是否存在聚类文件 row = aiBusModel.selectClusterFileId( (fileProperty["fileName"] + "_聚类", 1, fileId)) if not row: #插入新的聚类文件 #fileName,fileProperty,fileStatus,siteFileId,clusterStatus,clusterRadius,clusterMinSamples,destination,mapType,longitude,latitude,userCitycode,createUser,updateUser aiBusModel.insertClusterFile((fileProperty["fileName"]+"_聚类",1,1,fileId,\ 1,epsRadius,minSamples,fileProperty["destination"],fileProperty["mapType"], fileProperty["longitude"],fileProperty["latitude"],userInfo["citycode"],userInfo["userName"],userInfo["userName"])) #查询对应聚类文件id clusterFile = aiBusModel.selectClusterFileId( (fileProperty["fileName"] + "_聚类", 1, fileId)) fileId = clusterFile["id"] else: aiBusModel.updateClusterParams( (epsRadius, minSamples, userInfo["userName"], row["id"])) fileId = row["id"] #对文件的之前的聚类结果进行失效 aiBusModel.updateClusterResultByFileId( (0, userInfo["userName"], fileId), [1, 2]) #2)插入边界点 for point in clusterAroundPoints: if point["siteProperty"] == "固定": relativeProperty = 1 elif point["siteProperty"] == "临时": relativeProperty = 0 else: relativeProperty = 2 siteSet = ",".join(point["users"]).strip(",") if point["id"] != "": #clusterName=%s,fileId=%s,clusterProperty=%s,clusterStatus=%s,relativeProperty=%s,longitude=%s,latitude=%s, number=%s,siteSet=%s,updateUser=%s aiBusModel.updateClusterPointById( (point["siteName"], fileId, 2, 1, relativeProperty, float(point["longitude"]), float(point["latitude"]), point["number"], siteSet, userInfo["userName"], point["id"])) else: aiBusModel.insertClusterPoint( (fileId, "", relativeProperty, point["siteName"], 2, 1, float(point["longitude"]), float(point["latitude"]), point["number"], siteSet, userInfo["userName"], userInfo["userName"])) #3)插入聚类点 for point in clusterCorePoints: if point["siteProperty"] == "固定": relativeProperty = 1 elif point["siteProperty"] == "临时": relativeProperty = 0 else: relativeProperty = 2 siteSet = ",".join(point["users"]).strip(",") if point["id"] != "": #clusterName=%s,fileId=%s,clusterProperty=%s,clusterStatus=%s,relativeProperty=%s,longitude=%s,latitude=%s, number=%s,siteSet=%s,updateUser=%s aiBusModel.updateClusterPointById( (point["siteName"], fileId, 1, 1, relativeProperty, float(point["longitude"]), float(point["latitude"]), point["number"], siteSet, userInfo["userName"], point["id"])) else: aiBusModel.insertClusterPoint( (fileId, "", relativeProperty, point["siteName"], 1, 1, float(point["longitude"]), float(point["latitude"]), point["number"], siteSet, userInfo["userName"], userInfo["userName"])) #4)插入异常点 for point in clusterOutPoints: if point["siteProperty"] == "固定": relativeProperty = 1 elif point["siteProperty"] == "临时": relativeProperty = 0 else: relativeProperty = 2 siteSet = ",".join(point["users"]).strip(",") if point["id"] != "": #clusterName=%s,fileId=%s,clusterProperty=%s,clusterStatus=%s,relativeProperty=%s,longitude=%s,latitude=%s, number=%s,siteSet=%s,updateUser=%s aiBusModel.updateClusterPointById( (point["siteName"], fileId, 0, 1, relativeProperty, float(point["longitude"]), float(point["latitude"]), point["number"], siteSet, userInfo["userName"], point["id"])) else: aiBusModel.insertClusterPoint( (fileId, "", relativeProperty, point["siteName"], 0, 1, float(point["longitude"]), float(point["latitude"]), point["number"], siteSet, userInfo["userName"], userInfo["userName"])) res.update(code=ResponseCode.Success, msg="成功保存聚类结果!") return res.data except Exception as e: logger.error("generateClusterPoints exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="保存聚类点保存!") return res.data
def reSortRouteNode(): """ 调整路径规划结点 """ res = ResMsg() try: logger.info("begin reSortRouteNode!") aiBusModel = AiBusModel() data = request.get_json() fileId = data["fileId"] routeId = data["routeId"] roundStatus = data["roundStatus"] passengers = data["passengers"] vehicleType = int(data["vehicleType"]) routeNodeList = data["routeNodeList"] invalidNodeList = data["invalidNodeList"] #根据结点顺序获取对应信息 nodeIndex = 0 newInvalidNodeList = [] for node in invalidNodeList: #aiBusModel.updateRouteDetail((nodeIndex,0,0,0,2,2,routeId,node["id"])) newInvalidNodeList.append({"id":node["id"],"nodeIndex":nodeIndex,"nodeName":node["nodeName"],\ "lng":float(node["lng"]),"lat":float(node["lat"]),"number":node["number"]}) nodeIndex += 1 nodeIndex = 0 routeDist = 0 routeTime = 0 routeNumber = 0 newRouteNodeList = [] length = len(routeNodeList) dist = 0 time = 0 for i in range(length - 1): fromNode = routeNodeList[i] toNode = routeNodeList[i + 1] fromLngLat = str(round(float(fromNode["lng"]), 6)) + "," + str( round(float(fromNode["lat"]), 6)) toLngLat = str(round(float(toNode["lng"]), 6)) + "," + str( round(float(toNode["lat"]), 6)) #手动生成id,批量查询 paramId = generate_md5_key(fromLngLat + "," + toLngLat) row = aiBusModel.selectRouteParams(vehicleType, [paramId]) if row is None or len(row) < 1 or row[0]["dist"]: startPoint = str(fromNode["lng"]) + "," + str(fromNode["lat"]) endPoint = str(toNode["lng"]) + "," + str(toNode["lat"]) distTime = get_route_distance_time(startPoint, endPoint, routeType=vehicleType) dist += distTime["dist"] time += distTime["time"] routeDist += distTime["dist"] routeTime += distTime["time"] else: dist += row[0]["dist"] time += row[0]["time"] routeDist += row[0]["dist"] routeTime += row[0]["time"] #判断结点中type if fromNode["nodeType"] == 0: newRouteNodeList.append({"nodeIndex":nodeIndex,"nodeName":fromNode["nodeName"],\ "lng":float(fromNode["lng"]),"lat":float(fromNode["lat"]),"number":fromNode["number"],\ "nextDist":dist,"nextTime":time,"nodeType":fromNode["nodeType"]}) else: routeNumber += fromNode["number"] newRouteNodeList.append({"id":fromNode["id"],"nodeIndex":nodeIndex,"nodeName":fromNode["nodeName"],\ "lng":float(fromNode["lng"]),"lat":float(fromNode["lat"]),"number":fromNode["number"],\ "nextDist":dist,"nextTime":time,"nodeType":fromNode["nodeType"]}) dist = 0 time = 0 nodeIndex += 1 if i + 1 == length - 1: newRouteNodeList.append({"id":toNode["id"],"nodeIndex":nodeIndex,"nodeName":toNode["nodeName"],\ "lng":float(toNode["lng"]),"lat":float(toNode["lat"]),"number":toNode["number"],"nextDist":0,"nextTime":0,"nodeType":toNode["nodeType"]}) routeNumber += toNode["number"] #获取网点人数 orderNumber = -1 fileInfo = aiBusModel.selectSiteFileStatus(fileId) if fileInfo: if fileInfo["clusterStatus"] == 1: siteInfo = aiBusModel.selectSiteFileStatus( fileInfo["siteFileId"]) if siteInfo: orderNumber = siteInfo["siteCount"] else: orderNumber = fileInfo["siteCount"] if orderNumber is None or orderNumber <= 0: orderNumber = passengers #返回结果 routeOccupancyRate = float(routeNumber) / orderNumber * 100 result={"routeId":routeId,"routeDist":int(routeDist),\ "routeTime":routeTime,"routeNumber":routeNumber,"orderNumber":orderNumber,\ "routeOccupancyRate":routeOccupancyRate,"routeNodeList":newRouteNodeList,\ "invalidNodeList":newInvalidNodeList,"roundStatus":roundStatus} res.update(code=ResponseCode.Success, data={"routeList": [result]}) return res.data except Exception as e: logger.error("reSortRouteNode exception:{}".format(str(e))) res.update(code=ResponseCode.Fail, msg="路线规划结点调整报错!") return res.data