Exemplo n.º 1
0
    public float GetContoursSquareMeters()
    {
        if (grid.countX == 0)
        {
            return(0);
        }

        double x, y;

        GeoCalculator.GetDistanceInMeters(grid.west, grid.south, grid.east, grid.north, out x, out y);
        double xSize = x / grid.countX;
        double ySize = y / grid.countY;

        return((float)(xSize * ySize));
    }
    public void ComputeAndUpdateTotalLength(LineInfo[] lineInfos, int index)
    {
        currLineInspectionIndex = index;
        LineInfo lineInfo = lineInfos[index];

        // Computations
        double lon1 = lineInfo.coords[0].Longitude, lat1 = lineInfo.coords[0].Latitude,
               lon2 = lineInfo.coords[1].Longitude, lat2 = lineInfo.coords[1].Latitude,
               totalLength = GeoCalculator.GetDistanceInMeters(lon1, lat1, lon2, lat2) / 1000.0;

        linePS[currLineInspectionIndex].totalLength = totalLength;

        // Update total length shown
        if (linePSUIRef.summaryDropdown.value == LinePS.SelectedLine)
        {
            linePSUIRef.SelectedTotalLength(linePS[currLineInspectionIndex]);
        }
        else if (linePSUIRef.summaryDropdown.value == LinePS.AllLinesCombined)
        {
            lineDO.AllCombinedTotalLength(linePS, linePSUIRef);
        }
    }
Exemplo n.º 3
0
    public void ComputeAndUpdateTotalLength(LineInfo[] lineInfos, int index)
    {
        currLineInspectionIndex = index;
        LineInfo lineInfo = lineInfos[index];

        // Computations
        double lon1 = lineInfo.coords[0].Longitude, lat1 = lineInfo.coords[0].Latitude,
               lon2 = lineInfo.coords[1].Longitude, lat2 = lineInfo.coords[1].Latitude,
               totalLength = GeoCalculator.GetDistanceInMeters(lon1, lat1, lon2, lat2) / 1000.0;

        propertiesAndSummaries[currLineInspectionIndex].totalLength = totalLength;

        // Update total length shown
        if (summaryDropdown.value == SelectedLine)
        {
            SelectedLineTotalLength();
        }
        else if (summaryDropdown.value == AllLinesCombined)
        {
            AllLinesCombinedTotalLength();
        }
    }
