def test_join_line_ABC_extends_line_BA(): data = { "ba": {"type": "LineString", "coordinates": [[1, 0], [0, 0]]}, "abc": {"type": "LineString", "coordinates": [[0, 0], [1, 0], [2, 0]]}, } topo = Join(data).to_dict() assert geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(1.0, 0.0), (0.0, 0.0)]) )
def test_line_DBC_merge_reversed_line_CBA(self): data = { "cba": {"type": "LineString", "coordinates": [[2, 0], [1, 0], [0, 0]]}, "dbc": {"type": "LineString", "coordinates": [[3, 0], [1, 0], [2, 0]]}, } topo = Join(data).to_dict() self.assertTrue( geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(2.0, 0.0), (1.0, 0.0), (3.0, 0.0)]) ) )
def test_line_ABD_deviates_line_CBA(self): data = { "cba": {"type": "LineString", "coordinates": [[2, 0], [1, 0], [0, 0]]}, "abd": {"type": "LineString", "coordinates": [[0, 0], [1, 0], [3, 0]]}, } topo = Join(data).to_dict() self.assertTrue( geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(2.0, 0.0), (0.0, 0.0)]) ) )
def test_line_ABC_extends_line_BC(self): data = { "abc": {"type": "LineString", "coordinates": [[0, 0], [1, 0], [2, 0]]}, "bc": {"type": "LineString", "coordinates": [[1, 0], [2, 0]]}, } topo = Join(data).to_dict() self.assertTrue( geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(1.0, 0.0), (0.0, 0.0), (2.0, 0.0)]) ) )
def alpha_shape(points, alpha): """Compute the alpha shape (concave hull) of a set of points. @param points: Iterable container of points. @param alpha: alpha value to influence the gooeyness of the border. Smaller numbers don't fall inward as much as larger numbers. Too large, and you lose everything! """ if len(points) < 4: # When you have a triangle, there is no sense # in computing an alpha shape. return geometry.MultiPoint( list(points)).convex_hull, geometry.MultiPoint(list(points)) def add_edge(edges, edge_points, coords, i, j): """Add a line between the i-th and j-th points, if not in the list already""" if (i, j) in edges or (j, i) in edges: # already added return edges.add((i, j)) edge_points.append(coords[[i, j]]) coords = np.array([point.coords[0] for point in points]) tri = Delaunay(coords) edges = set() edge_points = [] # loop over triangles: # ia, ib, ic = indices of corner points of the # triangle for ia, ib, ic in tri.vertices: pa = coords[ia] pb = coords[ib] pc = coords[ic] # Lengths of sides of triangle a = math.sqrt((pa[0] - pb[0])**2 + (pa[1] - pb[1])**2) b = math.sqrt((pb[0] - pc[0])**2 + (pb[1] - pc[1])**2) c = math.sqrt((pc[0] - pa[0])**2 + (pc[1] - pa[1])**2) # Semiperimeter of triangle s = (a + b + c) / 2.0 # Area of triangle by Heron's formula area = math.sqrt(s * (s - a) * (s - b) * (s - c)) circum_r = a * b * c / (4.0 * area) # Here's the radius filter. #print circum_r if circum_r < 1.0 / alpha: add_edge(edges, edge_points, coords, ia, ib) add_edge(edges, edge_points, coords, ib, ic) add_edge(edges, edge_points, coords, ic, ia) m = geometry.MultiLineString(edge_points) triangles = list(polygonize(m)) return cascaded_union(triangles), edge_points
def crowding(track, Roads, buffersize=500, pointsToAdd=1000): def getRoadSegments(track, Roads, buffersize=500): Buffer = track.buffer(buffersize) #shapely.ops.cascaded_union(track['geometry'].apply(lambda x: x.buffer(buffersize))) return Roads[Roads["geometry"].intersects(Buffer)] FakePoints = [point for road in getRoadSegments(track, Roads, buffersize)['geometry'] for point in list(road.coords)] try: FakePointsToAdd = geometry.MultiPoint(random.sample(FakePoints, pointsToAdd)) except ValueError: FakePointsToAdd = geometry.MultiPoint(FakePoints) #print("Not enough points available. Added "+str(len(FakePoints))) return track.union(FakePointsToAdd)
def test_ptconvex2(self): print "testing geomutil.ptconvex2" points = shg.MultiPoint([(0, 0), (0, 1), (3.2, 1), (3.2, 0.7), (0.4, 0.7), (0.4, 0)]) polyg = Polygon(points) cvex,ccave = polyg.ptconvex2() assert_equal(cvex,[-5] ) assert_equal(ccave,[-1, -2, -3, -4, -6] ) points = shg.MultiPoint([(0, 0), (0, 1), (-3.2, 1), (-3.2, 0.7), (-0.4, 0.7), (-0.4, 0)]) polyg = Polygon(points) cvex,ccave = polyg.ptconvex2() assert_equal(cvex,[-5] ) assert_equal(ccave,[-1, -2, -3, -4, -6] )
def inc(self, cy): """ Returns True if self includes cy """ npoints = filter(lambda x: x < 0, self.cycle) coords = map(lambda x: self.G.pos[x], npoints) polyself = geu.Polygon(sh.MultiPoint(tuple(coords)), self.cycle) npoints = filter(lambda x: x < 0, cy.cycle) coords = map(lambda x: cy.G.pos[x], npoints) polycy = geu.Polygon(sh.MultiPoint(tuple(coords)), cy.cycle) pdb.set_trace() bool = polyself.intersect(polycy) return (bool)
def serialize_as_svg(topo_object, separate=False, include_junctions=False): from IPython.display import SVG, display from shapely import geometry keys = topo_object.keys() if "arcs" in keys: arcs = topo_object["arcs"] if arcs: # dequantize if quantization is applied if "transform" in keys: np_arcs = np_array_from_arcs(arcs) transform = topo_object["transform"] scale = transform["scale"] translate = transform["translate"] np_arcs = dequantize(np_arcs, scale, translate) l_arcs = [] for ls in np_arcs: l_arcs.append(ls[~np.isnan(ls)[:, 0]].tolist()) arcs = l_arcs arcs = [geometry.LineString(arc) for arc in arcs] else: arcs = topo_object["linestrings"] if separate and not include_junctions: for ix, line in enumerate(arcs): svg = line._repr_svg_() print(ix, line.wkt) display(SVG(svg)) elif separate and include_junctions: pts = topo_object["junctions"] for ix, line in enumerate(arcs): svg = geometry.GeometryCollection( [line, geometry.MultiPoint(pts)] )._repr_svg_() print(ix, line.wkt) display(SVG(svg)) elif not separate and include_junctions: pts = topo_object["junctions"] display( geometry.GeometryCollection( [geometry.MultiLineString(arcs), geometry.MultiPoint(pts)] ) ) else: display(geometry.MultiLineString(arcs))
def test_line_ABD_deviates_line_ABC(self): data = { "abc": { "type": "LineString", "coordinates": [[0, 0], [1, 0], [2, 0]] }, "abd": { "type": "LineString", "coordinates": [[0, 0], [1, 0], [3, 0]] }, } topo = topojson.join(topojson.extract(data)) self.assertTrue( geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(0.0, 0.0), (2.0, 0.0)])))
def test_join_shared_paths_dict(): data = { "cba": { "type": "LineString", "coordinates": [[2, 0], [1, 0], [0, 0]] }, "ab": { "type": "LineString", "coordinates": [[0, 0], [1, 0]] }, } topo = Join(data, options={"shared_coords": True}).to_dict() assert geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(0.0, 0.0), (1.0, 0.0)]))
def test_join_line_BC_start_middle_reversed_line_CBA(): data = { "cba": { "type": "LineString", "coordinates": [[2, 0], [1, 0], [0, 0]] }, "bc": { "type": "LineString", "coordinates": [[1, 0], [2, 0]] }, } topo = Join(data).to_dict() assert geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(2.0, 0.0), (1.0, 0.0)]))
def test_line_BC_start_middle_reversed_line_CBA(self): data = { "cba": { "type": "LineString", "coordinates": [[2, 0], [1, 0], [0, 0]] }, "bc": { "type": "LineString", "coordinates": [[1, 0], [2, 0]] }, } topo = topojson.join(topojson.extract(data)) self.assertTrue( geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(2.0, 0.0), (1.0, 0.0)])))
def test_join_true_for_junction_points(): data = { "cba": { "type": "LineString", "coordinates": [[2, 0], [1, 0], [0, 0]] }, "ab": { "type": "LineString", "coordinates": [[0, 0], [1, 0]] }, } topo = Join(data).to_dict() assert geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(1.0, 0.0), (0.0, 0.0), (2.0, 0.0)]))
def test_join_line_DBC_merge_line_ABC(): data = { "abc": { "type": "LineString", "coordinates": [[0, 0], [1, 0], [2, 0]] }, "dbc": { "type": "LineString", "coordinates": [[3, 0], [1, 0], [2, 0]] }, } topo = Join(data).to_dict() assert geometry.MultiPoint(topo["junctions"]).equals( geometry.MultiPoint([(1.0, 0.0), (2.0, 0.0), (3.0, 0.0), (0.0, 0.0)]))
def test_geometry(self): import shapely.geometry as shpg g = Grid(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=wgs84, pixel_ref='corner') p = shpg.Polygon([(1.5, 1.), (2., 1.5), (1.5, 2.), (1., 1.5)]) o = gis.transform_geometry(p, to_crs=g) assert_allclose(p.exterior.coords, o.exterior.coords) q = gis.transform_geometry(o, crs=g) assert_allclose(p.exterior.coords, q.exterior.coords) o = gis.transform_geometry(p, to_crs=g.center_grid) totest = np.array(o.exterior.coords) + 0.5 assert_allclose(p.exterior.coords, totest) x, y = g.corner_grid.xy_coordinates p = shpg.MultiPoint( [shpg.Point(i, j) for i, j in zip(x.flatten(), y.flatten())]) o = gis.transform_geometry(p, to_crs=g.proj) assert_allclose([_p.coords for _p in o], [_p.coords for _p in p])
def compute_convex_hull(feed): """ Return a Shapely Polygon representing the convex hull formed by the stops of the given Feed. """ m = sg.MultiPoint(feed.stops[['stop_lon', 'stop_lat']].values) return m.convex_hull
def test_index_multigeom(self): c = [(float(x), float(-x)) for x in range(4)] g = geometry.MultiPoint(c) for i in range(-4, 4): self.assertTrue(g[i].equals(geometry.Point(c[i]))) self.assertRaises(IndexError, lambda: g[4]) self.assertRaises(IndexError, lambda: g[-5])
def test_multipolygon(self): g = geometry.MultiPoint([(0, 1), (0, 4)]).buffer(1.0) h = transform(lambda x, y, z=None: (x + 1.0, y + 1.0), g) self.assertEqual(h.geom_type, 'MultiPolygon') self.assertAlmostEqual(g.area, h.area) self.assertAlmostEqual(h.centroid.x, 1.0) self.assertAlmostEqual(h.centroid.y, 3.5)
def alpha_shape(points, alpha): """ Compute the alpha shape (concave hull) of a set of points. @param points: Iterable container of points. @param alpha: alpha value to influence the gooeyness of the border. Smaller numbers don't fall inward as much as larger numbers. Too large, and you lose everything! """ if len(points) < 4: # When you have a triangle, there is no sense # in computing an alpha shape. return geometry.MultiPoint(list(points)).convex_hull coords = np.array([point.coords[0] for point in points]) tri = Delaunay(coords) triangles = coords[tri.vertices] a = ((triangles[:,0,0] - triangles[:,1,0]) ** 2 + (triangles[:,0,1] - triangles[:,1,1]) ** 2) ** 0.5 b = ((triangles[:,1,0] - triangles[:,2,0]) ** 2 + (triangles[:,1,1] - triangles[:,2,1]) ** 2) ** 0.5 c = ((triangles[:,2,0] - triangles[:,0,0]) ** 2 + (triangles[:,2,1] - triangles[:,0,1]) ** 2) ** 0.5 s = ( a + b + c ) / 2.0 areas = (s*(s-a)*(s-b)*(s-c)) ** 0.5 circums = a * b * c / (4.0 * areas) filtered = triangles[circums < (1.0 / alpha)] edge1 = filtered[:,(0,1)] edge2 = filtered[:,(1,2)] edge3 = filtered[:,(2,0)] edge_points = np.unique(np.concatenate((edge1,edge2,edge3)), axis = 0).tolist() m = geometry.MultiLineString(edge_points) triangles = list(polygonize(m)) return cascaded_union(triangles), edge_points
def project_mps(self, positions, datadir, filename="some.csv"): """For the projection of spot coordinates onto the vector.""" xy_positions = list( zip(positions['Position X'], positions['Position Y'])) # The shapely packages reguires transformation into Multipoints for the # projection. points = gm.MultiPoint(xy_positions) # Find point of projection on the vector. positions["VectPoint"] = [ self.vector.interpolate(self.vector.project(gm.Point(x))) for x in points ] # Find normalized distance (0->1) positions["NormDist"] = [ self.vector.project(x, normalized=True) for x in positions["VectPoint"] ] # Find the bins that the points fall into # Determine bins of each feature edges = np.linspace(0, 1, Sett.projBins + 1) labels = np.arange(0, Sett.projBins) positions["DistBin"] = pd.cut(positions["NormDist"], edges, labels=labels) mp_bin = pd.Series(positions.loc[:, "DistBin"], name=self.name) self.data = positions self.test_projection(Sett.MPname) # Save the obtained data: system.save_to_file(mp_bin.astype(int), datadir, filename) return mp_bin
def evaluate_interface(self, positive, negative): config = Configuration.config plane_samples = self.grid_sample_polygon() if len(plane_samples) == 0: return False mesh_samples = trimesh.transform_points( np.column_stack((plane_samples, np.zeros(plane_samples.shape[0]))), self.xform) pos_dists = positive.nearest.signed_distance( mesh_samples + (1 + self.connector_diameter) * self.normal) neg_dists = negative.nearest.signed_distance( mesh_samples + (1 + self.connector_diameter) * -1 * self.normal) # overestimate sqrt(2) to make the radius larger than half the diagonal of a square connector pos_valid_mask = pos_dists > 1.5 * self.connector_diameter / 2 neg_valid_mask = neg_dists > 1.5 * self.connector_diameter / 2 ch_area_mask = np.logical_or(pos_valid_mask, neg_valid_mask) if ch_area_mask.sum() == 0: return False convex_hull_area = sg.MultiPoint(plane_samples[ch_area_mask]).buffer( self.connector_diameter / 2).convex_hull.area self.objective = max( self.area / convex_hull_area - config.connector_objective_th, 0) self.positive_sites = mesh_samples[pos_valid_mask] self.negative_sites = mesh_samples[neg_valid_mask] self.all_sites = np.concatenate( (self.positive_sites, self.negative_sites), axis=0) return True
def get_cluster_centroids( self, clustered_guids, none_clustered_guids=None): """Get centroids for clustered data""" resultshapes_and_meta = list() for post_cluster in clustered_guids: posts = [self.cleaned_post_dict[x] for x in post_cluster] unique_user_count = len(set([post.user_guid for post in posts])) # get points and project coordinates to suitable UTM points = [geometry.Point( self._proj_coords(post.lng, post.lat) ) for post in posts] point_collection = geometry.MultiPoint(list(points)) # convex hull enough for calculating centroid result_polygon = point_collection.convex_hull result_centroid = result_polygon.centroid if result_centroid is not None and not result_centroid.is_empty: resultshapes_and_meta.append( (result_centroid, unique_user_count) ) if not none_clustered_guids: return resultshapes_and_meta # noclusterphotos = [cleanedPhotoDict[x] for x in singlePhotoGuidList] for no_cluster_post in none_clustered_guids: post = self.cleaned_post_dict[no_cluster_post] x_point, y_point = self._proj_coords( post.lng, post.lat) p_center = geometry.Point(x_point, y_point) if p_center is not None and not p_center.is_empty: resultshapes_and_meta.append((p_center, 1)) sys.stdout.flush() # log.debug(f'{resultshapes_and_meta[:10]}') return resultshapes_and_meta
def make_grid(block, step=0.1): bbox = block.surface.bounds xs = np.arange(bbox[0], bbox[2] + step, step) ys = np.arange(bbox[1], bbox[3] + step, step) grid = np.array(np.meshgrid(xs, ys)).T.reshape(-1, 2) grid = np.round(grid, 2) return geometry.MultiPoint(grid)
def number_intersecting_pts(self, pt): """The number of the sample points which intersect, once centred at `pt`.""" pts = _sgeometry.MultiPoint(self.edge_sample_points(pt)) pts = pts.intersection(self.transformed_geometry) # Seems the fastest method return _np.asarray(pts).shape[0]
def compute_convex_hull(feed: "Feed") -> Polygon: """ Return a Shapely Polygon representing the convex hull formed by the stops of the given Feed. """ m = sg.MultiPoint(feed.stops[["stop_lon", "stop_lat"]].values) return m.convex_hull
def determine_side_order(self, sides): """ determine which of the sides is the ventral side based on geometric properties and return indices such that the ventral side comes first """ # define a line connecting both end points k1, k2 = self.endpoint_indices line = geometry.LineString([self.contour[k1], self.contour[k2]]) # cut the shape using this line and return the largest part parts = self.polygon.difference(line.buffer(0.1)) if isinstance(parts, geometry.MultiPolygon): areas = [part.area for part in parts] polygon = parts[np.argmax(areas)].buffer(0.1) else: polygon = parts # measure the fraction of points that lie in the polygon fs = [] for c in sides: mp = geometry.MultiPoint(c) intersection = mp.intersection(polygon) if isinstance(intersection, geometry.Point): frac = 1 / len(mp) else: frac = len(intersection) / len(mp) fs.append(frac) # return the order in which the sides should be put if np.argmax(fs) == 0: return (0, 1) else: return (1, 0)
def nodes_in_ring(list1, list2): ''' Return the coordinates of the nodes in the ring formed by two circles center in the center of mas of the first list and of radius the max distance to all other nodes of list1 for circle 1 and of list 2 for circle 2 Parameters : - list1 : list of coordinates [(x1,y1), (x2,y2), ...] - list2 : same ''' CM = center_mass(list1) r1 = dist_max(CM, list1)+0.5 r2 = dist_max(CM, list2)+0.5 mp2 = sg.MultiPoint(list2) circle1 = sg.Point(CM).buffer(r1) circle2 = sg.Point(CM).buffer(r2) ring = circle2.difference(circle1) nodes = ring.intersection(mp2) ret = [] for i in range(len(nodes)): ret.append([nodes.geoms[i].x , nodes.geoms[i].y]) return ret
def project_channel(self, channel): """For projecting coordinates onto the vector.""" data = channel.data xy_positions = list(zip(data['Position X'], data['Position Y'])) # Transformation into Multipoints required for projection: points = gm.MultiPoint(xy_positions) # Find projection distance on the vector. proj_vector_dist = [self.vector.project(x) for x in points] # Find the exact point of projection proj_points = [self.vector.interpolate(p) for p in proj_vector_dist] # Find distance between feature and the point of projection proj_dist = [p.distance(proj_points[i]) for i, p in enumerate(points)] # Find normalized distance (0->1) data["NormDist"] = [d / self.vector_length for d in proj_vector_dist] # Determine bins of each feature edges = np.linspace(0, 1, Sett.projBins + 1) labels = np.arange(0, Sett.projBins) data["DistBin"] = pd.cut(data["NormDist"], labels=labels, bins=edges, include_lowest=True).astype('int') # Assign data to DF and save the dataframe: data["VectPoint"] = [(round(p.x, 3), round(p.y, 3)) for p in proj_points] data["ProjDist"] = proj_dist self.data = data self.test_projection(channel.name) channel_string = f'{channel.name}.csv' system.save_to_file(data, self.sampledir, channel_string, append=False) return data
def alpha_shape(points, alpha): # No alpha shape for a triangle. if len(points) < 4: return geometry.MultiPoint(list(points)).convex_hull coords = np.array([point.coords[0] for point in points]) tri = Delaunay(coords) triangles = coords[tri.vertices] a = ((triangles[:, 0, 0] - triangles[:, 1, 0])**2 + (triangles[:, 0, 1] - triangles[:, 1, 1])**2)**0.5 b = ((triangles[:, 1, 0] - triangles[:, 2, 0])**2 + (triangles[:, 1, 1] - triangles[:, 2, 1])**2)**0.5 c = ((triangles[:, 2, 0] - triangles[:, 0, 0])**2 + (triangles[:, 2, 1] - triangles[:, 0, 1])**2)**0.5 s = (a + b + c) / 2.0 areas = (s * (s - a) * (s - b) * (s - c))**0.5 circums = a * b * c / (4.0 * areas) filtered = triangles[circums < (1.0 / alpha)] edge1 = filtered[:, (0, 1)] edge2 = filtered[:, (1, 2)] edge3 = filtered[:, (2, 0)] edge_points = np.unique(np.concatenate((edge1, edge2, edge3)), axis=0).tolist() m = geometry.MultiLineString(edge_points) triangles = list(polygonize(m)) return cascaded_union(triangles), edge_points