def test_issue_7b():
    centroids = np.array([[496712, 232672], [497987, 235942], [496425, 230252],
                          [497482, 234933], [499331, 238351], [496081, 231033],
                          [497090, 233846], [496755, 231645], [498604,
                                                               237018]])
    n_pts = len(centroids)
    polygon = Polygon([[495555, 230875], [496938, 235438], [499405, 239403],
                       [499676, 239474], [499733, 237877], [498863, 237792],
                       [499120, 237335], [498321, 235010], [497295, 233185],
                       [497237, 231359], [496696, 229620], [495982, 230047],
                       [496154, 230347], [496154, 230347], [495555, 230875]])

    region_polys, region_pts = voronoi_regions_from_coords(centroids, polygon)

    assert isinstance(region_polys, dict)
    assert isinstance(region_pts, dict)
    assert len(region_polys) == len(region_pts) == n_pts

    assert all([
        len(pts_in_region) == 1 for pts_in_region in region_pts.values()
    ])  # no duplicates

    fig, ax = subplot_for_map(show_spines=True)
    plot_voronoi_polys_with_points_in_area(ax, polygon, region_polys,
                                           centroids, region_pts)

    return fig
def createVoronoi(boundary, cities):
    """process the boundary (polygon border) and points to create the voronoi diagram.
    Params:
        boundary (geoDataFrame)   : the polygon representing the container of the diagram
        cities   (geoDataFrame)   : the points that represent the "seeds" for the diagram
    Returns:
        All the datastructures needed to plot the voronoi diagram. Most important for us however,
        is the "regionPolys" needed for us to determine which ufos are each of the polygons.

        cityCoords    -  the seeds converted to proper coordinate system for the diagram
        boundaryShape -  the boundary simplified or converted to a single outer ring polygon
        regionPolys   -  a dict of the internal polygons created around each seed
        regionPoints  -  a dict of the points used in the creation of the polygon
    """
    # pre-process data so it works with voronoi
    boundaryProj = boundary.to_crs(epsg=3395)
    citiesProj = cities.to_crs(boundaryProj.crs)
    boundaryShape = unary_union(boundaryProj.geometry)
    cityCoords = points_to_coords(citiesProj.geometry)

    # create the polygons and such
    regionPolys, regionPoints = voronoi_regions_from_coords(cityCoords, boundaryShape)

    # return all the things created so we can use / plot
    return cityCoords, boundaryShape, regionPolys, regionPoints
def test_voronoi_spain_area_with_plot():
    area_shape = _get_country_shape('Spain')
    coords = _rand_coords_in_shape(area_shape, 20)

    # generate Voronoi regions
    region_polys, region_pts = voronoi_regions_from_coords(coords, area_shape)

    # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy()

    assert isinstance(region_polys, dict)
    assert isinstance(region_pts, dict)
    assert len(region_polys) == len(region_pts)
    assert 0 < len(region_polys) <= 20

    # generate covered area
    region_areas = calculate_polygon_areas(
        region_polys, m2_to_km2=True)  # converts m² to km²
    assert isinstance(region_areas, dict)
    assert set(region_areas.keys()) == set(region_polys.keys())

    # generate plot
    fig, ax = subplot_for_map(show_x_axis=True, show_y_axis=True)
    voronoi_labels = {k: '%d km²' % round(a) for k, a in region_areas.items()}
    plot_voronoi_polys_with_points_in_area(ax,
                                           area_shape,
                                           region_polys,
                                           coords,
                                           region_pts,
                                           voronoi_labels=voronoi_labels,
                                           voronoi_label_fontsize=7,
                                           voronoi_label_color='gray')

    return fig
def test_voronoi_geopandas_with_plot():
    world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
    cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities'))

    # focus on South America, convert to World Mercator (unit: meters)
    south_am = world[world.continent == 'South America'].to_crs(epsg=3395)
    cities = cities.to_crs(
        south_am.crs)  # convert city coordinates to same CRS!

    # create the bounding shape as union of all South American countries' shapes
    south_am_shape = unary_union(south_am.geometry)
    south_am_cities = cities[cities.geometry.within(
        south_am_shape)]  # reduce to cities in South America

    # convert the pandas Series of Point objects to NumPy array of coordinates
    coords = points_to_coords(south_am_cities.geometry)

    # calculate the regions
    region_polys, region_pts = voronoi_regions_from_coords(coords,
                                                           south_am_shape,
                                                           per_geom=False)

    # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy()

    assert isinstance(region_polys, dict)
    assert isinstance(region_pts, dict)
    assert len(region_polys) == len(region_pts) == len(coords)

    # generate plot
    fig, ax = subplot_for_map(show_spines=True)
    plot_voronoi_polys_with_points_in_area(ax, south_am_shape, region_polys,
                                           coords, region_pts)

    return fig
def test_voronoi_italy_with_plot(n_pts, per_geom):
    area_shape = _get_country_shape('Italy')
    coords = _rand_coords_in_shape(area_shape, n_pts)

    # generate Voronoi regions
    region_polys, region_pts = voronoi_regions_from_coords(coords,
                                                           area_shape,
                                                           per_geom=per_geom)

    # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy()

    assert isinstance(region_polys, dict)
    assert isinstance(region_pts, dict)
    assert len(region_polys) == len(region_pts)
    assert 0 < len(region_polys) <= n_pts

    # generate plot
    fig, ax = subplot_for_map(show_spines=True)
    plot_voronoi_polys_with_points_in_area(ax,
                                           area_shape,
                                           region_polys,
                                           coords,
                                           region_pts,
                                           point_labels=list(
                                               map(str, range(len(coords)))))

    return fig
