Exemplo n.º 1
0
    def compute_distance_to_nodes(self, x, y, edge):
        """
        Given an observation on a network edge, return the distance to the two nodes that
        bound that end.

        Parameters
        ----------
        x:      float
                x-coordinate of the snapped point.

        y:      float
                y-coordiante of the snapped point.

        edge:   tuple
                (node0, node1) representation of the network edge.

        Returns
        -------
        d1:     float
                The distance to node0.
                    - always the node with the lesser id

        d2:     float
                The distance to node1.
                    - always the node with the greater id
        """

        d1 = util.compute_length((x, y), self.node_coords[edge[0]])
        d2 = util.compute_length((x, y), self.node_coords[edge[1]])
        return d1, d2
Exemplo n.º 2
0
    def compute_distance_to_nodes(self, x, y, edge):
        """
        Given an observation on a network edge, return the distance to the two nodes that 
        bound that end.

        Parameters
        ----------
        x:      float
                x-coordinate of the snapped point.

        y:      float
                y-coordiante of the snapped point.

        edge:   tuple
                (node0, node1) representation of the network edge.

        Returns
        -------
        d1:     float
                The distance to node0.
                    - always the node with the lesser id

        d2:     float
                The distance to node1.
                    - always the node with the greater id
        """

        d1 = util.compute_length((x,y), self.node_coords[edge[0]])
        d2 = util.compute_length((x,y), self.node_coords[edge[1]])
        return d1, d2
Exemplo n.º 3
0
    def extractnetwork(self):
        """
        Using the same logic as the high efficiency areal unit weights creation
        extract the network from the edges / vertices.
        """
        nodecount = 0
        edgetpl = namedtuple('Edge', ['source', 'destination'])
        shps = ps.open(self.in_shp)
        for shp in shps:
            vertices = shp.vertices
            for i, v in enumerate(vertices[:-1]):
                try:
                    vid = self.nodes[v]
                except:
                    self.nodes[v] = vid = nodecount
                    nodecount += 1
                try:
                    nvid = self.nodes[vertices[i+1]]
                except:
                    self.nodes[vertices[i+1]] = nvid = nodecount
                    nodecount += 1

                self.adjacencylist[vid].append(nvid)
                self.adjacencylist[nvid].append(vid)

                #Sort the edges so that mono-directional keys can be stored.
                edgenodes = sorted([vid, nvid])
                edge = tuple(edgenodes)
                self.edges.append(edge)
                length = util.compute_length(v, vertices[i+1])
                self.edge_lengths[edge] = length
Exemplo n.º 4
0
    def _extractnetwork(self):
        """
        Used internally, to extract a network from a polyline shapefile
        """
        nodecount = 0
        shps = ps.open(self.in_shp)
        for shp in shps:
            vertices = shp.vertices
            for i, v in enumerate(vertices[:-1]):
                try:
                    vid = self.nodes[v]
                except:
                    self.nodes[v] = vid = nodecount
                    nodecount += 1
                try:
                    nvid = self.nodes[vertices[i + 1]]
                except:
                    self.nodes[vertices[i + 1]] = nvid = nodecount
                    nodecount += 1

                self.adjacencylist[vid].append(nvid)
                self.adjacencylist[nvid].append(vid)

                #Sort the edges so that mono-directional keys can be stored.
                edgenodes = sorted([vid, nvid])
                edge = tuple(edgenodes)
                self.edges.append(edge)
                length = util.compute_length(v, vertices[i + 1])
                self.edge_lengths[edge] = length
