1

Is there a built-in function for dividing a polygon without using another polygon or linestring? Simply by dividing the polygon on itself into n parts of approximately equivalent area.

An idea would be to transform the polygon into linestrings and to get the interpolation points of these lines for example with:

import geopandas as gpd
from shapely.wkt import loads
from shapely.geometry import MultiPoint, LineString
from shapely.ops import linemerge, unary_union, polygonize


def get_linesegments(line, n):
    points = MultiPoint([line.interpolate(i/n, normalized=True)
                         for i in range(1, n)])
    list_points = [i for i in points]
    return list_points


poly_str = "POLYGON ((47.69206466941654 28.53890921704794, 47.67430241940002 28.49805546700986, 47.67430241940002 28.41306221693071, 47.66580291939209 28.30257071682786, 47.58930891932084 28.23457596676451, 47.53831291927338 28.17508046670912, 47.58930891932084 28.09008721662997, 47.60630766933667 28.01359296655869, 47.60630766933667 27.97109621651913, 47.60630766933667 27.95409771650327, 47.55531141928918 27.90310146645578, 47.49581616923376 27.83510696639246, 47.34282791909129 27.89460221644788, 47.1303444188934 27.96259696651123, 47.05385041882215 27.97109621651913, 46.97735616875093 28.02209246656662, 46.81586866860056 28.01359296655869, 46.75637341854514 27.89460221644788, 46.70537716849765 27.8011094663608, 46.63738266843433 27.75861271632124, 46.44189766825224 27.75861271632124, 46.3059081681256 27.75861271632124, 46.28041016810187 27.8096087163687, 46.13592141796727 27.8096087163687, 46.14442066797523 27.75011346631334, 46.20391616803062 27.72461546628955, 46.20391616803062 27.63962196621043, 46.16991866799896 27.56312796613918, 46.16991866799896 27.51213171609169, 46.10192391793561 27.46113571604417, 45.9914324178327 27.44413696602834, 45.88944041773772 27.38464171597292, 45.88944041773772 27.27415021587007, 45.88944041773772 27.12116196572754, 45.88944041773772 26.976673215593, 45.88738216773584 26.9066957155278, 45.76887891762544 26.96002221557751, 45.62060091748737 27.02742146564026, 45.5734214174434 27.12178021572811, 45.47906266735555 27.14199996574695, 45.29034516717979 27.17569946577834, 45.20946616710444 27.18917921579089, 45.13532716703543 27.30375771589763, 45.13532716703543 27.41159646599806, 45.09488766699775 27.55987446613614, 45.04096841694752 27.62727371619889, 44.92638991684083 27.55987446613614, 44.81181141673409 27.51943496609846, 44.74583066667265 27.49544221607613, 44.73767241666508 27.49247546607336, 44.70397266663366 27.51943496609846, 44.65679341658972 27.55987446613614, 44.6163539165521 27.68119296624911, 44.54221491648303 27.74859196631189, 44.48308391642797 27.82743346638534, 44.48155566642652 27.82947096638725, 44.56243466650187 27.88339021643742, 44.58265441652071 27.91708996646884, 44.79159166671531 27.91708996646884, 44.95334941686593 27.91708996646884, 44.95334941686593 28.06536796660691, 45.04770841695381 28.08558771662575, 45.04770841695381 28.11254746665088, 45.17576666707305 28.13950696667598, 45.21620616711073 28.16646671670105, 45.34426441723002 28.20016621673244, 45.33752441722373 28.24060571677012, 45.31056491719863 28.32822446685174, 45.2566456671484 28.40236371692077, 45.15554691705427 28.48998246700239, 45.07466791697891 28.58434121709024, 45.01400866692245 28.68543996718438, 45.03422841694123 28.75283896724716, 45.23642591712957 28.73935921723461, 45.43862316731787 28.76631896725974, 45.67452016753759 28.76631896725974, 45.73517941759405 28.87415746736013, 45.83627816768825 28.93481671741665, 45.96433641780749 29.00895571748572, 46.03847541787655 29.07635496754847, 46.04712816788458 29.09208721756312, 46.12215441795445 29.08607346755753, 46.42667241823807 29.0616634675348, 46.54694566835008 29.10419971757443, 46.54860866835162 29.10305471757334, 46.58777266838808 29.09805471756869, 46.80028166858602 29.07527271754748, 46.99666366876892 29.05305471752678, 47.45999066920041 28.99943546747681, 47.46339041920356 28.98446371746292, 47.50694566924415 28.92305471740571, 47.54054566927545 28.85055471733818, 47.56470841929797 28.796663467288, 47.57484566930736 28.77013646726328, 47.57665466930905 28.73305471722875, 47.57499066930751 28.70305471720081, 47.60276341933337 28.63499046713741, 47.61777341934737 28.61416346711803, 47.68888141941358 28.5388817170479, 47.69206466941654 28.53890921704794))"
poly = loads(poly_str)

p = get_linesegments(poly.boundary, 20)
lines = [LineString([i, poly.centroid]) for i in p]

lines.append(poly.boundary)
lines = unary_union(lines)
lines = linemerge(lines)
polygons = polygonize(lines)

geos = gpd.GeoSeries(polygons)
geos.to_file("test.geojson", driver="GeoJSON")

Isn't there something better and more 'stringent' in your opinion?

Tim
  • 513
  • 5
  • 20
  • 'approximately equal' - how approximate? Does your code still work if the centroid is outside the polygon? Are you looking for code that provides a more equal split? Or just for a simpler way? – Stuart Oct 14 '21 at 14:51
  • Yes actually the centroid is the centroid of the main polygon. Yes, a code that allows for a more equitable sharing. Use Voronoi seems to be a good idea I was wondering if there was not a function for that directly. – Tim Oct 16 '21 at 15:28

0 Answers0