示例#6
0
def split_poly_into_equal_parts(poly, num_parts):
    '''
    '''
    points_df = generate_random(2500, poly)
    km = KMeans(n_clusters=num_parts)

    points_df.loc[:, 'lat'] = points_df.loc[:, 'geometry'].apply(lambda x: x.y)
    points_df.loc[:, 'lon'] = points_df.loc[:, 'geometry'].apply(lambda x: x.x)
    points_for_cluster = points_df.copy()
    points_for_cluster.drop(labels=['geometry', 'pt_id'], axis=1, inplace=True)

    kmcls = km.fit(points_for_cluster.values)

    points_w_cl = points_df.assign(cluster=kmcls.labels_)
    centers = kmcls.cluster_centers_

    centers_gseries = gpd.GeoSeries(
        map(Point, zip(centers[:, 1], centers[:, 0])))

    centroid_coords = np.array(
        [coords for coords in (zip(centers[:, 1], centers[:, 0]))])

    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        centroid_coords, poly)

    poly_shapes_df = gpd.GeoDataFrame(pd.DataFrame(poly_to_pt_assignments,
                                                   columns=['group']),
                                      crs="EPSG:4326",
                                      geometry=poly_shapes)

    return poly_shapes_df
示例#7
0
def test_issue_7b():
    centroids = np.array([[496712, 232672], [497987, 235942], [496425, 230252],
                          [497482, 234933], [499331, 238351], [496081, 231033],
                          [497090, 233846], [496755, 231645], [498604,
                                                               237018]])
    polygon = Polygon([[495555, 230875], [496938, 235438], [499405, 239403],
                       [499676, 239474], [499733, 237877], [498863, 237792],
                       [499120, 237335], [498321, 235010], [497295, 233185],
                       [497237, 231359], [496696, 229620], [495982, 230047],
                       [496154, 230347], [496154, 230347], [495555, 230875]])

    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        centroids, polygon)

    assert isinstance(poly_shapes, list)
    assert 0 < len(poly_shapes) <= len(centroids)
    assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes])

    assert np.array_equal(points_to_coords(pts), centroids)

    assert isinstance(poly_to_pt_assignments, list)
    assert len(poly_to_pt_assignments) == len(poly_shapes)
    assert all([isinstance(assign, list) for assign in poly_to_pt_assignments])
    assert all([len(assign) == 1 for assign in poly_to_pt_assignments
                ])  # in this case there is a 1:1 correspondance

    fig, ax = subplot_for_map()
    plot_voronoi_polys_with_points_in_area(ax, polygon, poly_shapes, centroids,
                                           poly_to_pt_assignments)

    return fig
    def create_voronoi(self, towers_for_voronoi, shape):

        # Create np array of vertices
        points = towers_for_voronoi.loc[:, ['LNG', 'LAT']].to_numpy()

        # Create voronoi shapes
        self.poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
            points, shape)

        return self.poly_shapes
示例#9
0
def test_voronoi_sweden_duplicate_points_with_plot():
    area_shape = _get_country_shape('Sweden')
    coords = _rand_coords_in_shape(area_shape, 20)

    # duplicate a few points
    rand_dupl_ind = np.random.randint(len(coords), size=10)
    coords = np.concatenate((coords, coords[rand_dupl_ind]))

    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        coords, area_shape, accept_n_coord_duplicates=10)

    assert isinstance(poly_shapes, list)
    assert 0 < len(poly_shapes) <= 20
    assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes])

    assert np.array_equal(points_to_coords(pts), coords)

    assert isinstance(poly_to_pt_assignments, list)
    assert len(poly_to_pt_assignments) == len(poly_shapes)
    assert all([isinstance(assign, list) for assign in poly_to_pt_assignments])
    assert all([0 < len(assign) <= 10 for assign in poly_to_pt_assignments
                ])  # in this case there is not
    # everywhere a 1:1 correspondance

    pts_to_poly_assignments = np.array(
        get_points_to_poly_assignments(poly_to_pt_assignments))

    # make point labels: counts of duplicates per points
    count_per_pt = [
        sum(pts_to_poly_assignments == i_poly)
        for i_poly in pts_to_poly_assignments
    ]
    pt_labels = list(map(str, count_per_pt))

    # highlight voronoi regions with point duplicates
    count_per_poly = np.array(list(map(len, poly_to_pt_assignments)))
    vor_colors = np.repeat('blue', len(poly_shapes))  # default color
    vor_colors[count_per_poly > 1] = 'red'  # hightlight color

    fig, ax = subplot_for_map()

    plot_voronoi_polys_with_points_in_area(
        ax,
        area_shape,
        poly_shapes,
        coords,
        plot_voronoi_opts={'alpha': 0.2},
        plot_points_opts={'alpha': 0.4},
        voronoi_color=list(vor_colors),
        point_labels=pt_labels,
        points_markersize=np.array(count_per_pt) * 10)

    return fig
def test_voronoi_sweden_duplicate_points_with_plot():
    area_shape = _get_country_shape('Sweden')
    coords = _rand_coords_in_shape(area_shape, 20)

    # duplicate a few points
    rand_dupl_ind = np.random.randint(len(coords), size=10)
    coords = np.concatenate((coords, coords[rand_dupl_ind]))
    n_pts = len(coords)

    # generate Voronoi regions
    region_polys, region_pts = voronoi_regions_from_coords(coords, area_shape)

    # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy()

    assert isinstance(region_polys, dict)
    assert isinstance(region_pts, dict)
    assert 0 < len(region_polys) <= n_pts
    assert 0 < len(region_pts) <= n_pts

    assert all([
        0 < len(pts_in_region) <= 10 for pts_in_region in region_pts.values()
    ])

    # make point labels: counts of duplicate assignments per points
    count_per_pt = {
        pt_indices[0]: len(pt_indices)
        for pt_indices in region_pts.values()
    }
    pt_labels = list(map(str, count_per_pt.values()))
    distinct_pt_coords = coords[np.asarray(list(count_per_pt.keys()))]

    # highlight voronoi regions with point duplicates
    vor_colors = {
        i_poly: (1, 0, 0) if len(pt_indices) > 1 else (0, 0, 1)
        for i_poly, pt_indices in region_pts.items()
    }

    # generate plot
    fig, ax = subplot_for_map(show_spines=True)
    plot_voronoi_polys_with_points_in_area(
        ax,
        area_shape,
        region_polys,
        distinct_pt_coords,
        plot_voronoi_opts={'alpha': 0.2},
        plot_points_opts={'alpha': 0.4},
        voronoi_color=vor_colors,
        voronoi_edgecolor=(0, 0, 0, 1),
        point_labels=pt_labels,
        points_markersize=np.square(np.array(list(count_per_pt.values()))) *
        10)

    return fig
