Address, buffer, select

1046
11
Jump to solution
03-23-2020 09:04 AM
jaykapalczynski
Frequent Contributor

I am looking for the best way to eventually publish a GP tool that will accept an address, geocode the address, buffer the location X amount of distance and then select all the features it intersects.  Resulting in a list of intersected features.

Any examples?  

0 Kudos
1 Solution

Accepted Solutions
jaykapalczynski
Frequent Contributor

Well here is the final result.....and I will try and explain what is going on.....

Right now its set up to grab a few parameters that are going to be passed to it once it is published as a Rest Endpoint service....I have those 3 parameters hardcoded for testing purposes (address, distance, and unique ID)

# PARAMETERS PASSED FROM CALL TO THE SERVICE
searchAddress = "86 Rockland Street West Davenport, NY 13860"
searchDistance = 20
searchid = "123"

The script takes the address and geocodes it to get XY

The XY are then used to create a temp Buffer at the user specified distance

this buffer is then used to select counties that INTERSECT it 

this returned data is then packaged up to be send back to the requester...

Any questions please feel free to ask.....

THANK YOU ALL FOR YOUR HELP

OH one more thing....I was tripping up on the spatial reference....my Counties were in UTM and the XY being returned from the Geocode was Decimal Degrees....it could never find anything in the spatial select.  Knowing that my data was in UTM I made sure that I set the output of the Geocode result to UTM as well

def singleAdressGeocode(address, geoCodeUrl, outSR = "26917"):

Last thing my data was also in meters so when the Miles were sent as parameters from the requester I had to convert those to meters to feed the buffer parameters

searchDistance = 20
searchid = "123"

# CONVERT MILE TO METERS FOR SPATIAL BUFFER
distanceMeters = searchDistance * 1609.34

FINAL CODE

import arcpy
import requests

# PARAMETERS PASSED FROM CALL TO THE SERVICE
searchAddress = "86 Rockland Street West Davenport, NY 13860"
searchDistance = 20
searchid = "123"

# GEOCODERS
# esri geocoding service
geoCodeUrl = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"

# CONVERT MILE TO METERS FOR SPATIAL BUFFER
distanceMeters = searchDistance * 1609.34

# SEARCH PARAMETERS
print " - SEARCH PARAMETERS -"
print "search address: " + searchAddress
print "passed unique ID : " + searchid
print "search miles: " + str(searchDistance)
print "search meters: " + str(distanceMeters)
print ""
print "-------------------"

# LOCAL VARIABLES
coordinates = ""
countList = []   
countyField = "FIPS2"  
countList2 = []
finalList = []
txt_list = ""
txt_list2 = ""

def singleAdressGeocode(address, geoCodeUrl, outSR = "26917"):
  ##clean up the address for url encoding
  address = address.replace(" ", "+")
  address = address.replace(",", "%3B")

  #send address to geocode service
  lookup = requests.get(geoCodeUrl + "?SingleLine=" + address + "&outSR=" + outSR + "&maxLocations=1&f=pjson")

  data = lookup.json()
  
  if data["candidates"]:
    ##coords = data["candidates"][0]["location"]
    ##return coords
    return data
  else:
    ##no results
    return "Address not geocoded: " + address


# DEFINE VARIABLES FOR THE ADDRESS AND X AND Y VALUES
geocodeResult = singleAdressGeocode(searchAddress, geoCodeUrl)
addressResult = geocodeResult["candidates"][0]["address"]
coordinateX = geocodeResult["candidates"][0]["location"]["x"]
coordinateY = geocodeResult["candidates"][0]["location"]["y"]
strcoordinateX = str(coordinateX)
strcoordinateY = str(coordinateY)


print "gecode result: " + str(geocodeResult)
print "-------------------"
print "geocoded address: " + addressResult
print "-------------------"
print "X coordinate: " + str(coordinateX)
print "-------------------"
print "Y coordinate: " + str(coordinateY)
print "-------------------"

# CREATE THE POINT FROM THE X AND Y
point = arcpy.Point(coordinateX, coordinateY)
ptGeometry = arcpy.PointGeometry(point)

# FEED THE BUFFER ANALYSIS THE POINT GEOMETRY THE DISTANCE PARAMETERS
arcpy.Buffer_analysis(ptGeometry, 'IN_MEMORY/BufferGeom', distanceMeters)

arcpy.env.workspace = "C:\Work\CountySelection\Data\SelectCounties.gdb"
arcpy.MakeFeatureLayer_management('CountiesDissolved', 'counties_lyr')