Exemplo n.º 5
0
    def _extractnetwork(self):
        """
        Used internally, to extract a network from a polyline shapefile
        """
        nodecount = 0
        shps = ps.open(self.in_shp)
        for shp in shps:
            vertices = shp.vertices
            for i, v in enumerate(vertices[:-1]):
                try:
                    vid = self.nodes[v]
                except:
                    self.nodes[v] = vid = nodecount
                    nodecount += 1
                try:
                    nvid = self.nodes[vertices[i+1]]
                except:
                    self.nodes[vertices[i+1]] = nvid = nodecount
                    nodecount += 1

                self.adjacencylist[vid].append(nvid)
                self.adjacencylist[nvid].append(vid)

                #Sort the edges so that mono-directional keys can be stored.
                edgenodes = sorted([vid, nvid])
                edge = tuple(edgenodes)
                self.edges.append(edge)
                length = util.compute_length(v, vertices[i+1])
                self.edge_lengths[edge] = length
Exemplo n.º 6
0
    def _extractnetwork(self):
        """
        Used internally, to extract a network from a polyline shapefile.
        """
        nodecount = 0
        shps = ps.open(self.in_shp)
        for shp in shps:
            vertices = shp.vertices
            for i, v in enumerate(vertices[:-1]):
                v = self._round_sig(v)
                try:
                    vid = self.nodes[v]
                except:
                    self.nodes[v] = vid = nodecount
                    nodecount += 1
                v2 = self._round_sig(vertices[i + 1])
                try:
                    nvid = self.nodes[v2]
                except:
                    self.nodes[v2] = nvid = nodecount
                    nodecount += 1

                self.adjacencylist[vid].append(nvid)
                self.adjacencylist[nvid].append(vid)

                # Sort the edges so that mono-directional keys can be stored.
                edgenodes = sorted([vid, nvid])
                edge = tuple(edgenodes)
                self.edges.append(edge)
                length = util.compute_length(v, vertices[i + 1])
                self.edge_lengths[edge] = length
        if self.unique_segs == True:
            # Remove duplicate edges and duplicate adjacent nodes.
            self.edges = list(set(self.edges))
            for k, v in self.adjacencylist.iteritems():
                self.adjacencylist[k] = list(set(v))
Exemplo n.º 7
0
    def _extractnetwork(self):
        """
        Used internally, to extract a network from a polyline shapefile.
        """
        nodecount = 0
        shps = ps.open(self.in_shp)
        for shp in shps:
            vertices = shp.vertices
            for i, v in enumerate(vertices[:-1]):
                v = self._round_sig(v)
                try:
                    vid = self.nodes[v]
                except:
                    self.nodes[v] = vid = nodecount
                    nodecount += 1
                v2 = self._round_sig(vertices[i+1])
                try:
                    nvid = self.nodes[v2]
                except:
                    self.nodes[v2] = nvid = nodecount
                    nodecount += 1

                self.adjacencylist[vid].append(nvid)
                self.adjacencylist[nvid].append(vid)

                # Sort the edges so that mono-directional keys can be stored.
                edgenodes = sorted([vid, nvid])
                edge = tuple(edgenodes)
                self.edges.append(edge)
                length = util.compute_length(v, vertices[i+1])
                self.edge_lengths[edge] = length
        if self.unique_segs == True:
            # Remove duplicate edges and duplicate adjacent nodes.
            self.edges = list(set(self.edges))
            for k, v in self.adjacencylist.iteritems():
                self.adjacencylist[k] = list(set(v))
