def snap(self, p):
        """
        Test tag <tc>#is#Snapper.snap</tc>
        """
        """
        Initialize the closest location found so far to be infinitely far away.
        Then begin with a neighborhood on the order of the maximum edge allowed and
        repeatedly growing it. When a closest edge is found, grow once more and check again.
        """

        cur_s_rad = self.search_rad
        found_something = False
        # Whle neighborhood is empty, enlarge and check again
        while not found_something:
            if self.grid.proximity(Point(p), cur_s_rad) != []:
                found_something = True
            cur_s_rad *= 2
        # Expand to include any edges whose endpoints might lie just outside
        # the search radius
        cur_s_rad += self.search_rad
        # Now find closest in this neighborhood
        best_seg_dist = 1e600
        for e in self.grid.proximity(Point(p), cur_s_rad):
            seg = LineSegment(Point(e[0]), Point(e[1]))
            p2seg = pysal.cg.get_segment_point_dist(seg, Point(p))
            dist = p2seg[0]
            if p2seg[0] < best_seg_dist:
                # (src, dest, dist_from_src, dist_from_dest)
                best_proj = (e[0], e[1], dist * p2seg[1],
                             dist * (1 - p2seg[1]))
                best_seg_dist = p2seg[0]
        return best_proj
Esempio n. 2
0
def random_segments(n):
    segs = []
    for i in range(n):
        a, b, c, d = [random.random() for x in [1, 2, 3, 4]]
        seg = LineSegment(Point((a, b)), Point((c, d)))
        segs.append(seg)
    return segs
def proj_pnt_coor(proj_pnt):
    n1, n2 = proj_pnt[0], proj_pnt[1]
    dist_n12 = pysal.cg.get_points_dist(Point(n1), Point(n2))
    len_ratio = proj_pnt[2] * 1.0 / dist_n12
    xrange, yrange = n2[0] - n1[0], n2[1] - n1[1]
    x = n1[0] + xrange * len_ratio
    y = n1[1] + yrange * len_ratio
    return (x, y)
def write_list_network_to_shp(filename, fields, types, net):
    oShp = pysal.open(filename, 'w')
    oDbf = pysal.open(filename[:-3] + 'dbf', 'w')
    oDbf.header = ['ID'] + fields
    oDbf.field_spec = [('N', 9, 0)] + types
    for i, rec in enumerate(net):
        geom = rec[0]
        table_data = list(rec[1:])
        oShp.write(Chain([Point(geom[0]), Point(geom[1])]))
        oDbf.write([i] + table_data)
    oShp.close()
    oDbf.close()
def network_from_allvertices(s, d):
    G = {}
    for g, r in zip(s, d):
        vertices = g.vertices
        for i, vertex in enumerate(vertices[:-1]):
            n1, n2 = vertex, vertices[i + 1]
            dist = pysal.cg.get_points_dist(Point(n1), Point(n2))
            G.setdefault(n1, {})
            G.setdefault(n2, {})
            G[n1][n2] = dist
            G[n2][n1] = dist
    s.close()
    d.close()
    return G
def inject_points(network, proj_pnts):

    pnts_by_seg = {}
    proj_pnt_coors = []
    for pnt in proj_pnts:
        target_edge = None
        if (pnt[0], pnt[1]) not in pnts_by_seg and (pnt[1],
                                                    pnt[0]) not in pnts_by_seg:
            target_edge = (pnt[0], pnt[1])
            pnts_by_seg[target_edge] = set()
        elif (pnt[0], pnt[1]) in pnts_by_seg:
            target_edge = (pnt[0], pnt[1])
        elif (pnt[1], pnt[0]) in pnts_by_seg:
            target_edge = (pnt[1], pnt[0])
        coor = proj_pnt_coor(pnt)
        pnts_by_seg[target_edge].add(coor)
        proj_pnt_coors.append(coor)

    new_network = copy.deepcopy(network)

    for seg in pnts_by_seg:
        proj_nodes = set(list(pnts_by_seg[seg]) + [seg[0], seg[1]])
        proj_nodes = list(proj_nodes)
        if seg[0][0] == seg[1][0]:
            proj_nodes.sort(key=lambda coords: coords[1])
        else:
            proj_nodes.sort()
        proj_nodes_len = len(proj_nodes)
        prev_seg_d, next_seg_d = 0.0, 0.0
        for i in range(proj_nodes_len - 1):
            start, end = proj_nodes[i], proj_nodes[i + 1]
            if start not in new_network:
                new_network[start] = {}
            if end not in new_network:
                new_network[end] = {}
            d = pysal.cg.get_points_dist(Point(start), Point(end))
            new_network[start][end] = d
            new_network[end][start] = d
        if seg[0] in new_network and seg[1] in new_network[seg[0]]:
            del new_network[seg[0]][seg[1]]
            del new_network[seg[1]][seg[0]]
        else:
            print(seg, seg[0] in network, network[seg[0]], seg[1] in network,
                  network[seg[1]])

    return new_network, proj_pnt_coors