results = arcpy.SelectLayerByLocation_management('counties_lyr', 'INTERSECT', 'IN_MEMORY/BufferGeom')

# GET THE FIPS CODES
rows = arcpy.SearchCursor(results,"","","FIPS2")
for row in rows:  
 neighborVal = str(row.FIPS2)  
 #print(neighborVal)  
 countList.append(neighborVal)  
 txt_list = ','.join(countList)
print "FIPS codes: " + str(txt_list)
print "-------------------"

# GET THE JURIS NAME
rows2 = arcpy.SearchCursor(results,"","","FIRST_JURI")
for row in rows2:  
 neighborVal2 = str(row.FIRST_JURI)  
 #print(neighborVal)  
 countList2.append(neighborVal2)  
 txt_list2 = ','.join(countList2)
print "County Name: " + str(txt_list2)
print "-------------------"

# GET BOTH THE FIPS AND JURIS NAME
fields = ['FIPS2', 'FIRST_JURI']
with arcpy.da.SearchCursor(results, fields) as cursor:
    for row in cursor:
        finalList.append('[{0}-{1}]'.format(row[0], row[1]))
        #print('{0}, {1}'.format(row[0], row[1]))
print "[" + "[" + strcoordinateX + "]," + "[" + strcoordinateY + "]," + "[" + str(searchDistance) + "]," + "[" + searchid + "]," + "[" + txt_list + "]," + "[" + txt_list2 + "], [" + str(finalList) + "] ]"
print "-------------------"


# GET THE COUNT OF THE RETURNED VALUES    
# If features matched criteria write them to a new feature class
matchcount = int(arcpy.GetCount_management('counties_lyr')[0]) 
if matchcount == 0:
    print('no features matched spatial and attribute criteria')
else:
    print('{0} counties were located within {1} miles of your location'.format(
                                                  matchcount, searchDistance))
print "-------------------"
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

0 Kudos
11 Replies
JakeSkinner
Esri Esteemed Contributor

Hey Jay,

Take a look at the Public Notification widget:

Public Notification widget—Web AppBuilder for ArcGIS | Documentation 

You have the option to write the result to a CSV.

0 Kudos
jaykapalczynski
Frequent Contributor

could I stand this up and then call it from .Net C#, passing it an address and buffer distance and get a JSON list back?

0 Kudos
jaykapalczynski
Frequent Contributor

this is one cog in a larger wheel here and need to do this grammatically, which is why I am asking if I can call it, pass parameters, and get JSON back....this is the workflow that I need

0 Kudos
jaykapalczynski
Frequent Contributor

OK its really easy to Geocode an address I send to a python script...which yeilds an XY coordinate.

I am now looking at the Buffer analysis and it appears that I have to input a Feature Class.....Is there a way that I can pass it XY coordinates instead.  I am not finding a reason to create a FC....

I want to Take an XY and create a Temp Buffer and select features from another FC without creating a Point Feature and a Buffer Feature.....Can I do this with temp features?  Or do I have to create a point in a FC when its goecoded, then create a buffer FC from that point FC, then select the features from another FC and get a list of unique IDs.

Only to have to delete the point FC and Buffer FC everything I run the python script

0 Kudos
JakeSkinner
Esri Esteemed Contributor

You could create a point geometry from the XY coordinate, and then create an IN_MEMORY output for the buffer:

point = arcpy.Point(35.723, -75.706)
ptGeometry = arcpy.PointGeometry(point)

arcpy.Buffer_analysis(ptGeometry, "IN_MEMORY/BufferGeom", "100 Feet")
jaykapalczynski
Frequent Contributor

This is what I have right now.....and it is working...ALTHOUGH I am using my own buffer FC....I still have not figure out how to use the in memory buffer:

arcpy.Buffer_analysis(ptGeometry, "IN_MEMORY/BufferGeom", "50 miles")

I am returning the correct number of results with my fake buffer FC so thats good....I just need to figure out how to implement the in memory buffer that I am trying to create.

I try and add the testBuffer instead of the direct call to my buffer FC....to this but it errors out....

testBuffer = arcpy.Buffer_analysis(ptGeometry, "IN_MEMORY/BufferGeom", "50 miles")

Successful in using FC buffer  

finalResults = arcpy.SelectLayerByLocation_management('counties_lyr', 'INTERSECT', 'buffer_1')

Trying to Use IN memory buffer

finalResults = arcpy.SelectLayerByLocation_management('counties_lyr', 'INTERSECT', 'testBuffer')

