Создать случайные точки внутри многоугольника в классе - PullRequest
1 голос
/ 16 октября 2019

Я пытаюсь создать одну точку внутри многоугольника, используя класс для использования в агентной модели.

В настоящее время я могу создавать случайные точки, ограниченные границами многоугольника, но неСам полигон. В настоящее время мой код игнорирует оператор if в цикле while. Я очень плохо знаком с 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.

1 Ответ

2 голосов
/ 16 октября 2019

Не используйте переменную counter, а оператор break, когда точка выбирается в пределах многоугольника. Переменная counter всегда будет равна единице при выходе, поэтому она не несет новую информацию. Я не очень знаком с библиотекой 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()
...