Exemplo n.º 8
0
    def allneighbordistances(self,
                             sourcepattern,
                             destpattern=None,
                             fill_diagonal=None,
                             n_processes=None):
        """
        Compute either all distances between i and j in a single point pattern or all
        distances between each i from a source pattern and all j from a destination pattern.

        Parameters
        ----------
        sourcepattern:  str
                        The key of a point pattern snapped to the network.

        destpattern:    str
                        (Optional) The key of a point pattern snapped to the network.

        fill_diagonal:  float, int
                        (Optional) Fill the diagonal of the cost matrix.
                        Default in None and will populate the diagonal with numpy.nan
                        Do not declare a destpattern for a custom fill_diagonal.

        n_processes:    int, str
                        (Optional) Specify the number of cores to utilize.
                        Default is 1 core. Use (int) to specify an exact number or cores.
                        Use ("all") to request all available cores.
        Returns
        -------
        nearest:        array (n,n)
                        An array of shape (n,n) storing distances between all points.
        """

        if not hasattr(self, 'alldistances'):
            self.node_distance_matrix(n_processes)

        # Source setup
        src_indices = sourcepattern.points.keys()
        nsource_pts = len(src_indices)
        src_dist_to_node = sourcepattern.dist_to_node
        src_nodes = {}
        for s in src_indices:
            e1, e2 = src_dist_to_node[s].keys()
            src_nodes[s] = (e1, e2)

        # Destination setup
        symmetric = False
        if destpattern is None:
            symmetric = True
            destpattern = sourcepattern
        dest_indices = destpattern.points.keys()
        ndest_pts = len(dest_indices)
        dest_dist_to_node = destpattern.dist_to_node
        dest_searchpts = copy.deepcopy(dest_indices)
        dest_nodes = {}
        for s in dest_indices:
            e1, e2 = dest_dist_to_node[s].keys()
            dest_nodes[s] = (e1, e2)

        # Output setup
        nearest = np.empty((nsource_pts, ndest_pts))
        nearest[:] = np.inf

        for p1 in src_indices:
            # Get the source nodes and dist to source nodes.
            source1, source2 = src_nodes[p1]
            set1 = set(src_nodes[p1])
            # Distance from node1 to p, distance from node2 to p.
            sdist1, sdist2 = src_dist_to_node[p1].values()

            if symmetric:
                # Only compute the upper triangle if symmetric.
                dest_searchpts.remove(p1)
            for p2 in dest_searchpts:
                dest1, dest2 = dest_nodes[p2]
                set2 = set(dest_nodes[p2])
                if set1 == set2:  # same edge
                    x1, y1 = sourcepattern.snapped_coordinates[p1]
                    x2, y2 = destpattern.snapped_coordinates[p2]
                    computed_length = util.compute_length((x1, y1), (x2, y2))
                    nearest[p1, p2] = computed_length

                else:
                    ddist1, ddist2 = dest_dist_to_node[p2].values()
                    d11 = self.alldistances[source1][0][dest1]
                    d21 = self.alldistances[source2][0][dest1]
                    d12 = self.alldistances[source1][0][dest2]
                    d22 = self.alldistances[source2][0][dest2]

                    # Find the shortest distance from the path passing through each of the
                    # two origin nodes to the first destination node.
                    sd_1 = d11 + sdist1
                    sd_21 = d21 + sdist2
                    if sd_1 > sd_21:
                        sd_1 = sd_21
                    # Now add the point to node one distance on the destination edge.
                    len_1 = sd_1 + ddist1

                    # Repeat the prior but now for the paths entering at the second node
                    # of the second edge.
                    sd_2 = d12 + sdist1
                    sd_22 = d22 + sdist2
                    b = 0
                    if sd_2 > sd_22:
                        sd_2 = sd_22
                        b = 1
                    len_2 = sd_2 + ddist2

                    # Now find the shortest distance path between point 1 on edge 1 and
                    # point 2 on edge 2, and assign.
                    sp_12 = len_1
                    if len_1 > len_2:
                        sp_12 = len_2
                    nearest[p1, p2] = sp_12
                if symmetric:
                    # Mirror the upper and lower triangle when symmetric.
                    nearest[p2, p1] = nearest[p1, p2]
        # Populate the main diagonal when symmetric.
        if symmetric:
            if fill_diagonal == None:
                np.fill_diagonal(nearest, np.nan)
            else:
                np.fill_diagonal(nearest, fill_diagonal)

        return nearest
