def build_voronois(xValues, yValues, shapename=None): """ Create an new Layer with Voronoi Polygons from clusters :return: """ print 'building Voronoi Polygons from Cluster Centroids' layer = mem_source.CreateLayer('VoronoiLayer', WGS84, ogr.wkbPoint) layer.CreateField(ogr.FieldDefn('lon', ogr.OFTReal)) layer.CreateField(ogr.FieldDefn('lat', ogr.OFTReal)) layer.CreateField(ogr.FieldDefn('cluster', ogr.OFTInteger64)) voronois = pytess.voronoi(zip(xValues, yValues)) print 'wirte features in Voronoi Layer' for label, (centre, coordinates) in enumerate(voronois): wkt = 'Polygon ((' coordinates.append(coordinates[0]) for x, y in coordinates: wkt = '%s %f %f,' % (wkt, x, y) wkt = '%s))' % wkt[:-1] feature = ogr.Feature(layer.GetLayerDefn()) feature.SetGeometry(ogr.CreateGeometryFromWkt(wkt)) feature.SetField('lon', centre[0] if centre is not None else 0) feature.SetField('lat', centre[1] if centre is not None else 0) feature.SetField('cluster', label) layer.CreateFeature(feature) if shapename is not None: ut.CreateShapefile(shapename, ogr.wkbPolygon, layer) print 'Voronois Done' return layer
def from_voronoi(n=3, verbose=False): _, areas = generic(n=n) points = np.random.rand(n, 2) vor = Voronoi(points) # hack to move voronois about a bit import pytess vor2 = pytess.voronoi(points.tolist()) vor2 = {tuple(x): np.asarray(y) for x, y in vor2 if x is not None} rpm = np.zeros((n, n, 2), dtype=int) # construct cij matrix from vor-adjacencvy if verbose: print(vor.ridge_points) # keep track of bounds bnd_lr_ud = np.zeros((n, 2), dtype=int) for r, (i, j) in enumerate(vor.ridge_points): # ridge index, adj i, j = sorted([i, j]) reg_i_pt = vor2[tuple(points[i].tolist())].mean(0) reg_j_pt = vor2[tuple(points[j].tolist())].mean(0) dx, dy = np.abs(points[i] - points[j]) # print(points[i], points[j], ' -> ', reg_i_pt, reg_j_pt, ) if dx >= dy: # Left/right if points[i, 0] >= points[j, 0]: # i to right of j rpm[i, j, 0] = 2 else: # i rpm[i, j, 0] = 1 bnd_lr_ud[[i, j], 0] = 1 else: # Up/down if points[i, 1] >= points[j, 1]: rpm[i, j, 1] = 1 else: rpm[i, j, 1] = 2 bnd_lr_ud[[i, j], 1] = 1 for i, (bnd_lr, bnd_ud) in enumerate(bnd_lr_ud.tolist()): if bnd_lr == 0: pass if bnd_ud == 0: pass return None, areas, points, rpm, vor
def test_voronoi(points): # Run test polygons = pytess.voronoi(points) # Visualize import sys sys.path.append("/Volumes/karim/Desktop/Python Programming/site_packages") import pydraw crs = pydraw.CoordinateSystem([0, 0, 500, 500]) img = pydraw.Image(500, 500) for i, (center, poly) in enumerate(polygons): #print i, poly ## def pairwise(iterable): ## a, b = itertools.tee(iterable) ## next(b, None) ## return itertools.izip(a, b) ## ## for line in pairwise(poly): ## (x1,y1),(x2,y2) = line ## img.drawline( x1,y1,x2,y2, fillcolor=(i/1.3,111,111), ## outlinecolor=None ) ## img.view() img.drawpolygon(poly, fillcolor=(i / 1.3, 111, 111), outlinecolor=(0, 0, 0)) ## ## img.view() if center: img.drawsquare(*center[:2], fillsize=2, fillcolor=(0, 222, 0)) ## for point in points: ## img.drawsquare(*point[:2], fillsize=2, fillcolor=(0,222,0)) img.save("test.png") img.view()
def test_voronoi(points): # Run test polygons = pytess.voronoi(points) print(len(polygons)) # Visualize import sys sys.path.append("/Volumes/karim/Desktop/Python Programming/site_packages") import pydraw crs = pydraw.CoordinateSystem([0,0,500,500]) img = pydraw.Image(500,500) for i,(center,poly) in enumerate(polygons): #print i, poly ## def pairwise(iterable): ## a, b = itertools.tee(iterable) ## next(b, None) ## return itertools.izip(a, b) ## ## for line in pairwise(poly): ## (x1,y1),(x2,y2) = line ## img.drawline( x1,y1,x2,y2, fillcolor=(i/1.3,111,111), ## outlinecolor=None ) ## img.view() img.drawpolygon( poly, fillcolor=(i/1.3,111,111), outlinecolor=(0,0,0) ) ## ## img.view() if center: img.drawsquare(*center[:2], fillsize=2, fillcolor=(0,222,0)) ## for point in points: ## img.drawsquare(*point[:2], fillsize=2, fillcolor=(0,222,0)) img.save("test.png") img.view()
def get_s0_approximation( block: Polygon, centroids: Sequence[Tuple[float, float]]) -> PlanarGraph: """ approximates the initial connectivity graph by partitioning the block into a voronoi decomposition and feeds those faces into a planar graph """ boundary_points = list(block.exterior.coords) boundary_set = set(boundary_points) # get internal parcels from the voronoi decomposition of space, given building centroids intersected_polygons = [] debug("generating Voronoi decomposition") decomposition = pytess.voronoi(centroids) debug("intersecting Voronoi decomposition (N=%s) with block geometry", len(decomposition)) for (anchor, vs) in decomposition: if anchor and anchor not in boundary_set and len(vs) > 2: anchor_pt = Point(anchor) try: polygon = Polygon(vs).buffer(0).intersection(block) intersected_polygons.append((anchor_pt, polygon)) except shapely.errors.TopologicalError as e: debug("invalid geometry at polygon %s\n%s", vs, e) # simplify geometry when multiple areas intersect original block debug("simplifying multi-polygon intersections") simplified_polygons = [ polygon if polygon.type == "Polygon" else next( (segment for segment in polygon if segment.contains(anchor)), None) for (anchor, polygon) in intersected_polygons ] debug("building planar graph approximation") return PlanarGraph.from_polygons( [polygon for polygon in simplified_polygons if polygon])
def corner_voronoi(buildings, boundary): building_points = buildings["geometry"].apply( lambda poly: list(zip(*poly.exterior.coords.xy))).sum() # building_points_x, building_points_y = list(zip(*building_points)) # voronoi = Voronoi(building_points + list(zip(*boundary.exterior.coords.xy)), qhull_options='Qbb Qc Qx Tv') # spatial.voronoi_plot_2d(voronoi, ax=plt.gca()) voronoi_points, voronoi_polygons = zip( *pytess.voronoi(building_points + list(zip(*boundary.exterior.coords.xy)))) gpd.GeoDataFrame(geometry=[Polygon(p) for p in voronoi_polygons]).plot(ax=plt.gca()) gpd.GeoDataFrame(geometry=[Point(p) for p in voronoi_points if p]).plot(ax=plt.gca(), facecolor="white", zorder=10) buildings.plot(ax=plt.gca(), zorder=5, facecolor="red") plt.gca().add_patch( PolygonPatch(boundary, fc='#999999', ec='#999999', alpha=0.1)) plt.show()
npd34Lats, npd34Lons = npd34[1], npd34[0] coords = [] for i in range(len(npd34Lats)): lat, lon = npd34Lats[i], npd34Lons[i] out = {'lat': lat, 'lon': lon} coords.append(out) dfcnt = pd.DataFrame(coords) # -- # use centroids to do voronoi tesselation subset = dfcnt[['lon', 'lat']] points = [tuple(x) for x in subset.values] vPolys = pytess.voronoi(points) # -- # limit polygons to finite polygons within ROI rectangle (must improve method) region = dfCorners[['lon', 'lat']] bounds = [tuple(x) for x in region.values] ps = [Point(i) for i in bounds] boundary = geometry.Polygon([[p.x, p.y] for p in ps]) finite_polygons = [] for i in range(len(vPolys)): verts = vPolys[i][1] cent = vPolys[i][0] pList = [Point(i) for i in verts] val = 'in'
else: sites[point] = c.division points = [loc for loc in list(sites.keys()) if len(sites[loc]) == 1] # Gross hack to put Gilroy in Division A Gilroy = (37.005782, -121.568275) sites[Gilroy] = 'A' points.append(Gilroy) # And another gross hack for Rancho San Antonio RanchoSanAntonio = (37.321972, -122.096326) sites[RanchoSanAntonio] = 'B' points.append(RanchoSanAntonio) voronoipolys = pytess.voronoi(points, buffer_percent=200) # Compute the union of polygons for each division and write it to the file polygons = {} for (point, poly) in voronoipolys: if point in sites: div = sites[point] if div not in polygons: polygons[div] = [] polygons[div].append(Polygon(poly)) def dopoly(outfile, outline, div, num=0): if num > 0: varname = '%s%d' % (div, num) else: varname = div
def voronoi(rows): def edge(x0, x1): if x0[0] < x1[0]: return (x0, x1) if x0[0] > x1[0]: return (x1, x0) if x0[1] < x1[1]: return (x0, x1) if x0[1] > x1[1]: return (x1, x0) return (x0, x1) def edges(pts, first): if len(pts) == 1: yield edge(pts[0], first) return yield edge(pts[0], pts[1]) if first is None: first = pts[0] for e in edges(pts[1:], first): yield e kindx = {} centroids = [] for pt, kind in rows: kindx[pt] = kind centroids.append(pt) minx = float_info.max miny = float_info.max maxx = float_info.min maxy = float_info.min for (x, y) in centroids: if x < minx: minx = x if x > maxx: maxx = x if y < miny: miny = y if y > maxy: maxy = y def oob(polygon): for (x, y) in polygon: if x < minx: return True if x > maxx: return True if y < miny: return True if y > maxy: return True return False polyx = dict(pytess.voronoi(centroids)) centroids = [] polygons = [] edgex = {} for centroid, poly in polyx.items(): if centroid is None: continue if oob(poly): continue for e in edges(poly, None): edgex.setdefault(e, []).append(centroid) centroids.append(centroid) polygons.append(poly) n = len(centroids) lattice = { "types": list(kindx[c] for c in centroids), "polygons": polygons, "adjacencies": [], "shape": (n, n) } centx = {} for i in range(len(centroids)): centx[centroids[i]] = i for adj in edgex.values(): if len(adj) == 2: i = centx[adj[0]] j = centx[adj[1]] lattice["adjacencies"].append((i, j)) lattice["adjacencies"].append((j, i)) return lattice