Exemple #1
0
 public CellItem(CellItem cellItem, double minDist)
 {
     this.cellId  = cellItem.cellId;
     this.minDist = minDist;
 }
Exemple #2
0
        public static List<CabMetaData> RangeQuery(Grid grid, CabMetaData queryPoint, double radious, List<CabMetaData> cabLine)
        {
            List<CabMetaData> result = new List<CabMetaData>();//结果集

            //获取中心点所在单元格,并计算向四个方向最多扩展的次数
            int centerCell = LocateCell(queryPoint);
            int left = centerCell % gridTier;
            int right = gridTier - (centerCell % gridTier) - 1;
            int up = centerCell / gridTier;
            int down = gridTier - (centerCell / gridTier) - 1;

            Queue<CellItem> candidateCells=new Queue<CellItem>();
            bool[] validArray = new bool[gridTier * gridTier];//对应网格是否已入队列,已入为true
            for (int i = 0;i!=gridTier*gridTier ;i++ )
            {
                validArray[i] = false;
            }

            candidateCells.Enqueue(new CellItem(centerCell,0.0));
            validArray[centerCell] = true;
            int times = 1;//扩散次数
            while (candidateCells.Count > 0)
            {
                CellItem nextCell = candidateCells.Dequeue();
                if (nextCell.minDist > radious)//网格完全在圆外面
                {
                    break;
                }
                double cellMaxDist = GetMaxDist(queryPoint, nextCell.cellId);
                List<CabMetaData> pointsOfCell = grid.cellList[nextCell.cellId].GetAllPoints();
                if (cellMaxDist <= radious)//网格完全被圆包含
                {
                    foreach (CabMetaData point in pointsOfCell)
                    {
                        result.Add(point);
                    }
                }
                else//网格与圆部分相交
                {
                    //检查网格每个点是否落于圆中
                    foreach (CabMetaData point in pointsOfCell)
                    {
                        if (Program.GetDistance(queryPoint.Latitude, queryPoint.Longitude, point.Latitude, point.Longitude) <= radious)
                        {
                            result.Add(point);
                        }
                    }
                }
                //扩散邻居网络
                if (candidateCells.Count == 0)
                {
                    if (times <= up)//未上溢出
                    {
                        int upMidCell = centerCell - times * gridTier;
                        if (!validArray[upMidCell])
                        {
                            candidateCells.Enqueue(new CellItem(upMidCell,GetMinDist(queryPoint,upMidCell)));
                        }
                        for (int i = 1; i <= (times < left ? times : left); i++)
                        {
                            int nextCellInt = upMidCell - i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt)));
                            }
                        }
                        for (int i = 1; i <= (times < right ? times : right); i++)
                        {
                            int nextCellInt = upMidCell + i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCellInt,GetMinDist(queryPoint,nextCellInt)));
                            }
                        }
                    }
                    if (times <= down)//未下溢出
                    {
                        int downMidCell = centerCell + times * gridTier;
                        if (!validArray[downMidCell])
                        {
                            candidateCells.Enqueue(new CellItem(downMidCell,GetMinDist(queryPoint,downMidCell)));
                        }
                        for (int i = 1; i <= (times < left ? times : left); i++)
                        {
                            int nextCellInt = downMidCell - i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt)));
                            }
                        }
                        for (int i = 1; i <= (times < right ? times : right); i++)
                        {
                            int nextCellInt = downMidCell + i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt)));
                            }
                        }
                    }
                    if (times <= left)//未左溢出
                    {
                        int leftMidCell = centerCell - times;
                        if (!validArray[leftMidCell])
                        {
                            candidateCells.Enqueue(new CellItem(leftMidCell, GetMinDist(queryPoint, leftMidCell)));
                        }
                        for (int i = 1; i <= (times<up?times:up); i++)
                        {
                            int nextCellInt = leftMidCell - gridTier * i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCell, GetMinDist(queryPoint, nextCellInt)));
                            }
                        }
                        for (int i = 1; i <= (times<down?times:down); ++i)
                        {
                            int nextCellInt = leftMidCell +gridTier * i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt)));
                            }
                        }
                    }
                    if (times <= right)	//未右溢出
                    {
                        int rightMidCell = centerCell + times;
                        if (!validArray[rightMidCell])
                        {
                            candidateCells.Enqueue(new CellItem(rightMidCell, GetMinDist(queryPoint, rightMidCell)));
                        }
                        for (int i = 1; i <= (times<up?times:up); ++i)
                        {
                            int nextCellInt = rightMidCell - gridTier * i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCell, GetMinDist(queryPoint, nextCellInt)));
                            }
                        }
                        for (int i = 1; i <= (times<down?times:down); ++i)
                        {
                            int nextCellInt = rightMidCell + gridTier * i;
                            if (!validArray[nextCellInt])
                            {
                                candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt)));
                            }
                        }
                    }
                    times++;
                }
            }
            return result;
        }