示例#11
0
def split_one_poly_into_parts(square_id):
    '''
    '''
    logging.info(f"working on shape_id: {square_id}")
    try:
        select_square = squares[squares.loc[:, 'SQUARE'] == square_id].copy()
        if (select_square.geometry.type == 'MultiPolygon').any():
            select_square = select_square.explode()
        address_pts = addresses[addresses.loc[:, 'SQUARE'] == square_id].copy()
        square_part = 1
        for index, one_square in select_square.iterrows():
            one_square_shape = one_square['geometry']
            address_points_for_cluster = prep_addresses_for_cluster(
                address_pts, one_square_shape)
            if len(address_points_for_cluster) < 4:
                split_type = "equal_area"
                poly_shapes_df = split_poly_into_equal_parts(
                    one_square_shape, 4)
            else:
                split_type = "address_cluster"
                centroid_coords = find_address_clusters(
                    address_points_for_cluster)

                poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
                    centroid_coords, one_square_shape)

                poly_shapes_df = gpd.GeoDataFrame(pd.DataFrame(
                    poly_to_pt_assignments, columns=['group']),
                                                  crs="EPSG:4326",
                                                  geometry=poly_shapes)

                poly_shapes_df.loc[:, 'SQUARE'] = square_id
                poly_shapes_df.loc[:, 'SQUARE_PART'] = square_part

            if square_part == 1:
                full_poly_shape_df = poly_shapes_df.copy()
            else:
                full_poly_shape_df = full_poly_shape_df.append(poly_shapes_df)
            square_part += 1
    except:
        bad_shape_df = pd.DataFrame(
            [[0, Polygon([(0, 0), (1, 1), (0, 1)]), square_id, '', '', 0]],
            columns=[
                'group', 'geometry', 'SQUARE', 'SSL', 'STNAME', 'SQUARE_PART'
            ])

        full_poly_shape_df = gpd.GeoDataFrame(bad_shape_df,
                                              crs="EPSG:4326",
                                              geometry='geometry')

    return full_poly_shape_df
示例#12
0
def split_one_poly_into_parts_forplotting(square_id):
    '''
    '''
    one_square = squares[squares.loc[:, 'SQUARE'] == square_id].copy()
    address_pts = addresses[addresses.loc[:, 'SQUARE'] == square_id].copy()
    address_points_for_cluster = address_pts[['LATITUDE', 'LONGITUDE']].values
    if len(address_points_for_cluster) < 4:
        split_type = "equal_area"
        poly_shapes_df = split_poly_into_equal_parts(one_square.unary_union, 4)
    else:
        split_type = "address_cluster"
        km_silhouette = {}
        max_cluster = min(10, len(address_points_for_cluster))
        #     print(f"max_num_clusters = {max_cluster-1}")
        for i in range(2, max_cluster):
            km = KMeans(n_clusters=i,
                        random_state=0).fit(address_points_for_cluster)
            preds = km.predict(address_points_for_cluster)

            silhouette = silhouette_score(address_points_for_cluster, preds)
            km_silhouette[silhouette] = i
    #         print("Silhouette score for number of cluster(s) {}: {}".format(i,silhouette))
    #         print("-"*100)
        best_num_clusters = max(4, km_silhouette[max(km_silhouette.keys())])
        km = KMeans(n_clusters=best_num_clusters,
                    random_state=0).fit(address_points_for_cluster)
        centers = km.cluster_centers_
        centroid_coords = np.array(
            [coords for coords in (zip(centers[:, 1], centers[:, 0]))])
        centers_gseries = gpd.GeoSeries(
            map(Point, zip(centers[:, 1], centers[:, 0])))
        address_pts_w_cluster = address_pts.assign(cluster=km.labels_)
        centroid_filtered = centers_gseries[centers_gseries.apply(
            lambda x: one_square.unary_union.contains(x))].copy()
        centroid_coords_filtered = np.array([
            coords for coords in (zip(centroid_filtered.apply(lambda x: x.x),
                                      centroid_filtered.apply(lambda x: x.y)))
        ])

        poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
            centroid_coords_filtered, one_square.unary_union)

        poly_shapes_df = gpd.GeoDataFrame(pd.DataFrame(poly_to_pt_assignments,
                                                       columns=['group']),
                                          crs="EPSG:4326",
                                          geometry=poly_shapes)

    poly_shapes_export = poly_shapes_df.assign(square=square_id)

    return (poly_shapes_export, address_pts, one_square)
def test_issue_7a():
    centroids = np.array([[537300, 213400], [538700, 213700], [536100,
                                                               213400]])
    n_pts = len(centroids)
    polygon = Polygon([[540000, 214100], [535500, 213700], [535500, 213000],
                       [539000, 213200]])
    region_polys, region_pts = voronoi_regions_from_coords(centroids, polygon)

    assert isinstance(region_polys, dict)
    assert isinstance(region_pts, dict)
    assert len(region_polys) == len(region_pts) == n_pts

    assert all([
        len(pts_in_region) == 1 for pts_in_region in region_pts.values()
    ])  # no duplicates