def write_valued_network_to_shp(filename, fields, types, net, values, valFunc):
    oShp = pysal.open(filename, 'w')
    oDbf = pysal.open(filename[:-3] + 'dbf', 'w')
    oDbf.header = fields
    oDbf.field_spec = types
    #for n in net:
    #    for m in net:
    #        oShp.write(Chain([Point(n), Point(m)]))
    #        oDbf.write([valFunc(values, n), valFunc(values, m)])
    used, counter = set(), 0
    for n in net:
        for m in net[n]:
            if m in used: continue
            oShp.write(Chain([Point(n), Point(m)]))
            oDbf.write([valFunc(values, n), valFunc(values, m)])
            counter += 1
        used.add(n)
    oShp.close()
    oDbf.close()
def write_network_to_pysalshp(network, filename, header=None, field_spec=None):

    if not filename.endswith('shp') and not filename.endswith('SHP'):
        print('filename would end with shp or SHP')
        return

    shp = pysal.open(filename, 'w')
    dbf = pysal.open(filename[:-3] + 'dbf', 'w')
    if not header:
        dbf.header = ['ID', 'VALUE']
    else:
        dbf.header = ['ID'] + header
    if not field_spec:
        dbf.field_spec = [('N', 9, 0), ('N', 15, 8)]

        def getValue(G, n, m):
            return [G[n][m]]
    else:
        dbf.field_spec = [('N', 9, 0)] + field_spec
        v = network[list(network.keys())[0]]
        if type(v) == dict:
            v = list(v.values())[0]
        if type(v) == list:
            wrap_func = list
        else:

            def wrap_func(value):
                return [value]

        def getValue(G, n, m):
            return wrap_func(G[n][m])

    used, counter = set(), 0
    for n1 in network:
        for n2 in network[n1]:
            if n2 in used: continue
            shp.write(Chain([Point(n1), Point(n2)]))
            dbf.write([counter] + getValue(network, n1, n2))
            counter += 1
        used.add(n1)

    shp.close()
    dbf.close()
Esempio n. 9
0
def read_hierarchical_network(s, d):
    G, Gj, G_to_Gj = {}, {}, {}
    for g, r in zip(s, d):
        vertices = g.vertices
        Gj.setdefault(vertices[0], {}) 
        Gj.setdefault(vertices[-1], {}) 
        d_total = 0.0 
        for i, vertex in enumerate(vertices[:-1]):
            n1, n2 = vertex, vertices[i+1]
            dist = pysal.cg.get_points_dist(Point(n1), Point(n2)) 
            G.setdefault(n1, {}) 
            G.setdefault(n2, {}) 
            G[n1][n2] = dist 
            G[n2][n1] = dist
            G_to_Gj[(n1,n2)] = [(vertices[0], vertices[-1]), d_total] # info for the opposite direction 
            d_total += dist
        Gj[vertices[0]][vertices[-1]] = d_total
        Gj[vertices[-1]][vertices[0]] = d_total
    s.close()
    d.close()
    return G, Gj, G_to_Gj
