【问题标题】:Create random points within a polygon within a class在类内的多边形内创建随机点
【发布时间】:2020-02-13 08:53:18
【问题描述】:

我正在尝试使用类在基于代理的模型中创建一个多边形内的单个点。

目前,我能够创建限制在多边形边界内的随机点,但不能创建多边形本身。我目前的代码似乎忽略了 while 循环中的 if 语句。我对 python 很陌生,所以这可能是我缺少的限制。

这是我当前的代码:

import geopandas as gpd
import matplotlib.pyplot as plt
import random
import pandas as pd

bounds = gpd.read_file("./data/liverpool_bounds.gpkg")


class Agent():
    def __init__(self, bounds):
        x_min, y_min, x_max, y_max = bounds.total_bounds

        counter = 0
        while counter != 1:
            x = random.uniform(x_min, x_max)
            y = random.uniform(y_min, y_max)
            df = pd.DataFrame({'x': [x], 'y': [y]})
            self.agent = gpd.GeoDataFrame(
                df, geometry=gpd.points_from_xy(df.x, df.y))

            if self.agent.within(bounds) is True:
                counter = 1

            # counter does not increase
            print(counter)
            # gives both True and False
            print(self.agent.within(bounds))


Agent(bounds).agent

这段代码给出了一个无限循环。预期的行为是在给定布尔 True 值的情况下停止,并以 False 继续,直到出现 True 值。

【问题讨论】:

    标签: python class gis polygon point


    【解决方案1】:

    不要使用 counter 变量,而是在多边形内对点进行采样时使用 break 语句。计数器变量在退出时将始终为 1,因此它不携带新信息。我对 Geopandas 库不是很熟悉,但是您可以使用 Shapely 实现解决方案,这是一个非常好的库 imo。使用这种程序结构,您的对象变得更普遍可用。

    from shapely.geometry import Point, Polygon
    import random
    
    
    bounds = [(0, 0), (1, 0), (1, 1), (0, 1)]
    
    
    class Agent():
        def __init__(self, bounds):
            self.polygon = Polygon(bounds)
    
            # implement your object wide dataframe here to which you can append
    
        def add_random_point(self):
            xmin, ymin, xmax, ymax = self.polygon.bounds
            while True:
                x = random.uniform(xmin, xmax)
                y = random.uniform(ymin, ymax)
    
                if Point(x, y).within(self.polygon):
                    # if this condition is true, add to a dataframe here
    
                    print(x, y)
                    break
    
    
    obj = Agent(bounds)
    obj.add_random_point()
    

    【讨论】:

    • 您好,感谢您的回复。这似乎不起作用,但是,我仍然得到一个无限循环,self.agent.within(bounds) 的值同时具有 TrueFalse
    • self.agent.within() 的返回值是一个geopandas.Series 对象,但是在这个条件中需要一个原子值才能通过。
    • @CillianBeragan 此更新可能会解决您的问题。
    • 感谢您的更新,我个人想在我的应用程序中坚持使用 geopandas,但是您关于 inside() 输出的建议给出了解决方案。我基本上只需将 if 循环转换为布尔值即可工作; within = int(gdf.within(self.bounds)。可能不是最好的方法,但它确实有效。
    • 更好:gdf.within(self.bounds)[0] 用作布尔值。
    猜你喜欢
    • 2011-03-21
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 2021-10-16
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    相关资源
    最近更新 更多