Exemplo n.º 4
0
    private IEnumerator Traverse(int countPerFrame)
    {
        GraphPatch graphPatch = networkPatch;
        GraphData  graph      = graphPatch.graph;
        GridData   grid       = reachabilityPatch.grid;

        // Initialize the grid values and the node costs to infinite
        PrepareGrid();

        yield return(null);

        // Prepare the starting cells/nodes
        var nodes    = new Queue <int>();
        var nodesSet = new HashSet <int>();

        foreach (var coord in startPoints)
        {
            // For each point find its grid index
            var startIndex = networkPatch.GetIndex(coord.Longitude, coord.Latitude);

            // Check if highway node is available and we're allowed to be on it
            if (graph.indexToNode.TryGetValue(-startIndex, out GraphNode highwayNode) &&
                classificationToMinutesPerMeter[highwayNode.classifications] > 0)
            {
                startIndex = -startIndex;
            }

            // Snap to the nearest network node?
            if (SnapToNetwork)
            {
                if (startIndex > 0 && !graph.indexToNode.ContainsKey(startIndex))
                {
                    FindClosestNode(coord.Longitude, coord.Latitude, ref startIndex);
                    yield return(null);
                }
            }

            // Initialize the cell value and node cost
            int gridIndex = Math.Abs(startIndex);
            grid.values[gridIndex]     = 0f;
            grid.valuesMask[gridIndex] = 1;
            if (graph.indexToNode.TryGetValue(startIndex, out GraphNode first))
            {
                first.cost = 0;
            }

            nodes.Enqueue(startIndex);
            nodesSet.Add(startIndex);
        }

        // Prepare data for off-grid computation
        GeoCalculator.GetDistanceInMeters(grid.west, grid.south, grid.east, grid.north, out double cellSizeX, out double cellSizeY);
        cellSizeX /= grid.countX;
        cellSizeY /= grid.countY;
        float distanceXY = (float)Math.Sqrt(cellSizeX * cellSizeX + cellSizeY * cellSizeY);
        float distanceX  = (float)cellSizeX;
        float distanceY  = (float)cellSizeY;
        int   lastIndexX = grid.countX - 1;
        int   lastIndexY = grid.countY - 1;

        var visitedNeighbours = new bool[8];
        var indexToOffsetMap  = new int[8]
        {
            -grid.countX - 1,
            -grid.countX,
            -grid.countX + 1,
            -1,
            +1,
            grid.countX - 1,
            grid.countX,
            grid.countX + 1,
        };
        var offsetToIndexMap = new Dictionary <int, int>()
        {
            { -grid.countX - 1, 0 },
            { -grid.countX, 1 },
            { -grid.countX + 1, 2 },
            { -1, 3 },
            { +1, 4 },
            { grid.countX - 1, 5 },
            { grid.countX, 6 },
            { grid.countX + 1, 7 }
        };
        var linkDistances = new float[8]
        {
            distanceXY,
            distanceY,
            distanceXY,
            distanceX,
            distanceX,
            distanceXY,
            distanceY,
            distanceXY,
        };
        float invWalkingSpeed = classificationToMinutesPerMeter[0];


        int count = 0;
        int nodeIndex, neighbourIndex;
        var overlapedLink = new HashSet <int>();

        // Start going thru the nodes
        while (nodes.Count > 0)
        {
            nodeIndex = nodes.Dequeue();
            nodesSet.Remove(nodeIndex);

            // Check if it's a node. It could be an empty cell when going off-track
            if (graph.indexToNode.TryGetValue(nodeIndex, out GraphNode node))
            {
                nodeIndex = Math.Abs(node.index);

                overlapedLink.Clear();

                for (int k = 0; k < newRoads.Count; k++)
                {
                    var newGraph = newRoads[k].graph;

                    // if the node is overlapped by new road
                    if (newRoads[k].graph.indexToNode.ContainsKey(nodeIndex))
                    {
                        var newNode = newGraph.indexToNode[nodeIndex];

                        for (int i = newNode.links.Count - 1; i >= 0; i--)
                        {
                            neighbourIndex = Math.Abs(newNode.links[i].index);
                            overlapedLink.Add(neighbourIndex);

                            if (!graph.indexToNode.ContainsKey(neighbourIndex))
                            {
                                neighbourIndex = -neighbourIndex;
                            }

                            var neighbour = graph.indexToNode[neighbourIndex];

                            // Calculate time: cost (minutes) = distance (meters) / speed (meters/minute)
                            float invSpeed = classificationToMinutesPerMeter[newNode.linkClassifications[i]];
                            float cost     = newNode.linkDistances[i] * invSpeed + node.cost;

                            if (cost < neighbour.cost && cost <= grid.maxFilter)
                            {
                                neighbour.cost = cost;
                                grid.values[neighbourIndex]     = Math.Min(cost, grid.values[neighbourIndex]);
                                grid.valuesMask[neighbourIndex] = 1;

                                if (!nodesSet.Contains(neighbour.index))
                                {
                                    nodes.Enqueue(neighbour.index);
                                    nodesSet.Add(neighbour.index);
                                }

                                count++;
                            }
                        }
                    }
                }

                for (int i = node.links.Count - 1; i >= 0; i--)
                {
                    var neighbour = node.links[i];
                    neighbourIndex = Math.Abs(neighbour.index);

                    var indexOffset = neighbourIndex - nodeIndex;
                    var idx         = offsetToIndexMap[indexOffset];
                    visitedNeighbours[idx] = true;

                    if (overlapedLink.Contains(neighbourIndex))
                    {
                        continue;
                    }

                    // Calculate time: cost (minutes) = distance (meters) / speed (meters/minute)
                    float invSpeed = classificationToMinutesPerMeter[node.linkClassifications[i]];
                    float cost     = node.linkDistances[i] * invSpeed + node.cost;
                    if (cost < neighbour.cost && cost <= travelTime)
                    {
                        neighbour.cost = cost;
                        // Note: a cell may have 2 nodes (e.g. primary + highway). Therefore we need to check the min value
                        grid.values[neighbourIndex]     = cost < grid.values[neighbourIndex]? cost : grid.values[neighbourIndex];
                        grid.valuesMask[neighbourIndex] = 1;

                        if (!nodesSet.Contains(neighbour.index))
                        {
                            nodes.Enqueue(neighbour.index);
                            nodesSet.Add(neighbour.index);
                        }

                        count++;
                    }
                }
            }

            // Calculate off-track
            if (node == null || node.classifications < ClassificationValue.HighwayLink)
            {
                int   nodeY    = nodeIndex / grid.countX;
                int   nodeX    = nodeIndex - nodeY * grid.countX;
                float nodeCost = node == null? grid.values[nodeIndex] : node.cost;

                // Check non-visited neighbours
                for (int i = 0; i < 8; ++i)
                {
                    if (!visitedNeighbours[i])
                    {
                        int x = nodeX + indexToOffsetXMap[i];
                        int y = nodeY + indexToOffsetYMap[i];
                        if (x < 0 || y < 0 || x > lastIndexX || y > lastIndexY)
                        {
                            continue;
                        }

                        neighbourIndex = nodeIndex + indexToOffsetMap[i];

                        // Calculate time: cost (minutes) = distance (meters) / speed (meters/minute)
                        float cost = linkDistances[i] * invWalkingSpeed + nodeCost;
                        if (cost < grid.values[neighbourIndex] && cost <= travelTime)
                        {
                            bool valid = false;
                            if (graph.indexToNode.TryGetValue(neighbourIndex, out GraphNode neighbour))
                            {
                                if (neighbour.classifications < ClassificationValue.HighwayLink)
                                {
                                    neighbour.cost = cost;
                                    valid          = true;
                                }
                            }
                            else
                            {
                                valid = true;
                            }

                            if (valid)
                            {
                                grid.values[neighbourIndex]     = cost;
                                grid.valuesMask[neighbourIndex] = 1;
                                if (!nodesSet.Contains(neighbourIndex))
                                {
                                    nodes.Enqueue(neighbourIndex);
                                    nodesSet.Add(neighbourIndex);
                                }
                            }

                            count++;
                        }
                    }
                    else
                    {
                        visitedNeighbours[i] = false;
                    }
                }
            }

            if (count > countPerFrame)
            {
                count = 0;
                grid.ValuesChanged();
                yield return(null);
            }
        }

        yield return(null);

        CommitPatchChanges();

        gridGeneration = null;
    }