Esempio n. 10
0
    def test_multipart_chain(self):
        vertices = [[Point((0, 0)),
                     Point((1, 0)),
                     Point((1, 5))],
                    [Point((-5, -5)),
                     Point((-5, 0)),
                     Point((0, 0))]]

        #part A
        chain0 = Chain(vertices[0])
        #part B
        chain1 = Chain(vertices[1])
        #part A and B
        chain2 = Chain(vertices)

        json = chain0.__geo_interface__
        self.assertEquals(json['type'], 'LineString')
        self.assertEquals(len(json['coordinates']), 3)

        json = chain1.__geo_interface__
        self.assertEquals(json['type'], 'LineString')
        self.assertEquals(len(json['coordinates']), 3)

        json = chain2.__geo_interface__
        self.assertEquals(json['type'], 'MultiLineString')
        self.assertEquals(len(json['coordinates']), 2)

        chain3 = pysal.cg.asShape(json)
        self.assertEquals(chain2.parts, chain3.parts)
def mesh_network(network, cellwidth, at_center=False):
    mesh_net = {}
    done = {}
    #done = set()
    for n1 in network:
        for n2 in network[n1]:
            #if n2 in done: continue
            if (n1, n2) in done or (n2, n1) in done:
                continue
            len_ratio = cellwidth * 1.0 / network[n1][n2]
            start, end = n1, n2
            # The order for reading a network edge is slightly different from SANET.
            # SANET does not seem to have a set of consistent rules.
            if n1[0] < n2[0] or (n1[0] == n2[0] and n1[1] < n2[1]):
                start, end = n2, n1
            xrange, yrange = end[0] - start[0], end[1] - start[1]
            dx, dy = xrange * len_ratio, yrange * len_ratio
            no_segments = int(math.floor(1.0 / len_ratio))
            if at_center:
                xs = [start[0], start[0] + dx / 2.0]
                ys = [start[1], start[1] + dy / 2.0]
                xs = xs + [xs[-1] + i * dx for i in range(1, no_segments + 1)]
                ys = ys + [ys[-1] + i * dy for i in range(1, no_segments + 1)]
            else:
                xs = [start[0] + i * dx for i in range(no_segments + 1)]
                ys = [start[1] + i * dy for i in range(no_segments + 1)]
            if xs[-1] != end[0] or ys[-1] != end[1]:
                xs.append(end[0])
                ys.append(end[1])
            new_nodes = list(zip(xs, ys))
            for i in range(len(new_nodes) - 1):
                n, m = new_nodes[i], new_nodes[i + 1]
                d = pysal.cg.get_points_dist(Point(n), Point(m))
                if n not in mesh_net: mesh_net[n] = {}
                if m not in mesh_net: mesh_net[m] = {}
                mesh_net[n][m] = d
                mesh_net[m][n] = d
            done[(n1, n2)] = True
        #done.add(n1)
    return mesh_net
Esempio n. 12
0
def convert_geometries(df, pkg='pysal', strict=False):
    first = df['geometry'].head(1).tolist()[0]
    if pkg.lower() == 'pysal':
        from pysal.cg.shapes import Chain, Point, asShape
        try:
            df['geometry'] = pd.Series([asShape(e) for e in df['geometry']])
        except:
            if 'Polygon' in first['type']:
                df['geometry'] = pd.Series([parse_polygon_to_pysal(e)\
                                            for e in df['geometry']])
            elif 'Line' in first['type']:
                df['geometry'] = pd.Series([Chain(e['coordinates'])\
                                            for e in df['geometry']])
            elif 'MultiPoint' in first['type']:
                df['geometry'] = pd.Series([[Point(c) for c in e['coordinates']]\
                                            for e in df['geometry']])
            elif 'Point' in first['type']:
                df['geometry'] = pd.Series([Point(e['coordinates'][0])\
                                            for e in df['geometry']])
    elif pkg.lower() == 'shapely':
        from shapely import geometry as g
        try:
            df['geometry'] = pd.Series(
                [g.__dict__[e['type']](e) for e in df['geometry']])
        except:
            if 'Polygon' in first['type']:
                df['geometry'] = pd.Series([parse_polygon_to_shapely(e, strict=strict)\
                                            for e in df['geometry']])
            elif 'MultiLine' in first['type']:
                df['geometry'] = pd.Series([g.MultiLineString(e['coordinates'])\
                                            for e in df['geometry']])
            elif 'MultiPoint' in first['type']:
                df['geometry'] = pd.Series(
                    [g.MultiPoint(e['coordinates']) for e in df['geometry']])
            elif 'Point' in first['type']:
                df['geometry'] = pd.Series([g.Point(e['coordinates'][0])\
                                            for e in df['geometry']])
    return df
