How to Select By Location and Attribute?

5564
6
02-23-2015 11:24 PM
ChittayongSurakitbanharn
New Contributor

Hi,

I have 120 individual data points (each representing a small airport) that I would like to perform the following analysis:

  1. Select a county that the airport is located in and extract a statistic from that county (e.g. income/capita).  Let’s call this County A and the statistic X.
  2. Select another county (let’s call it County B) subjected to the following constraint: County B must be intersected by a circle of the same geodesic radius as the distance between the airport in County A and a central location.
    1. The selection of County B should be based on another given statistic of County B being most similar to County A.  Let’s call this selection criteria statistic Y.  (E.g. If statistic Y is population, I would like to select the county with closest population to County A that is intersected by the circle.)
  3. Extract the names of County A, B as well as statistic X, Y for County A and B to a table.
  4. Repeat for the other rows of data (i.e. the other small airports and central locations they are paired with.)

The image below is an example of one of these situations.  The small green dot towards the right is the airport in consideration, the selected county is County A in this situation.  Thus, County B is the county that is closest to County A for a statistic Y (e.g. most similar in population) and is intersected by the geodesic circle.

2015__02_23-Select_EAS_county.JPG

I believe this is a combination of Selection by Location and Selection by Attribute.  Would Model Builder be the best approach for this problem?

Thanks ahead for the help!

Regards,

Jao

0 Kudos
6 Replies
DanPatterson_Retired
MVP Emeritus

Have to tried this in modelbuilder for one case?  If so you can examine the use of iterators in modelbuilder to automate the workflow.  Examples are available in the help files once you get a single case working.

0 Kudos
ChittayongSurakitbanharn
New Contributor

Hi Dan,

I'm a bit stuck on the modeling for even one case.  The two specific points I'm stuck on for modeling one case is:

  1. How do I select all the county polygons which are intersected by the edge of my circle polygon?
  2. How do I select by attribute based on the most similar value rather than an exact value?

Any suggestions?

0 Kudos
ChittayongSurakitbanharn
New Contributor

I was able to address Point 1, however I'm still uncertain on how to Select By Attribute based on the most similar value rather than an exact value.  Any ideas?

0 Kudos
ChittayongSurakitbanharn
New Contributor

I addressed Point 2 using a Similarity Search tool.  Just need to iterate now.

0 Kudos
forestknutsen1
MVP Regular Contributor

I would use python for something like this:

First in arc I would cut the counties with a intersect and your circle. Using this and your airports as input to the code.

Read the columns of interest into lists (arrays) and then iterate over the lists and do the matching. Then output data to a new table.

SearchCursor http://resources.arcgis.com/en/help/main/10.1/index.html#//018w00000011000000

UpdateCursor ArcGIS Help 10.1

Python tutorial

If you have not used python before this may look very hard at first. But it is not that bad as it is a small code project. I would think the hardest part would be the logic in the matching. That could be harder depending on the complexity of your criteria....

0 Kudos
XanderBakker
Esri Esteemed Contributor

This sounds like fun, so I tried something and this is the result:

county01.png

and this is what the connecting lines look like:

county02.png

This is the code used. Change lines according to your data and needs:

  • 6 input featureclass
  • 7, 8 and 9 the input fields
  • 12 the output connector featureclass
  • 15 the distance for the buffer

import arcpy
import os

def main():
    # inputs
    fc = r"D:\Xander\GeoNet\County\data.gdb\Counties_test"
    fld_id = "GEOID"
    fld_name = "NAME"
    fld_pop = "POP010210D"

    # output for validation
    fc_out = r"D:\Xander\GeoNet\County\data.gdb\connections03"

    # the geodesic distance
    distance = "300000 Meters"

    # internal settings
    ws_mem = "IN_MEMORY"
    arcpy.env.overwriteOutput = True
    sr = arcpy.Describe(fc).spatialReference

    # create featurelayer for selection
    arcpy.MakeFeatureLayer_management(fc, "county_lyr")

    # list to store output conector lines (between counties)
    lst_feats = []

    # start search cursor over counties
    flds = ("SHAPE@", fld_id, fld_name, fld_pop)
    with arcpy.da.SearchCursor(fc, flds) as curs:
        for row in curs:
            polygon = row[0]
            geoid = row[1]
            name = row[2]
            pop = int(row[3])

            # determine label point in input county
            pnt = polygon.labelPoint
            pntg = arcpy.PointGeometry(pnt, sr)

            # buffer label point
            fc_tmp = os.path.join(ws_mem, "tmp_buf")
            arcpy.Buffer_analysis(in_features=pntg, out_feature_class=fc_tmp,
                                  buffer_distance_or_field=distance,
                                  method="GEODESIC")

            # get first feature of buffer
            buf_pol = arcpy.da.SearchCursor(fc_tmp, ("SHAPE@",)).next()[0]
            # boundary = buf_pol.boundary()
            # lst_feats.append(boundary)

            # select by location
            arcpy.SelectLayerByLocation_management("county_lyr", "CROSSED_BY_THE_OUTLINE_OF",
                                                  buf_pol, selection_type="NEW_SELECTION")

            # search selected counties for similar population
            min_dif = 999999
            with arcpy.da.SearchCursor("county_lyr", flds) as curs_s:
                for row_s in curs_s:
                    pnt_s = row_s[0].labelPoint
                    pop2 = int(row_s[3])
                    dif = abs(pop - pop2)
                    if dif < min_dif:
                        # found a county
                        min_dif = dif
                        pop_found = pop2
                        geoid_found = row_s[1]
                        name_found = row_s[2]
                        pnt_found = arcpy.Point(pnt_s.X, pnt_s.Y)

            # create line between two counties
            line = arcpy.Polyline(arcpy.Array([pnt, pnt_found]), sr)
            lst_feats.append(line)

            # print result
            print "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}".format(name, geoid, pop, name_found, geoid_found, pop_found, min_dif)

    # copy line features to output featureclass
    arcpy.CopyFeatures_management(lst_feats, fc_out)


if __name__ == '__main__':
    main()