0

I have above 2000 points where each point has a field which indicates a number of incidents from 0 to 300. I want to draw a polygon around each of these points where the total number of incidents should be 1000 (with small deviance).

One polygon should cover more than 4 points in order to achieve a minimum sum of 1000.

The distance of the points should be minimal therefore we will have multiple neighboring polygons which has same/similar number of incidents covering multiple points.

Its logically simple and can be done manually but I couldn't find out how to do it automatically.

  • Welcome to GIS SE. As a new user, please take the Tour. The way GIS packages do very specific tasks "automatically" is via scripting languages. In order to prevent this group from becoming a coding service, we require coding questions to contain code. Please edit the question to contain the specific ArcGIS package you are using, some graphics to clarify your meaning, and your initial best effort for coding this in Python with ArcPy with a description of where you are stuck. – Vince Jul 10 '17 at 10:25
  • What have you tried? I would recommend to write down what you've done manually to solve this problem and then incorporate those order of tools and methods into a model using ModelBuilder. – artwork21 Jul 10 '17 at 12:16
  • You could create this tool using Python. The tool would 1. Select a point. 2. Have a recursive function make select by locations at ever increasing distances. 3. Once 4 points are selected sum the incidents. 4. Repeat step 3 if the conditions are not met to include more points. 5. If the condition is met generate minimum bounding geometry around the selected points. Trouble may ensue if two of the points are the same distance from the selected point but you could flag those points in the code. – GBG Jul 10 '17 at 17:43
  • @ Artwork21: Unfortunately I couldnt find a way yet. – Nas Jul 11 '17 at 3:50
  • @GBG: Indeed your words reflecting my thoughts but I am not really familiar with coding... :( – Nas Jul 11 '17 at 3:52
1

this python script should do the trick. The output polygon vertex will overlap some existing point, so run the Buffer tool if you need some padding around the polygon. Give it a try, I hope this works for you.

import arcpy
from arcpy import env

# Please change these variable according to your environment
in_fc = "random_points"
out_fc = "polygon"          # This is your final output 
env.workspace = "C:/Users/Umesh/Documents/ArcGIS/Scratch"



sr = arcpy.Describe(in_fc).spatialReference

# Add polygon index field
poly = arcpy.CreateFeatureclass_management(env.workspace, out_fc, "POLYGON", "","","",sr)
poly_fl = arcpy.MakeFeatureLayer_management(poly,"polygon_layer")
arcpy.AddField_management(poly_fl,"poly_index","LONG")

# Adding Field
arcpy.AddField_management(in_fc,"value_sum","LONG")
arcpy.AddField_management(in_fc,"poly_index","LONG")

# Getting values from each point feature and adding them to the new field
uc = arcpy.da.UpdateCursor(in_fc, ["value", "value_sum", "poly_index"])
sum = 0
poly_index = set() # Create an empty set to store (future) polygon_ids

for row in uc:
    sum += row[0]
    poly_id = int(sum/1000+1)
    poly_index.add(poly_id)
    uc.updateRow([row[0], sum, poly_id ])

del sum
del uc

# Now preparation is done

# Iterating through polygon index list 
for i in poly_index:
    x_list = []
    y_list = []
    sc = arcpy.da.SearchCursor(in_fc, ["SHAPE@X", "SHAPE@Y"],"{} = {}".format(arcpy.AddFieldDelimiters(env.workspace, "poly_index"), i))
    for row in sc:
        # Add x and y coordinates into seperate list
        x_list.append(row[0])
        y_list.append(row[1])
    del row
    del sc
    max_x = max(x_list)
    max_y = max(y_list)
    min_x = min(x_list)
    min_y = min(y_list)

    p1 = arcpy.Point(min_x, min_y)
    p2 = arcpy.Point(min_x, max_y)
    p3 = arcpy.Point(max_x, max_y)
    p4 = arcpy.Point(max_x, min_y)

    # Creating a polygon geometry and inserting into the output fc    
    poly = arcpy.Polygon(arcpy.Array([p1,p2,p3,p4]))
    ic = arcpy.da.InsertCursor(poly_fl, ["SHAPE@", "poly_index"])
    ic.insertRow([poly, i])
    del poly
    del ic

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.