示例#14
0
def image_gen_main():
    coords = hexagonal_lattice(session['ROWS'], session['COLS'],
                               session['NOISE'])[:, :2]
    x_min, x_max, y_min, y_max = coords[:, 0].min(), coords[:, 0].max(
    ), coords[:, 1].min(), coords[:, 1].max()
    bounding_box = Polygon([(x_min, y_min), (x_min, y_max), (x_max, y_max),
                            (x_max, y_min)])
    region_polys, _ = voronoi_regions_from_coords(coords, bounding_box)
    dirname = "/home/suvigya/PycharmProjects/MapGeneratorApp/images/"

    ocean = 0.07
    if int(session['OCEAN']) == 0:
        ocean = 0

    displayMap(list(region_polys.values()),
               filename=dirname + session['HEXAGON_FILE'],
               bounds=bounding_box.bounds)

    multi = []
    for poly in region_polys:
        multi.append(region_polys[poly])

    multi = MultiPolygon(multi)
    cmap = combine_polys(multi, session['DISTRIBUTION'])

    if ocean != 0:
        setBoundingOcean(multi,
                         bounding_box.boundary,
                         bounds=(x_max, x_min),
                         cmap=cmap,
                         buffer=ocean,
                         noise=float(session['NOISE']))
    else:
        setBoundingOcean(multi,
                         bounding_box.boundary,
                         bounds=(x_max, x_min),
                         cmap=cmap,
                         buffer=0,
                         noise=0.00)

    displayMap(multi,
               fillcolors=cmap,
               filename=dirname + session['COLORED_W_OCEAN_FILE'],
               bounds=bounding_box.bounds)

    with open(dirname + session['WKT_FILE'], "w") as fp:
        fp.write(multi.wkt)
    del multi, cmap, region_polys, coords,
示例#15
0
def main():

    df = pd.read_csv('data.csv', header=None)
    lon = df[1]
    lat = df[2]
    #points = np.delete(df.values, 0, 1)
    #print(points)
    box = (0, 0, 15, 15)

    area = [[0, 0], [15, 0], [15, 13], [13, 13], [13, 15], [0, 15]]

    ext = [(0, 0), (15, 0), (15, 13), (13, 13), (13, 15), (0, 15)]
    int = [(11, 12), (12, 12), (12, 11), (11, 11)]
    grint = [(1, 14), (1, 12), (3, 12), (3, 14)]

    area_shape = Polygon(ext, [grint, int])

    coords = np.random.randint(1, 12, size=(3, 2))
    print(coords)

    points = []
    for point in coords:
        if area_shape.contains(Point(point)) is True:
            points.append(point)

    points = coords
    #points = [point for point in coords if area_shape.contains(Point(point)) is True]
    print("points:")

    print(area_shape)

    vor = spatial.Voronoi(points)

    #regions, vertices = voronoi_finite_polygons_2d(vor)

    poly_shapes, pts, poly_to_pt_assignment = voronoi_regions_from_coords(
        points, area_shape)

    print(type(poly_shapes))
    print(dir(pts))
    print(poly_to_pt_assignment)
    fig, ax = subplot_for_map()
    plt.figure(dpi=96, figsize=(20 / 96, 20 / 96))
    plot_voronoi_polys_with_points_in_area(ax, area_shape, poly_shapes, points,
                                           poly_to_pt_assignment)

    polygons = []
示例#16
0
def test_issue_7a():
    centroids = np.array([[537300, 213400], [538700, 213700], [536100,
                                                               213400]])
    polygon = Polygon([[540000, 214100], [535500, 213700], [535500, 213000],
                       [539000, 213200]])
    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        centroids, polygon)

    assert isinstance(poly_shapes, list)
    assert 0 < len(poly_shapes) <= len(centroids)
    assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes])

    assert np.array_equal(points_to_coords(pts), centroids)

    assert isinstance(poly_to_pt_assignments, list)
    assert len(poly_to_pt_assignments) == len(poly_shapes)
    assert all([isinstance(assign, list) for assign in poly_to_pt_assignments])
    assert all([len(assign) == 1 for assign in poly_to_pt_assignments
                ])  # in this case there is a 1:1 correspondance
示例#17
0
    def calculate_apl(self, leaflet="upper"):
        """
        Calculate the area per lipid for the chosen leaflet.
        :param leaflet: str. The label of the leaflet to calculate APL for. Defaults to "upper".
        :return:
        """
        # Construct the 2D projection for this leaflet
        self.get_projection(leaflet=leaflet)

        # Perform Voronoi tesselation for this projection, bounded by the simulation box.
        self.voronoi[leaflet] = [voronoi_regions_from_coords(points, bound) for points, bound in
                                 zip(self.projection[leaflet], self.data_bounds)]

        # Calculate the area of each lipid in this leaflet
        self.apl[leaflet] = [calculate_polygon_areas(i[0]) for i in self.voronoi[leaflet]]

        # Find the average area per lipid for this leaflet in each frame
        self.apl_mean[leaflet] = [np.mean(x) for x in self.apl[leaflet]]

        # Log the result
        self.add_results(lipid="All", value=self.apl_mean[leaflet], leaflet=leaflet)
示例#18
0
    def create_voronoi_polygons(self):
        """
        creates Voronoi polygons with `self.antennas_data` as centers, bounded by `self.contour`

        :return: GeoPandas DF with VCs
        """

        if self.antennas_data.crs == self.contour.crs:

            coords = points_to_coords(self.antennas_data.geometry)
            poly_shapes, pts = voronoi_regions_from_coords(
                coords, self.contour.geometry[0])

            voronoi_polygons = gpd.GeoDataFrame({'geometry': poly_shapes},
                                                crs=SWEREF_EPSG)

            return voronoi_polygons

        else:
            logger.error('Objects have different CRSs: %s and %s ' %
                         (self.antennas_data.crs, self.contour.crs))
