Is it possible to make a buffer that has four quadrants with different radii?

3205
19
12-16-2016 04:24 PM
PatrickPrendergast
New Contributor II

Hello,

I couldn't find an answer to this in previous discussions so hopefully I'm asking a new question.

I am using ArcMap 10.2.2 and I have "extended best track" data for tropical cyclones which has latitude and longitude locations of storms at 6 hour intervals as well as estimated wind radii for the NE, SE, SW, and NW quadrants at those locations. For instance, at lat x long y, this data might have estimated radius for a 64 kt wind of 100 nautical miles in the NE quadrant, 75 nm to the SE, etc.

So basically, I want to buffer these point locations with quadrant specific radii based on the attribute for that quadrant. Is this possible to do? I'm not well versed in coding but I would be willing to try to figure it out if it is possible and can be automated either with python or model builder to do for multiple storms. Any suggestions would be much appreciated.

Thanks,

Pat

Tags (1)
19 Replies
PatrickPrendergast
New Contributor II

Thanks for the suggestion Rebecca. Per Dan Patterson's suggestion, I projected my points to meters, reran the code, and got the same error at the end:

>>> fc = "Katrina_Project" # points feature class
... sr = arcpy.Describe(fc).spatialReference # points spatial reference
... out_buffs = [] # placeholder for wedges
... max = 1000000 # distance larger than the maximum wedge
... with arcpy.da.SearchCursor(fc,['SHAPE@','NE_50','SE_50','SW_50','NW_50','NE_64','SE_64','SW_64','NW_64'], spatial_reference=sr) as cursor: # loop through points
...     for row in cursor:
...         cur = row[0].centroid # convert point geometry to point object
...         up = arcpy.Point(cur.X,cur.Y+max) # make points from which to make boxes later
...         upright = arcpy.Point(cur.X+max,cur.Y+max)
...         right = arcpy.Point(cur.X+max,cur.Y)
...         downright = arcpy.Point(cur.X+max,cur.Y-max)
...         down = arcpy.Point(cur.X,cur.Y-max)
...         downleft = arcpy.Point(cur.X-max,cur.Y-max)
...         left = arcpy.Point(cur.X-max,cur.Y)
...         upleft = arcpy.Point(cur.X-max,cur.Y+max)
...         boxes = {'NE':arcpy.Polygon(arcpy.Array([[cur,up,upright,right]]),sr),
...                 'SE':arcpy.Polygon(arcpy.Array([[cur,right,downright,down]]),sr),
...                 'SW':arcpy.Polygon(arcpy.Array([[cur,down,downleft,left]]),sr),
...                 'NW':arcpy.Polygon(arcpy.Array([[cur,left,upleft,up]]),sr)} # make boxes
...         for field in cursor.fields[1:]: # loop through the fields following the point geometry field
...             cur_buff = row[0].buffer(row[cursor.fields.index(field)]) # make a buffer
...             clip_buff = boxes[field[:2]].intersect(cur_buff,4) # clip the buffer by the corresponding box
...             out_buffs.append(clip_buff) # record the wedge
... arcpy.CopyFeatures_management(out_buffs,r'in_memory\out_buffs') # write the wedges
... 
Runtime error 
Traceback (most recent call last):
  File "<string>", line 22, in <module>
  File "c:\program files (x86)\arcgis\desktop10.2\arcpy\arcpy\arcobjects\arcobjects.py", line 809, in intersect
    return convertArcObjectToPythonObject(self._arc_object.Intersect(*gp_fixargs((other, dimension))))
ValueError: <geoprocessing describe geometry object object at 0x2A2F8380>

Any suggestions would be greatly appreciated. Also, is the geonet email working again?

Thanks,

Pat

0 Kudos
DarrenWiens2
MVP Honored Contributor

Hmmm... I'm not sure. I reran your code against my feature class and it works. What coordinate reference system are you using? I was using NAD83 UTM 17, but with a different CRS you may be out of bounds using such a large value for 'max'. Also, did you change the values in your table to meters? The buffer makes buffers of the number of linear units in the dataset, so if your dataset is in meters, the buffers will be meters, if feet, then the buffers will be in feet, etc.

Can you also try adding the following line above line 23 to get a count of out_buffs? len(out_buffs)

PatrickPrendergast
New Contributor II

Hi Darren,

