public CellItem(CellItem cellItem, double minDist) { this.cellId = cellItem.cellId; this.minDist = minDist; }
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; }