Exemplo n.º 5
0
    //
    // Private Method
    //

    private void CreateRoad(List <Coordinate> points)
    {
        // Check if all points are inside of graph
        if (!PointsInsideGraph(points, graph))
        {
            Debug.LogWarning("New road is not inside the graph");
            return;
        }

        double kX = 1.0 / graph.cellSizeX;
        double kY = 1.0 / graph.cellSizeY;

        for (int i = 0; i < points.Count - 1; i++)
        {
            Coordinate coorStart = points[i];
            Coordinate coorEnd   = points[i + 1];

            int startIndex = (int)((coorStart.Longitude - graph.west) * kX) + grid.countX * (int)((graph.north - coorStart.Latitude) * kY);
            int endIndex   = (int)((coorEnd.Longitude - graph.west) * kX) + grid.countX * (int)((graph.north - coorEnd.Latitude) * kY);

            var startNode = new GraphNode(coorStart.Longitude, coorStart.Latitude, classification, startIndex);
            var endNode   = new GraphNode(coorEnd.Longitude, coorEnd.Latitude, classification, endIndex);

            int startRow    = startIndex / grid.countX;
            int startColumn = startIndex - startRow * grid.countX;

            int endRow    = endIndex / grid.countX;
            int endColumn = endIndex - endRow * grid.countX;

            if (startIndex == endIndex)
            {
                if (i == 0)
                {
                    AddNode(startIndex, startNode);
                }
                continue;
            }

            int countX = Math.Abs(startColumn - endColumn);
            int countY = Math.Abs(startRow - endRow);

            double k;
            if (countX >= countY)
            {
                k = (endNode.latitude - startNode.latitude) / (endNode.longitude - startNode.longitude);
            }
            else
            {
                k = (endNode.longitude - startNode.longitude) / (endNode.latitude - startNode.latitude);
            }

            for (int j = 0; j <= Math.Max(countY, countX); j++)
            {
                if (j == 0) // startNode
                {
                    if (i == 0)
                    {
                        if (startNode.classifications == ClassificationValue.Highway)                         // 16
                        {
                            // The first point is highway link
                            startNode.classifications = ClassificationValue.HighwayLink;                             // 8
                        }
                        AddNode(startIndex, startNode);
                        continue;
                    }
                    else
                    {
                        continue;
                    }
                }
                else if (j == Math.Max(countY, countX)) // endNode
                {
                    GraphNode lastNode = graph.nodes[graph.nodes.Count - 1];

                    if ((i == points.Count - 2) && endNode.classifications == ClassificationValue.Highway) // 16
                    {
                        endNode.classifications = ClassificationValue.HighwayLink;                         // 8
                    }

                    AddNode(endIndex, endNode);

                    var distance = (float)GeoCalculator.GetDistanceInMeters(endNode.longitude, endNode.latitude, lastNode.longitude, lastNode.latitude);

                    GraphNode.AddLink(endNode, lastNode, distance, endNode.classifications);
                }
                else
                {
                    GraphNode lastNode = graph.nodes[graph.nodes.Count - 1];
                    double    lon;
                    double    lat;

                    if (countX >= countY)
                    {
                        if (endColumn > startColumn)
                        {
                            lon = lastNode.longitude + graph.cellSizeX;
                            lat = lastNode.latitude + k * graph.cellSizeX;
                        }
                        else
                        {
                            lon = lastNode.longitude - graph.cellSizeX;
                            lat = lastNode.latitude - k * graph.cellSizeX;
                        }
                    }
                    else
                    {
                        if (endRow < startRow)
                        {
                            lat = lastNode.latitude + graph.cellSizeY;
                            lon = lastNode.longitude + k * graph.cellSizeY;
                        }
                        else
                        {
                            lat = lastNode.latitude - graph.cellSizeY;
                            lon = lastNode.longitude - k * graph.cellSizeY;
                        }
                    }

                    int index   = (int)((lon - graph.west) * kX) + grid.countX * (int)((graph.north - lat) * kY);
                    var newNode = new GraphNode(lon, lat, classification, index);

                    var distance = (float)GeoCalculator.GetDistanceInMeters(endNode.longitude, endNode.latitude, lastNode.longitude, lastNode.latitude);

                    AddNode(index, newNode);

                    if (i == 0 && j == 1)
                    {
                        GraphNode.AddLink(endNode, lastNode, distance, ClassificationValue.HighwayLink); // 8
                    }
                    else
                    {
                        GraphNode.AddLink(newNode, lastNode, distance, classification);
                    }
                }
            }
        }
    }
