Now it is easier than before to add all of the location intelligence functions of TransCAD, including routing and geocoding, in any Windows desktop application written in C# or any other .NET programming languages. TransCAD has included the GISDK (Geographical Information Systems Developer Kit) for many years. With the updated GISDK .NET APIs, programming TransCAD in .NET has been simplified.
Firstly, the GISDK Extension Engine API lets you extend the TransCAD desktop application itself by writing in-process extensions in C# or any other .NET language, without the need to learn a new programming language.
Secondly, the GISDK Connection API lets you connect a new or existing .NET stand-alone Windows desktop application to TransCAD out-of-process.
Either way, you can program TransCAD in .NET to build custom applications for the desktop, and analyze and share data generated from a wide range of maps, including those that show demographic trends, population density, and sales potential.
Whether you use the in-process extension API or the out-of-process connection API, you can access more than 850 GIS functions. These functions include:
While the GISDK provides a rich set of geo-processing APIs, the TransCAD country packages installed on the user computer include all the geographic data needed by the application. So TransCAD and the GISDK are well-suited for offline usage. No network connectivity is required for the API functionality.
When you redistribute applications that you have developed using TransCAD, make sure that the target machines have TransCAD installed as well. Also, note that the TransCAD desktop licensing model prevents you from developing web-based applications.
Below are some C# examples. The order in which they are listed is the order of difficulty.
The following example shows how to open a map and list its contents.
using System;
using System.Collections.Generic;
using System.Text;
using CaliperForm;
///
/// Open a map in the tutorial folder, and list its content.
///
static void Open_Map() {
CaliperForm.Connection Conn = new CaliperForm.Connection { MappingServer = "TransCAD" };
Boolean opened = false;
try {
opened = Conn.Open();
if (opened) {
// You must declare dk as "dynamic" or the compiler will throw an error
dynamic dk = Conn.Gisdk;
string tutorial_folder = dk.Macro("G30 Tutorial Folder") as string;
// Obtain information about Conn: an array of
// [ "program_path" , "program name" , "program type" ,
// build number (integer) , version number (real) , instance number ]
Object[] program_info = dk.GetProgram();
string program_name = program_info[1] as string;
int build_number = (int)program_info[3];
double version_number = (double)program_info[4];
// Set the path that will be used to look for layers used in map files
string search_path = "c:\\ccdata\\USA (HERE) - 2013 Quarter 4;d:\\ccdata";
dk.SetSearchPath(search_path);
// Open a map file in the tutorial folder
string map_file = tutorial_folder + "BestRout.map";
var map_options = new OptionsArray(); // you can also use Dictionary or Hashtable
map_options["Auto Project"] = "true";
string data_directory = System.IO.Path.GetDirectoryName(map_file);
map_options["Force Directory"] = data_directory; // path used to look for layers used in the map
string map_name = dk.OpenMap(map_file, map_options) as string;
if (map_name == null) {
Console.Out.WriteLine("Cannot open map " + map_file + ". Perhaps some layers cannot be found?");
return;
} else {
Console.Out.WriteLine("map_name = " + map_name);
}
// Set the current layer
dk.SetLayer("County");
// Get information about the list of layers contained in this map
dynamic layers = dk.GetMapLayers(map_name, "All");
dynamic layer_names = layers[0];
int current_idx = (int)layers[1];
string current_layer = layers[2] as string;
dk.CloseMap(map_name);
Conn.Close();
}
} catch (System.Exception error) {
Console.Out.WriteLine(error.Message);
}
}
The following example shows how to open a table and select some records by an SQL-like expression.
using System;
using System.Collections.Generic;
using System.Text;
using CaliperForm;
///
/// Open a table in the tutorial folder, and select some rows by an SQL-like expression
///
static void Open_Table() {
CaliperForm.Connection Conn = new CaliperForm.Connection { MappingServer = "TransCAD" };
Boolean opened = false;
try {
opened = Conn.Open();
if (opened) {
// You must declare dk as "dynamic" or the compiler will throw an error
dynamic dk = Conn.Gisdk;
string tutorial_folder = dk.Macro("G30 Tutorial Folder") as string;
// Open a table
string table_name = dk.OpenTable("sales", "ffb", new Object[] { tutorial_folder + "ctsales.bin", null });
object[] fields = dk.GetFields(table_name, "All");
var field_names = fields[0] as object[];
var field_specs = fields[1] as object[];
// select some records and get record values
dk.SetView(table_name);
int num_rows = dk.GetRecordCount(table_name, null);
string query = "select * where Population > 200000";
int num_found = dk.SelectByQuery("large towns", "several", query, new Object[] { new Object[] { "Index Limit", 0 } });
if (num_found > 0) {
string view_set = table_name + "|large towns";
object[] sort_order = null;
object[] options = null;
string order = "Row";
string first_record = dk.GetFirstRecord(view_set, null);
Console.Out.WriteLine(query);
Console.Out.WriteLine(string.Join(",", field_names));
foreach (object[] row in dk.GetRecordsValues(view_set, first_record, field_names, sort_order, num_found, order, null)) {
string row_values = string.Join(",", row);
Console.Out.WriteLine(row_values);
}
}
dk.CloseView(table_name);
Console.Out.WriteLine();
Conn.Close();
}
} catch (System.Exception error) {
Console.Out.WriteLine(error.Message);
}
}
The following example shows how to geocode a street address.
using System;
using System.Collections.Generic;
using System.Text;
using CaliperForm;
///
/// Geocode a street address in the current region.
///
static void Geocode_Street_Address() {
CaliperForm.Connection Conn = new CaliperForm.Connection { MappingServer = "TransCAD" };
Boolean opened = false;
try {
opened = Conn.Open();
if (opened) {
// You must declare dk as "dynamic" or the compiler will throw an error
dynamic dk = Conn.Gisdk;
string tutorial_folder = dk.Macro("G30 Tutorial Folder") as string;
// geocode an address
dynamic located_coord = null;
string street_layer_db = null;
dynamic finder = dk.CreateObject("Data.Finder");
finder.SetRegion();
string region_name = finder.GetRegionName();
// Change the address to be in the current region
var args = new OptionsArray();
args["address"] = "200 Beacon Street";
args["city"] = "Boston MA";
args["silent"] = true;
Dictionary result = Cast.ToDictionary(finder.Find("ADDRESS", args));
// If Success:
// result = {"Coord": coord object, ...}
// If Failure:
// result = {"Error": true, "Message": error message }
if (result != null) {
foreach (string key in result.Keys) {
Console.Out.WriteLine(key + " = " + Convert.ToString(result[key]));
}
var coord = result["Coord"] as dynamic;
if (coord != null) {
// Success: convert output lat,lon to doubles
double lon = ((double)coord.Lon) / 1000000;
double lat = ((double)coord.Lat) / 1000000;
located_coord = coord;
street_layer_db = result["StreetLayer"] as string;
Console.Out.WriteLine("Address: " + result["Address"] as string + ", Location: " + lat + "," + lon);
} else {
// Failure, report error message
var has_errors = result["Error"];
var error_message = result["Message"] as string;
Console.Out.WriteLine("Error: " + has_errors as string + ", Message: " + error_message);
}
}
Console.Out.WriteLine();
Conn.Close();
}
} catch (System.Exception error) {
Console.Out.WriteLine(error.Message);
}
}
The following example shows how to use a table of street addresses to locate records from a table or spreadsheet.
using System;
using System.Collections.Generic;
using System.Text;
using CaliperForm;
///
/// Geocode a table of street addresses and produce a geographic layer that can be added to a map.
///
static void Geocode_Table() {
CaliperForm.Connection Conn = new CaliperForm.Connection { MappingServer = "TransCAD" };
Boolean opened = false;
try {
opened = Conn.Open();
if (opened) {
// You must declare dk as "dynamic" or the compiler will throw an error
dynamic dk = Conn.Gisdk;
string tutorial_folder = dk.Macro("G30 Tutorial Folder") as string;
string excel_file = tutorial_folder + "Sample Customers United States.xls";
if (!System.IO.File.Exists(excel_file)) {
Console.Out.WriteLine("Cannot find tutorial example file: " + excel_file);
return;
}
string sheet_name = "My Customers$";
string binary_table = tutorial_folder + "My Example Customers.bin";
string exported_table = dk.Macro("G30 export an Excel sheet", excel_file, sheet_name, binary_table) as string;
if (exported_table != null) {
Console.Out.WriteLine("Exported Excel file: " + excel_file + " to: " + exported_table);
dynamic geo = dk.CreateObject("Data.Geocoder");
geo.SetRegion();
string region_name = geo.GetRegionName();
// Open the exported table
string table_name = dk.OpenTable("customers", "ffb", new Object[] { exported_table , null });
int num_records = dk.GetRecordCount(table_name, null);
Console.Out.WriteLine("Locating " + Convert.ToString(num_records) +
" records in table " + table_name + " in region " + region_name + "...");
// Get the input field specifications
var id_field = dk.GetFieldFullSpec(table_name, "Customer ID") as string;
var address_field = dk.GetFieldFullSpec(table_name, "Street Address") as string;
var postal_field = dk.GetFieldFullSpec(table_name, "ZIP Code") as string;
var city_field = dk.GetFieldFullSpec(table_name,"City") as string;
var state_field = dk.GetFieldFullSpec(table_name, "State") as string;
string output_layer_db = tutorial_folder + "Located Customers.dbd";
var opts = new OptionsArray();
opts["new_layer_name"] = "Located Customers";
opts["out_db"] = output_layer_db;
// First, locate records by street address and postal code, and save the result to "Located Customers.dbd"
// input_fields = { address_field , address_field_2 , postal_code_field , city_field_or_value , state_field_or_value }
object[] input_fields = new object[] { address_field, null, postal_field };
Dictionary result = Cast.ToDictionary(geo.LocateView("ADDRESS", table_name + "|", id_field, input_fields, opts));
// if success:
// result = {"Message":"OK","NotFoundSet":"Address Not Found",
// "LayerName":"Located Customers","NumRecords":4800,
// "NumLocated":..., "OutputLayer":...,"GeocodingLayer":...}
// else:
// result = {"Message":"Error Message","Error":1}
if ((result != null) && (result["LayerName"] as string != null) && (result["NotFoundSet"] as string != null)) {
// Then, locate the records not found by postal code
string not_found_set = result["NotFoundSet"] as string;
string layer_name = result["LayerName"] as string;
int num_not_found = dk.GetRecordCount(layer_name, not_found_set);
string street_layer_db = result["GeocodingLayer"] as string;
Console.Out.WriteLine(Convert.ToString(num_not_found) +
" records not found by street address using street layer " + street_layer_db);
id_field = dk.GetFieldFullSpec(layer_name, "ID") as string;
postal_field = dk.GetFieldFullSpec(layer_name, "ZIP Code") as string;
input_fields = new object[] { postal_field };
result = Cast.ToDictionary(geo.LocateView("POSTAL_CODE", layer_name + "|" + not_found_set, id_field, input_fields, null));
var located_by_postal_code = (int) result["NumLocated"];
string postal_layer_db = result["GeocodingLayer"] as string;
Console.Out.WriteLine(Convert.ToString(located_by_postal_code) +
" records located by postal code using postal code layer " + postal_layer_db);
}
if (System.IO.File.Exists(output_layer_db)) {
Console.Out.WriteLine("Stored output geographic layer to: " + output_layer_db);
}
}
Conn.Close();
}
} catch (System.Exception error) {
Console.Out.WriteLine(error.Message);
}
}
The following example shows how to use select all of the point features on a map that are within a circle about a specific coordinate.
using System;
using System.Collections.Generic;
using System.Text;
using CaliperForm;
///
/// Select all landmark point features in a circle near a specific geographic coordinate.
///
static void Find_Nearest_Features() {
CaliperForm.Connection Conn = new CaliperForm.Connection { MappingServer = "TransCAD" };
Boolean opened = false;
try {
opened = Conn.Open();
if (opened) {
dynamic dk = Conn.Gisdk;
// Locate by radius landmark points near located_coord
dynamic located_coord = dk.Coord((int) (-71.071359 * 1000000.0) , (int)( 42.353844 * 1000000.0)); // Downtown Boston
Dictionary region_prefs = Cast.ToDictionary(dk.Macro("Get Geocoding Preferences"));
if (region_prefs == null) {
Console.Out.WriteLine("Macro 'Get Geocoding Preferences' returned null");
Conn.Close();
return;
}
string region_file = region_prefs["region_file"] as string;
if (region_file != null) {
string data_directory = System.IO.Path.GetDirectoryName(region_file);
string map_wizard_map_file = data_directory + "\\Map Wizard Maps\\MapWizardUSMap.map";
// Open the map wizard map witht the layers for this country package
var map_options = new OptionsArray();
map_options["Auto Project"] = "true";
// path used to look for layers used in the map, before other locations usually searched for
map_options["Force Directory"] = data_directory;
string map_name = dk.OpenMap(map_wizard_map_file, map_options);
if (map_name == null) {
Console.Out.WriteLine("Cannot open map wizard map file " + map_wizard_map_file +
". Perhaps some layers are missing?");
Conn.Close();
return;
}
var search_area = dk.Circle(located_coord, (double)1.0); // 3 Current Map Units (Mile, Kilometers,...)
string layer_name = "Landmark";
dk.SetLayer(layer_name);
var opts = new OptionsArray();
opts["Inclusion"] = "Intersecting";
opts["Max"] = 50;
opts["Display"] = "False";
opts["Auto Redraw"] = "False";
int n_found = dk.SelectByCircle("Near Coordinate", "several", search_area, opts);
if (n_found > 0) {
string view_set = layer_name + "|Near Coordinate";
object[] fields = dk.GetFields(layer_name, "All");
var field_names = fields[0] as object[];
var field_specs = fields[1] as object[];
object[] sort_order = null;
object[] options = null;
string order = "Row";
string first_record = dk.GetFirstRecord(view_set, null);
string query = Convert.ToString(n_found) + " " + layer_name + " Features Near Coordinate: " +
Convert.ToString((double) located_coord.Lat / 1000000.00) + "," +
Convert.ToString((double) located_coord.Lon / 1000000.00) ;
Console.Out.WriteLine(query);
Console.Out.WriteLine(string.Join(",", field_names));
object[] cells;
foreach (object row in dk.GetRecordsValues(view_set, first_record, field_names, sort_order, n_found, order, null)) {
cells = row as object[];
if (cells != null) {
string row_values = string.Join(",", cells);
Console.Out.WriteLine(row_values);
}
}
} else {
Console.Out.WriteLine("No " + layer_name + " Features Found Near Address.");
}
}
Conn.Close();
}
} catch (System.Exception error) {
Console.Out.WriteLine(error.Message);
}
}
The following example shows how to use travel times to find a best route between two addresses.
using System;
using System.Collections.Generic;
using System.Text;
using CaliperForm;
///
/// Calculate the fastest route between 2 addresses
///
static void Calculate_Route()
{
CaliperForm.Connection Conn = new CaliperForm.Connection { MappingServer = "TransCAD" };
Boolean opened = false;
try
{
opened = Conn.Open();
if (opened)
{
// You must declare dk as "dynamic" or the compiler will throw an error
dynamic dk = Conn.Gisdk;
OptionsArray region_prefs = new OptionsArray(dk.Macro("Get Geocoding Preferences"));
if (!region_prefs.ContainsKey("region_file")) {
Console.Out.WriteLine("Region File missing from 'Get Geocoding Preferences'");
Conn.Close();
return;
}
string region_file = region_prefs["region_file"] as string;
string map_wizard_map_file = System.IO.Path.GetDirectoryName(region_file) +
"\\Map Wizard Maps\\MapWizardUSMap.map";
// Open the map wizard map witht the layers for this country package
var map_options = new OptionsArray();
map_options["Auto Project"] = "true";
// path used to look for layers used in the map, before other locations usually searched for
map_options["Force Directory"] = data_directory;
string map_name = dk.OpenMap(map_wizard_map_file, map_options);
if (map_name == null) {
Console.Out.WriteLine("Cannot open map wizard map file " + map_wizard_map_file
+ ". Perhaps some layers are missing?");
Conn.Close();
return;
}
// geocode an address
dynamic finder = dk.CreateObject("Data.Finder");
finder.SetRegion();
var args = new OptionsArray();
args["silent"] = true;
args["address"] = "200 Beacon Street";
args["city"] = "Boston MA";
var found_origin = new OptionsArray(finder.Find("ADDRESS", args));
args["address"] = "100 Seaport Blvd";
var found_destination = new OptionsArray(finder.Find("ADDRESS", args));
if (found_origin["Coord"] == null || found_destination["Coord"] == null) {
Console.Out.WriteLine("Unable to locate origin or destination address.");
Conn.Close();
return;
}
//Calculate path using the Routing API
var router = dk.CreateObject("Routing.Router");
router.Minimize = "Time";
var options = new OptionsArray();
string xml_directions_file = dk.Macro("G30 Tutorial Folder") + "Example Directions.xml";
options["Directions"] = xml_directions_file;
options["DirectionsField"] = "NAME";
options["StopDescriptions"] = new string[] { "100 Beacon St" , "200 Seaport Blvd" };
dynamic path = router.CalculatePath(found_origin["Coord"], found_destination["Coord"],options);
if (path == null) {
Console.Out.WriteLine("Router error: {0}", router.ErrorMessage);
Conn.Close();
return;
}
Console.Out.WriteLine("Shortest Travel Time Path between two addresses: {0:F2} minutes.", path.Value);
//add annotation
var annotationOpts = new OptionsArray();
annotationOpts["Points"] = path.Coords;
annotationOpts["Line Color"] = dk.ColorRGB(65535, 32768, 0);
object[] lineStyles = dk.Macro("G30 setup line styles");
annotationOpts["Line Style"] = lineStyles[1];
annotationOpts["Line Width"] = 8;
dk.AddAnnotation("Map|" + map_name, "Polyline", annotationOpts);
//calculate scope from path points
dynamic scope = dk.GetArrayScope(path.Coords);
//back up a little
scope.Width = scope.Width * 1.05;
scope.Height = scope.Height * 1.05;
//zoom map to scope of path
dk.SetMapScope(map_name, scope);
dk.RedrawMap(map_name);
// Dump the directions to the standard output
if (System.IO.File.Exists(xml_directions_file)) {
Console.Out.WriteLine("XML Turn by Turn Directions:");
Console.Out.WriteLine(System.IO.File.ReadAllText(xml_directions_file));
}
Conn.Close();
}
}
catch (System.Exception error)
{
Console.Out.WriteLine(error.Message);
}
}
Home | Products | Contact | Secure Store