<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Select nearest polygons from point that sum to a value in the point in ArcGIS Pro Questions</title>
    <link>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1547456#M89051</link>
    <description>&lt;P&gt;Here's an attempt. Hexagons have "populations" between 1 and 5 (light to dark). Black points are the child care centers and their capacities are shown in the adjacent black labels. Regions made up of hexagons that have aggregated enough "population" to reach each capacity for each center are shown in the colors, with the "actual" population gathered labeled with the callouts.&lt;/P&gt;&lt;P&gt;The caveats:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Regions can overlap if centers are too close (see red/blue). Lots of fixes for this, depending on what you're after.&lt;/LI&gt;&lt;LI&gt;Childcare centers can be "over" capacity. See green region, where the max capacity is 80, and 81 have been "gathered" from adjacent hexagons. Also lots of fixes, depending on needs.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="VinceE_0-1728525155937.png" style="width: 689px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/116953i3CE14B8415A0BC90/image-dimensions/689x643?v=v2" width="689" height="643" role="button" title="VinceE_0-1728525155937.png" alt="VinceE_0-1728525155937.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Code below, in simple terms: for each center, add the closest hexagon to a region, followed by the next closest, etc., until enough hexagons have been added so the summed population reaches the capacity of the child care center. This runs extremely quickly with ~1,300 hexagons, but is definitely not the most optimized.&lt;/P&gt;&lt;P&gt;You'll have to edit this code if you want to use it with your own feature classes. Happy to provide more details if you need them.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
import math
import os
import sys

arcpy.env.workspace = r"YOUR_GEODATABASE_PATH"
arcpy.env.overwriteOutput = True

# Names of hexagon bins and the associated points.
hex_bin = "HexBin"
hex_pnt = "HexAggPoint"

# Create an info dictionary about the hexagons
# {oid: {HEX_GEOM: geometry, POP: integer}}
with arcpy.da.SearchCursor(hex_bin, ["OID@", "SHAPE@", "POP"]) as scurs:
    hex_pop_dict = {oid: {"HEX_GEOM": geom, "POP": pop} for oid, geom, pop in scurs}

# Empty dictionary to store info about our output regions.
clusters = {}

# Loop over points, logging assembled region information in 'clusters' dict.
with arcpy.da.SearchCursor(hex_pnt, ["OID@", "SHAPE@XY", "CAPACITY"]) as scurs:
    for oid, centroid, capacity in scurs:

        # Get list of (hex_id, distance_to_point) tuples.
        distances = []
        for hex_id, hex_record in hex_pop_dict.items():
            hex_centroid_coor = hex_record["HEX_GEOM"].centroid
            dist = math.dist(centroid, (hex_centroid_coor.X, hex_centroid_coor.Y))
            distances.append((hex_id, dist), )

        # Sort tuples ascending distance from the point in question.
        distances.sort(key=lambda x: x[1])

        # Loop distance tuples, using the hex ID to accumulate population per hex.
        # Log the hex IDs that are used. Stop adding more hexes onces the capacity
        #   of the point is reached.
        gathered_hexes = []
        accumulated_pop = 0
        for hex_id, _ in distances:
            gathered_hexes.append(hex_id)
            accumulated_pop += hex_pop_dict[hex_id]["POP"]

            if accumulated_pop &amp;gt;= capacity:
                break

        # For this Point ID, associated a list of hexes that will create region.
        clusters[oid] = gathered_hexes
        print(f"HEX ID: {oid}\nCAPACITY: {capacity}"
              f"\nACTUAL ACCUM: {accumulated_pop}"
              f"\nHEX IDS: {gathered_hexes}\n")

# CREATE OUTPUT FC, ADD FIELDS
region_fc = arcpy.management.CreateFeatureclass(out_path=arcpy.env.workspace,
    out_name="HEX_REGION", geometry_type="POLYGON", spatial_reference=2232)
for fld_name in ["POINT_ID", "HEX_ID", "POP"]:
    arcpy.management.AddField(region_fc, fld_name, "SHORT")

# WRITE OUTPUT RECORDS
with arcpy.da.InsertCursor(region_fc, ["SHAPE@", "POINT_ID", "HEX_ID", "POP"]) as icurs:
    # For this point and list of hexes that should create the region...
    for point_id, hex_id_list in clusters.items():

        # ...and for each hex in the list...
        for hex_id in hex_id_list:

            # Using hex's ID, insert Geometry and Population,
            #   plus the ID of both the parent point and the hex.
            icurs.insertRow([hex_pop_dict[hex_id]["HEX_GEOM"],
                             point_id,
                             hex_id,
                             hex_pop_dict[hex_id]["POP"]])

