Exemple #1
0
        private static double GetMaxDist(CabMetaData point,int cellId)
        {
            //获得网格左上角点坐标
            double cellMinX = gridXLowBound + (cellId % gridTier) * gridLength;
            double cellMaxY = gridYUpperBound - (cellId / gridTier) * gridLength;

            //判断与网格相对位置
            if (point.Longitude < cellMinX + gridLength * 0.5)//网格垂直平分线左边
            {
                if (point.Latitude > cellMaxY - gridLength * 0.5)//网格水平平分线上边
                {
                    return Program.GetDistance(point.Latitude,point.Longitude, cellMaxY - gridLength,cellMinX + gridLength);
                }
                else//网格水平平分线下边
                {
                    return Program.GetDistance(point.Latitude,point.Longitude, cellMaxY,cellMinX + gridLength);
                }
            }
            else//网格垂直平分线右边
            {
                if (point.Latitude > cellMaxY - gridLength * 0.5)//网格水平平分线上边
                {
                    return Program.GetDistance(point.Latitude,point.Longitude, cellMaxY - gridLength,cellMinX);
                }
                else//网格水平平分线下边
                {
                    return Program.GetDistance(point.Latitude,point.Longitude,cellMaxY,cellMinX);
                }
            }
        }
Exemple #2
0
 public void Add(CabMetaData point)
 {
     pointsList.Add(point);
     cabNameList.Add(point.CabName);
     point.clusterId = clusterId;
     cabInOrNotList.ChangeObjectStatus(point.CabName);
 }
Exemple #3
0
        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);
        }
Exemple #4
0
 private static int LocateCell(CabMetaData cabMetaData)
 {
     double longitude = cabMetaData.Longitude;
     double latitude = cabMetaData.Latitude;
     int cellID = (int)(((gridYUpperBound - latitude) / gridLength) * gridTier) + (int)((longitude - gridXLowBound) / gridLength);
     return cellID;
 }
Exemple #5
0
        /*计算给定点和给定单元格的最大距离
         * 方法:返回给定点和给定单元格四个顶点的距离最大者
         */
        private static double GetMaxDistBetweenPointAndCell(CabMetaData point, int indexX, int indexY)
        {
            double distLeftDown  = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + indexY * gridLength, gridXLowBound + indexX * gridLength);
            double distLeftUp    = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + (indexY + 1) * gridLength, gridXLowBound + indexX * gridLength);
            double distRightDown = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + indexY * gridLength, gridXLowBound + (indexX + 1) * gridLength);
            double distRightUp   = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + (indexY + 1) * gridLength, gridXLowBound + (indexX + 1) * gridLength);

            return(Math.Max(Math.Max(distLeftDown, distLeftUp), Math.Max(distRightDown, distRightUp)));
        }
Exemple #6
0
        private List <int> LocateCell(CabMetaData cabMetaData)
        {
            double     x      = cabMetaData.Longitude;
            double     y      = cabMetaData.Latitude;
            List <int> result = new List <int>(2);

            result.Add((int)((x - gridXLowBound) / gridLength));
            result.Add((int)((y - gridYLowBound) / gridLength));
            return(result);
        }
Exemple #7
0
 public static bool Check(Cell cell, CabMetaData cab)
 {
     if (cell.points.Contains(cab, new CabMetaDataComparer()))
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Exemple #8
0
 public CabMetaData(CabMetaData cabMetaData)
 {
     this.cabName       = cabMetaData.cabName;
     this.cabMetaDataId = cabMetaData.cabMetaDataId;
     this.longitude     = cabMetaData.longitude;
     this.latitude      = cabMetaData.latitude;
     this.fare          = cabMetaData.fare;
     this.timeStamp     = cabMetaData.timeStamp;
     this.extension     = "";
     this.clusterId     = cabMetaData.clusterId;
 }
Exemple #9
0
 public static bool Check(Grid 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);
     foreach (Cell cell in grid.cellList)
     {
         if (Cell.Check(cell, cab))
         {
             return true;
         }
     }
     return false;
 }
Exemple #10
0
 public void insert(CabMetaData metadata)
 {
     points.Add(metadata);
 }
Exemple #11
0
        /*范围查询:给定查询点和查询范围,返回所有在查询范围中的网格上的点
         * 方法:首先,根据查询范围得到要访问的网格上下左右界,使界不超过网格范围
         * 然后,遍历在上述界内的所有点,对完全处在查询范围内的单元格,把其中所含的点全部加入结果集;否则,对每个单元格中的点再检查是否在查询范围内
         */
        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);
        }
Exemple #12
0
        //判断是否是核心点
        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);
            }
        }
Exemple #13
0
        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);
        }
Exemple #14
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;
        }
Exemple #15
0
        private static double GetMinDist(CabMetaData point, int cellId)
        {
            //获得网格左上角点坐标
            double cellMinX = gridXLowBound + (cellId % gridTier) * gridLength;
            double cellMaxY = gridYUpperBound + (cellId / gridTier) * gridLength;

            //判断与网格相对位置
            if (point.Longitude < cellMinX)//网格左边
            {
                if (point.Latitude > cellMaxY)//左上
                {
                    return Program.GetDistance(point.Latitude, point.Longitude, cellMaxY, cellMinX);
                }
                else
                {
                    if (point.Latitude >= cellMaxY - gridLength)//正左
                    {
                        return Program.GetDistance(point.Latitude, point.Longitude, point.Latitude, cellMinX);
                    }
                    else//左下
                    {
                        return Program.GetDistance(point.Latitude, point.Longitude, cellMaxY - gridLength, cellMinX);
                    }
                }
            }
            else
            {
                if (point.Longitude < cellMinX + gridLength)//网格上中下
                {
                    if (point.Latitude > cellMaxY)//正上
                    {
                        return point.Latitude - cellMaxY;
                    }
                    else
                    {
                        if (point.Latitude >= cellMaxY - gridLength)//正中
                        {
                            return 0;
                        }
                        else//正下
                        {
                            return cellMaxY - gridLength - point.Latitude;
                        }
                    }
                }
                else//网格右边
                {
                    if (point.Latitude > cellMaxY)//右上
                    {
                        return Program.GetDistance(point.Latitude, point.Longitude, cellMaxY, cellMinX + gridLength);
                    }
                    else
                    {
                        if (point.Latitude >= cellMaxY - gridLength)//正右
                        {
                            return Program.GetDistance(point.Latitude, point.Longitude, point.Latitude, cellMinX + gridLength);
                        }
                        else//右下
                        {
                            return Program.GetDistance(point.Latitude,point.Longitude,cellMaxY-gridLength,cellMinX+gridLength);
                        }
                    }
                }
            }
        }