The code below is a prototype created to determine the speed with which MapSuite can take a starting address, and an array of many addresses, and calculate the driving distance between the starting address, and each of the destination addresses.
The results will be displayed to the user in a web interface indicating how many addresses fall within a certain radius of the starting address. Example UI:
Radius from Address Number of Records
2.5 - 5.0 miles 400
5.0 - 7.5 miles 700
With the code below, we're seeing performance of about 1 second per record. How can this performance be improved to something usable within our web app?
///
/// The function below is used to test the ThinkGeo Geocoder and Route Extension. Purpose of the code is to get
/// get driving distance from one location to another
///
public void TestCode()
{
UsaGeocoder usaGeocoder;
// Assign .shp and .rtg objects
FeatureSource featureSource = new ShapeFileFeatureSource(Server.MapPath(@"\ChicagoRouteData\tl_2009_17031_edges.shp"));
RoutingSource routingSource = new RtgRoutingSource(Server.MapPath(@"\ChicagoRouteData\tl_2009_17031_edges.rtg"));
dataPath = Server.MapPath("~/ChicagoData");
usaGeocoder = new UsaGeocoder(dataPath, MatchMode.ExactMatch);
try
{
featureSource.Open();
routingSource.Open();
addresses.Clear();
SQLDatabase objSQLDatabase = new SQLDatabase(conn);
int found = 0;
int notFound = 0;
SqlParameter[] sqlParam = new SqlParameter[1];
sqlParam[0] = new SqlParameter("@username", txtUserName.Text);
// Open the geocoder
Collection<GeocoderMatch> matchResult;
usaGeocoder.Open();
// Get starting address
DataTable userAddress = objSQLDatabase.GetDataTable(userAddressQuery, CommandType.Text, sqlParam);
SqlParameter[] sqlParam2 = new SqlParameter[1];
sqlParam2[0] = new SqlParameter("@username", txtUserName.Text);
// Get Set of Address. approx 1200 records
DataTable resultSet = objSQLDatabase.GetDataTable(addressQuery, CommandType.Text, sqlParam2);
string startAddress = string.Format("{0}, {1}, {2}, {3}", userAddress.Rows[0]["StreetAddress"].ToString(),
userAddress.Rows[0]["City"].ToString(), userAddress.Rows[0]["State"].ToString(),
userAddress.Rows[0]["Zip"].ToString());
lblStartAddress.Text = startAddress;
matchResult = usaGeocoder.Match(startAddress);
string startLat = "0.0";
string startLon = "0.0";
// Get Lan and Lon for the starting Address
//-----------------------------------------------------------------------------------------
if (!matchResult[0].Ranking.Equals(0))
{
matchItems = matchResult;
if (matchResult[0].NameValuePairs.ContainsKey("FromLatitude") && matchResult[0].NameValuePairs.ContainsKey("FromLongitude"))
{
lblStartCoordinates.Text = matchResult[0].NameValuePairs["FromLatitude"].ToString() + "," + matchResult[0].NameValuePairs["FromLongitude"].ToString();
startLat = matchResult[0].NameValuePairs["FromLatitude"].ToString();
startLon = matchResult[0].NameValuePairs["FromLongitude"].ToString();
}
else
{
lblStartCoordinates.Text = "Not Found";
}
}
//-----------------------------------------------------------------------------------------
// Get Driving Distance
//-----------------------------------------------------------------------------------------
RoutingEngine routingEngine = new RoutingEngine(routingSource, featureSource);
RoutingResult routingResult;
routingEngine.RoutingSource = routingSource; // Assign the spatial or rtg data.
// Loop through the address
foreach (DataRow dr in resultSet.Rows)
{
matchResult = usaGeocoder.Match(string.Format("{0}, {1}, {2}, {3}", dr["StreetAddress"].ToString(),
dr["City"].ToString(), dr["State"].ToString(), dr["Zip"].ToString()));
// Show result in the page
if (!matchResult[0].Ranking.Equals(0))
{
matchItems = matchResult;
if (matchResult[0].NameValuePairs.ContainsKey("FromLatitude") && matchResult[0].NameValuePairs.ContainsKey("FromLongitude"))
{
try
{
routingResult = routingEngine.GetRoute(new PointShape(Double.Parse(startLon), Double.Parse(startLat)),
new PointShape(Double.Parse(matchResult[0].NameValuePairs["FromLongitude"].ToString()),
Double.Parse(matchResult[0].NameValuePairs["FromLatitude"].ToString())));
addresses.Add(new Addresses(string.Format("{0}, {1}, {2}, {3}", dr["StreetAddress"].ToString(),
dr["City"].ToString(), dr["State"].ToString(), dr["Zip"].ToString()),
string.Format(" {0}", (routingResult.Distance * 0.621371192).ToString() + "driving miles")));
found++; // Increment found address
}
catch (Exception)
{
System.Diagnostics.Debug.WriteLine(dr["StreetAddress"].ToString() + "," +
dr["City"].ToString() + "," + dr["State"].ToString() + "," +
dr["Zip"].ToString());
notFound++; // Increment found non address
}
}
else
{
notFound++; // Increment found non address
}
}
else
{
notFound++; // Increment found non address
}
}
//-----------------------------------------------------------------------------------------
//Show Results
lblTotal.Text = resultSet.Rows.Count.ToString();
lblFound.Text = found.ToString();
lblNotFound.Text = notFound.ToString();
var q = (from p in addresses.AsEnumerable()
select p).Take(50);
GridView1.DataSource = q;
GridView1.DataBind();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
usaGeocoder.Close();
featureSource.Close();
routingSource.Close();
}
}