# coding:utf-8

"""
<NAME>, <NAME>
May 15, 2017
排班逻辑修改 Wangmeng Song
June 20, 2017
June 29, 2017
June 30, 2017
添加新逻辑
July 21,2017
增加新逻辑
August 8,2017
优化人少
August 29,2017
东边2.5环增加新逻辑
July 05, 2017
July 08, 2017 继续增加特殊情况的判断
"""

import numpy as np
import copy
from compiler.ast import flatten

import schedule
import mapAPI
import auxfn
from recomTimeOnTheBus import eastandwestside

AMAPKEYCOORDINATE = [30.599403, 104.040368]  # 高速交汇点
AMAPAIRPORTCOORDINATE = [30.574590, 103.955020]  # 成都机场
TIANFUSQUIRE = [30.604043, 104.074086]
SEARCHRADIUS = 1500  # 1500m的范围
CARSEATS = 5     # 一辆车最大乘客为6个人
TIMELIMIT = 6000    # 时间限制为6000s
# event = threading.Event()  # 设置全局变量event为True


def startschedul(resdict):
    # ------------------
    # initialization
    # event.wait()    # 设置全局变量event为false,是其他线程处于等待状态
    dis = schedule.DIST()   # 实例化DIST类
    GTI = mapAPI.AMapAPI()   # 实例化AMapAPI类
    area = eastandwestside.SIDE()  # 实例化区分区域的类
    # 获得两个list，specifyDriverDic, normalPassengerDic
    specifyDriverDic = []  # 存储指定司机的乘客
    normalPassengerDic = []  # 存储普通乘客
    # 分辨指定司机的乘客和普通乘客
    dis.getTheSpecifyAndNormal(specifyDriverDic, normalPassengerDic, resdict)
    # 处理指定司机的订单
    if len(specifyDriverDic) > 0:
        specifyDriverOrder = dis.getTheSpecifyDriverOrder(specifyDriverDic)
    else:
        specifyDriverOrder = None
    arrangedPassengerIdx = []  # store order index on all cars
    currentScheduleVec = []  # temporary using, store each passenger's travelling time on the same car
    currentPassengerIdx = []  # 存储当前车的乘客
    time2AirportVec = []  # store each passenger's travelling time
    numPassengerVec = []  # store the number of passengers on each car
    # ------------------
    # Get all the order coordinates, save in a 2D-array, 1st row is latitude, 2nd row is longitude
    getonthecar = []  # [[A,,B,C],[D,E,F]] 存储一个满足条件上车的或者乘客==5or6的订单
    getonthecarLoc = []  # [(lat1,lng1),(lat2,lng2)] 存储一个地点的lat,lng， 不需要
    getonthecarseatnum = []  # [[1,2,3],[2,3]] 存储一个地点的乘客人数,不需要
    repeatpoid = []     # 存储第一次处理的传入数据的订单号
    repeatloc = []      # 存储第一次处理的传入数据的经纬度
    repeatseatnum = []      # 存储第一次处理的传入数据的乘客人数
    # 处理第一次传入的数据，第一次处理：过滤一个订单乘客人数==5or6
    # 待修改（一个订单==5或者一个订单==6直接上车，或者在2.5环外直接上车，修改待确认）
    # 获得所有的订单数据将订单格式转换为id:[[],[],[]], loc:[(),(),()], seatnum:[[],[],[],[]]
    dis.getAllRepeatData(repeatpoid, repeatloc, repeatseatnum, getonthecar, getonthecarLoc, getonthecarseatnum, normalPassengerDic)
    duplicateOrderID = []   # 存储唯一地点的订单号（整合100m的范围的订单）
    duplicateSeatNum = []   # 存储与地点对应的乘客人数
    # 整合100m范围内的订单
    duplicateLoc = dis.getDuplicateData(repeatpoid, repeatloc, repeatseatnum, duplicateOrderID, duplicateSeatNum)
    RMMTSixpassengerOrderID = []    # 存储去除100m范围内5/6人的订单的订单号
    RMMTSixpassengerLoc = []        # 存储去除100m范围内5/6人的订单的经纬度
    RMMTSixpassengerseatnum = []    # 存储去除100m范围内5/6的订单的乘客人数
    # 过滤100m范围内的订单人数为5/6的情况
    dis.removeMoreThanSixPassenger(duplicateOrderID, duplicateLoc, duplicateSeatNum,
                                   RMMTSixpassengerOrderID, RMMTSixpassengerLoc, RMMTSixpassengerseatnum,
                                   getonthecar, getonthecarLoc, getonthecarseatnum)
    # 判断已经上车的人中的车，如果车上有5个人那么在500m范围再找一个人，有就上车，没有也走，已经不再需要
    # if len(getonthecarLoc) > 0:
    #     # 寻找一个地点乘客人数==5的周围是否存在1个订单1个人的情况
    #     dis.getTheFivePersonAroundOnlyOne(getonthecar, getonthecarLoc, getonthecarseatnum,
    #                                       RMMTSixpassengerOrderID, RMMTSixpassengerLoc, RMMTSixpassengerseatnum)
    # 判断loc是否在纬度以北，如果在纬度以南就直接上车，纬度以北进入排班
    northOrderID = []   # [[A,,B,C],[D,E,F]]
    northOrderLoc = []  # [(lat1,lng1),(lat2,lng2)]
    northOrderSeatnum = []  # [[1,2,3],[2,3]]
    # 超出接送范围的订单单独上车
    dis.distinguish(getonthecar, getonthecarLoc, getonthecarseatnum, RMMTSixpassengerOrderID, RMMTSixpassengerLoc, RMMTSixpassengerseatnum, northOrderID, northOrderLoc, northOrderSeatnum)
    # 进入调用schedule的订单数
    orderNum = len(northOrderLoc)     # 进入排班算法的总地点数
    seatNumVec = dis.getOrderNumVec(northOrderSeatnum)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
    sidevec = area.ateast(northOrderLoc, orderNum)   # 地区东边和西边的代码，地图东为1，西为2,array
    eastareaVec = np.where(sidevec <= 1)[0]  # 东边地区的index集合，一维array
    westareaVec = np.where(sidevec >= 2)[0]  # 西边地区的index集合，一维array
    # 如果两边小于等于就直接上车
    # if sum(seatNumVec) <= 1:
    #     dis.leftandrightgetonthecar(getonthecar, northOrderID, northOrderLoc)
    #     if len(specifyDriverDic) > 0:
    #         AllCarOrder = getonthecar + specifyDriverOrder
    #     else:
    #         AllCarOrder = getonthecar
    #     return AllCarOrder
    # 如果东边和西边的人数同时小于或等于6就分别上车
    if sum(seatNumVec[eastareaVec]) <= 6 and sum(seatNumVec[westareaVec]) <= 6:
        eastcar = [northOrderID[e] for e in eastareaVec]
        if len(eastcar) > 0:
            eastloc = [northOrderLoc[lc] for lc in eastareaVec]
            eastcarpool = [ewd for (elc, ewd) in sorted(zip([elat[0] for elat in eastloc], eastcar), reverse=True)]
            getonthecar.append(flatten(eastcarpool))
        westcar = [northOrderID[w] for w in westareaVec]
        if len(westcar) > 0:
            westloc = [northOrderLoc[wl] for wl in westareaVec]
            westcarpool = [wd for (lc, wd) in sorted(zip([lat[0] for lat in westloc], westcar), reverse=True)]
            getonthecar.append(flatten(westcarpool))
        if specifyDriverOrder is None:
            AllCarOrder = copy.copy(getonthecar)
        else:
            AllCarOrder = getonthecar + specifyDriverOrder
        return AllCarOrder
    # 如果东边小于等于6，西边大于6,东边上车
    elif sum(seatNumVec[eastareaVec]) <= 6 and sum(seatNumVec[westareaVec]) > 6:
        eastcar = [northOrderID[e] for e in eastareaVec]
        if len(eastcar) > 0:
            eastloc = [northOrderLoc[f] for f in eastareaVec]
            carpool = [wd for (lc, wd) in sorted(zip([lat[0] for lat in eastloc], eastcar), reverse=True)]
            getonthecar.append(flatten(carpool))
            for delindex in reversed(eastareaVec):
                del(northOrderID[delindex])
                del(northOrderLoc[delindex])
                del(northOrderSeatnum[delindex])
        restorderNo = []  # [[A,,B,C],[D,E,F]]
        restorderLoc = []  # [(lat1,lng1),(lat2,lng2)]
        restorderSeatNo = []  # [[1,2,3],[2,3]]
        newwestareaVec = np.arange(len(northOrderLoc))
        dis.westschedule(northOrderID, northOrderLoc, northOrderSeatnum, newwestareaVec, restorderNo, restorderLoc,
                         restorderSeatNo, getonthecar)
        if sum(flatten(restorderSeatNo)) <= 6:
            if len(restorderSeatNo) > 0:
                carsorted = [wd for (lc, wd) in sorted(zip([lat[0] for lat in restorderLoc], restorderNo), reverse=True)]
                getonthecar.append(flatten(carsorted))
            if specifyDriverOrder is None:
                AllCarOrder = copy.copy(getonthecar)
            else:
                AllCarOrder = getonthecar + specifyDriverOrder
            return AllCarOrder
        else:
            restorderNum = len(restorderLoc)
            restsideVec = area.ateast(restorderLoc, restorderNum)  # 地区东边和西边的代码，地图东为1，西为2,array
            restSeatNoVec = dis.getOrderNumVec(restorderSeatNo)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
            orderVec = dis.getOrderLocVec(restorderLoc)  # 一维的经纬度列表转换为二维的经纬度数组
            keypointDistVec = auxfn.calcDistVec(TIANFUSQUIRE, orderVec)  # 获取每个地点到天府高速交汇点的一维数组
            # Calculate the time distance from airport for each order
            airportTimeDistVec = GTI.getTimeDistVec(AMAPAIRPORTCOORDINATE, orderVec, restorderNum)  # 获取每个地点到机场的时间距离
            while len(arrangedPassengerIdx) < restorderNum:
                firstPassengerIdx = np.argmax(keypointDistVec)  # 寻找距离机场最远的第一个上车的人
                arrangedPassengerIdx.append(firstPassengerIdx)  # 存储地点位置的索引[3,4,1,0]
                currentScheduleVec.append(airportTimeDistVec[firstPassengerIdx])  # 存储时间的索引，2017/6/19时间已经不再使用
                currentPassengerIdx.append(firstPassengerIdx)
                numPassenger = restSeatNoVec[firstPassengerIdx]  # 每辆车上的乘客
                keypointDistVec[firstPassengerIdx] = 0  # 找到后进行虚拟删除，将值赋为0
                while numPassenger < CARSEATS:
                    # Searching next passenger
                    # ----------------------------
                    # find the passengers in the neighborhood area, remove the previous arranged passenger location
                    # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                    neighborhoodIdxVec1 = auxfn.getNeighborhoodIdx(orderVec, orderVec[firstPassengerIdx, :],
                                                                   SEARCHRADIUS, firstPassengerIdx, restsideVec)
                    neighborhoodIdxVec = [x for x in neighborhoodIdxVec1 if x not in arrangedPassengerIdx]
                    # ----------------------------
                    # if there is someone in the neighborhood， choose that one as next passenger
                    # else if there is no unarranged passenger in the neighborhood, search all the rest of points
                    # choose the closest point && closer to key point than current passenger
                    if len(neighborhoodIdxVec) >= 1:
                        nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc,
                                                                     neighborhoodIdxVec)
                    else:
                        ix = np.where(np.in1d(np.arange(restorderNum), arrangedPassengerIdx, invert=True))
                        if len(ix[0]) == 0:  # 最后一个人直接上车
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            break
                        else:
                            # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                            currentside = restsideVec[firstPassengerIdx]
                            tmpnextPassengerIdx = auxfn.getSortedPointIdx(orderVec[ix[0], :],
                                                                          orderVec[firstPassengerIdx, :],
                                                                          restsideVec[ix[0]], currentside)
                            tmpPassengerIdx = [ix[0][y] for y in tmpnextPassengerIdx]
                            nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc,
                                                                         tmpPassengerIdx)
                    # 周围没有人了结束循环叫新车
                    if len(nextPassengerIdx) == 0:
                        numPassengerVec.append(numPassenger)
                        time2AirportVec.append(currentScheduleVec)
                        currentScheduleVec = []
                        currentPassengerIdx = []
                        break
                    else:
                        # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制
                        # 时间限制暂时没有写（后面加上速度后补上）
                        neighborGetOnCar = [restSeatNoVec[element] for element in nextPassengerIdx]
                        carseatsWithNeighbor = np.array(neighborGetOnCar) + numPassenger
                        if carseatsWithNeighbor.min() > CARSEATS:
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            currentPassengerIdx = []
                            break
                    # compute the driving time from current to the next passenger
                    for i in xrange(len(nextPassengerIdx)):
                        if (numPassenger + restSeatNoVec[nextPassengerIdx[i]]) > CARSEATS:
                            continue
                        elif (dis.checkTimeLimitCondition(TIMELIMIT, orderVec[firstPassengerIdx, :],
                                                          orderVec[nextPassengerIdx[i], :], AMAPAIRPORTCOORDINATE,
                                                          currentScheduleVec, currentPassengerIdx,
                                                          nextPassengerIdx[i])):
                            numPassenger += restSeatNoVec[nextPassengerIdx[i]]
                            arrangedPassengerIdx.append(nextPassengerIdx[i])
                            firstPassengerIdx = nextPassengerIdx[i]
                            keypointDistVec[firstPassengerIdx] = 0
                            break
                else:
                    # 车上有6个人就结束循环叫新车
                    numPassengerVec.append(numPassenger)
                    time2AirportVec.append(currentScheduleVec)
                    currentScheduleVec = []
                    currentPassengerIdx = []
            # 获取每辆车的地点的下标[[],[]]二维列表
            carList = dis.getCarPassengerList(time2AirportVec, arrangedPassengerIdx)
            # 对获取结果排序 f**k
            # sortcarList = dis.sortPassenger(carList, northOrderLoc)
            # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表
            carOrderList = dis.getThePassengerOrderForEachCar(carList, restorderNo)
            # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表
            # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec)
            if specifyDriverOrder is None:
                AllCarOrder = carOrderList + getonthecar  # [[a,v,s],[q,w,e,r,f]]
            else:
                AllCarOrder = carOrderList + getonthecar + specifyDriverOrder
            return AllCarOrder
    # 如果西边小于等于6，东边大于6
    elif sum(seatNumVec[eastareaVec]) > 6 and sum(seatNumVec[westareaVec]) <= 6:
        westcar = [northOrderID[w] for w in westareaVec]
        if len(westcar) > 0:
            westloc = [northOrderLoc[g] for g in westareaVec]
            carpool = [wd for (lc, wd) in sorted(zip([lat[0] for lat in westloc], westcar), reverse=True)]
            getonthecar.append(flatten(carpool))
            for delindex in reversed(westareaVec):
                del(northOrderID[delindex])
                del(northOrderLoc[delindex])
                del(northOrderSeatnum[delindex])
        # 增加东边2环到2.5环之间的算法逻辑
        dis.eastschedule(northOrderID, northOrderLoc, northOrderSeatnum, getonthecar)
        if sum(flatten(northOrderSeatnum)) <= 6:
            if len(northOrderID) > 0:
                eastcarsorted = [wd for (lc, wd) in sorted(zip([lat[0] for lat in northOrderLoc], northOrderID), reverse=True)]
                getonthecar.append(flatten(eastcarsorted))
            if specifyDriverOrder is None:
                AllCarOrder = copy.copy(getonthecar)
            else:
                AllCarOrder = getonthecar + specifyDriverOrder
            return AllCarOrder
        else:
            restorderNum = len(northOrderLoc)
            restsideVec = area.ateast(northOrderLoc, restorderNum)  # 地区东边和西边的代码，地图东为1，西为2,array
            restSeatNoVec = dis.getOrderNumVec(northOrderSeatnum)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
            orderVec = dis.getOrderLocVec(northOrderLoc)  # 一维的经纬度列表转换为二维的经纬度数组
            keypointDistVec = auxfn.calcDistVec(TIANFUSQUIRE, orderVec)  # 获取每个地点到天府高速交汇点的一维数组
            # Calculate the time distance from airport for each order
            airportTimeDistVec = GTI.getTimeDistVec(AMAPAIRPORTCOORDINATE, orderVec, restorderNum)  # 获取每个地点到机场的时间距离
            while len(arrangedPassengerIdx) < restorderNum:
                firstPassengerIdx = np.argmax(keypointDistVec)  # 寻找距离机场最远的第一个上车的人
                arrangedPassengerIdx.append(firstPassengerIdx)  # 存储地点位置的索引[3,4,1,0]
                currentScheduleVec.append(airportTimeDistVec[firstPassengerIdx])  # 存储时间的索引，2017/6/19时间已经不再使用
                currentPassengerIdx.append(firstPassengerIdx)
                numPassenger = restSeatNoVec[firstPassengerIdx]  # 每辆车上的乘客
                keypointDistVec[firstPassengerIdx] = 0  # 找到后进行虚拟删除，将值赋为0
                while numPassenger < CARSEATS:
                    # Searching next passenger
                    # ----------------------------
                    # find the passengers in the neighborhood area, remove the previous arranged passenger location
                    # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                    neighborhoodIdxVec1 = auxfn.getNeighborhoodIdx(orderVec, orderVec[firstPassengerIdx, :], SEARCHRADIUS,
                                                                   firstPassengerIdx, restsideVec)
                    neighborhoodIdxVec = [x for x in neighborhoodIdxVec1 if x not in arrangedPassengerIdx]
                    # ----------------------------
                    # if there is someone in the neighborhood， choose that one as next passenger
                    # else if there is no unarranged passenger in the neighborhood, search all the rest of points
                    # choose the closest point && closer to key point than current passenger
                    if len(neighborhoodIdxVec) >= 1:
                        nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, northOrderLoc, neighborhoodIdxVec)
                    else:
                        ix = np.where(np.in1d(np.arange(restorderNum), arrangedPassengerIdx, invert=True))
                        if len(ix[0]) == 0:  # 最后一个人直接上车
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            break
                        else:
                            # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                            currentside = restsideVec[firstPassengerIdx]
                            tmpnextPassengerIdx = auxfn.getSortedPointIdx(orderVec[ix[0], :],
                                                                          orderVec[firstPassengerIdx, :],
                                                                          restsideVec[ix[0]], currentside)
                            tmpPassengerIdx = [ix[0][y] for y in tmpnextPassengerIdx]
                            nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, northOrderLoc, tmpPassengerIdx)
                    # 周围没有人了结束循环叫新车
                    if len(nextPassengerIdx) == 0:
                        numPassengerVec.append(numPassenger)
                        time2AirportVec.append(currentScheduleVec)
                        currentScheduleVec = []
                        currentPassengerIdx = []
                        break
                    else:
                        # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制
                        # 时间限制暂时没有写（后面加上速度后补上）
                        neighborGetOnCar = [restSeatNoVec[element] for element in nextPassengerIdx]
                        carseatsWithNeighbor = np.array(neighborGetOnCar) + numPassenger
                        if carseatsWithNeighbor.min() > CARSEATS:
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            currentPassengerIdx = []
                            break
                    # compute the driving time from current to the next passenger
                    for i in xrange(len(nextPassengerIdx)):
                        if (numPassenger + restSeatNoVec[nextPassengerIdx[i]]) > CARSEATS:
                            continue
                        elif (dis.checkTimeLimitCondition(TIMELIMIT, orderVec[firstPassengerIdx, :],
                                                          orderVec[nextPassengerIdx[i], :], AMAPAIRPORTCOORDINATE,
                                                          currentScheduleVec, currentPassengerIdx, nextPassengerIdx[i])):
                            numPassenger += restSeatNoVec[nextPassengerIdx[i]]
                            arrangedPassengerIdx.append(nextPassengerIdx[i])
                            firstPassengerIdx = nextPassengerIdx[i]
                            keypointDistVec[firstPassengerIdx] = 0
                            break
                else:
                    # 车上有6个人就结束循环叫新车
                    numPassengerVec.append(numPassenger)
                    time2AirportVec.append(currentScheduleVec)
                    currentScheduleVec = []
                    currentPassengerIdx = []
            # 获取每辆车的地点的下标[[],[]]二维列表
            carList = dis.getCarPassengerList(time2AirportVec, arrangedPassengerIdx)
            # 对获取结果排序 f**k
            # sortcarList = dis.sortPassenger(carList, northOrderLoc)
            # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表
            carOrderList = dis.getThePassengerOrderForEachCar(carList, northOrderID)
            # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表
            # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec)
            if specifyDriverOrder is None:
                # hasgetonthecarLocandTime = dis.gethasgotonthecartimedistance(getonthecarLoc, getonthecar)
                AllCarOrder = carOrderList + getonthecar  # [[a,v,s],[q,w,e,r,f]]
                # jsondata = dis.incodejs(AllCarOrderAndTime)
            else:
                AllCarOrder = carOrderList + getonthecar + specifyDriverOrder
            return AllCarOrder
    else:
        # 对订单在西边2环到2.5环的情况进行排班
        restorderNo = []   # [[A,,B,C],[D,E,F]]
        restorderLoc = []   # [(lat1,lng1),(lat2,lng2)]
        restorderSeatNo = []    # [[1,2,3],[2,3]]
        dis.westschedule(northOrderID, northOrderLoc, northOrderSeatnum, westareaVec, restorderNo, restorderLoc, restorderSeatNo, getonthecar)
        # 排班开始
        dis.eastschedule(restorderNo, restorderLoc, restorderSeatNo, getonthecar)
        # 判断东西边的人数
        dis.judgepeople(restorderNo, restorderLoc, restorderSeatNo, getonthecar)
        # 待修改
        restorderNum = len(restorderLoc)
        if restorderNum > 0:
            restsideVec = area.ateast(restorderLoc, restorderNum)   # 地区东边和西边的代码，地图东为1，西为2,array
            restSeatNoVec = dis.getOrderNumVec(restorderSeatNo)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
            orderVec = dis.getOrderLocVec(restorderLoc)     # 一维的经纬度列表转换为二维的经纬度数组
            keypointDistVec = auxfn.calcDistVec(TIANFUSQUIRE, orderVec)    # 获取每个地点到天府高速交汇点的一维数组
            # Calculate the time distance from airport for each order
            airportTimeDistVec = GTI.getTimeDistVec(AMAPAIRPORTCOORDINATE, orderVec, restorderNum)  # 获取每个地点到机场的时间距离
            while len(arrangedPassengerIdx) < restorderNum:
                firstPassengerIdx = np.argmax(keypointDistVec)  # 寻找距离机场最远的第一个上车的人
                arrangedPassengerIdx.append(firstPassengerIdx)  # 存储地点位置的索引[3,4,1,0]
                currentScheduleVec.append(airportTimeDistVec[firstPassengerIdx])  # 存储时间的索引，2017/6/19时间已经不再使用
                currentPassengerIdx.append(firstPassengerIdx)
                numPassenger = restSeatNoVec[firstPassengerIdx]    # 每辆车上的乘客
                keypointDistVec[firstPassengerIdx] = 0  # 找到后进行虚拟删除，将值赋为0
                while numPassenger < CARSEATS:
                    # Searching next passenger
                    # ----------------------------
                    # find the passengers in the neighborhood area, remove the previous arranged passenger location
                    # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                    neighborhoodIdxVec1 = auxfn.getNeighborhoodIdx(orderVec, orderVec[firstPassengerIdx, :], SEARCHRADIUS, firstPassengerIdx, restsideVec)
                    neighborhoodIdxVec = [x for x in neighborhoodIdxVec1 if x not in arrangedPassengerIdx]
                    # ----------------------------
                    # if there is someone in the neighborhood， choose that one as next passenger
                    # else if there is no unarranged passenger in the neighborhood, search all the rest of points
                    # choose the closest point && closer to key point than current passenger
                    if len(neighborhoodIdxVec) >= 1:
                        nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc, neighborhoodIdxVec)
                    else:
                        ix = np.where(np.in1d(np.arange(restorderNum), arrangedPassengerIdx, invert=True))
                        if len(ix[0]) == 0:   # 最后一个人直接上车
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            break
                        else:
                            # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                            currentside = restsideVec[firstPassengerIdx]
                            tmpnextPassengerIdx = auxfn.getSortedPointIdx(orderVec[ix[0], :], orderVec[firstPassengerIdx, :], restsideVec[ix[0]], currentside)
                            tmpPassengerIdx = [ix[0][y] for y in tmpnextPassengerIdx]
                            nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc, tmpPassengerIdx)
                    # 周围没有人了结束循环叫新车
                    if len(nextPassengerIdx) == 0:
                        numPassengerVec.append(numPassenger)
                        time2AirportVec.append(currentScheduleVec)
                        currentScheduleVec = []
                        currentPassengerIdx = []
                        break
                    else:
                        # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制
                        # 时间限制暂时没有写（后面加上速度后补上）
                        neighborGetOnCar = [restSeatNoVec[element] for element in nextPassengerIdx]
                        carseatsWithNeighbor = np.array(neighborGetOnCar) + numPassenger
                        if carseatsWithNeighbor.min() > CARSEATS:
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            currentPassengerIdx = []
                            break
                    # compute the driving time from current to the next passenger
                    for i in xrange(len(nextPassengerIdx)):
                        if (numPassenger + restSeatNoVec[nextPassengerIdx[i]]) > CARSEATS:
                            continue
                        elif (dis.checkTimeLimitCondition(TIMELIMIT, orderVec[firstPassengerIdx, :],
                                                          orderVec[nextPassengerIdx[i], :], AMAPAIRPORTCOORDINATE, currentScheduleVec, currentPassengerIdx, nextPassengerIdx[i])):
                            numPassenger += restSeatNoVec[nextPassengerIdx[i]]
                            arrangedPassengerIdx.append(nextPassengerIdx[i])
                            firstPassengerIdx = nextPassengerIdx[i]
                            keypointDistVec[firstPassengerIdx] = 0
                            break
                else:
                    # 车上有5个人就结束循环叫新车
                    numPassengerVec.append(numPassenger)
                    time2AirportVec.append(currentScheduleVec)
                    currentScheduleVec = []
                    currentPassengerIdx = []
            # 获取每辆车的地点的下标[[],[]]二维列表
            carList = dis.getCarPassengerList(time2AirportVec, arrangedPassengerIdx)
            # 对获取结果排序 f**k
            # sortcarList = dis.sortPassenger(carList, northOrderLoc)
            # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表
            carOrderList = dis.getThePassengerOrderForEachCar(carList, restorderNo)
            # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表
            # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec)
            if specifyDriverOrder is None:
                if len(getonthecar) == 0:
                    # 如果没有已经上车的订单就封装成json数组
                    AllCarOrder = copy.copy(carOrderList)
                else:
                    # 如果有已经上车的订单就将两个列表相加
                    # hasgetonthecarLocandTime = dis.gethasgotonthecartimedistance(getonthecarLoc, getonthecar)
                    AllCarOrder = carOrderList + getonthecar  # [[a,v,s],[q,w,e,r,f]]
                # jsondata = dis.incodejs(AllCarOrderAndTime)
                return AllCarOrder
            # 有指定司机的情况
            else:
                if len(getonthecar) == 0:
                    # 没有人提前上车
                    AllCarOrder = carOrderList + specifyDriverOrder
                else:
                    # 有人提前上车
                    AllCarOrder = carOrderList + getonthecar + specifyDriverOrder
                return AllCarOrder
        # 乘客已经全部提前上车
        else:
            if specifyDriverOrder is None:
                # 没有指定司机的乘客
                AllCarOrder = copy.copy(getonthecar)
            else:
                # 有指定司机的乘客
                AllCarOrder = getonthecar + specifyDriverOrder
            return AllCarOrder
