How to bulk geocode addresses in a database
Description
Write an Xbasic script that loops over all data and updates fields for DBF and SQL tables.
The Xbasic function called geocode_address() that allows you to convert addresses to latitude and longitude. See geocode_address Function for a full description. The function does a web service call to accomplish the conversion, which can take a good fraction of a second.
To bulk geocode a table, you could write an Xbasic script that looped over all of the data and updated fields.
Here is an Xbasic loop for .DBF tables:
dim t as p
t = table.open("addresses")
dim pa as p
while .not. t.fetch_eof()
pa = geocode_address(t.address,"Google")
t.change_begin()
t.latitude = pa.lat
t.longitude = pa.lon
t.change_end(.t.)
t.fetch_next()
end while
t.close()For a SQL table, the code is similar in spirit.
dim cn as sql::Connection
flag = cn.open("::Name::<MyConnectionString>")
dim sql as c
'execute a query to get the primary key of each record you want to update
sql = "select id from table1"
cn.Execute(sql)
rs = cn.ResultSet
dim flag as l
'check to see if any rows in resultset
flag = rs.nextRow()
delete args
dim args as sql::Arguments
dim sql1 as c
'this assumes that the address field has the full address --
'if not, modify the sql query appropriately
sql1 = "select address from table1 where id = :primaryKey"
sql2 = "update table1 set latitude = :lat, longitude = :lon where id = :primaryKey"
dim pa as p
dim rs2 as sql::ResultSet
while flag
args.add("primaryKey",rs.data(1))
flag = cn.Execute(sql1,args)
rs2 = cn.ResultSet
pa = geocode_address(rs2.data("address"),"Google")
args.add("Google",pa.lat)
args.add("lat",pa.lon)
flag = cn.execute(sql2,args)
flag = rs.nextRow()
end flagIf you also want to update a Geography field named Location, the sql2 query would change to:
UPDATE table1 SET latitude = :lat, longitude = :lon,
location = GeogCreateLocation(:lon, :lat) WHERE id = :primaryKeyGeogCreateLocation is a Portable SQL function. To make it work in code, you may have to set your connection to use Portable SQL, e.g. cn.PortableSQLEnabled = .t.
Another way to geocode addresses would be to use https://geocoding.geo.census.gov/.