Exemplo n.º 6
0
    public void CreatePotentialNetwork(GridData grid)
    {
        int existingNodeCount = nodes.Count;

        for (int i = grid.countX * grid.countY - 1; i >= 0; i--)
        {
            if (indexToNode.ContainsKey(i) && indexToNode.ContainsKey(-i))             // there are both highway and highway link
            {
                if (indexToNode[i].value >= ClassificationValue.HighwayLink)           // 8
                {
                    CreateHighwayLink(i);
                }
            }

            if (grid.values[i] == ClassificationValue.None)             // 0
            {
                // Create new nodes
                int    row    = i / grid.countX;
                int    column = i - row * grid.countX;
                double lonX   = column * cellSizeX + west;
                double latY   = north - row * cellSizeY;

                GraphNode newNode = new GraphNode(lonX, latY, 0);
                newNode.index = i;
                nodes.Add(newNode);
                indexToNode.Add(i, newNode);
            }
        }

        double x, y;

        GeoCalculator.GetDistanceInMeters(west, south, east, north, out x, out y);
        x /= grid.countX;
        y /= grid.countY;
        float distanceXY = (float)Math.Pow(x * x + y * y, 0.5);
        float distanceX  = (float)x;
        float distanceY  = (float)y;

        // create links for each new node
        int nodeCount = nodes.Count;

        for (int i = existingNodeCount; i < nodeCount; i++)
        {
            GraphNode node = nodes[i];
            if (node.value == 0)
            {
                int thisIndex = node.index;
                int row       = thisIndex / grid.countX;
                int column    = thisIndex - row * grid.countX;
                if (row > 0)
                {
                    int upIndex = thisIndex - grid.countX;
                    if (indexToNode.ContainsKey(upIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[upIndex], distanceY, ClassificationValue.None);
                    }
                }

                if (column > 0)                 // not on the left edge
                {
                    int leftIndex = thisIndex - 1;
                    if (indexToNode.ContainsKey(leftIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[leftIndex], distanceX, ClassificationValue.None);
                    }
                }

                if (row < grid.countY - 1)                 // not on the bottom
                {
                    int downIndex = thisIndex + grid.countX;
                    if (indexToNode.ContainsKey(downIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[downIndex], distanceY, ClassificationValue.None);
                    }
                }

                if (column < grid.countX - 1)
                {
                    int rightIndex = thisIndex + 1;
                    if (indexToNode.ContainsKey(rightIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[rightIndex], distanceX, ClassificationValue.None);
                    }
                }

                if (row > 0 && column > 0)
                {
                    int upleftIndex = thisIndex - grid.countX - 1;
                    if (indexToNode.ContainsKey(upleftIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[upleftIndex], distanceXY, ClassificationValue.None);
                    }
                }

                if (row > 0 && column < grid.countX - 1)
                {
                    int uprightIndex = thisIndex - grid.countX + 1;
                    if (indexToNode.ContainsKey(uprightIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[uprightIndex], distanceXY, ClassificationValue.None);
                    }
                }

                if (row < grid.countY - 1 && column > 0)
                {
                    int downleftIndex = thisIndex + grid.countX - 1;
                    if (indexToNode.ContainsKey(downleftIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[downleftIndex], distanceXY, ClassificationValue.None);
                    }
                }

                if (row < grid.countY - 1 && column < grid.countX - 1)
                {
                    int downrightIndex = thisIndex + grid.countX + 1;
                    if (indexToNode.ContainsKey(downrightIndex))
                    {
                        GraphNode.AddLink(node, indexToNode[downrightIndex], distanceXY, ClassificationValue.None);
                    }
                }
            }
        }
    }