# event.set()




# coding:utf-8

"""
<NAME>, <NAME>
May 15, 2017
排班逻辑修改 Wangmeng Song
June 20, 2017
June 29, 2017
June 30, 2017
添加新逻辑
July 21,2017
增加新逻辑
August 8,2017
优化人少
August 29,2017
东边2.5环增加新逻辑
July 05, 2017
July 08, 2017 继续增加特殊情况的判断
"""

import numpy as np
import copy
from compiler.ast import flatten

import schedule
import mapAPI
import auxfn
from recomTimeOnTheBus import eastandwestside

AMAPKEYCOORDINATE = [30.599403, 104.040368]  # 高速交汇点
AMAPAIRPORTCOORDINATE = [30.574590, 103.955020]  # 成都机场
TIANFUSQUIRE = [30.604043, 104.074086]
SEARCHRADIUS = 1500  # 1500m的范围
CARSEATS = 5     # 一辆车最大乘客为6个人
TIMELIMIT = 6000    # 时间限制为6000s
# event = threading.Event()  # 设置全局变量event为True


def startschedul(resdict):
    # ------------------
    # initialization
    # event.wait()    # 设置全局变量event为false,是其他线程处于等待状态
    dis = schedule.DIST()   # 实例化DIST类
    GTI = mapAPI.AMapAPI()   # 实例化AMapAPI类
    area = eastandwestside.SIDE()  # 实例化区分区域的类
    # 获得两个list，specifyDriverDic, normalPassengerDic
    specifyDriverDic = []  # 存储指定司机的乘客
    normalPassengerDic = []  # 存储普通乘客
    # 分辨指定司机的乘客和普通乘客
    dis.getTheSpecifyAndNormal(specifyDriverDic, normalPassengerDic, resdict)
    # 处理指定司机的订单
    if len(specifyDriverDic) > 0:
        specifyDriverOrder = dis.getTheSpecifyDriverOrder(specifyDriverDic)
    else:
        specifyDriverOrder = None
    arrangedPassengerIdx = []  # store order index on all cars
    currentScheduleVec = []  # temporary using, store each passenger's travelling time on the same car
    currentPassengerIdx = []  # 存储当前车的乘客
    time2AirportVec = []  # store each passenger's travelling time
    numPassengerVec = []  # store the number of passengers on each car
    # ------------------
    # Get all the order coordinates, save in a 2D-array, 1st row is latitude, 2nd row is longitude
    getonthecar = []  # [[A,,B,C],[D,E,F]] 存储一个满足条件上车的或者乘客==5or6的订单
    getonthecarLoc = []  # [(lat1,lng1),(lat2,lng2)] 存储一个地点的lat,lng， 不需要
    getonthecarseatnum = []  # [[1,2,3],[2,3]] 存储一个地点的乘客人数,不需要
    repeatpoid = []     # 存储第一次处理的传入数据的订单号
    repeatloc = []      # 存储第一次处理的传入数据的经纬度
    repeatseatnum = []      # 存储第一次处理的传入数据的乘客人数
    # 处理第一次传入的数据，第一次处理：过滤一个订单乘客人数==5or6
    # 待修改（一个订单==5或者一个订单==6直接上车，或者在2.5环外直接上车，修改待确认）
    # 获得所有的订单数据将订单格式转换为id:[[],[],[]], loc:[(),(),()], seatnum:[[],[],[],[]]
    dis.getAllRepeatData(repeatpoid, repeatloc, repeatseatnum, getonthecar, getonthecarLoc, getonthecarseatnum, normalPassengerDic)
    duplicateOrderID = []   # 存储唯一地点的订单号（整合100m的范围的订单）
    duplicateSeatNum = []   # 存储与地点对应的乘客人数
    # 整合100m范围内的订单
    duplicateLoc = dis.getDuplicateData(repeatpoid, repeatloc, repeatseatnum, duplicateOrderID, duplicateSeatNum)
    RMMTSixpassengerOrderID = []    # 存储去除100m范围内5/6人的订单的订单号
    RMMTSixpassengerLoc = []        # 存储去除100m范围内5/6人的订单的经纬度
    RMMTSixpassengerseatnum = []    # 存储去除100m范围内5/6的订单的乘客人数
    # 过滤100m范围内的订单人数为5/6的情况
    dis.removeMoreThanSixPassenger(duplicateOrderID, duplicateLoc, duplicateSeatNum,
                                   RMMTSixpassengerOrderID, RMMTSixpassengerLoc, RMMTSixpassengerseatnum,
                                   getonthecar, getonthecarLoc, getonthecarseatnum)
    # 判断已经上车的人中的车，如果车上有5个人那么在500m范围再找一个人，有就上车，没有也走，已经不再需要
    # if len(getonthecarLoc) > 0:
    #     # 寻找一个地点乘客人数==5的周围是否存在1个订单1个人的情况
    #     dis.getTheFivePersonAroundOnlyOne(getonthecar, getonthecarLoc, getonthecarseatnum,
    #                                       RMMTSixpassengerOrderID, RMMTSixpassengerLoc, RMMTSixpassengerseatnum)
    # 判断loc是否在纬度以北，如果在纬度以南就直接上车，纬度以北进入排班
    northOrderID = []   # [[A,,B,C],[D,E,F]]
    northOrderLoc = []  # [(lat1,lng1),(lat2,lng2)]
    northOrderSeatnum = []  # [[1,2,3],[2,3]]
    # 超出接送范围的订单单独上车
    dis.distinguish(getonthecar, getonthecarLoc, getonthecarseatnum, RMMTSixpassengerOrderID, RMMTSixpassengerLoc, RMMTSixpassengerseatnum, northOrderID, northOrderLoc, northOrderSeatnum)
    # 进入调用schedule的订单数
    orderNum = len(northOrderLoc)     # 进入排班算法的总地点数
    seatNumVec = dis.getOrderNumVec(northOrderSeatnum)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
    sidevec = area.ateast(northOrderLoc, orderNum)   # 地区东边和西边的代码，地图东为1，西为2,array
    eastareaVec = np.where(sidevec <= 1)[0]  # 东边地区的index集合，一维array
    westareaVec = np.where(sidevec >= 2)[0]  # 西边地区的index集合，一维array
    # 如果两边小于等于就直接上车
    # if sum(seatNumVec) <= 1:
    #     dis.leftandrightgetonthecar(getonthecar, northOrderID, northOrderLoc)
    #     if len(specifyDriverDic) > 0:
    #         AllCarOrder = getonthecar + specifyDriverOrder
    #     else:
    #         AllCarOrder = getonthecar
    #     return AllCarOrder
    # 如果东边和西边的人数同时小于或等于6就分别上车
    if sum(seatNumVec[eastareaVec]) <= 6 and sum(seatNumVec[westareaVec]) <= 6:
        eastcar = [northOrderID[e] for e in eastareaVec]
        if len(eastcar) > 0:
            eastloc = [northOrderLoc[lc] for lc in eastareaVec]
            eastcarpool = [ewd for (elc, ewd) in sorted(zip([elat[0] for elat in eastloc], eastcar), reverse=True)]
            getonthecar.append(flatten(eastcarpool))
        westcar = [northOrderID[w] for w in westareaVec]
        if len(westcar) > 0:
            westloc = [northOrderLoc[wl] for wl in westareaVec]
            westcarpool = [wd for (lc, wd) in sorted(zip([lat[0] for lat in westloc], westcar), reverse=True)]
            getonthecar.append(flatten(westcarpool))
        if specifyDriverOrder is None:
            AllCarOrder = copy.copy(getonthecar)
        else:
            AllCarOrder = getonthecar + specifyDriverOrder
        return AllCarOrder
    # 如果东边小于等于6，西边大于6,东边上车
    elif sum(seatNumVec[eastareaVec]) <= 6 and sum(seatNumVec[westareaVec]) > 6:
        eastcar = [northOrderID[e] for e in eastareaVec]
        if len(eastcar) > 0:
            eastloc = [northOrderLoc[f] for f in eastareaVec]
            carpool = [wd for (lc, wd) in sorted(zip([lat[0] for lat in eastloc], eastcar), reverse=True)]
            getonthecar.append(flatten(carpool))
            for delindex in reversed(eastareaVec):
                del(northOrderID[delindex])
                del(northOrderLoc[delindex])
                del(northOrderSeatnum[delindex])
        restorderNo = []  # [[A,,B,C],[D,E,F]]
        restorderLoc = []  # [(lat1,lng1),(lat2,lng2)]
        restorderSeatNo = []  # [[1,2,3],[2,3]]
        newwestareaVec = np.arange(len(northOrderLoc))
        dis.westschedule(northOrderID, northOrderLoc, northOrderSeatnum, newwestareaVec, restorderNo, restorderLoc,
                         restorderSeatNo, getonthecar)
        if sum(flatten(restorderSeatNo)) <= 6:
            if len(restorderSeatNo) > 0:
                carsorted = [wd for (lc, wd) in sorted(zip([lat[0] for lat in restorderLoc], restorderNo), reverse=True)]
                getonthecar.append(flatten(carsorted))
            if specifyDriverOrder is None:
                AllCarOrder = copy.copy(getonthecar)
            else:
                AllCarOrder = getonthecar + specifyDriverOrder
            return AllCarOrder
        else:
            restorderNum = len(restorderLoc)
            restsideVec = area.ateast(restorderLoc, restorderNum)  # 地区东边和西边的代码，地图东为1，西为2,array
            restSeatNoVec = dis.getOrderNumVec(restorderSeatNo)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
            orderVec = dis.getOrderLocVec(restorderLoc)  # 一维的经纬度列表转换为二维的经纬度数组
            keypointDistVec = auxfn.calcDistVec(TIANFUSQUIRE, orderVec)  # 获取每个地点到天府高速交汇点的一维数组
            # Calculate the time distance from airport for each order
            airportTimeDistVec = GTI.getTimeDistVec(AMAPAIRPORTCOORDINATE, orderVec, restorderNum)  # 获取每个地点到机场的时间距离
            while len(arrangedPassengerIdx) < restorderNum:
                firstPassengerIdx = np.argmax(keypointDistVec)  # 寻找距离机场最远的第一个上车的人
                arrangedPassengerIdx.append(firstPassengerIdx)  # 存储地点位置的索引[3,4,1,0]
                currentScheduleVec.append(airportTimeDistVec[firstPassengerIdx])  # 存储时间的索引，2017/6/19时间已经不再使用
                currentPassengerIdx.append(firstPassengerIdx)
                numPassenger = restSeatNoVec[firstPassengerIdx]  # 每辆车上的乘客
                keypointDistVec[firstPassengerIdx] = 0  # 找到后进行虚拟删除，将值赋为0
                while numPassenger < CARSEATS:
                    # Searching next passenger
                    # ----------------------------
                    # find the passengers in the neighborhood area, remove the previous arranged passenger location
                    # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                    neighborhoodIdxVec1 = auxfn.getNeighborhoodIdx(orderVec, orderVec[firstPassengerIdx, :],
                                                                   SEARCHRADIUS, firstPassengerIdx, restsideVec)
                    neighborhoodIdxVec = [x for x in neighborhoodIdxVec1 if x not in arrangedPassengerIdx]
                    # ----------------------------
                    # if there is someone in the neighborhood， choose that one as next passenger
                    # else if there is no unarranged passenger in the neighborhood, search all the rest of points
                    # choose the closest point && closer to key point than current passenger
                    if len(neighborhoodIdxVec) >= 1:
                        nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc,
                                                                     neighborhoodIdxVec)
                    else:
                        ix = np.where(np.in1d(np.arange(restorderNum), arrangedPassengerIdx, invert=True))
                        if len(ix[0]) == 0:  # 最后一个人直接上车
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            break
                        else:
                            # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                            currentside = restsideVec[firstPassengerIdx]
                            tmpnextPassengerIdx = auxfn.getSortedPointIdx(orderVec[ix[0], :],
                                                                          orderVec[firstPassengerIdx, :],
                                                                          restsideVec[ix[0]], currentside)
                            tmpPassengerIdx = [ix[0][y] for y in tmpnextPassengerIdx]
                            nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc,
                                                                         tmpPassengerIdx)
                    # 周围没有人了结束循环叫新车
                    if len(nextPassengerIdx) == 0:
                        numPassengerVec.append(numPassenger)
                        time2AirportVec.append(currentScheduleVec)
                        currentScheduleVec = []
                        currentPassengerIdx = []
                        break
                    else:
                        # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制
                        # 时间限制暂时没有写（后面加上速度后补上）
                        neighborGetOnCar = [restSeatNoVec[element] for element in nextPassengerIdx]
                        carseatsWithNeighbor = np.array(neighborGetOnCar) + numPassenger
                        if carseatsWithNeighbor.min() > CARSEATS:
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            currentPassengerIdx = []
                            break
                    # compute the driving time from current to the next passenger
                    for i in xrange(len(nextPassengerIdx)):
                        if (numPassenger + restSeatNoVec[nextPassengerIdx[i]]) > CARSEATS:
                            continue
                        elif (dis.checkTimeLimitCondition(TIMELIMIT, orderVec[firstPassengerIdx, :],
                                                          orderVec[nextPassengerIdx[i], :], AMAPAIRPORTCOORDINATE,
                                                          currentScheduleVec, currentPassengerIdx,
                                                          nextPassengerIdx[i])):
                            numPassenger += restSeatNoVec[nextPassengerIdx[i]]
                            arrangedPassengerIdx.append(nextPassengerIdx[i])
                            firstPassengerIdx = nextPassengerIdx[i]
                            keypointDistVec[firstPassengerIdx] = 0
                            break
                else:
                    # 车上有6个人就结束循环叫新车
                    numPassengerVec.append(numPassenger)
                    time2AirportVec.append(currentScheduleVec)
                    currentScheduleVec = []
                    currentPassengerIdx = []
            # 获取每辆车的地点的下标[[],[]]二维列表
            carList = dis.getCarPassengerList(time2AirportVec, arrangedPassengerIdx)
            # 对获取结果排序 f**k
            # sortcarList = dis.sortPassenger(carList, northOrderLoc)
            # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表
            carOrderList = dis.getThePassengerOrderForEachCar(carList, restorderNo)
            # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表
            # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec)
            if specifyDriverOrder is None:
                AllCarOrder = carOrderList + getonthecar  # [[a,v,s],[q,w,e,r,f]]
            else:
                AllCarOrder = carOrderList + getonthecar + specifyDriverOrder
            return AllCarOrder
    # 如果西边小于等于6，东边大于6
    elif sum(seatNumVec[eastareaVec]) > 6 and sum(seatNumVec[westareaVec]) <= 6:
        westcar = [northOrderID[w] for w in westareaVec]
        if len(westcar) > 0:
            westloc = [northOrderLoc[g] for g in westareaVec]
            carpool = [wd for (lc, wd) in sorted(zip([lat[0] for lat in westloc], westcar), reverse=True)]
            getonthecar.append(flatten(carpool))
            for delindex in reversed(westareaVec):
                del(northOrderID[delindex])
                del(northOrderLoc[delindex])
                del(northOrderSeatnum[delindex])
        # 增加东边2环到2.5环之间的算法逻辑
        dis.eastschedule(northOrderID, northOrderLoc, northOrderSeatnum, getonthecar)
        if sum(flatten(northOrderSeatnum)) <= 6:
            if len(northOrderID) > 0:
                eastcarsorted = [wd for (lc, wd) in sorted(zip([lat[0] for lat in northOrderLoc], northOrderID), reverse=True)]
                getonthecar.append(flatten(eastcarsorted))
            if specifyDriverOrder is None:
                AllCarOrder = copy.copy(getonthecar)
            else:
                AllCarOrder = getonthecar + specifyDriverOrder
            return AllCarOrder
        else:
            restorderNum = len(northOrderLoc)
            restsideVec = area.ateast(northOrderLoc, restorderNum)  # 地区东边和西边的代码，地图东为1，西为2,array
            restSeatNoVec = dis.getOrderNumVec(northOrderSeatnum)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
            orderVec = dis.getOrderLocVec(northOrderLoc)  # 一维的经纬度列表转换为二维的经纬度数组
            keypointDistVec = auxfn.calcDistVec(TIANFUSQUIRE, orderVec)  # 获取每个地点到天府高速交汇点的一维数组
            # Calculate the time distance from airport for each order
            airportTimeDistVec = GTI.getTimeDistVec(AMAPAIRPORTCOORDINATE, orderVec, restorderNum)  # 获取每个地点到机场的时间距离
            while len(arrangedPassengerIdx) < restorderNum:
                firstPassengerIdx = np.argmax(keypointDistVec)  # 寻找距离机场最远的第一个上车的人
                arrangedPassengerIdx.append(firstPassengerIdx)  # 存储地点位置的索引[3,4,1,0]
                currentScheduleVec.append(airportTimeDistVec[firstPassengerIdx])  # 存储时间的索引，2017/6/19时间已经不再使用
                currentPassengerIdx.append(firstPassengerIdx)
                numPassenger = restSeatNoVec[firstPassengerIdx]  # 每辆车上的乘客
                keypointDistVec[firstPassengerIdx] = 0  # 找到后进行虚拟删除，将值赋为0
                while numPassenger < CARSEATS:
                    # Searching next passenger
                    # ----------------------------
                    # find the passengers in the neighborhood area, remove the previous arranged passenger location
                    # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                    neighborhoodIdxVec1 = auxfn.getNeighborhoodIdx(orderVec, orderVec[firstPassengerIdx, :], SEARCHRADIUS,
                                                                   firstPassengerIdx, restsideVec)
                    neighborhoodIdxVec = [x for x in neighborhoodIdxVec1 if x not in arrangedPassengerIdx]
                    # ----------------------------
                    # if there is someone in the neighborhood， choose that one as next passenger
                    # else if there is no unarranged passenger in the neighborhood, search all the rest of points
                    # choose the closest point && closer to key point than current passenger
                    if len(neighborhoodIdxVec) >= 1:
                        nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, northOrderLoc, neighborhoodIdxVec)
                    else:
                        ix = np.where(np.in1d(np.arange(restorderNum), arrangedPassengerIdx, invert=True))
                        if len(ix[0]) == 0:  # 最后一个人直接上车
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            break
                        else:
                            # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                            currentside = restsideVec[firstPassengerIdx]
                            tmpnextPassengerIdx = auxfn.getSortedPointIdx(orderVec[ix[0], :],
                                                                          orderVec[firstPassengerIdx, :],
                                                                          restsideVec[ix[0]], currentside)
                            tmpPassengerIdx = [ix[0][y] for y in tmpnextPassengerIdx]
                            nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, northOrderLoc, tmpPassengerIdx)
                    # 周围没有人了结束循环叫新车
                    if len(nextPassengerIdx) == 0:
                        numPassengerVec.append(numPassenger)
                        time2AirportVec.append(currentScheduleVec)
                        currentScheduleVec = []
                        currentPassengerIdx = []
                        break
                    else:
                        # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制
                        # 时间限制暂时没有写（后面加上速度后补上）
                        neighborGetOnCar = [restSeatNoVec[element] for element in nextPassengerIdx]
                        carseatsWithNeighbor = np.array(neighborGetOnCar) + numPassenger
                        if carseatsWithNeighbor.min() > CARSEATS:
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            currentPassengerIdx = []
                            break
                    # compute the driving time from current to the next passenger
                    for i in xrange(len(nextPassengerIdx)):
                        if (numPassenger + restSeatNoVec[nextPassengerIdx[i]]) > CARSEATS:
                            continue
                        elif (dis.checkTimeLimitCondition(TIMELIMIT, orderVec[firstPassengerIdx, :],
                                                          orderVec[nextPassengerIdx[i], :], AMAPAIRPORTCOORDINATE,
                                                          currentScheduleVec, currentPassengerIdx, nextPassengerIdx[i])):
                            numPassenger += restSeatNoVec[nextPassengerIdx[i]]
                            arrangedPassengerIdx.append(nextPassengerIdx[i])
                            firstPassengerIdx = nextPassengerIdx[i]
                            keypointDistVec[firstPassengerIdx] = 0
                            break
                else:
                    # 车上有6个人就结束循环叫新车
                    numPassengerVec.append(numPassenger)
                    time2AirportVec.append(currentScheduleVec)
                    currentScheduleVec = []
                    currentPassengerIdx = []
            # 获取每辆车的地点的下标[[],[]]二维列表
            carList = dis.getCarPassengerList(time2AirportVec, arrangedPassengerIdx)
            # 对获取结果排序 f**k
            # sortcarList = dis.sortPassenger(carList, northOrderLoc)
            # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表
            carOrderList = dis.getThePassengerOrderForEachCar(carList, northOrderID)
            # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表
            # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec)
            if specifyDriverOrder is None:
                # hasgetonthecarLocandTime = dis.gethasgotonthecartimedistance(getonthecarLoc, getonthecar)
                AllCarOrder = carOrderList + getonthecar  # [[a,v,s],[q,w,e,r,f]]
                # jsondata = dis.incodejs(AllCarOrderAndTime)
            else:
                AllCarOrder = carOrderList + getonthecar + specifyDriverOrder
            return AllCarOrder
    else:
        # 对订单在西边2环到2.5环的情况进行排班
        restorderNo = []   # [[A,,B,C],[D,E,F]]
        restorderLoc = []   # [(lat1,lng1),(lat2,lng2)]
        restorderSeatNo = []    # [[1,2,3],[2,3]]
        dis.westschedule(northOrderID, northOrderLoc, northOrderSeatnum, westareaVec, restorderNo, restorderLoc, restorderSeatNo, getonthecar)
        # 排班开始
        dis.eastschedule(restorderNo, restorderLoc, restorderSeatNo, getonthecar)
        # 判断东西边的人数
        dis.judgepeople(restorderNo, restorderLoc, restorderSeatNo, getonthecar)
        # 待修改
        restorderNum = len(restorderLoc)
        if restorderNum > 0:
            restsideVec = area.ateast(restorderLoc, restorderNum)   # 地区东边和西边的代码，地图东为1，西为2,array
            restSeatNoVec = dis.getOrderNumVec(restorderSeatNo)  # 二维的乘客人数转换为与地点对应的一维数组 array[3,1]
            orderVec = dis.getOrderLocVec(restorderLoc)     # 一维的经纬度列表转换为二维的经纬度数组
            keypointDistVec = auxfn.calcDistVec(TIANFUSQUIRE, orderVec)    # 获取每个地点到天府高速交汇点的一维数组
            # Calculate the time distance from airport for each order
            airportTimeDistVec = GTI.getTimeDistVec(AMAPAIRPORTCOORDINATE, orderVec, restorderNum)  # 获取每个地点到机场的时间距离
            while len(arrangedPassengerIdx) < restorderNum:
                firstPassengerIdx = np.argmax(keypointDistVec)  # 寻找距离机场最远的第一个上车的人
                arrangedPassengerIdx.append(firstPassengerIdx)  # 存储地点位置的索引[3,4,1,0]
                currentScheduleVec.append(airportTimeDistVec[firstPassengerIdx])  # 存储时间的索引，2017/6/19时间已经不再使用
                currentPassengerIdx.append(firstPassengerIdx)
                numPassenger = restSeatNoVec[firstPassengerIdx]    # 每辆车上的乘客
                keypointDistVec[firstPassengerIdx] = 0  # 找到后进行虚拟删除，将值赋为0
                while numPassenger < CARSEATS:
                    # Searching next passenger
                    # ----------------------------
                    # find the passengers in the neighborhood area, remove the previous arranged passenger location
                    # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                    neighborhoodIdxVec1 = auxfn.getNeighborhoodIdx(orderVec, orderVec[firstPassengerIdx, :], SEARCHRADIUS, firstPassengerIdx, restsideVec)
                    neighborhoodIdxVec = [x for x in neighborhoodIdxVec1 if x not in arrangedPassengerIdx]
                    # ----------------------------
                    # if there is someone in the neighborhood， choose that one as next passenger
                    # else if there is no unarranged passenger in the neighborhood, search all the rest of points
                    # choose the closest point && closer to key point than current passenger
                    if len(neighborhoodIdxVec) >= 1:
                        nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc, neighborhoodIdxVec)
                    else:
                        ix = np.where(np.in1d(np.arange(restorderNum), arrangedPassengerIdx, invert=True))
                        if len(ix[0]) == 0:   # 最后一个人直接上车
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            break
                        else:
                            # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2
                            currentside = restsideVec[firstPassengerIdx]
                            tmpnextPassengerIdx = auxfn.getSortedPointIdx(orderVec[ix[0], :], orderVec[firstPassengerIdx, :], restsideVec[ix[0]], currentside)
                            tmpPassengerIdx = [ix[0][y] for y in tmpnextPassengerIdx]
                            nextPassengerIdx = dis.checkLongdiscondition(currentPassengerIdx, restorderLoc, tmpPassengerIdx)
                    # 周围没有人了结束循环叫新车
                    if len(nextPassengerIdx) == 0:
                        numPassengerVec.append(numPassenger)
                        time2AirportVec.append(currentScheduleVec)
                        currentScheduleVec = []
                        currentPassengerIdx = []
                        break
                    else:
                        # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制
                        # 时间限制暂时没有写（后面加上速度后补上）
                        neighborGetOnCar = [restSeatNoVec[element] for element in nextPassengerIdx]
                        carseatsWithNeighbor = np.array(neighborGetOnCar) + numPassenger
                        if carseatsWithNeighbor.min() > CARSEATS:
                            numPassengerVec.append(numPassenger)
                            time2AirportVec.append(currentScheduleVec)
                            currentScheduleVec = []
                            currentPassengerIdx = []
                            break
                    # compute the driving time from current to the next passenger
                    for i in xrange(len(nextPassengerIdx)):
                        if (numPassenger + restSeatNoVec[nextPassengerIdx[i]]) > CARSEATS:
                            continue
                        elif (dis.checkTimeLimitCondition(TIMELIMIT, orderVec[firstPassengerIdx, :],
                                                          orderVec[nextPassengerIdx[i], :], AMAPAIRPORTCOORDINATE, currentScheduleVec, currentPassengerIdx, nextPassengerIdx[i])):
                            numPassenger += restSeatNoVec[nextPassengerIdx[i]]
                            arrangedPassengerIdx.append(nextPassengerIdx[i])
                            firstPassengerIdx = nextPassengerIdx[i]
                            keypointDistVec[firstPassengerIdx] = 0
                            break
                else:
                    # 车上有5个人就结束循环叫新车
                    numPassengerVec.append(numPassenger)
                    time2AirportVec.append(currentScheduleVec)
                    currentScheduleVec = []
                    currentPassengerIdx = []
            # 获取每辆车的地点的下标[[],[]]二维列表
            carList = dis.getCarPassengerList(time2AirportVec, arrangedPassengerIdx)
            # 对获取结果排序 f**k
            # sortcarList = dis.sortPassenger(carList, northOrderLoc)
            # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表
            carOrderList = dis.getThePassengerOrderForEachCar(carList, restorderNo)
            # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表
            # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec)
            if specifyDriverOrder is None:
                if len(getonthecar) == 0:
                    # 如果没有已经上车的订单就封装成json数组
                    AllCarOrder = copy.copy(carOrderList)
                else:
                    # 如果有已经上车的订单就将两个列表相加
                    # hasgetonthecarLocandTime = dis.gethasgotonthecartimedistance(getonthecarLoc, getonthecar)
                    AllCarOrder = carOrderList + getonthecar  # [[a,v,s],[q,w,e,r,f]]
                # jsondata = dis.incodejs(AllCarOrderAndTime)
                return AllCarOrder
            # 有指定司机的情况
            else:
                if len(getonthecar) == 0:
                    # 没有人提前上车
                    AllCarOrder = carOrderList + specifyDriverOrder
                else:
                    # 有人提前上车
                    AllCarOrder = carOrderList + getonthecar + specifyDriverOrder
                return AllCarOrder
        # 乘客已经全部提前上车
        else:
            if specifyDriverOrder is None:
                # 没有指定司机的乘客
                AllCarOrder = copy.copy(getonthecar)
            else:
                # 有指定司机的乘客
                AllCarOrder = getonthecar + specifyDriverOrder
            return AllCarOrder