# Dissolve the hex polygons based on the associated point. Sum the pop of the region.
dissolve_fc_path = os.path.join(arcpy.env.workspace, "HEX_REGION_DISSOLVE")
arcpy.management.Dissolve(in_features="HEX_REGION", out_feature_class=dissolve_fc_path,
            dissolve_field="POINT_ID", statistics_fields=[["POP", "SUM"], ])&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Thu, 10 Oct 2024 02:08:25 GMT</pubDate>
    <dc:creator>VinceE</dc:creator>
    <dc:date>2024-10-10T02:08:25Z</dc:date>
    <item>
      <title>Select nearest polygons from point that sum to a value in the point</title>
      <link>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1545040#M88822</link>
      <description>&lt;P&gt;I have a polygon tessellation representing 5 acres, and is populated with an estimated value of children between the ages of 0-10. I have a point feature class that represents child care locations and it contains a capacity number. I want to somehow represent how many of the nearest polygons would be needed to fill the capacity of the point value. So if I have a point with a capacity of 50, I would want to know how many of the closest polygons that point would cover.&lt;BR /&gt;&lt;BR /&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Screenshot 2024-10-02 165401.png" style="width: 400px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/116400i346291E31DE4CAEF/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Screenshot 2024-10-02 165401.png" alt="Screenshot 2024-10-02 165401.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 03 Oct 2024 00:05:50 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1545040#M88822</guid>
      <dc:creator>LRoberts_RDM</dc:creator>
      <dc:date>2024-10-03T00:05:50Z</dc:date>
    </item>
    <item>
      <title>Re: Select nearest polygons from point that sum to a value in the point</title>
      <link>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1545077#M88828</link>
      <description>&lt;P&gt;I think in this case the Weighted Thiessen Polygons built for your child care locations (weighted by the capacity field) can be useful.&lt;/P&gt;</description>
      <pubDate>Thu, 03 Oct 2024 05:16:29 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1545077#M88828</guid>
      <dc:creator>SeaRM</dc:creator>
      <dc:date>2024-10-03T05:16:29Z</dc:date>
    </item>
    <item>
      <title>Re: Select nearest polygons from point that sum to a value in the point</title>
      <link>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1545231#M88850</link>
      <description>&lt;P&gt;Hi &lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/534220"&gt;@SeaRM&lt;/a&gt;,&lt;BR /&gt;I feel like that would be basically the same as symbolizing my points by proportional symbol, using the capacity as my value. I need it to somehow be affected by the polygons below it. So if I have a point with a capacity of 50, and it's surrounded by polygons with a value of 1, it would cover more. But if I had a point with a capacity of 50 and it sits on top of a polygon of 50, it would just cover that polygon. Maybe this is more a spatial analyst function?&lt;/P&gt;</description>
      <pubDate>Thu, 03 Oct 2024 15:30:27 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1545231#M88850</guid>
      <dc:creator>LRoberts_RDM</dc:creator>
      <dc:date>2024-10-03T15:30:27Z</dc:date>
    </item>
    <item>
      <title>Re: Select nearest polygons from point that sum to a value in the point</title>
      <link>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1547456#M89051</link>
      <description>&lt;P&gt;Here's an attempt. Hexagons have "populations" between 1 and 5 (light to dark). Black points are the child care centers and their capacities are shown in the adjacent black labels. Regions made up of hexagons that have aggregated enough "population" to reach each capacity for each center are shown in the colors, with the "actual" population gathered labeled with the callouts.&lt;/P&gt;&lt;P&gt;The caveats:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Regions can overlap if centers are too close (see red/blue). Lots of fixes for this, depending on what you're after.&lt;/LI&gt;&lt;LI&gt;Childcare centers can be "over" capacity. See green region, where the max capacity is 80, and 81 have been "gathered" from adjacent hexagons. Also lots of fixes, depending on needs.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="VinceE_0-1728525155937.png" style="width: 689px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/116953i3CE14B8415A0BC90/image-dimensions/689x643?v=v2" width="689" height="643" role="button" title="VinceE_0-1728525155937.png" alt="VinceE_0-1728525155937.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Code below, in simple terms: for each center, add the closest hexagon to a region, followed by the next closest, etc., until enough hexagons have been added so the summed population reaches the capacity of the child care center. This runs extremely quickly with ~1,300 hexagons, but is definitely not the most optimized.&lt;/P&gt;&lt;P&gt;You'll have to edit this code if you want to use it with your own feature classes. Happy to provide more details if you need them.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