示例#19
0
def test_voronoi_geopandas_with_plot():
    world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
    cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities'))

    # focus on South America, convert to World Mercator (unit: meters)
    south_am = world[world.continent == 'South America'].to_crs(epsg=3395)
    cities = cities.to_crs(
        south_am.crs)  # convert city coordinates to same CRS!

    # create the bounding shape as union of all South American countries' shapes
    south_am_shape = cascaded_union(south_am.geometry)
    south_am_cities = cities[cities.geometry.within(
        south_am_shape)]  # reduce to cities in South America

    # convert the pandas Series of Point objects to NumPy array of coordinates
    coords = points_to_coords(south_am_cities.geometry)

    # calculate the regions
    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        coords, south_am_shape)

    assert isinstance(poly_shapes, list)
    assert 0 < len(poly_shapes) <= len(coords)
    assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes])

    assert np.array_equal(points_to_coords(pts), coords)

    assert isinstance(poly_to_pt_assignments, list)
    assert len(poly_to_pt_assignments) == len(poly_shapes)
    assert all([isinstance(assign, list) for assign in poly_to_pt_assignments])
    assert all([len(assign) == 1 for assign in poly_to_pt_assignments
                ])  # in this case there is a 1:1 correspondance

    fig, ax = subplot_for_map()

    plot_voronoi_polys_with_points_in_area(ax, south_am_shape, poly_shapes,
                                           pts, poly_to_pt_assignments)

    return fig
示例#20
0
def test_voronoi_spain_area_with_plot():
    area_shape = _get_country_shape('Spain')
    coords = _rand_coords_in_shape(area_shape, 20)
    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        coords, area_shape)

    assert isinstance(poly_shapes, list)
    assert 0 < len(poly_shapes) <= 20
    assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes])

    assert np.array_equal(points_to_coords(pts), coords)

    assert isinstance(poly_to_pt_assignments, list)
    assert len(poly_to_pt_assignments) == len(poly_shapes)
    assert all([isinstance(assign, list) for assign in poly_to_pt_assignments])
    assert all([len(assign) == 1 for assign in poly_to_pt_assignments
                ])  # in this case there is a 1:1 correspondance

    poly_areas = calculate_polygon_areas(poly_shapes,
                                         m2_to_km2=True)  # converts m² to km²
    assert isinstance(poly_areas, np.ndarray)
    assert np.issubdtype(poly_areas.dtype, np.float_)
    assert len(poly_areas) == len(poly_shapes)
    assert np.all(poly_areas > 0)

    fig, ax = subplot_for_map(show_x_axis=True, show_y_axis=True)

    voronoi_labels = ['%d km²' % round(a) for a in poly_areas]
    plot_voronoi_polys_with_points_in_area(ax,
                                           area_shape,
                                           poly_shapes,
                                           coords,
                                           poly_to_pt_assignments,
                                           voronoi_labels=voronoi_labels,
                                           voronoi_label_fontsize=7,
                                           voronoi_label_color='gray')

    return fig
示例#21
0
def test_voronoi_italy_with_plot():
    area_shape = _get_country_shape('Italy')
    coords = _rand_coords_in_shape(area_shape, 100)
    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        coords, area_shape)

    assert isinstance(poly_shapes, list)
    assert 0 < len(poly_shapes) <= 100
    assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes])

    assert np.array_equal(points_to_coords(pts), coords)

    assert isinstance(poly_to_pt_assignments, list)
    assert len(poly_to_pt_assignments) == len(poly_shapes)
    assert all([isinstance(assign, list) for assign in poly_to_pt_assignments])
    assert all([len(assign) == 1 for assign in poly_to_pt_assignments
                ])  # in this case there is a 1:1 correspondance

    fig, ax = subplot_for_map()
    plot_voronoi_polys_with_points_in_area(ax, area_shape, poly_shapes, coords,
                                           poly_to_pt_assignments)

    return fig
示例#22
0
# Display map
display_map(gdf, chicago, proj)

# TO DO: maps well, but how to grab features of voronois?

###############################################################################
# FIND VORONOIS (plots a map and gets bounds?)
###############################################################################
# from: https://github.com/WZBSocialScienceCenter/geovoronoi
from geovoronoi import voronoi_regions_from_coords

points = np.array(list(cps_df.coordinates))
chicago_bounds = chicago.iloc[0].geometry

# TO DO: gets error abour hull distance or something
poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
    points, chicago_bounds)

###############################################################################
vor = Voronoi(points)
voronoi_plot_2d(vor)

new_point = [50, 50]
plt.plot(new_point[0], new_point[1], 'ro')

point_index = np.argmin(np.sum((points - new_point)**2, axis=1))
ridges = np.where(vor.ridge_points == point_index)[0]
vertex_set = set(np.array(vor.ridge_vertices)[ridges, :].ravel())
region = [x for x in vor.regions if set(x) == vertex_set][0]

polygon = vor.vertices[region]
plt.fill(*zip(*polygon), color='yellow')
示例#23
0
schools = []
schoolx = []
schooly = []
for i in range(50):
    x = random.randint(0, 99)
    y = random.randint(0, 99)
    if [x, y] not in streetsarr and [x, y] not in schools:
        schools.append([x, y])
        schoolx.append(x)
        schooly.append(y)
plt.plot(schoolx, schooly, 'bs')

# разбивам плоскость на диаграму вороного
coords = schools
boundary_shape = shapely.geometry.box(0, 0, 100, 100, ccw=True)
poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
    coords, boundary_shape)

#xt=int(input("Введите координату xlearn: "))
#yt=int(input("Введите координату ylearn: "))
xt = yt = 50

for i in range(len(poly_shapes)):
    if shapely.geometry.Point(xt, yt).within(poly_shapes[i]):
        x, y = poly_shapes[i].exterior.xy
        plt.plot(x, y, color="pink")
        plt.plot(xt, yt, "go")
        plt.plot(schools[poly_to_pt_assignments[i][0]][0],
                 schools[poly_to_pt_assignments[i][0]][1], "ro")
plt.show()
n_pts = len(pts)