import arcpy
import requests
geoCodeUrl = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"

searchAddress = "1520 split oak ln, Henrico, VA 23229"
searchDistance = "50"
coordinates = ""

def singleAdressGeocode(address, geoCodeUrl, outSR = "4326"):
  #clean up the address for url encoding
  address = address.replace(" ", "+")
  address = address.replace(",", "%3B")

  #send address to geocode service
  lookup = requests.get(geoCodeUrl + "?SingleLine=" + address + "&outSR=" + outSR + "&maxLocations=1&f=pjson")
  data = lookup.json()
  
  if data["candidates"]:
    #coords = data["candidates"][0]["location"]
    #return coords
    return data
  else:
    #no results
    return "Address not geocoded: " + address


# DEFINE VARIABLES FOR THE ADDRESS AND X AND Y VALUES
#print singleAdressGeocode("1520 split oak ln, Henrico, VA 23229", geoCodeUrl)
geocodeResult = singleAdressGeocode(searchAddress, geoCodeUrl)
addressResult = geocodeResult["candidates"][0]["address"]
coordinateX = geocodeResult["candidates"][0]["location"]["x"]
coordinateY = geocodeResult["candidates"][0]["location"]["y"]

print geocodeResult
print addressResult
print coordinateX
print coordinateY

# CREATE THE POINT FROM THE X AND Y
#point = arcpy.Point(35.723, -75.706)
point = arcpy.Point(coordinateY,coordinateX)
ptGeometry = arcpy.PointGeometry(point)
searchdistancevar = searchDistance + " miles"

print point
print searchdistancevar

# FEED THE BUFFER ANALYSIS THE POINT GEOMETRY THE DISTANCE PARAMETERS
testBuffer = arcpy.Buffer_analysis(ptGeometry, "IN_MEMORY/BufferGeom", "50 miles")

arcpy.env.workspace = "C:/Users/SelectCounties.gdb"
arcpy.MakeFeatureLayer_management('Counties', 'counties_lyr') 
finalResults = arcpy.SelectLayerByLocation_management('counties_lyr', 'INTERSECT', 'buffer_1')

# If features matched criteria write them to a new feature class
matchcount = int(arcpy.GetCount_management('counties_lyr')[0]) 
if matchcount == 0:
    print('no features matched spatial and attribute criteria')
else:
    print('{0} counties that matched criteria written to {0}'.format(
                                                  matchcount))



‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
JakeSkinner
Esri Esteemed Contributor

Here is an example on how to call the in memory buffer:

finalResults = arcpy.SelectLayerByLocation_management('counties_lyr', 'INTERSECT', 'IN_MEMORY/BufferGeom')
jaykapalczynski
Frequent Contributor

Thanks....although something is not right....below is what I am doing....

If I use the FC buffer (comment out below I get 23 features returned)

If I use the IN memory Buffer I get 0 and the 'no features matched spatial and attribute criteria'

Can you see anything I am doing wrong?

point = arcpy.Point(37.723, -77.706)
ptGeometry = arcpy.PointGeometry(point)

arcpy.Buffer_analysis(ptGeometry, "IN_MEMORY/BufferGeom", "50 miles")

arcpy.env.workspace = "C:/Users/Data/SelectCounties.gdb"

arcpy.MakeFeatureLayer_management('CountiesJurisdictions', 'counties_lyr')

# USING FC BUFFER
#results = arcpy.SelectLayerByLocation_management('counties_lyr', 'INTERSECT', 'buffer')

# USING IN MEMORY BUFFER
results = arcpy.SelectLayerByLocation_management('counties_lyr', 'INTERSECT', 'IN_MEMORY/BufferGeom')

# GET THE COUNT OF THE RETURNED VALUES    
# If features matched criteria write them to a new feature class
matchcount = int(arcpy.GetCount_management('counties_lyr')[0]) 
if matchcount == 0:
    print('no features matched spatial and attribute criteria')
else:
    print('{0} counties that matched criteria written to {0}'.format(
                                                  matchcount))
0 Kudos
jaykapalczynski
Frequent Contributor

I've tried the below.....got rid of the " " and replaced with ' ' which I believe is the proper syntax....BUT still nothing...

arcpy.Buffer_analysis(ptGeometry, 'IN_MEMORY/BufferGeom', '50 miles')

arcpy.Buffer_analysis(ptGeometry, 'IN_MEMORY/BufferGeom', '50')

Maybe a spatial reference issue?  I think the County Layer its trying to select from is in UTM....going to project it to decimal degrees and see if that works?

0 Kudos