예제 #1
0
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
예제 #2
0
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
예제 #3
0
 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
예제 #4
0
 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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #14
0
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
예제 #15
0
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
예제 #16
0
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
예제 #17
0
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
예제 #18
0
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
예제 #19
0
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
예제 #20
0
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
예제 #21
0
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
예제 #22
0
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