print(
    'will use %d of %d randomly generated points that are inside geographic area'
    % (n_pts, N_POINTS))
coords = points_to_coords(pts)  # convert back to simple NumPy coordinate array

del pts

#%%

#
# calculate the Voronoi regions, cut them with the geographic area shape and assign the points to them
#

region_polys, region_pts = voronoi_regions_from_coords(coords, area_shape)

# calculate area in km², too
poly_areas = calculate_polygon_areas(region_polys,
                                     m2_to_km2=True)  # converts m² to km²

print('areas in km²:')
pprint(poly_areas)

print('sum:')
print(sum(poly_areas.values()))

#%% plotting

fig, ax = subplot_for_map(show_x_axis=True, show_y_axis=True)
示例#25
0
def main(fn: str = "large_metro_voronoi.geojson",
         extra_metro_cbsa_ids: List[str] = []):

    logger.info("Loading files")
    us_outline = load_us_outline()
    ipm_gdf = load_ipm_shapefile()
    ipm_gdf["convex_hull"] = ipm_gdf.convex_hull
    # site_locations = load_site_locations()
    metro_gdf = load_metro_areas_shapefile()

    logger.info("Finding largest metros")
    if extra_metro_cbsa_ids:
        logger.info(
            f"The extra metros {extra_metro_cbsa_ids} will be included")
    largest_metros = find_largest_cities(
        metro_areas_gdf=metro_gdf,
        ipm_gdf=ipm_gdf,
        min_population=750000,
        extra_metro_cbsa_ids=extra_metro_cbsa_ids,
    )

    logger.info("Making voronoi polygons")
    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        largest_metros[["longitude", "latitude"]].values, us_outline)

    metro_voronoi = largest_metros.iloc[[x[0]
                                         for x in poly_to_pt_assignments], :]
    metro_voronoi["metro_id"] = metro_voronoi["cbsa_id"]
    metro_voronoi.geometry = poly_shapes

    logger.info("Fixing NYC/Long Island")
    ny_z_j_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J",
                              "convex_hull"].values[0]
    ny_z_k_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K",
                              "convex_hull"].values[0]
    ny_z_j_k_poly = cascaded_union([ny_z_j_poly, ny_z_k_poly])

    for cbsa_id in metro_voronoi.query(
            "IPM_Region.isin(['NENG_CT', 'PJM_EMAC']).values"
    )["cbsa_id"].to_list():
        # print(cbsa_id)
        metro_voronoi.loc[metro_voronoi["cbsa_id"] == cbsa_id,
                          "geometry"] = metro_voronoi.loc[
                              metro_voronoi["cbsa_id"] == cbsa_id,
                              "geometry"].difference(ny_z_j_k_poly)

    # Need the unary_union to make geometries valid
    ny_z_j_ipm = shapely.ops.unary_union(
        ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J", "geometry"].values[0])
    ny_z_k_ipm = shapely.ops.unary_union(
        ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K", "geometry"].values[0])

    # Get a simplified outline of Long Island
    # Start with the zone K convex hull, remove the overlap with zone J IPM region,
    # then take the intersection with the US outline.
    ny_z_k_ipm = ny_z_k_poly.difference(ny_z_j_ipm).intersection(us_outline)

    # Same with NYC, zone J. Remove the bordering regions (zone K, other IPM regions)
    # from the convex hull, then take intersection with US outline.
    ny_z_j_ipm = (ny_z_j_poly.difference(ny_z_k_ipm).difference(
        shapely.ops.unary_union(
            ipm_gdf.query("IPM_Region=='PJM_EMAC'")
            ["geometry"].values[0])).difference(
                shapely.ops.unary_union(
                    ipm_gdf.query("IPM_Region=='NY_Z_G-I'")
                    ["geometry"].values[0])).intersection(us_outline))

    data_dict = {
        "IPM_Region": ["NY_Z_J", "NY_Z_K"],
        "state": ["NY", "NY"],
        "metro_id": ["NY_Z_J", "NY_Z_K"],
        "latitude": [ny_z_j_ipm.centroid.y, ny_z_k_ipm.centroid.y],
        "longitude": [ny_z_j_ipm.centroid.x, ny_z_k_ipm.centroid.x],
    }

    ny_z_j_k_df = gpd.GeoDataFrame(data=data_dict,
                                   geometry=[ny_z_j_ipm, ny_z_k_ipm],
                                   crs=metro_voronoi.crs)

    final_metro_voronoi = pd.concat([metro_voronoi, ny_z_j_k_df],
                                    ignore_index=True,
                                    sort=False)

    logger.info("Writing polygons to file")
    cols = ["IPM_Region", "geometry", "latitude", "longitude", "metro_id"]
    final_metro_voronoi[cols].to_file(fn, driver="GeoJSON")
示例#26
0
 def computeCrossProduct(self, reference_old_entries, second_old_entries):
     # 1. Reference distribution is regions, second dist is regions
     #    - uniform distribute overlap of regions
     # 2. Reference distribution is regions, second dist is points
     #    - map points to regions and perform as usual
     # 3. Reference distribution is points, second dist is regions
     #    - create regions from reference dist. points with Voronoi diagram
     # 4. Reference distribution is points, second dist is points
     #    - " "
     if 'POLYGON' in reference_old_entries[0]:
         if 'POLYGON' in second_old_entries[0]:
             # For 1. compute cross product for new regions
             new_entries = SpatialHelper.computeNewRegions(
                 reference_old_entries, second_old_entries)
             #print('inside spatial handler')
             #print(len(reference_old_entries))
             #print(len(second_old_entries))
             #print(len(new_entries))
             #print('leaving spatial handler')
         elif 'POINT' in second_old_entries[0] or \
              type(second_old_entries[0]) is tuple:
             # For 2., don't need to compute cross product
             # Just use Regions of reference distribution
             new_entries = reference_old_entries
     elif 'POINT' in reference_old_entries[0] or \
          type(reference_old_entries[0]) is tuple:
         # For 3. compute Voronoi
         ref_points_obj = SpatialHelper.getGeoObjectsFromString(
             list(set(reference_old_entries)))
         sec_regions_obj = SpatialHelper.getGeoObjectsFromString(
             second_old_entries)
         sec_regions_obj_union = unary_union(sec_regions_obj)
         for point in ref_points_obj:
             #Remove points from reference that are outside sec_region_union
             if not point.within(sec_regions_obj_union):
                 raise ValueError(
                     "Points from reference distribution lie outside union of regions from secondary distribution."
                 )
                 #ref_points_obj.remove(point)
                 #train_df = train_df[train_df.Region != (point.x,point.y)]
         coords = points_to_coords(ref_points_obj)
         ref_vor_regions_obj, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
             coords, sec_regions_obj_union)
         #Convert back to string
         ref_vor_regions = SpatialHelper.convertGeoObjectsToString(
             ref_vor_regions_obj)
         #print(ref_vor_regions[0])
         new_entries = SpatialHelper.computeNewRegions(
             ref_vor_regions, second_old_entries)
         # For 3. and 4., return error for now
         #raise ValueError("Invalid input for the {} variable. Spatial\
         #                 mismatch variables of the reference distribution\
         #                 must be 'Multipolygon' or 'Polygon.'"
         #                 .format(str(self.node)))
         #print('inside spatial handler')
         #print(len(reference_old_entries))
         #print(len(second_old_entries))
         #print(len(new_entries))
         #print('leaving spatial handler')
     else:
         raise ValueError("Invalid input for {} variable. Spatial mismatch\
                          variables must be a 'Multipolygon', 'Polygon'\
                          or 'Point', or be a tuple of (X,Y) coordinates.".
                          format(str(self.node)))
     return reference_old_entries, second_old_entries, new_entries
示例#27
0
print('duplicated %d random points -> we have %d coordinates now' %
      (N_DUPL, len(coords)))

# if we didn't know in advance how many duplicates we have (and which points they are), we could find out like this:
# unique_coords, unique_ind, dupl_counts = np.unique(coords, axis=0, return_index=True, return_counts=True)
# n_dupl = len(coords) - len(unique_ind)
# n_dupl
# >>> 10

#
# calculate the Voronoi regions, cut them with the geographic area shape and assign the points to them
#
# the duplicate coordinates will belong to the same voronoi region
#

poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
    coords, area_shape, accept_n_coord_duplicates=N_DUPL)

