def setUp(self): # synthetic test data bounds, h, v = (0, 0, 3, 3), 2, 2 lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=True) self.ntw = self.spaghetti.Network(in_data=lattice) chains = [ cg.Chain([ cg.Point(self.ntw.vertex_coords[p1]), cg.Point(self.ntw.vertex_coords[p2]), ]) for (p1, p2) in self.ntw.arcs ] midpoints = [] for chain in chains: (v1x, v1y), (v2x, v2y) = chain.vertices mid = cg.Point(((v1x + v2x) / 2.0, (v1y + v2y) / 2.0)) midpoints.append(mid) self.mids = "mids" self.ntw.snapobservations(midpoints, self.mids) npts = self.ntw.pointpatterns[self.mids].npoints self.test_permutations = 99 self.test_steps = 10 # empirical test_data self.ntw_shp = self.spaghetti.Network(in_data=STREETS) self.ntw_shp.snapobservations(CRIMES, crimes, attribute=True)
def setUp(self): bounds, h, v = (0, 0, 3, 3), 2, 2 lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=True) self.ntw = self.spaghetti.Network(in_data=lattice) chains = [ cg.Chain([ cg.Point(self.ntw.vertex_coords[p1]), cg.Point(self.ntw.vertex_coords[p2]), ]) for (p1, p2) in self.ntw.arcs ] midpoints = [] for chain in chains: (v1x, v1y), (v2x, v2y) = chain.vertices mid = cg.Point(((v1x + v2x) / 2.0, (v1y + v2y) / 2.0)) midpoints.append(mid) self.mids = "mids" self.ntw.snapobservations(midpoints, self.mids) npts = self.ntw.pointpatterns[self.mids].npoints numpy.random.seed(0) self.ntw.simulate_observations(npts) self.test_permutations = 99 self.test_steps = 10
def test_pp_from_single_libpysal_point(self): # network instantiated from a single libpysal.cg.Chain known_dist = 1.4142135623730951 self.ntw_from_chain = self.spaghetti.Network(in_data=P11P22_CHAIN) self.ntw_from_chain.snapobservations(P00, synth_obs) snap_dist = self.ntw_from_chain.pointpatterns[synth_obs].dist_snapped[ 0] self.assertAlmostEqual(snap_dist, known_dist, places=10) # network instantiated from a single vertical (up) libpysal.cg.Chain chain = cg.Chain([P11, P12]) known_dist = 1.0 self.ntw_from_chain = self.spaghetti.Network(in_data=chain) self.ntw_from_chain.snapobservations(cg.Point((0, 1.5)), synth_obs) snap_dist = self.ntw_from_chain.pointpatterns[synth_obs].dist_snapped[ 0] self.assertEqual(snap_dist, known_dist) # network instantiated from a single vertical (down) libpysal.cg.Chain chain = cg.Chain([cg.Point((5, 5)), cg.Point((5, 4))]) known_dist = 1.5 self.ntw_from_chain = self.spaghetti.Network(in_data=chain) self.ntw_from_chain.snapobservations(cg.Point((6.5, 4.5)), synth_obs) snap_dist = self.ntw_from_chain.pointpatterns[synth_obs].dist_snapped[ 0] self.assertEqual(snap_dist, known_dist)
def test_element_as_gdf(self): # extract both vertices and arcs vertices, arcs = self.spaghetti.element_as_gdf(self.ntw_shp, vertices=True, arcs=True) # test arcs known_vertex_wkt = "POINT (728368.04762 877125.89535)" observed_vertex = vertices.loc[(vertices["id"] == 0), "geometry"].squeeze() observed_vertex_wkt = observed_vertex.wkt self.assertEqual(observed_vertex_wkt, known_vertex_wkt) # test arcs known_arc_wkt = ( "LINESTRING (728368.04762 877125.89535, 728368.13931 877023.27186)" ) observed_arc = arcs.loc[(arcs["id"] == (0, 1)), "geometry"].squeeze() observed_arc_wkt = observed_arc.wkt self.assertEqual(observed_arc_wkt, known_arc_wkt) # extract only arcs arcs = self.spaghetti.element_as_gdf(self.ntw_shp, arcs=True) observed_arc = arcs.loc[(arcs["id"] == (0, 1)), "geometry"].squeeze() observed_arc_wkt = observed_arc.wkt self.assertEqual(observed_arc_wkt, known_arc_wkt) # extract symmetric routes known_length, bounds, h, v = 2.6, (0, 0, 3, 3), 2, 2 lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) ntw = self.spaghetti.Network(in_data=lattice) SYNTH_OBS = [ cg.Point([0.2, 1.3]), cg.Point([0.2, 1.7]), cg.Point([2.8, 1.5]) ] ntw.snapobservations(SYNTH_OBS, synth_obs) _, tree = ntw.allneighbordistances(synth_obs, gen_tree=True) paths = ntw.shortest_paths(tree, synth_obs) paths_gdf = self.spaghetti.element_as_gdf(ntw, routes=paths) observed_length = paths_gdf.loc[0, "geometry"].length self.assertEqual(observed_length, known_length) # extract asymmetric routes known_origins, bounds, h, v = 2, (0, 0, 3, 3), 2, 2 lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) ntw = self.spaghetti.Network(in_data=lattice) POINTS1 = [P0505, P2525] POINTS2 = [P0525, P2505] ntw.snapobservations(POINTS1, points1) ntw.snapobservations(POINTS2, points2) _, tree = ntw.allneighbordistances(points1, points2, gen_tree=True) paths = ntw.shortest_paths(tree, points1, pp_dest=points2) paths_gdf = self.spaghetti.element_as_gdf(ntw, routes=paths) observed_origins = paths_gdf["O"].nunique() self.assertEqual(observed_origins, known_origins)
def test_shortest_paths(self): # symmetric point pattern known_vertices = 10 self.ntw_shp.snapobservations(SCHOOLS, schools) _, tree = self.ntw_shp.allneighbordistances(schools, gen_tree=True) observed_paths = self.ntw_shp.shortest_paths(tree, schools) observed_vertices = len(observed_paths[0][1].vertices) self.assertEqual(observed_vertices, known_vertices) # asymmetric point pattern bounds, h, v = (0, 0, 3, 3), 2, 2 lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) ntw = self.spaghetti.Network(in_data=lattice) POINTS1 = [P0505, P2525] POINTS2 = [P0525, P2505, cg.Point((0.75, 0.6))] ntw.snapobservations(POINTS1, points1) ntw.snapobservations(POINTS2, points2) _, tree = ntw.allneighbordistances(points1, points2, gen_tree=True) observed_paths = ntw.shortest_paths(tree, points1, pp_dest=points2) # observed values observed_vertices1 = observed_paths[2][1].vertices observed_vertices2 = len(observed_paths[3][1].vertices) # known values known_vertices1 = [(1.0, 0.5), (1.0, 0.6)] known_vertices2 = 4 self.assertEqual(observed_vertices1, observed_vertices1) self.assertEqual(observed_vertices2, known_vertices2) # test error with self.assertRaises(AttributeError): lattice = self.spaghetti.regular_lattice((0, 0, 4, 4), 4) ntw = self.spaghetti.Network(in_data=lattice) paths = ntw.shortest_paths([], synth_obs)
def _chain_constr(_vcoords, _vs): """Construct a libpysal.cg.Chain object. Parameters ---------- _vcoords : {dict, None} See ``vcoords`` in ``get_chains()``. _vs : tuple Start and end vertex IDs of arc. Returns ------- chain : libpysal.cg.Chain Spatial representation of the arc. """ if _vcoords: chain_vtx_points = [cg.Point((_vcoords[v])) for v in _vs] else: chain_vtx_points = _vs chain = cg.Chain(chain_vtx_points) return chain
def test_pp_from_libpysal_points(self): # known cpp = self.ntw.pointpatterns[crimes] known_snapped = set(cpp.snapped_coordinates.values()) cg_crimes = "cg_%s" % crimes # points from pysal geometries points = [cg.Point(cpp.points[i]["coordinates"]) for i in cpp.points] for dtype in (list, tuple): point_data = dtype(points) self.ntw.snapobservations(point_data, cg_crimes, attribute=True) observed = self.ntw.pointpatterns[cg_crimes] observed_snapped = set(observed.snapped_coordinates.values()) self.assertEqual(observed_snapped, known_snapped)
def setUp(self): # empirical network instantiated from shapefile self.ntw_shp = self.spaghetti.Network(in_data=STREETS, weightings=True) self.n_known_shp_arcs, self.n_known_shp_vertices = 303, 230 # native pysal geometries self.chains_from_shp = [ cg.Chain([ cg.Point(self.ntw_shp.vertex_coords[vertex]) for vertex in arc ]) for arc in self.ntw_shp.arcs ] # lattice and ring + extension bounds, h, v = (0, 0, 2, 2), 1, 1 self.lattice = self.spaghetti.regular_lattice(bounds, h, nv=v) self.lines = self.lattice + RING + EXTENSION self.ntw_from_lattice_ring = self.spaghetti.Network(in_data=self.lines) self.ntw_from_lattice_ring.snapobservations([P0505, P052], "points")
GEOPANDAS_EXTINCT = False except ImportError: GEOPANDAS_EXTINCT = True # empirical data --------------------------------------------------------------- # network shapefile STREETS = examples.get_path("streets.shp") # observations schools = "schools" SCHOOLS = examples.get_path(schools + ".shp") crimes = "crimes" CRIMES = examples.get_path(crimes + ".shp") # native pysal geometries ------------------------------------------------------ P00 = cg.Point((0, 0)) P03 = cg.Point((0, 3)) P030001 = cg.Point((0, 3.0001)) P01 = cg.Point((0, 1)) P10 = cg.Point((1, 0)) P11 = cg.Point((1, 1)) P12 = cg.Point((1, 2)) P21 = cg.Point([2, 1]) P22 = cg.Point((2, 2)) P33 = cg.Point((3, 3)) P34 = cg.Point((3, 4)) P40 = cg.Point((4, 0)) P400010 = cg.Point((4.0001, 0)) P11P22_CHAIN = cg.Chain([P11, P22]) P0505 = cg.Point([0.5, 0.5])
def build_chains(space_h, space_v, exterior, bounds, h=True): """Generate line segments for a lattice. Parameters ---------- space_h : list Horizontal spacing. space_v : list Vertical spacing. exterior : bool Flag for including the outer bounding box segments. bounds : list Area bounds in the form - <minx,miny,maxx,maxy>. h : bool Generate horizontal line segments. Default is ``True``. ``False`` generates vertical segments. Returns ------- chains : list All horizontal or vertical line segments in the lattice. """ # Initialize starting and ending indices start_h, end_h, start_v, end_v = 0, len(space_h), 0, len(space_v) # set inital index track back to 0 minus_y, minus_x = 0, 0 if h: # start track back at 1 for horizontal lines minus_x = 1 if not exterior: # do not include borders start_v += 1 end_v -= 1 else: # start track back at 1 for vertical lines minus_y = 1 if not exterior: # do not include borders start_h += 1 end_h -= 1 # Create empty line list and fill chains = [] # for element in the horizontal index for plus_h in range(start_h, end_h): # for element in the vertical index for plus_v in range(start_v, end_v): # ignore if a -1 index if plus_h - minus_x == -1 or plus_v - minus_y == -1: continue else: # Point 1 (start point + previous slot in # horizontal or vertical space index) p1x = bounds[0] + space_h[plus_h - minus_x] p1y = bounds[1] + space_v[plus_v - minus_y] p1 = cg.Point((p1x, p1y)) # Point 2 (start point + current slot in # horizontal or vertical space index) p2x = bounds[0] + space_h[plus_h] p2y = bounds[1] + space_v[plus_v] p2 = cg.Point((p2x, p2y)) # libpysal.cg.Chain chains.append(_chain_constr(None, [p1, p2])) return chains