# event.set()




# coding:utf-8 <NAME>, <NAME> May 15, 2017 排班逻辑修改 Wangmeng Song June 20, 2017 June 29, 2017 June 30, 2017 添加新逻辑 July 21,2017 增加新逻辑 August 8,2017 优化人少 August 29,2017 东边2.5环增加新逻辑 July 05, 2017 July 08, 2017 继续增加特殊情况的判断 # 高速交汇点 # 成都机场 # 1500m的范围 # 一辆车最大乘客为6个人 # 时间限制为6000s # event = threading.Event()  # 设置全局变量event为True # ------------------ # initialization # event.wait()    # 设置全局变量event为false,是其他线程处于等待状态 # 实例化DIST类 # 实例化AMapAPI类 # 实例化区分区域的类 # 获得两个list，specifyDriverDic, normalPassengerDic # 存储指定司机的乘客 # 存储普通乘客 # 分辨指定司机的乘客和普通乘客 # 处理指定司机的订单 # store order index on all cars # temporary using, store each passenger's travelling time on the same car # 存储当前车的乘客 # store each passenger's travelling time # store the number of passengers on each car # ------------------ # Get all the order coordinates, save in a 2D-array, 1st row is latitude, 2nd row is longitude # [[A,,B,C],[D,E,F]] 存储一个满足条件上车的或者乘客==5or6的订单 # [(lat1,lng1),(lat2,lng2)] 存储一个地点的lat,lng， 不需要 # [[1,2,3],[2,3]] 存储一个地点的乘客人数,不需要 # 存储第一次处理的传入数据的订单号 # 存储第一次处理的传入数据的经纬度 # 存储第一次处理的传入数据的乘客人数 # 处理第一次传入的数据，第一次处理：过滤一个订单乘客人数==5or6 # 待修改（一个订单==5或者一个订单==6直接上车，或者在2.5环外直接上车，修改待确认） # 获得所有的订单数据将订单格式转换为id:[[],[],[]], loc:[(),(),()], seatnum:[[],[],[],[]] # 存储唯一地点的订单号（整合100m的范围的订单） # 存储与地点对应的乘客人数 # 整合100m范围内的订单 # 存储去除100m范围内5/6人的订单的订单号 # 存储去除100m范围内5/6人的订单的经纬度 # 存储去除100m范围内5/6的订单的乘客人数 # 过滤100m范围内的订单人数为5/6的情况 # 判断已经上车的人中的车，如果车上有5个人那么在500m范围再找一个人，有就上车，没有也走，已经不再需要 # if len(getonthecarLoc) > 0: #     # 寻找一个地点乘客人数==5的周围是否存在1个订单1个人的情况 #     dis.getTheFivePersonAroundOnlyOne(getonthecar, getonthecarLoc, getonthecarseatnum, #                                       RMMTSixpassengerOrderID, RMMTSixpassengerLoc, RMMTSixpassengerseatnum) # 判断loc是否在纬度以北，如果在纬度以南就直接上车，纬度以北进入排班 # [[A,,B,C],[D,E,F]] # [(lat1,lng1),(lat2,lng2)] # [[1,2,3],[2,3]] # 超出接送范围的订单单独上车 # 进入调用schedule的订单数 # 进入排班算法的总地点数 # 二维的乘客人数转换为与地点对应的一维数组 array[3,1] # 地区东边和西边的代码，地图东为1，西为2,array # 东边地区的index集合，一维array # 西边地区的index集合，一维array # 如果两边小于等于就直接上车 # if sum(seatNumVec) <= 1: #     dis.leftandrightgetonthecar(getonthecar, northOrderID, northOrderLoc) #     if len(specifyDriverDic) > 0: #         AllCarOrder = getonthecar + specifyDriverOrder #     else: #         AllCarOrder = getonthecar #     return AllCarOrder # 如果东边和西边的人数同时小于或等于6就分别上车 # 如果东边小于等于6，西边大于6,东边上车 # [[A,,B,C],[D,E,F]] # [(lat1,lng1),(lat2,lng2)] # [[1,2,3],[2,3]] # 地区东边和西边的代码，地图东为1，西为2,array # 二维的乘客人数转换为与地点对应的一维数组 array[3,1] # 一维的经纬度列表转换为二维的经纬度数组 # 获取每个地点到天府高速交汇点的一维数组 # Calculate the time distance from airport for each order # 获取每个地点到机场的时间距离 # 寻找距离机场最远的第一个上车的人 # 存储地点位置的索引[3,4,1,0] # 存储时间的索引，2017/6/19时间已经不再使用 # 每辆车上的乘客 # 找到后进行虚拟删除，将值赋为0 # Searching next passenger # ---------------------------- # find the passengers in the neighborhood area, remove the previous arranged passenger location # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2 # ---------------------------- # if there is someone in the neighborhood， choose that one as next passenger # else if there is no unarranged passenger in the neighborhood, search all the rest of points # choose the closest point && closer to key point than current passenger # 最后一个人直接上车 # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2 # 周围没有人了结束循环叫新车 # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制 # 时间限制暂时没有写（后面加上速度后补上） # compute the driving time from current to the next passenger # 车上有6个人就结束循环叫新车 # 获取每辆车的地点的下标[[],[]]二维列表 # 对获取结果排序 f**k # sortcarList = dis.sortPassenger(carList, northOrderLoc) # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表 # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表 # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec) # [[a,v,s],[q,w,e,r,f]] # 如果西边小于等于6，东边大于6 # 增加东边2环到2.5环之间的算法逻辑 # 地区东边和西边的代码，地图东为1，西为2,array # 二维的乘客人数转换为与地点对应的一维数组 array[3,1] # 一维的经纬度列表转换为二维的经纬度数组 # 获取每个地点到天府高速交汇点的一维数组 # Calculate the time distance from airport for each order # 获取每个地点到机场的时间距离 # 寻找距离机场最远的第一个上车的人 # 存储地点位置的索引[3,4,1,0] # 存储时间的索引，2017/6/19时间已经不再使用 # 每辆车上的乘客 # 找到后进行虚拟删除，将值赋为0 # Searching next passenger # ---------------------------- # find the passengers in the neighborhood area, remove the previous arranged passenger location # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2 # ---------------------------- # if there is someone in the neighborhood， choose that one as next passenger # else if there is no unarranged passenger in the neighborhood, search all the rest of points # choose the closest point && closer to key point than current passenger # 最后一个人直接上车 # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2 # 周围没有人了结束循环叫新车 # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制 # 时间限制暂时没有写（后面加上速度后补上） # compute the driving time from current to the next passenger # 车上有6个人就结束循环叫新车 # 获取每辆车的地点的下标[[],[]]二维列表 # 对获取结果排序 f**k # sortcarList = dis.sortPassenger(carList, northOrderLoc) # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表 # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表 # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec) # hasgetonthecarLocandTime = dis.gethasgotonthecartimedistance(getonthecarLoc, getonthecar) # [[a,v,s],[q,w,e,r,f]] # jsondata = dis.incodejs(AllCarOrderAndTime) # 对订单在西边2环到2.5环的情况进行排班 # [[A,,B,C],[D,E,F]] # [(lat1,lng1),(lat2,lng2)] # [[1,2,3],[2,3]] # 排班开始 # 判断东西边的人数 # 待修改 # 地区东边和西边的代码，地图东为1，西为2,array # 二维的乘客人数转换为与地点对应的一维数组 array[3,1] # 一维的经纬度列表转换为二维的经纬度数组 # 获取每个地点到天府高速交汇点的一维数组 # Calculate the time distance from airport for each order # 获取每个地点到机场的时间距离 # 寻找距离机场最远的第一个上车的人 # 存储地点位置的索引[3,4,1,0] # 存储时间的索引，2017/6/19时间已经不再使用 # 每辆车上的乘客 # 找到后进行虚拟删除，将值赋为0 # Searching next passenger # ---------------------------- # find the passengers in the neighborhood area, remove the previous arranged passenger location # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2 # ---------------------------- # if there is someone in the neighborhood， choose that one as next passenger # else if there is no unarranged passenger in the neighborhood, search all the rest of points # choose the closest point && closer to key point than current passenger # 最后一个人直接上车 # 当前点side为1可以选择所有的点找周围的点，当前点为2就只能找2 # 周围没有人了结束循环叫新车 # 车上没有6个人，周围有人，但是周围上车后车上最小的人数都大于6就结束循环叫新车或是最小的时间都大于限制 # 时间限制暂时没有写（后面加上速度后补上） # compute the driving time from current to the next passenger # 车上有5个人就结束循环叫新车 # 获取每辆车的地点的下标[[],[]]二维列表 # 对获取结果排序 f**k # sortcarList = dis.sortPassenger(carList, northOrderLoc) # 获取每个地点的订单号[[a,b,c],[d,c,e]]二维列表 # 获取每个订单到机场的时间[[[],[],[]],[]]二维列表 # carOrderAndTimeList = dis.getOrderAndTimeInfos(carOrderList, time2AirportVec) # 如果没有已经上车的订单就封装成json数组 # 如果有已经上车的订单就将两个列表相加 # hasgetonthecarLocandTime = dis.gethasgotonthecartimedistance(getonthecarLoc, getonthecar) # [[a,v,s],[q,w,e,r,f]] # jsondata = dis.incodejs(AllCarOrderAndTime) # 有指定司机的情况 # 没有人提前上车 # 有人提前上车 # 乘客已经全部提前上车 # 没有指定司机的乘客 # 有指定司机的乘客 # event.set()