public static bool Check(NewGrid grid, CabMetaData cab) { //Console.WriteLine("网格数(单边):"+gridTier); //Console.WriteLine("网格变长:"+gridLength); //Console.WriteLine("网格边界:"+gridXLowBound+" "+gridXUpperBound+" "+gridYLowBound+" "+gridYUpperBound); //int count = 0; //foreach (Cell cell in grid.cellList) //{ // count+=Cell.Check(cell); //} //Console.WriteLine(count); int i = 0, j = 0; foreach (List <Cell> list in grid.cellList) { foreach (Cell cell in list) { if (Cell.Check(cell, cab)) { Console.Write("(" + i + "," + j + ")"); return(true); } j++; } i++; } return(false); }
//判断是否是核心点 public static List <CabMetaData> IsKeyPoint(NewGrid grid, List <CabMetaData> lst, CabMetaData point) { List <CabMetaData> indexList = NewGrid.RangeQuery(grid, point, eps); if (indexList.Count >= minPts) { point.extension = "true"; return(indexList); } else { return(null); } }
/*范围查询:给定查询点和查询范围,返回所有在查询范围中的网格上的点 * 方法:首先,根据查询范围得到要访问的网格上下左右界,使界不超过网格范围 * 然后,遍历在上述界内的所有点,对完全处在查询范围内的单元格,把其中所含的点全部加入结果集;否则,对每个单元格中的点再检查是否在查询范围内 */ public static List <CabMetaData> RangeQuery(NewGrid grid, CabMetaData queryPoint, double radious) { List <CabMetaData> result = new List <CabMetaData>();//结果集 //获取中心点所在单元格 //List<int> index = LocateCell(queryPoint); //要访问的网格上下左右界 int down, up, left, right; if (queryPoint.Longitude - radious >= gridXLowBound) { left = (int)((queryPoint.Longitude - radious - gridXLowBound) / gridLength); } else { left = 0; } if (queryPoint.Longitude + radious <= gridXUpperBound) { right = (int)((queryPoint.Longitude + radious - gridXLowBound) / gridLength); } else { right = gridTier - 1; } if (queryPoint.Latitude - radious >= gridYLowBound) { down = (int)((queryPoint.Latitude - radious - gridYLowBound) / gridLength); } else { down = 0; } if (queryPoint.Latitude + radious <= gridYUpperBound) { up = (int)((queryPoint.Latitude + radious - gridYLowBound) / gridLength); } else { up = gridTier - 1; } //遍历所有可能在查询范围内的单元格 for (int x = left; x <= right; x++) { for (int y = down; y <= up; y++) { //对完全处在查询范围内的单元格,把其中所含的点全部加入结果集 if (GetMaxDistBetweenPointAndCell(queryPoint, x, y) <= radious) { result.AddRange(grid.cellList[x][y].points); } else { //对于只有一部分在查询范围内的单元格,对其中的每个点再检查是否在查询范围内 foreach (CabMetaData point in grid.cellList[x][y].points) { if (Program.GetDistance(point.Latitude, point.Longitude, queryPoint.Latitude, queryPoint.Longitude) <= radious) { result.Add(point); } } } } } return(result); }
public static double eps = 0.005; //ε半径 //dbscan过程(深度优先方法) public static List <DBscanCluster> ApplyDbscan(NewGrid grid, List <CabMetaData> pointsList) { List <DBscanCluster> resultList = new List <DBscanCluster>();// 存储最后的聚类结果 foreach (CabMetaData point in pointsList) { if (!point.extension.Equals("")) { continue; } else { List <CabMetaData> neighboursList = NewGrid.RangeQuery(grid, point, eps); if (neighboursList.Count >= minPts) { point.extension = "core"; resultList.Add(new DBscanCluster()); resultList[resultList.Count - 1].Add(point); Stack <CabMetaData> neighbourStack = new Stack <CabMetaData>(); foreach (CabMetaData neightbour in neighboursList) { if (!neightbour.CabMetaDataId.Equals(point.CabMetaDataId))//没必要把查询点也压入栈中(尽管不影响正确性),减少出栈次数 { neighbourStack.Push(neightbour); } } while (neighbourStack.Count > 0) { CabMetaData currentPoint = neighbourStack.Pop(); if (currentPoint.extension.Equals("") || currentPoint.extension.Equals("noice"))//如果标记为"core"或"neighbour",说明已经被处理过了 { resultList[resultList.Count - 1].Add(currentPoint); if (currentPoint.extension.Equals(""))//如果标记为"noice",说明肯定不是核心点 { List <CabMetaData> newNeighboursList = NewGrid.RangeQuery(grid, currentPoint, eps); if (neighboursList.Count >= minPts)//ε邻域大于密度阈值,标记为"core" { currentPoint.extension = "core"; foreach (CabMetaData neightbour in newNeighboursList) { if (!neightbour.CabMetaDataId.Equals(currentPoint.CabMetaDataId))//没必要把查询点也压入栈中(尽管不影响正确性),减少出栈次数 { neighbourStack.Push(neightbour); } } } else//ε邻域小于密度阈值,标记为"neighbour" { currentPoint.extension = "neighbour"; } } } } } else { point.extension = "noice"; } } } return(resultList); }