2

Problem description:

I have two layers: 1) [Polygon] city blocks, and 2) [Point] the city center. The City blocks layer has 110,681 records. And The city center layer has just one record because there is only one city center in this city.

arcpy.SelectLayerByLocation_management("CityBlocks","WITHIN_A_DISTANCE","CityCenter","1 Kilometers","ADD_TO_SELECTION")

The code above selects census blocks that are 1 kilometer away from the city center in ArcMap.

Question:

Now, I have to add a field called "ring" onto the city blocks layer. And, I have to write a code that does:

ring = 1 if city blocks are 1km away from the city center.
ring = 2 if city blocks are in the ring of 1km to 2km from the city center.
ring = 3 if city blocks are in the ring of 2km to 3km from the city center.
...
It stops if there are no city blocks in the ring of (N-1)km to (N)km from the center.

How do we write a code for that selection process using arcpy?

Thanks a ton in advance!

6
  • I think you should focus this question on ArcGIS for Desktop and ask separate questions for PySal and QGIS if they are your preferred software.
    – PolyGeo
    Oct 30, 2013 at 12:58
  • Do you want a higher ring value to outweigh lower ones or vice versa? Because if you have square city blocks and circle buffers from the city center, some blocks will have multiple rings going through them.
    – Baltok
    Oct 30, 2013 at 13:23
  • @Baltok. Right. We can pick blocks completely within the 1st circle. Then, the 1st donut takes the blocks that have the boundary of the 1st circle and the blocks completely within the donut. And this applies to the remaining rings.
    – Bill TP
    Oct 30, 2013 at 13:41
  • Huh? I'm talking about what final value do you want placed in your "ring" field. E.g., if a city block falls within ring 1 & ring 2, what value should get priority, or overwrite the other?
    – Baltok
    Oct 30, 2013 at 13:48
  • I think it's ring 2..?? I think I don't fully understand what you're talking about.
    – Bill TP
    Oct 30, 2013 at 14:37

1 Answer 1

1

Something like this should work for what you are trying to get at or get you close at least. A few things to keep in mind:

  • This expects the ring field on CityBlocks to a numeric type (long, short, float, etc), and it's empty (NULL).
  • This won't find the blocks that are completely within N km. It looks for blocks that are at least partially within N km.
  • If a block is only partially within N km, ring will be set to N, not N+1
  • I set this up for layers that are in a FGDB. You'll need to change the select by attribute syntax slightly if you have shapefiles.

    ring = 1    
    while(True):
        # Select all of the blocks within <ring> km
        arcpy.SelectLayerByLocation_management("CityBlocks","WITHIN_A_DISTANCE",
                                               "CityCenter",
                                               "{0} Kilometers".format(ring),
                                               "NEW_SELECTION")
        # remove the blocks that already have a value for ring
        arcpy.SelectLayerByAttribute_management("CityBlocks","REMOVE_FROM_SELECTION",
                                                '"ring" IS NOT NULL')
        # How many blocks are selcted?
        count = int(arcpy.GetCount_management("CityBlocks").getOutput(0))
        if count == 0: break # Nothing selected, so exit the while loop
        # Set the value of ring (only on selected records)
        arcpy.CalculateField_management("CityBlocks","ring",str(ring),
                                        "PYTHON_9.3")
        ring += 1
    
3
  • It does not do the job so far. I think the first part of the code does not produce the "ring" variable, so '"ring" IS NOT NULL' produces an error. I will continue to test it.
    – Bill TP
    Oct 31, 2013 at 18:59
  • Another thing: I had to MakeFeatureLayer_management(CityBlocks, "CityBlocks_layer") first. Then, the SelectLayerByLocation_management("CityBlocks_layer", ...) works.
    – Bill TP
    Oct 31, 2013 at 19:01
  • @BillTP Exactly, in the bullet list I said that I expected the ring field to already exist. If it doesn't already you can add it easily with arcpy.AddField_management. Also, you are correct in that SelectLayerByLocation requires a feature layer instead of a feature class. Oct 31, 2013 at 19:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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