My dataset consists of storms that pass through UTM zones 14-18 so I thought it might be a good idea to project to WGS 1984 World Mercator to make sure I'm not going out of bounds anywhere. I am using just one storm (Katrina) to test the code on, so my attribute table looks like:

I made sure to change my values from nautical miles to meters per your suggestion. I ran the following code and got the same error:

fc = "Katrina_WGS" # points feature class
... sr = arcpy.Describe(fc).spatialReference # points spatial reference
... out_buffs = [] # placeholder for wedges
... max = 1000000 # distance larger than the maximum wedge
... with arcpy.da.SearchCursor(fc,['SHAPE@','NE_50','SE_50','SW_50','NW_50','NE_64','SE_64','SW_64','NW_64'], spatial_reference=sr) as cursor: # loop through points
...     for row in cursor:
...         cur = row[0].centroid # convert point geometry to point object
...         up = arcpy.Point(cur.X,cur.Y+max) # make points from which to make boxes later
...         upright = arcpy.Point(cur.X+max,cur.Y+max)
...         right = arcpy.Point(cur.X+max,cur.Y)
...         downright = arcpy.Point(cur.X+max,cur.Y-max)
...         down = arcpy.Point(cur.X,cur.Y-max)
...         downleft = arcpy.Point(cur.X-max,cur.Y-max)
...         left = arcpy.Point(cur.X-max,cur.Y)
...         upleft = arcpy.Point(cur.X-max,cur.Y+max)
...         boxes = {'NE':arcpy.Polygon(arcpy.Array([[cur,up,upright,right]]),sr),
...                 'SE':arcpy.Polygon(arcpy.Array([[cur,right,downright,down]]),sr),
...                 'SW':arcpy.Polygon(arcpy.Array([[cur,down,downleft,left]]),sr),
...                 'NW':arcpy.Polygon(arcpy.Array([[cur,left,upleft,up]]),sr)} # make boxes
...         for field in cursor.fields[1:]: # loop through the fields following the point geometry field
...             cur_buff = row[0].buffer(row[cursor.fields.index(field)]) # make a buffer
...             clip_buff = boxes[field[:2]].intersect(cur_buff,4) # clip the buffer by the corresponding box
...             len(out_buffs)
...             out_buffs.append(clip_buff) # record the wedge
... arcpy.CopyFeatures_management(out_buffs,r'in_memory\out_buffs') # write the wedges
... 
Runtime error 
Traceback (most recent call last):
  File "<string>", line 22, in <module>
  File "c:\program files (x86)\arcgis\desktop10.2\arcpy\arcpy\arcobjects\arcobjects.py", line 809, in intersect
    return convertArcObjectToPythonObject(self._arc_object.Intersect(*gp_fixargs((other, dimension))))
ValueError: <geoprocessing describe geometry object object at 0x2929FAA0>

Thanks again for your help,

Pat

0 Kudos
PatrickPrendergast
New Contributor II

Hi Darren,