import math
import os
import sys

arcpy.env.workspace = r"YOUR_GEODATABASE_PATH"
arcpy.env.overwriteOutput = True

# Names of hexagon bins and the associated points.
hex_bin = "HexBin"
hex_pnt = "HexAggPoint"

# Create an info dictionary about the hexagons
# {oid: {HEX_GEOM: geometry, POP: integer}}
with arcpy.da.SearchCursor(hex_bin, ["OID@", "SHAPE@", "POP"]) as scurs:
    hex_pop_dict = {oid: {"HEX_GEOM": geom, "POP": pop} for oid, geom, pop in scurs}

# Empty dictionary to store info about our output regions.
clusters = {}

# Loop over points, logging assembled region information in 'clusters' dict.
with arcpy.da.SearchCursor(hex_pnt, ["OID@", "SHAPE@XY", "CAPACITY"]) as scurs:
    for oid, centroid, capacity in scurs:

        # Get list of (hex_id, distance_to_point) tuples.
        distances = []
        for hex_id, hex_record in hex_pop_dict.items():
            hex_centroid_coor = hex_record["HEX_GEOM"].centroid
            dist = math.dist(centroid, (hex_centroid_coor.X, hex_centroid_coor.Y))
            distances.append((hex_id, dist), )

        # Sort tuples ascending distance from the point in question.
        distances.sort(key=lambda x: x[1])

        # Loop distance tuples, using the hex ID to accumulate population per hex.
        # Log the hex IDs that are used. Stop adding more hexes onces the capacity
        #   of the point is reached.
        gathered_hexes = []
        accumulated_pop = 0
        for hex_id, _ in distances:
            gathered_hexes.append(hex_id)
            accumulated_pop += hex_pop_dict[hex_id]["POP"]

            if accumulated_pop &amp;gt;= capacity:
                break

        # For this Point ID, associated a list of hexes that will create region.
        clusters[oid] = gathered_hexes
        print(f"HEX ID: {oid}\nCAPACITY: {capacity}"
              f"\nACTUAL ACCUM: {accumulated_pop}"
              f"\nHEX IDS: {gathered_hexes}\n")

# CREATE OUTPUT FC, ADD FIELDS
region_fc = arcpy.management.CreateFeatureclass(out_path=arcpy.env.workspace,
    out_name="HEX_REGION", geometry_type="POLYGON", spatial_reference=2232)
for fld_name in ["POINT_ID", "HEX_ID", "POP"]:
    arcpy.management.AddField(region_fc, fld_name, "SHORT")

# WRITE OUTPUT RECORDS
with arcpy.da.InsertCursor(region_fc, ["SHAPE@", "POINT_ID", "HEX_ID", "POP"]) as icurs:
    # For this point and list of hexes that should create the region...
    for point_id, hex_id_list in clusters.items():

        # ...and for each hex in the list...
        for hex_id in hex_id_list:

            # Using hex's ID, insert Geometry and Population,
            #   plus the ID of both the parent point and the hex.
            icurs.insertRow([hex_pop_dict[hex_id]["HEX_GEOM"],
                             point_id,
                             hex_id,
                             hex_pop_dict[hex_id]["POP"]])

# Dissolve the hex polygons based on the associated point. Sum the pop of the region.
dissolve_fc_path = os.path.join(arcpy.env.workspace, "HEX_REGION_DISSOLVE")
arcpy.management.Dissolve(in_features="HEX_REGION", out_feature_class=dissolve_fc_path,
            dissolve_field="POINT_ID", statistics_fields=[["POP", "SUM"], ])&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 10 Oct 2024 02:08:25 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-questions/select-nearest-polygons-from-point-that-sum-to-a/m-p/1547456#M89051</guid>
      <dc:creator>VinceE</dc:creator>
      <dc:date>2024-10-10T02:08:25Z</dc:date>
    </item>
  </channel>
</rss>