# poly_to_pt_assignments is a nested list because a voronoi region might contain several (duplicate) points

print('\n\nvoronoi region to points assignments:')
for i_poly, pt_indices in enumerate(poly_to_pt_assignments):
    print('> voronoi region', i_poly, '-> points', str(pt_indices))

print('\n\npoints to voronoi region assignments:')
pts_to_poly_assignments = np.array(
    get_points_to_poly_assignments(poly_to_pt_assignments))
for i_pt, i_poly in enumerate(pts_to_poly_assignments):
    print('> point ', i_pt, '-> voronoi region', i_poly)

#
# plotting
示例#28
0
    def update(self, outer_pos, inner_pos, UPDATE, EPS=0.1):
        global t
        t = time.time() - start

        outputs = []

        global FLAG
        if FLAG:
            fig, ax = subplot_for_map()
            global ax, fig
            FLAG = False

        def reshape_coords(coords):
            new_coords = []
            for p in poly_shapes:
                for n in coords:
                    m = Point(n)
                    if m.within(p):
                        new_coords.append(n)
            return new_coords

        def reshape_centroids(centroids):
            new_centroids = []
            for p in poly_shapes:
                for n in centroids:
                    m = Point(n)
                    if m.within(p):
                        new_cent
                        roids.append(n)
            return new_centroids

        def match_pair(poly_shapes, coords, new_centroids):
            sorted_coords = []
            points = coords_to_points(coords)
            for i, p in enumerate(points):
                c = coords[i]
                #print("c: ", c[0],c[1])
                for j, poly in enumerate(poly_shapes):
                    if p.within(poly):
                        pair = new_centroids[j]
                        sorted_coords.append(pair)
            return sorted_coords

        N = 4  #len(inner_pos)

        area_shape = Polygon(outer_pos)  #update_outer(outer_pos)

        # generate some random points within the bounds
        minx, miny, maxx, maxy = area_shape.bounds

        pts = [p for p in coords_to_points(inner_pos)
               if p.within(area_shape)]  # converts to shapely Point

        while len(pts) < N:  #isinstance(compensated, int):
            inner_pos = points_to_coords(pts)
            print('%d of %d drone"s pos is available' % (len(pts), N))
            #print("compensated!!", compensated, type(compensated))

            randx = np.random.uniform(minx, maxx, N - len(pts))
            randy = np.random.uniform(miny, maxy, N - len(pts))
            compensated = np.vstack((randx, randy)).T
            inner_pos = np.append(inner_pos, compensated, axis=0)
            #print(inner_pos)
            #inner_pos = inner_pos[sorted(np.random.choice(inner_pos.shape[0], N, replace=False)), :]
            pts = [
                p for p in coords_to_points(inner_pos) if p.within(area_shape)
            ]  # converts to shapely Point

        ax.clear()  # comment out if you want to plot trajectory
        coords = points_to_coords(
            pts)  # convert back to simple NumPy coordinate array
        poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
            coords, area_shape, accept_n_coord_duplicates=0)

        poly_centroids = np.array([p.centroid.coords[0] for p in poly_shapes])
        #new_centroids = reshape_centroids(poly_centroids)

        # plotting
        EPS = EPS
        err = 99999

        #old_coords = coords
        new_centroids = match_pair(poly_shapes, coords, poly_centroids)

        for i in range(len(coords)):
            xo = coords[i][0]
            yo = coords[i][1]
            #old_coords[i][0] = xo
            #old_coords[i][1] = yo
            xc = new_centroids[i][0]
            yc = new_centroids[i][1]
            #err = np.sqrt((xo-xc)**2 + (yo-yc)**2)

            data = [xc, yc]

            outputs.append(data)  #(np.array((xc, yc)).astype(np.float64))

            #if  err > EPS:
            #    # print("UPDARED!!")
            #    coords[i][0] = xc#xo + 0.2*(xc-xo)
            #    coords[i][1] = yc#yo + 0.2*(yc-yo)

        # draw centroid that each drone follow
        for i, centroid in enumerate(new_centroids):
            c1 = centroid
            ax.plot(c1[0], c1[1], '*', label=str(i))
        for coord in coords:
            c = coord
            ax.plot(c[0], c[1], 'o', alpha=0.5)

        fig = plot_voronoi_polys_with_points_in_area(ax, area_shape,
                                                     poly_shapes, coords,
                                                     poly_to_pt_assignments)
        plt.title(str(t) + "[s]")

        plt.pause(0.00001)
        return outputs