Me again. Thanks again for all your help. I'm trying to modify the great code you wrote in order to be able to loop through multiple storm point feature classes and create buffers. I'm not great with python but I gave it a shot but couldn't get it to work. Would you mind taking a look at it to let me know if I'm on the right track (or, more appropriately, where I'm going wrong)?

try:
...     arcpy.env.workspace = "C:\Users\Patrick\OneDrive\Dissertation\Cyclone GDP\Analysis\GIS\Katrina_ModelBuilder\Katrina_Test.gdb"
...  
...     # List the feature classes in gdb
...     fc = arcpy.ListFeatureClasses()
...  
...     # Loop through feature classes to create buffers:
...     for featureClass in fc:
...         sr = arcpy.Describe(fc).spatialReference # points spatial reference
...         Storm_buffs = [] # placeholder for wedges
...         max = 200 # distance larger than the maximum wedge
...         with arcpy.da.SearchCursor(fc,['SHAPE@','NE_34','SE_34','SW_34','NW_34','NE_50','SE_50','SW_50','NW_50','NE_64','SE_64','SW_64','NW_64'], spatial_reference=sr) as cursor: # loop through points
...              for row in cursor:
...                   cur = row[0].centroid # convert point geometry to point object
...                   up = arcpy.Point(cur.X,cur.Y+max) # make points from which to make boxes later
...                   upright = arcpy.Point(cur.X+max,cur.Y+max)
...                   right = arcpy.Point(cur.X+max,cur.Y)
...                   downright = arcpy.Point(cur.X+max,cur.Y-max)
...                   down = arcpy.Point(cur.X,cur.Y-max)
...                   downleft = arcpy.Point(cur.X-max,cur.Y-max)
...                   left = arcpy.Point(cur.X-max,cur.Y)
...                   upleft = arcpy.Point(cur.X-max,cur.Y+max)
...                   boxes = {'NE':arcpy.Polygon(arcpy.Array([[cur,up,upright,right]]),sr),
...                           'SE':arcpy.Polygon(arcpy.Array([[cur,right,downright,down]]),sr),
...                           'SW':arcpy.Polygon(arcpy.Array([[cur,down,downleft,left]]),sr),
...                           'NW':arcpy.Polygon(arcpy.Array([[cur,left,upleft,up]]),sr)} # make boxes
...                   for field in cursor.fields[1:]: # loop through the fields following the point geometry field
...                       cur_buff = row[0].buffer(row[cursor.fields.index(field)]) # make a buffer
...                       clip_buff = boxes[field[:2]].intersect(cur_buff,4) # clip the buffer by the corresponding box
...                       len(Storm_buffs)
...                       Storm_buffs.append(clip_buff) # record the wedge
...         arcpy.CopyFeatures_management(Storm_buffs,"C:\Users\Patrick\OneDrive\Dissertation\Cyclone GDP\Analysis\GIS\Katrina_ModelBuilder\Katrina_Test.gdb\Storm") # write the wedges
... except:
...     print "Script failed to complete"
...     print arcpy.GetMessages(2)

I know I'm not doing line 32 right because I want the output to have the same name as the input , or a variant of, but I'm just testing this out on one feature class right now and it won't work.

As always, I would appreciate any suggestions.

Thanks again,

Pat

0 Kudos
DarrenWiens2
MVP Honored Contributor

Can you post the error message, if there is one?

0 Kudos
PatrickPrendergast
New Contributor II

That's a good idea - I probably shouldn't have told the script to print a message if it didn't work. After taking out that part of the code, I found and fixed an error, but I have a new error now that I am trying to loop through multiple storms. I made point feature classes for Katrina and Rita (just as examples) in a gdb and am trying to loop through them to create buffers but I can't because I get an error that the output featureclass already exists:

arcpy.env.workspace = "C:\Users\Patrick\OneDrive\Dissertation\Cyclone GDP\Analysis\GIS\Katrina_ModelBuilder\Katrina_Test.gdb"
...  
... # List the feature classes in gdb
... fc = arcpy.ListFeatureClasses()
...  
... # Loop through feature classes to create buffers:
... for fc in fc:
...     sr = arcpy.Describe(fc).spatialReference # points spatial reference
...     Storm_buffs = [] # placeholder for wedges
...     max = 200 # distance larger than the maximum wedge
...     with arcpy.da.SearchCursor(fc,['SHAPE@','NE_34','SE_34','SW_34','NW_34','NE_50','SE_50','SW_50','NW_50','NE_64','SE_64','SW_64','NW_64'], spatial_reference=sr) as cursor: # loop through points
...          for row in cursor:
...               cur = row[0].centroid # convert point geometry to point object
...               up = arcpy.Point(cur.X,cur.Y+max) # make points from which to make boxes later
...               upright = arcpy.Point(cur.X+max,cur.Y+max)
...               right = arcpy.Point(cur.X+max,cur.Y)
...               downright = arcpy.Point(cur.X+max,cur.Y-max)
...               down = arcpy.Point(cur.X,cur.Y-max)
...               downleft = arcpy.Point(cur.X-max,cur.Y-max)
...               left = arcpy.Point(cur.X-max,cur.Y)
...               upleft = arcpy.Point(cur.X-max,cur.Y+max)
...               boxes = {'NE':arcpy.Polygon(arcpy.Array([[cur,up,upright,right]]),sr),
...                       'SE':arcpy.Polygon(arcpy.Array([[cur,right,downright,down]]),sr),
...                       'SW':arcpy.Polygon(arcpy.Array([[cur,down,downleft,left]]),sr),
...                       'NW':arcpy.Polygon(arcpy.Array([[cur,left,upleft,up]]),sr)} # make boxes
...               for field in cursor.fields[1:]: # loop through the fields following the point geometry field
...                   cur_buff = row[0].buffer(row[cursor.fields.index(field)]) # make a buffer
...                   clip_buff = boxes[field[:2]].intersect(cur_buff,4) # clip the buffer by the corresponding box
...                   len(Storm_buffs)
...                   Storm_buffs.append(clip_buff) # record the wedge
...     arcpy.CopyFeatures_management(Storm_buffs,"C:\Users\Patrick\OneDrive\Dissertation\Cyclone GDP\Analysis\GIS\Katrina_ModelBuilder\Katrina_Test.gdb\Storm") # write the wedges
...     
Runtime error  Traceback (most recent call last):   File "<string>", line 31, in <module>   File "c:\program files (x86)\arcgis\desktop10.2\arcpy\arcpy\management.py", line 2429, in CopyFeatures     raise e ExecuteError: ERROR 000725: Output Feature Class: Dataset C:\Users\Patrick\OneDrive\Dissertation\Cyclone GDP\Analysis\GIS\Katrina_ModelBuilder\Katrina_Test.gdb\Storm already exists.

This error makes sense because in line 31 I just save the buffers with a name that wouldn't changed after the script goes to the next storm. Do you know if it is possible to indicate the name of an output be the same or a variant of the input?

Thanks again for your time,

Pat

0 Kudos
DanPatterson_Retired
MVP Emeritus

coordinates for projected data are usually in meters (except sometimes in the U.S.)  Ensure you are working with projected data and not data in decimal degrees since Darren's max distance of 100,000 might be trying to use degrees as input which would probably blow the script up..  Of course, the script formatting is almost impossible to follow so it could be a formatting error.  Copy the contents into a script and run the script... it looks like you pasted the code into an IDE prompt instead

PatrickPrendergast
New Contributor II

Thanks for the suggestions Dan. I projected my points to meters, reran the code, and got the same error. I pasted the code under Rebecca Strauch's comment. I would appreciate any feedback.

Thanks,

Pat

0 Kudos
Jose_AngelCanizares
New Contributor
>>> fc = "HurdatProductARCMAP" # points feature class
... sr = arcpy.Describe("HurdatProductARCMAP").spatialReference # points spatial reference  
... out_buffs =[] # placeholder for wedges
... max = 100000 # distance larger than the maximum wedge
... with arcpy.da.SearchCursor("HurdatProductARCMAP",["SHAPE@","NeMtr","SEMtr","SWMtr","NWMtr"],spatial_reference=sr) as cursor : # loop through points
...     for row in cursor :
...         cur=row[0].centroid # convert point geometry to point object
...         up = arcpy.Point(cur.X,cur.Y+max) # make points from which to make boxes later
...         upright = arcpy.Point(cur.X+max,Cur.Y+max)
...         right = arcpy.Point(cur.X+max,cur.Y)
...         downright = arcpy.Point(cur.X+max,cur.Y-max)
...         down = arcpy.Point(cur.X,cur.Y-max)
...         downleft = arcpy.Point(cur.X-max,cur.Y-max)
...         left = arcpy.Point(cur.X-max,cur.Y)
...         upleft = arcpy.Point(cur.X-max,cur.Y+max)
...         boxes = {"NE":arcpy.Polygon(arcpy.Array([[cur,up,upright,right]]),sr),
...                 "SE":arcpy.Polygon(arcpy.Array([[cur,right,downright,down]]),sr),
...                 "SW":arcpy.Polygon(arcpy.Array([[cur,down,downleft,left]]),sr),
...                 "NW":arcpy.Polygon(arcpy.Array([[cur,left,upleft,up]]),sr)} # make boxes
...         for field in cursor.fields[1:]:# loop throught the fields following the point geometry field
...             cur_buff = row [0].buffer(row[cursor.fields.index(field)] # make a buffer
...             clip_buff = boxes[field[:2]].intersect(cur_buff,4) # clip the buffer by the corresponding box 
...             out_buff.append(clip_buff) # record the wedge
...     arcpy.CopyFeatures_management(out_buffs,r'in_memory\out_buffs') # write the wedges    
...     
Parsing error SyntaxError: invalid syntax (line 22)
>>> 

Hello, I have been trying the code provide but I receive an invalid syntax at line 22 and I don't know what can be. Can anyone take a look? 

Thank you

0 Kudos
DanPatterson_Retired
MVP Emeritus

out_buffs, maybe out_buff

0 Kudos