Exemplo n.º 9
0
    def allneighbordistances(self, sourcepattern, destpattern=None, fill_diagonal=None,
                             n_processes=None):
        """
        Compute either all distances between i and j in a single point pattern or all 
        distances between each i from a source pattern and all j from a destination pattern.

        Parameters
        ----------
        sourcepattern:  str
                        The key of a point pattern snapped to the network.

        destpattern:    str
                        (Optional) The key of a point pattern snapped to the network.

        fill_diagonal:  float, int
                        (Optional) Fill the diagonal of the cost matrix.
                        Default in None and will populate the diagonal with numpy.nan
                        Do not declare a destpattern for a custom fill_diagonal.
        
        n_processes:    int, str
                        (Optional) Specify the number of cores to utilize.
                        Default is 1 core. Use (int) to specify an exact number or cores.
                        Use ("all") to request all available cores.
        Returns
        -------
        nearest:        array (n,n)
                        An array of shape (n,n) storing distances between all points.
        """

        if not hasattr(self,'alldistances'):
            self.node_distance_matrix(n_processes)
            
        # Source setup
        src_indices = sourcepattern.points.keys()
        nsource_pts = len(src_indices)
        src_dist_to_node = sourcepattern.dist_to_node
        src_nodes = {}
        for s in src_indices:
            e1, e2 = src_dist_to_node[s].keys()
            src_nodes[s] = (e1, e2)

        # Destination setup
        symmetric = False
        if destpattern is None:
            symmetric = True
            destpattern = sourcepattern
        dest_indices = destpattern.points.keys()
        ndest_pts = len(dest_indices)
        dest_dist_to_node = destpattern.dist_to_node
        dest_searchpts = copy.deepcopy(dest_indices)
        dest_nodes = {}
        for s in dest_indices:
            e1, e2 = dest_dist_to_node[s].keys()
            dest_nodes[s] = (e1, e2)
        
        # Output setup
        nearest = np.empty((nsource_pts, ndest_pts))
        nearest[:] = np.inf

        for p1 in src_indices:
            # Get the source nodes and dist to source nodes.
            source1, source2 = src_nodes[p1]
            set1 = set(src_nodes[p1])
            # Distance from node1 to p, distance from node2 to p.
            sdist1, sdist2 = src_dist_to_node[p1].values()

            if symmetric:
                # Only compute the upper triangle if symmetric.
                dest_searchpts.remove(p1)
            for p2 in dest_searchpts:
                dest1, dest2 = dest_nodes[p2]
                set2 = set(dest_nodes[p2])
                if set1 == set2: # same edge
                    x1,y1 = sourcepattern.snapped_coordinates[p1]
                    x2,y2 = destpattern.snapped_coordinates[p2]
                    computed_length = util.compute_length((x1,y1),(x2,y2))
                    nearest[p1,p2] = computed_length

                else:
                    ddist1, ddist2 = dest_dist_to_node[p2].values()
                    d11 = self.alldistances[source1][0][dest1]
                    d21 = self.alldistances[source2][0][dest1]
                    d12 = self.alldistances[source1][0][dest2]
                    d22 = self.alldistances[source2][0][dest2]

                    # Find the shortest distance from the path passing through each of the 
                    # two origin nodes to the first destination node.
                    sd_1 = d11 + sdist1
                    sd_21 = d21 + sdist2
                    if sd_1 > sd_21:
                        sd_1 = sd_21
                    # Now add the point to node one distance on the destination edge.
                    len_1 = sd_1 + ddist1

                    # Repeat the prior but now for the paths entering at the second node 
                    # of the second edge.
                    sd_2 = d12 + sdist1
                    sd_22 = d22 + sdist2
                    b = 0
                    if sd_2 > sd_22:
                        sd_2 = sd_22
                        b = 1
                    len_2 = sd_2 + ddist2

                    # Now find the shortest distance path between point 1 on edge 1 and
                    # point 2 on edge 2, and assign.
                    sp_12 = len_1
                    if len_1 > len_2:
                        sp_12 = len_2
                    nearest[p1, p2] = sp_12
                if symmetric:
                    # Mirror the upper and lower triangle when symmetric.
                    nearest[p2,p1] = nearest[p1,p2]                    
        # Populate the main diagonal when symmetric.
        if symmetric:
            if fill_diagonal == None:
                np.fill_diagonal(nearest, np.nan)
            else:
                np.fill_diagonal(nearest, fill_diagonal)
            
        return nearest