def build_voronoi(us_outline,
                  ipm_gdf,
                  largest_metros,
                  extra_metro_cbsa_ids: List[str] = []):

    logger.info("Making voronoi polygons")
    poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords(
        largest_metros[["longitude", "latitude"]].values, us_outline)

    metro_voronoi = largest_metros.iloc[[x[0]
                                         for x in poly_to_pt_assignments], :]
    metro_voronoi["metro_id"] = metro_voronoi["cbsa_id"]
    metro_voronoi.geometry = poly_shapes

    logger.info("Fixing NYC/Long Island")
    ny_z_j_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J",
                              "convex_hull"].values[0]
    ny_z_k_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K",
                              "convex_hull"].values[0]
    ny_z_j_k_poly = cascaded_union([ny_z_j_poly, ny_z_k_poly])

    for cbsa_id in metro_voronoi.query(
            "IPM_Region.isin(['NENG_CT', 'PJM_EMAC']).values"
    )["cbsa_id"].to_list():
        # print(cbsa_id)
        metro_voronoi.loc[metro_voronoi["cbsa_id"] == cbsa_id,
                          "geometry"] = metro_voronoi.loc[
                              metro_voronoi["cbsa_id"] == cbsa_id,
                              "geometry"].difference(ny_z_j_k_poly)

    # Need the unary_union to make geometries valid
    ny_z_j_ipm = shapely.ops.unary_union(
        ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J", "geometry"].values[0])
    ny_z_k_ipm = shapely.ops.unary_union(
        ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K", "geometry"].values[0])

    # Get a simplified outline of Long Island
    # Start with the zone K convex hull, remove the overlap with zone J IPM region,
    # then take the intersection with the US outline.
    ny_z_k_ipm = ny_z_k_poly.difference(ny_z_j_ipm).intersection(us_outline)

    # Same with NYC, zone J. Remove the bordering regions (zone K, other IPM regions)
    # from the convex hull, then take intersection with US outline.
    ny_z_j_ipm = (ny_z_j_poly.difference(ny_z_k_ipm).difference(
        shapely.ops.unary_union(
            ipm_gdf.query("IPM_Region=='PJM_EMAC'")
            ["geometry"].values[0])).difference(
                shapely.ops.unary_union(
                    ipm_gdf.query("IPM_Region=='NY_Z_G-I'")
                    ["geometry"].values[0])).intersection(us_outline))

    data_dict = {
        "IPM_Region": ["NY_Z_J", "NY_Z_K"],
        "state": ["NY", "NY"],
        "metro_id": ["NY_Z_J", "NY_Z_K"],
        "latitude": [ny_z_j_ipm.centroid.y, ny_z_k_ipm.centroid.y],
        "longitude": [ny_z_j_ipm.centroid.x, ny_z_k_ipm.centroid.x],
    }

    ny_z_j_k_df = gpd.GeoDataFrame(data=data_dict,
                                   geometry=[ny_z_j_ipm, ny_z_k_ipm],
                                   crs=metro_voronoi.crs)

    final_metro_voronoi = pd.concat([metro_voronoi, ny_z_j_k_df],
                                    ignore_index=True,
                                    sort=False)

    # Assign the Sacramento metro to WEC_BANC rather than WEC_CALN
    final_metro_voronoi.loc[final_metro_voronoi["metro_id"] == "40900",
                            "IPM_Region"] = "WEC_BANC"

    return final_metro_voronoi
buffer = valleypoly.buffer(BUFFER_DISTANCE)

features = [0]
geometry = [valleypoly]
df = {'features': features, 'geometry': geometry}
gdf = gpd.GeoDataFrame(df)
gdf.to_file('C:/Users/pmitc/Documents/QGIS/Zumbro/Zumbro_SamplePoints/TestGround/ValleyPoly.shp')

features = [0]
geometry = [buffer]
df = {'features': features, 'geometry': geometry}
gdf = gpd.GeoDataFrame(df)
gdf.to_file('C:/Users/pmitc/Documents/QGIS/Zumbro/Zumbro_SamplePoints/TestGround/ValleyBuffer.shp')

# Create Voronoi Polygons
region_polys, region_pts = voronoi_regions_from_coords(points, buffer)

#Export the voronoi polygons

features = [i for i in range(len(region_polys))]
geometry = [geom for geom in region_polys.values()]
df = {'features': features, 'geometry': geometry}
gdf = gpd.GeoDataFrame(df)
gdf.to_file('C:/Users/pmitc/Documents/QGIS/Zumbro/Zumbro_SamplePoints/TestGround/Voronoi_Demo.shp')

print("Voronoi Polygons created.")
voronoi_edges = []

for poly in region_polys.values():
    if poly.geom_type == 'MultiPolygon':
        # If the buffer distance is too small (<0.0006 in this case), some of the voronoi outputs are MultiPolygons.