Esempio n. 13
0
def random_points(n):
    return [Point((random.random(), random.random())) for x in range(n)]
 def wgt(g, r):
     return pysal.cg.get_points_dist(Point(g.vertices[0]),
                                     Point(g.vertices[-1]))
 def wgt(g, r):
     d = pysal.cg.get_points_dist(Point(g.vertices[0]),
                                  Point(g.vertices[-1]))
     return [d] + [r[w] for w in w_indices]
    def __init__(self, network):
        """
        Test tag <tc>#is#Snapper.__init__</tc>
        """
        """
        Generate a list of the edge lengths and pick a maximum length
        allowed based on the median length. This maximum length will be
        used to use multiple midpoints to represent edges which are 
        exceptionally long, lest they ruin the efficiency of the algorithm.
        """

        # Generate list of lengths
        self.network = network
        edge_lens = []
        for n in network:
            for m in network[n]:
                if n != m:
                    edge_lens.append(
                        pysal.cg.get_points_dist(
                            Point(n), Point(m)))  # it can be optional
        if edge_lens == []:
            raise ValueError('Network has no positive-length edges')
        edge_lens.sort()
        max_allowed_edge_len = 5 * edge_lens[len(edge_lens) / 2]
        """ 
        Create a bin structures with proper range to hold all of the edges.
        The size of the bin is on the order of the length of the longest edge (and
        of the neighborhoods searched around each query point.
        """
        endpoints = list(network.keys())
        endpoints_start, endpoints_end = [ep[0] for ep in endpoints
                                          ], [ep[1] for ep in endpoints]
        bounds = Rectangle(min(endpoints_start), min(endpoints_end),
                           max(endpoints_start), max(endpoints_end))
        self.grid = Grid(bounds, max_allowed_edge_len)
        """
        Insert the midpoint of each edge into the grid. If an edge is too long, 
        break it into edges of length less than the maximum allowed length and
        add the midpoint of each.
        """
        self.search_rad = max_allowed_edge_len * 0.55
        for n in network:
            for m in network[n]:
                edge_len = pysal.cg.get_points_dist(
                    Point(n), Point(m))  # it can be a direct extraction
                if edge_len > max_allowed_edge_len:
                    mid_edge = []
                    num_parts = int(math.ceil(edge_len / max_allowed_edge_len))
                    part_step = 1.0 / num_parts
                    dx = m[0] - n[0]
                    dy = m[1] - n[1]
                    midpoint = (n[0] + dx * part_step / 2,
                                n[1] + dy * part_step / 2)
                    for r in [part_step * t for t in range(num_parts)]:
                        mid_edge.append(((n, m), midpoint))
                        midpoint = (midpoint[0] + dx * part_step,
                                    midpoint[1] + dy * part_step)
                    for me in mid_edge:
                        self.grid.add(me[0], Point(me[1]))
                else:
                    self.grid.add((n, m),
                                  Point(
                                      ((n[0] + m[0]) / 2, (n[1] + m[1]) / 2)))
        """
        During the snapping of a query point we will initialize the closest point on the network
        to be a dummy location known to be invalid. This must be done in case the neighborhood
        search does not find any edge midpoints and it must be grown repeatedly. In this case
        we want to make sure we don't give up having not found a valid closest edge.
        """
        self.dummy_proj = (None, None, 0, 0
                           )  # Src, dest, dist_from_src, dist_from_dest)