User Tools

Site Tools


source_code_routing_index_generator_cs_100325.zip

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
source_code_routing_index_generator_cs_100325.zip [2015/08/20 03:08]
127.0.0.1 external edit
source_code_routing_index_generator_cs_100325.zip [2016/11/30 21:20] (current)
ryanduan Updated source code for RoutingIndexGenerator sample
Line 1: Line 1:
-====== ​Source_Code_Routing_Index_Generator_CS_100325.zip ======+====== ​Source Code Routing Index Generator.zip ======
  
-<​noinclude>​{{article rating}}</​noinclude>​ 
 ====RoutingIndexGenerator.cs==== ====RoutingIndexGenerator.cs====
-^ Code ^ 
-| <source lang="​csharp"​ line="​1"> ​ \\  \\ using System; ​ \\ using System.Collections.ObjectModel; ​ \\ using System.IO; ​ \\ using System.Linq; ​ \\ using System.Threading.Tasks; ​ \\ using System.Windows.Forms; ​ \\ using RoutingIndexGenerator.Properties; ​ \\ using ThinkGeo.MapSuite.Core; ​ \\ using ThinkGeo.MapSuite.Routing; ​ \\  \\ namespace RoutingIndexGenerator ​ \\ {  \\     ​public partial class RoutingIndexGenerator : Form  \\     ​{ ​ \\         ​private bool isBuildingRtgFile; ​ \\         ​private RoutingIndexFileBuilder builder; ​ \\         ​private BuildRoutingIndexParameters buildRoutingIndexParameters; ​ \\  \\         ​public RoutingIndexGenerator() ​ \\         ​{ ​ \\             ​InitializeComponent(); ​ \\  \\             <​nowiki>//</​nowiki>​initialization parameters. ​ \\             ​buildRoutingIndexParameters = new BuildRoutingIndexParameters(); ​ \\  \\             <​nowiki>//</​nowiki>​read the options for parameter and refresh the Uis  \\             ​cmbGeographyUnit.SelectedIndex = (int)buildRoutingIndexParameters.GeographyUnit; ​ \\             ​cmbDistanceUnit.SelectedIndex = (int)buildRoutingIndexParameters.DistanceUnit; ​ \\             ​cmbRouteIndexType.SelectedIndex = (int)buildRoutingIndexParameters.RouteIndexType; ​ \\             ​cmbSpeedUnit.SelectedIndex = (int)buildRoutingIndexParameters.SpeedOption.SpeedUnit; ​ \\         ​} ​ \\  \\         ​private void btnGenerate_Click(object sender, EventArgs e)  \\         ​{ ​ \\             ​isBuildingRtgFile = true;  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\  \\             <​nowiki>//</​nowiki>​display the ProgressBar. ​ \\             ​pnlProgress.Visible = true;  \\  \\             <​nowiki>//</​nowiki>​create a new RoutingIndexFileBuilder. ​ \\             ​builder = new RoutingIndexFileBuilder(buildRoutingIndexParameters); ​ \\  \\             <​nowiki>//</​nowiki>​Add a event to display refresh the ProgressBar. ​ \\             ​builder.BuildingRouteSegment += new EventHandler<​EventArgs>​(builder_BuildingRouteSegment); ​ \\  \\             <​nowiki>//</​nowiki>​Start build index file(.rtg). ​ \\             ​Task.Factory.StartNew(() =>  \\             ​{ ​ \\                 ​builder.StartBuildingRtgFile(); ​ \\             ​}); ​ \\         ​} ​ \\  \\         ​private void builder_BuildingRouteSegment(object sender, EventArgs e)  \\         ​{ ​ \\             ​this.BeginInvoke(new Action(() =>  \\             ​{ ​ \\                 <​nowiki>//</​nowiki>​refresh the progress and display the total record count. ​ \\                 ​lblSegmentCount.Text = builder.TotalRecordCount.ToString(); ​ \\                 ​pgbBuildProgress.Value = builder.ProcessedRecordCount * 100 / builder.TotalRecordCount; ​ \\  \\                 if (pgbBuildProgress.Value == 100)  \\                 ​{ ​ \\                     ​isBuildingRtgFile = false; ​ \\                     ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\                     ​MessageBox.Show(this,​ Resources.FinishBuildIndexFile,​ "​Completed"​); ​ \\                 ​} ​ \\             ​})); ​ \\         ​} ​ \\  \\         ​private void btnBrowseShapeFile_Click(object sender, EventArgs e)  \\         ​{ ​ \\             <​nowiki>//</​nowiki>​create dialog to select the shape file.  \\             ​OpenFileDialog fileDialog = new OpenFileDialog(); ​ \\             ​fileDialog.Multiselect = false; ​ \\             ​fileDialog.Filter = Resources.ShapeFileFilterString; ​ \\  \\             if (fileDialog.ShowDialog() == DialogResult.OK) ​ \\             ​{ ​ \\                 ​CheckFileIsRequirement(fileDialog.FileName); ​ \\  \\                 ​txtShapeFilePath.Text = buildRoutingIndexParameters.ShapefilePathName; ​ \\                 ​txtIndexFilePath.Text = buildRoutingIndexParameters.RtgFilePathName; ​ \\             ​} ​ \\  \\             <​nowiki>//</​nowiki>​check can build index file.  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void btnSaveRtgFile_Click(object sender, EventArgs e)  \\         ​{ ​ \\             <​nowiki>//</​nowiki>​create dialog to save the .rtg file.  \\             ​SaveFileDialog saveFileDialog = new SaveFileDialog(); ​ \\             ​saveFileDialog.FileName = buildRoutingIndexParameters.RtgFilePathName; ​ \\             ​saveFileDialog.Filter = Resources.RoutingIndexFileFilterString; ​ \\             ​saveFileDialog.DefaultExt = "​.rtg"; ​ \\             if (saveFileDialog.ShowDialog() == DialogResult.OK) ​ \\             ​{ ​ \\                 ​txtIndexFilePath.Text = saveFileDialog.FileName; ​ \\             ​} ​ \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void txtIndexFilePath_TextChanged(object sender, EventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.RtgFilePathName = txtIndexFilePath.Text; ​ \\             ​txtIndexFilePath.Text = buildRoutingIndexParameters.RtgFilePathName; ​ \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void txtDefaultSpeed_TextChanged(object sender, EventArgs e)  \\         ​{ ​ \\             float speed = buildRoutingIndexParameters.SpeedOption.DefaultSpeed; ​ \\             ​buildRoutingIndexParameters.SpeedOption.DefaultSpeed = float.TryParse(txtDefaultSpeed.Text,​ out speed) ? speed : 0;  \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void chkSkipOnewayOptions_CheckedChanged(object sender, EventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.SkipOnewayOptions = chkSkipOnewayOptions.Checked; ​ \\             ​pnlOnewayOptions.Enabled = !chkSkipOnewayOptions.Checked; ​ \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void chkRebuildRtgFile_CheckedChanged(object sender, EventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.BuildRoutingDataMode = chkRebuildRtgFile.Checked ? BuildRoutingDataMode.Rebuild : BuildRoutingDataMode.DoNotRebuild; ​ \\         ​} ​ \\  \\         ​private void RouteOptionComboBox_SelectedIndexChanged(object sender, EventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.GeographyUnit = cmbGeographyUnit.SelectedIndex != -1 ? (GeographyUnit)cmbGeographyUnit.SelectedIndex ​ \\                 : buildRoutingIndexParameters.GeographyUnit; ​ \\  \\             ​buildRoutingIndexParameters.DistanceUnit = cmbDistanceUnit.SelectedIndex != -1 ? (DistanceUnit)cmbDistanceUnit.SelectedIndex ​ \\                 : buildRoutingIndexParameters.DistanceUnit; ​ \\  \\             ​buildRoutingIndexParameters.RouteIndexType = cmbRouteIndexType.SelectedIndex != -1 ? (RouteIndexType)cmbRouteIndexType.SelectedIndex ​ \\                 : buildRoutingIndexParameters.RouteIndexType; ​ \\  \\             ​buildRoutingIndexParameters.SpeedOption.SpeedUnit = cmbSpeedUnit.SelectedIndex != -1 ? (SpeedUnit)cmbSpeedUnit.SelectedIndex ​ \\                 : buildRoutingIndexParameters.SpeedOption.SpeedUnit; ​ \\         ​} ​ \\  \\         ​private void chkRouteSpeedOptions_CheckedChanged(object sender, EventArgs e)  \\         ​{ ​ \\             if (!chkRouteSpeedOptions.Checked) ​ \\             ​{ ​ \\                 ​buildRoutingIndexParameters.SpeedOption.SpeedType = SpeedType.DefaultSpeed; ​ \\             ​} ​ \\             ​else ​ \\             ​{ ​ \\                 ​buildRoutingIndexParameters.SpeedOption.SpeedType = rbtnClassSpeed.Checked ? SpeedType.RoadClass : SpeedType.RoadSpeed; ​ \\             ​} ​ \\  \\             ​pnlRouteSpeedOptions.Enabled = chkRouteSpeedOptions.Checked; ​ \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void ShapeFileColumnComboBox_SelectedValueChanged(object sender, EventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.OneWayRoadOption.IndicatorColumnName = cmbOnewayIndicatorColumn.Text; ​ \\             ​buildRoutingIndexParameters.OneWayRoadOption.OneWayColumnName = cmbOnewayRoadColumn.Text; ​ \\             ​buildRoutingIndexParameters.SpeedOption.SpeedColumnName = cmbSpeedColumn.Text; ​ \\             ​buildRoutingIndexParameters.SpeedOption.RoadClassColumnName = cmbRoadClassColumn.Text; ​ \\  \\             if (sender.Equals(cmbRoadClassColumn)) ​ \\             ​{ ​ \\                 ​colRoadClass.Items.Clear(); ​ \\                 ​dgvRoadClassSpeed.Rows.Clear(); ​ \\                 ​buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Clear(); ​ \\  \\                 ​ShapeFileFeatureSource source = new ShapeFileFeatureSource(buildRoutingIndexParameters.ShapefilePathName); ​ \\                 ​source.Open(); ​ \\                 ​Collection<​Feature>​ features = source.GetAllFeatures(new string[[]] { cmbRoadClassColumn.Text });  \\                 ​source.Close(); ​ \\  \\                 ​foreach (Feature feature in features) ​ \\                 ​{ ​ \\                     if (!colRoadClass.Items.Contains(feature.ColumnValues[[cmbRoadClassColumn.Text]])) ​ \\                     ​{ ​ \\                         ​colRoadClass.Items.Add(feature.ColumnValues[[cmbRoadClassColumn.Text]]); ​ \\                     ​} ​ \\                 ​} ​ \\                 ​colRoadClass.Items.Remove(string.Empty); ​ \\             ​} ​ \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void SpeedTypeRadioButton_CheckedChanged(object sender, EventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.SpeedOption.SpeedType = rbtnClassSpeed.Checked ? SpeedType.RoadClass : SpeedType.RoadSpeed; ​ \\  \\             ​lblSpeedColumn.Enabled = false; ​ \\             ​cmbSpeedColumn.Enabled = false; ​ \\             ​lblRoadClassColumn.Enabled = false; ​ \\             ​cmbRoadClassColumn.Enabled = false; ​ \\             ​dgvRoadClassSpeed.Enabled = false; ​ \\  \\             if (rbtnClassSpeed.Checked) ​ \\             ​{ ​ \\                 ​lblRoadClassColumn.Enabled = true;  \\                 ​cmbRoadClassColumn.Enabled = true;  \\                 ​dgvRoadClassSpeed.Enabled = true;  \\             ​} ​ \\             else if (rbtnRoadSpeed.Checked) ​ \\             ​{ ​ \\                 ​lblSpeedColumn.Enabled = true;  \\                 ​cmbSpeedColumn.Enabled = true;  \\             ​} ​ \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void RouteOptionTextBox_TextChanged(object sender, EventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.OneWayRoadOption.BothWayRoadValue = txtBothWayRoadValue.Text; ​ \\             ​buildRoutingIndexParameters.OneWayRoadOption.FromToValue = txtFromToValue.Text; ​ \\             ​buildRoutingIndexParameters.OneWayRoadOption.ToFromValue = txtToFromValue.Text; ​ \\             ​buildRoutingIndexParameters.OneWayRoadOption.ClosedRoad = txtColsedRoad.Text; ​ \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void dgvRoadClassSpeed_CellEndEdit(object sender, DataGridViewCellEventArgs e)  \\         ​{ ​ \\             ​buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Clear(); ​ \\  \\             ​foreach (DataGridViewRow row in dgvRoadClassSpeed.Rows) ​ \\             ​{ ​ \\                 ​string value = row.Cells[[1]].Value == null ? string.Empty : row.Cells[[1]].Value.ToString(); ​ \\                 ​string key = row.Cells[[0]].Value == null ? string.Empty : row.Cells[[0]].Value.ToString(); ​ \\  \\                 ​double speed = 0;  \\  \\                 if (!buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Keys.Contains(key) && double.TryParse(value,​ out speed) && speed > 0)  \\                 ​{ ​ \\                     ​buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Add(key,​ speed); ​ \\                 ​} ​ \\             ​} ​ \\  \\             ​btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; ​ \\         ​} ​ \\  \\         ​private void btnCancel_Click(object sender, EventArgs e)  \\         ​{ ​ \\             if (builder != null)  \\             ​{ ​ \\                 ​builder.CancelBuildingRtgFile(); ​ \\             ​} ​ \\             ​this.Close(); ​ \\         ​} ​ \\  \\         ​private void CheckFileIsRequirement(string shapeFile) ​ \\         ​{ ​ \\             ​string errorMessage = string.Empty; ​ \\             ​try ​ \\             ​{ ​ \\                 <​nowiki>//</​nowiki>​read ShapeFileType and ShapeFileColumns from ShapeFile. ​ \\                 ​ShapeFileType fileType; ​ \\                 ​Collection<​FeatureSourceColumn>​ columns = ReadShapeFileTypeAndColumns(shapeFile,​ out fileType); ​ \\  \\                 <​nowiki>//</​nowiki>​check if ShapeFileType is Polyline. ​ \\                 if (fileType == ShapeFileType.Polyline) ​ \\                 ​{ ​ \\                     ​AddColumnItemsToComboBox(columns); ​ \\                     ​buildRoutingIndexParameters.ShapefilePathName = shapeFile; ​ \\                 ​} ​ \\                 ​else ​ \\                 ​{ ​ \\                     ​errorMessage = Resources.ShapeFileTypeError; ​ \\                 ​} ​ \\             ​} ​ \\             ​catch ​ \\             ​{ ​ \\                 ​errorMessage = Resources.ShapeFileFormatError; ​ \\             ​} ​ \\  \\             <​nowiki>//</​nowiki>​Display the ErrorMessage. ​ \\             if (!string.IsNullOrEmpty(errorMessage)) ​ \\             ​{ ​ \\                 ​MessageBox.Show(errorMessage,​ "​Error"​); ​ \\             ​} ​ \\         ​} ​ \\  \\         ​private Collection<​FeatureSourceColumn>​ ReadShapeFileTypeAndColumns(string shapeFilePath,​ out ShapeFileType fileType) ​ \\         ​{ ​ \\             ​Collection<​FeatureSourceColumn>​ columns; ​ \\  \\             ​ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(shapeFilePath); ​ \\             ​layer.Open(); ​ \\             ​fileType = layer.GetShapeFileType(); ​ \\             ​columns = layer.FeatureSource.GetColumns(); ​ \\             ​layer.Close(); ​ \\  \\             ​return columns; ​ \\         ​} ​ \\  \\         ​private void AddColumnItemsToComboBox(Collection<​FeatureSourceColumn>​ columns) ​ \\         ​{ ​ \\             ​cmbOnewayIndicatorColumn.Items.Clear(); ​ \\             ​cmbOnewayRoadColumn.Items.Clear(); ​ \\             ​cmbRoadClassColumn.Items.Clear(); ​ \\             ​cmbSpeedColumn.Items.Clear(); ​ \\  \\             ​foreach (FeatureSourceColumn column in columns) ​ \\             ​{ ​ \\                 ​cmbOnewayIndicatorColumn.Items.Add(column); ​ \\                 ​cmbOnewayRoadColumn.Items.Add(column); ​ \\                 ​cmbRoadClassColumn.Items.Add(column); ​ \\                 ​cmbSpeedColumn.Items.Add(column); ​ \\             ​} ​ \\         ​} ​ \\     ​} ​ \\ }  \\  \\  \\ </​source> ​  | 
  
 +<code csharp> ​  
 +  ​
 +using System;
 +using System.Collections.Generic;​
 +using System.Collections.ObjectModel;​
 +using System.Data;​
 +using System.IO;
 +using System.Linq;​
 +using System.Threading.Tasks;​
 +using System.Windows.Forms;​
 +using System.Xml.Linq;​
 +using ThinkGeo.MapSuite.Core;​
 +using ThinkGeo.MapSuite.Routing;​
  
-====RoutingIndexFileBuilder.cs==== +namespace RoutingIndexGenerator 
-^ Code ^ +
-| <​source ​lang="csharp" line="​1">  ​\\  \\ using System; ​ ​\\ ​using System.Collections.ObjectModel; ​ ​\\ ​using System.IO; ​ ​\\ ​using RoutingIndexGenerator.Properties ​\\ ​using ThinkGeo.MapSuite.Core; ​ ​\\ ​using ThinkGeo.MapSuite.Routing; ​ ​\\ ​ \\ namespace RoutingIndexGenerator ​ ​\\ ​ ​\\ ​    public class RoutingIndexFileBuilder ​ \\      ​\\ ​        public event EventHandler<​EventArgs> ​BuildingRouteSegment ​\\ ​ \\         ​private BuildRoutingIndexParameters buildRtgParameter; ​ \\         private bool cancelBuilding; ​ ​\\ ​        private ​ShapeFileFeatureSource routableFeatureSource ​\\ ​ \\         private int processedRecordCount; ​ ​\\ ​        private ​int totalRecordCount ​\\ ​        private Collection<​string>​ requiredColumns; ​ ​\\ ​ \\         public ​RoutingIndexFileBuilder()  ​\\ ​            : this(new ​BuildRoutingIndexParameters())  ​\\ ​        { }  ​\\ ​ \\         public ​RoutingIndexFileBuilder(BuildRoutingIndexParameters ​buildRtgParameter) ​ ​\\ ​         ​\\ ​            this.buildRtgParameter = buildRtgParameter; ​ ​\\ ​         ​\\ ​ \\         public ​int ProcessedRecordCount ​ \\          ​\\ ​            ​get ​return processedRecordCount; }  ​\\ ​        ​} ​ \\  \\         ​public ​int TotalRecordCount ​ \\          ​\\ ​            ​get ​return ​totalRecordCount;​ }  ​\\ ​         ​\\ ​ \\         public ​BuildRoutingIndexParameters BuildRtgParameter ​ \\          ​\\ ​            ​get ​return ​buildRtgParameter;​ }  ​\\ ​         ​\\ ​ \\         ​public void StartBuildingRtgFile()  ​\\ ​         ​\\ ​            if (!buildRtgParameter.CheckCanBuildIndexFile())  ​\\ ​             ​\\ ​                ​throw ​new NotSupportedException(Resources.ParametersNotSuppertBuildingIndex);  ​\\ ​             ​\\ ​ \\             processedRecordCount = 0;  ​\\ ​ \\             routableFeatureSource = new ShapeFileFeatureSource(buildRtgParameter.ShapefilePathName);  ​\\ ​            routableFeatureSource.Open(); ​ ​\\ ​ \\             totalRecordCount = routableFeatureSource.GetCount(); ​ ​\\ ​ \\             ​RtgRoutingSource.BuildingRoutingData += RtgRoutingSource_BuildingRoutingData; ​ \\             RtgRoutingSource.GenerateRoutingData(buildRtgParameter.RtgFilePathName,​ buildRtgParameter.ShapefilePathName, buildRtgParameter.ShapefilePathName, buildRtgParameter.BuildRoutingDataMode,​ buildRtgParameter.GeographyUnit, ​buildRtgParameter.DistanceUnit);  ​\\ ​            ​RtgRoutingSource.BuildingRoutingData -= RtgRoutingSource_BuildingRoutingData; ​ \\  \\             routableFeatureSource.Close(); ​ ​\\ ​ \\             if (cancelBuilding == true)  ​\\ ​             ​\\ ​                File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName,​ "​.rtg"​)); ​ ​\\ ​                File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName,​ "​.rtx"​)); ​ ​\\ ​             ​\\ ​         ​\\ ​ \\         public void CancelBuildingRtgFile() ​ ​\\ ​         ​\\ ​            cancelBuilding = true;  ​\\ ​         ​\\ ​ \\         private void RtgRoutingSource_BuildingRoutingData(object sender, BuildingRoutingDataRtgRoutingSourceEventArgs e)  ​\\ ​         ​\\ ​            <​nowiki>​//</​nowiki> ​Make progressBar move forward a step  ​\\ ​            processedRecordCount++; ​ ​\\ ​            ​OnBuildingRouteSegment();  ​\\ ​ \\             <​nowiki>​//</​nowiki> ​Get the processing Feature ​ ​\\ ​            if (requiredColumns == null)  ​\\ ​             ​\\ ​                requiredColumns = GetRequiredColumns(); ​ ​\\ ​             ​\\ ​ \\             Feature feature = routableFeatureSource.GetFeatureById(e.RouteSegment.FeatureId,​ requiredColumns); ​ ​\\ ​            if (!buildRtgParameter.SkipOnewayOptions ​\\ ​             ​\\ ​                ProcessOneWayRoad(e,​ feature, requiredColumns); ​ ​\\ ​             ​\\ ​ \\             if (buildRtgParameter.RouteIndexType == RouteIndexType.Fastest) ​ ​\\ ​             ​\\ ​                if (buildRtgParameter.SpeedOption.SpeedType ​== SpeedType.RoadClass ​&& !string.IsNullOrEmpty(buildRtgParameter.SpeedOption.RoadClassColumnName))  ​\\ ​                 ​\\ ​                    string featureRoadClassValue = feature.ColumnValues[[buildRtgParameter.SpeedOption.RoadClassColumnName]];  ​\\ ​                    e.RouteSegment.Weight = e.RouteSegment.Distance / GetSpeed(featureRoadClassValue); ​ ​\\ ​                 ​\\ ​                else if (buildRtgParameter.SpeedOption.SpeedType ​== SpeedType.RoadSpeed ​&& !string.IsNullOrEmpty(buildRtgParameter.SpeedOption.SpeedColumnName)) ​ ​\\ ​                 ​\\ ​                    float speed = 0;  \\                     string speedString = feature.ColumnValues[[buildRtgParameter.SpeedOption.SpeedColumnName]];  ​\\ ​                    speed = float.TryParse(speedString,​ out speed) ? speed : buildRtgParameter.SpeedOption.DefaultSpeed; ​ ​\\ ​                    e.RouteSegment.Weight = e.RouteSegment.Distance / speed; ​ ​\\ ​                 ​\\ ​                else  ​\\ ​                 ​\\ ​                    e.RouteSegment.Weight = e.RouteSegment.Distance / buildRtgParameter.SpeedOption.DefaultSpeed; ​ ​\\ ​                 ​\\ ​             ​\\ ​ \\             e.Cancel = cancelBuilding; ​ ​\\ ​         ​\\ ​ \\         private Collection<​string>​ GetRequiredColumns() ​ ​\\ ​         ​\\ ​            Collection<​string>​ requiredColumns = new Collection<​string>​(); ​ ​\\ ​            if (!buildRtgParameter.SkipOnewayOptions ​\\ ​             ​\\ ​                if (!string.IsNullOrEmpty(buildRtgParameter.OneWayRoadOption.OneWayColumnName)) ​ ​\\ ​                 ​\\ ​                    requiredColumns.Add(buildRtgParameter.OneWayRoadOption.OneWayColumnName); ​ ​\\ ​                 ​\\ ​                if (!string.IsNullOrEmpty(buildRtgParameter.OneWayRoadOption.IndicatorColumnName)) ​ ​\\ ​                 ​\\ ​                    requiredColumns.Add(buildRtgParameter.OneWayRoadOption.IndicatorColumnName); ​ ​\\ ​                 ​\\ ​             ​\\ ​ \\             string speedColumn = string.Empty; ​ ​\\ ​            switch (buildRtgParameter.SpeedOption.SpeedType ​\\ ​             ​\\ ​                case SpeedType.RoadClass ​\\ ​                    speedColumn = buildRtgParameter.SpeedOption.RoadClassColumnName ​\\ ​                    break; ​ ​\\ ​                case SpeedType.RoadSpeed ​\\ ​                    speedColumn = buildRtgParameter.SpeedOption.SpeedColumnName; ​ ​\\ ​                    break; ​ ​\\ ​                default: ​ ​\\ ​                    break; ​ ​\\ ​             ​\\ ​            if (!string.IsNullOrEmpty(speedColumn)) ​ ​\\ ​             ​\\ ​                requiredColumns.Add(speedColumn); ​ ​\\ ​             ​\\ ​ \\             return requiredColumns; ​ ​\\ ​         ​\\ ​ \\         private void ProcessOneWayRoad(BuildingRoutingDataRtgRoutingSourceEventArgs e, Feature roadFeature,​ Collection<​string>​ oneWayColumns) ​ ​\\ ​         ​\\ ​            LineShape lineShape = GetLineShape(roadFeature); ​ ​\\ ​ \\             <​nowiki>​//</​nowiki> ​handled feature is one-way road  ​\\ ​            if (!roadFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.OneWayColumnName]].Equals(buildRtgParameter.OneWayRoadOption.BothWayRoadValue,​ StringComparison.InvariantCultureIgnoreCase)) ​ \\             ​{ ​ \\                 ​if ​(roadFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.IndicatorColumnName]].Equals(buildRtgParameter.OneWayRoadOption.FromToValue))  ​\\ ​                 ​\\ ​                    e.RouteSegment.StartPointAdjacentIds.Clear(); ​ ​\\ ​                 ​\\ ​                else if (roadFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.IndicatorColumnName]].Equals(buildRtgParameter.OneWayRoadOption.ToFromValue))  ​\\ ​                 ​\\ ​                    e.RouteSegment.EndPointAdjacentIds.Clear(); ​ ​\\ ​                 ​\\ ​                else if (roadFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.IndicatorColumnName]].Equals(buildRtgParameter.OneWayRoadOption.ClosedRoad))  ​\\ ​                 ​\\ ​                    e.RouteSegment.StartPointAdjacentIds.Clear(); ​ ​\\ ​                    e.RouteSegment.EndPointAdjacentIds.Clear(); ​ ​\\ ​                 ​\\ ​             ​\\ ​ \\             <​nowiki>​//</​nowiki> ​analysis adjacent one-way road features ​ ​\\ ​            Collection<​string>​ removedStartPointAdjacentIds = GetRemovedAdjacentIds(e.RouteSegment.StartPointAdjacentIds,​ new PointShape(lineShape.Vertices[[0]]), oneWayColumns); ​ ​\\ ​            foreach (string id in removedStartPointAdjacentIds) ​ ​\\ ​             ​\\ ​                e.RouteSegment.StartPointAdjacentIds.Remove(id); ​ ​\\ ​             ​\\ ​            Collection<​string>​ removedEndPointAdjacentIds = GetRemovedAdjacentIds(e.RouteSegment.EndPointAdjacentIds,​ new PointShape(lineShape.Vertices[[lineShape.Vertices.Count|- 1]]), oneWayColumns); ​ ​\\ ​            foreach (string id in removedEndPointAdjacentIds) ​ ​\\ ​             ​\\ ​                e.RouteSegment.EndPointAdjacentIds.Remove(id); ​ ​\\ ​             ​\\ ​         ​\\ ​ \\         private Collection<​string>​ GetRemovedAdjacentIds(Collection<​string>​ adjacentIds,​ PointShape intersectingPoint,​ Collection<​string>​ oneWayColumns) ​ ​\\ ​         ​\\ ​            Collection<​string>​ removedIds = new Collection<​string>​(); ​ ​\\ ​            foreach (string id in adjacentIds) ​ ​\\ ​             ​\\ ​                Feature adjacentFeature = routableFeatureSource.GetFeatureById(id,​ oneWayColumns); ​ ​\\ ​                if (!adjacentFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.OneWayColumnName]].Equals(buildRtgParameter.OneWayRoadOption.BothWayRoadValue, StringComparison.InvariantCultureIgnoreCase)) ​ ​\\ ​                 ​\\ ​                    LineShape adjacentLineShape = GetLineShape(adjacentFeature); ​ ​\\ ​                    double distanceFromAdjacentStartToIntersecting = new PointShape(adjacentLineShape.Vertices[[0]]).GetDistanceTo(intersectingPoint,​ buildRtgParameter.GeographyUnit, ​buildRtgParameter.DistanceUnit); ​ ​\\ ​                    double distanceFromAdjacentEndToIntersecting = new PointShape(adjacentLineShape.Vertices[[adjacentLineShape.Vertices.Count|- 1]]).GetDistanceTo(intersectingPoint,​ buildRtgParameter.GeographyUnit, ​buildRtgParameter.DistanceUnit); ​ ​\\ ​                    if (distanceFromAdjacentStartToIntersecting <= distanceFromAdjacentEndToIntersecting ​ ​\\ ​                        && adjacentFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.IndicatorColumnName]].Equals(buildRtgParameter.OneWayRoadOption.ToFromValue))  ​\\ ​                     ​\\ ​                        removedIds.Add(id); ​ ​\\ ​                     ​\\ ​                    else if (distanceFromAdjacentEndToIntersecting <= distanceFromAdjacentStartToIntersecting ​ ​\\ ​                        && adjacentFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.IndicatorColumnName]].Equals(buildRtgParameter.OneWayRoadOption.FromToValue))  ​\\ ​                     ​\\ ​                        removedIds.Add(id); ​ ​\\ ​                     ​\\ ​                    else if (adjacentFeature.ColumnValues[[buildRtgParameter.OneWayRoadOption.IndicatorColumnName]].Equals(buildRtgParameter.OneWayRoadOption.ClosedRoad))  ​\\ ​                     ​\\ ​                        removedIds.Add(id); ​ ​\\ ​                     ​\\ ​                 ​\\ ​             ​\\ ​            return removedIds; ​ ​\\ ​         ​\\ ​ \\         private float GetSpeed(String featureRoadSpeedClassValue) ​ ​\\ ​         ​\\ ​            float result = buildRtgParameter.SpeedOption.DefaultSpeed; ​ ​\\ ​            foreach (var item in buildRtgParameter.SpeedOption.RoadSpeeds) ​ ​\\ ​             ​\\ ​                if (item.Key.Equals(featureRoadSpeedClassValue,​ StringComparison.OrdinalIgnoreCase)) ​ ​\\ ​                 ​\\ ​                    result = (float)item.Value; ​ ​\\ ​                    break; ​ ​\\ ​                 ​\\ ​             ​\\ ​ \\             return result; ​ ​\\ ​         ​\\ ​ \\         private static LineShape GetLineShape(Feature lineFeature) ​ ​\\ ​         ​\\ ​            BaseShape baseShape = lineFeature.GetShape(); ​ ​\\ ​ \\             LineShape lineShape = baseShape as LineShape; ​ ​\\ ​            if (lineShape == null)  ​\\ ​             ​\\ ​                MultilineShape lineShapes = ((MultilineShape)baseShape); ​ ​\\ ​                Collection<​Vertex>​ vertices = new Collection<​Vertex>​(); ​ ​\\ ​ \\                 foreach (LineShape line in lineShapes.Lines) ​ ​\\ ​                 ​\\ ​                    for (int i = 0; i < line.Vertices.Count;​ i++)  ​\\ ​                     ​\\ ​                        vertices.Add(line.Vertices[[i]]);  ​\\ ​                     ​\\ ​                 ​\\ ​ \\                 lineShape = new LineShape(vertices); ​ ​\\ ​                lineShape.Id = baseShape.Id; ​ ​\\ ​                lineShape.Tag = baseShape.Tag; ​ ​\\ ​             ​\\ ​ \\             return lineShape; ​ ​\\ ​         ​\\ ​ \\         protected virtual void OnBuildingRouteSegment()  ​\\ ​         ​\\ ​            if (BuildingRouteSegment ​!= null)  ​\\ ​             ​\\ ​                ​BuildingRouteSegment(this, ​new EventArgs()); ​ ​\\ ​             ​\\ ​         ​\\ ​     ​\\ ​}  ​\\  \\  \\ </source  |+    public partial class RoutingIndexGenerator : Form 
 +    { 
 +        // If the area is more than 1,000,000 square miles, we would throw a warning as the index generating might take too much time.  
 +        private double warningAreaInSquareMiles ​1000000; 
 +        private ConfigModel currentConfigModel;​ 
 +        private RoutingIndexBuilder routingIndexbuilder;​ 
 +        private Dictionary<​string,​ ConfigModel>​ configModelsDictionary;​ 
 + 
 +        public RoutingIndexGenerator() 
 +        { 
 +            InitializeComponent();​ 
 + 
 +            configModelsDictionary ​new Dictionary<​string,​ ConfigModel>​();​ 
 + 
 +            if (File.Exists("​InitConfig.xml"​)) 
 +            { 
 +                ConfigModel model new ConfigModel("​InitConfig.xml"​);​ 
 +                string key model.FileType.Split('​|'​).Last();​ 
 +                configModelsDictionary.Add(key,​ model); 
 +            } 
 + 
 +            if (File.Exists("​WkbConfig.xml"​)) 
 +            { 
 +                ConfigModel model new ConfigModel("​WkbConfig.xml"​);​ 
 +                string key model.FileType.Split('​|'​).Last();​ 
 +                configModelsDictionary.Add(key,​ model); 
 +            } 
 + 
 +            // We will always load shapefile configuration by default, even there is no configuration file. 
 +            if (!configModelsDictionary.Any(i ​=> i.Value.FileType.Contains("​*.shp"​))) 
 +            { 
 +                ConfigModel model new ConfigModel(XDocument.Parse(Properties.Resources.DefaultConfig));​ 
 +                ​string key = model.FileType.Split('​|'​).Last();​ 
 +                ​configModelsDictionary.Add(key,​ model); 
 +            } 
 +        } 
 + 
 +        private void btnBrowseSqliteFile_Click(object sender, EventArgs e) 
 +        { 
 +            OpenFileDialog fileDialog = new OpenFileDialog();​ 
 +            fileDialog.Filter = GetSelectFileFilter();​ 
 + 
 +            if (fileDialog.ShowDialog() == DialogResult.OK) 
 +            { 
 +                string currentKey = string.Format("​*.{0}",​ fileDialog.FileName.Split('​.'​).Last());​ 
 +                currentConfigModel = configModelsDictionary[currentKey];​ 
 + 
 +                // Get the bounding box of the feature source.  
 + 
 +                FeatureSource featureSource = null; 
 +                if (currentConfigModel.FileType.EndsWith("​.sqlite",​ StringComparison.InvariantCultureIgnoreCase)) 
 +                { 
 +                    featureSource = new SqliteFeatureSource(string.Format("​Data Source={0};​Version=3;",​ fileDialog.FileName),​ currentConfigModel.TableName,​ currentConfigModel.FeatureIdColumn,​ currentConfigModel.GeometryColumnName);​ 
 +                } 
 +                if (currentConfigModel.FileType.EndsWith("​.shp",​ StringComparison.InvariantCultureIgnoreCase)) 
 +                { 
 +                    featureSource = new ShapeFileFeatureSource(fileDialog.FileName);​ 
 +                    ((ShapeFileFeatureSource)featureSource).RequireIndex = false; 
 +                } 
 +                if (currentConfigModel.FileType.EndsWith("​.wkb",​ StringComparison.InvariantCultureIgnoreCase)) 
 +                { 
 +                    featureSource = new WkbFileFeatureSource(fileDialog.FileName);​ 
 +                } 
 + 
 +                featureSource.Open();​ 
 +                WellKnownType wellKnownType = featureSource.GetFirstFeaturesWellKnownType();​ 
 +                if (wellKnownType != WellKnownType.Line && wellKnownType != WellKnownType.Multiline) 
 +                { 
 +                    ShowErrorMessageBox();​ 
 +                    return; 
 +                } 
 + 
 +                txtDataProviderFilePath.Text = fileDialog.FileName;​ 
 +                txtRoutableFile.Text = Path.ChangeExtension(fileDialog.FileName,​ "​.routable.shp"​);​ 
 +                txtIndexFilePath.Text = Path.ChangeExtension(fileDialog.FileName,​ "​.routable.rtg"​);​ 
 + 
 +                RectangleShape boundingBox = featureSource.GetBoundingBox();​ 
 +                txtUpperLeftX.Text = string.Format("​{0},​{1}",​ boundingBox.UpperLeftPoint.X,​ boundingBox.UpperLeftPoint.Y);​ 
 +                txtLowerRightX.Text = string.Format("​{0},​{1}",​ boundingBox.LowerRightPoint.X,​ boundingBox.LowerRightPoint.Y);​ 
 + 
 +                // Get the columns of the feature source.  
 +                Collection<​FeatureSourceColumn>​ columns = featureSource.GetColumns();​ 
 +                featureSource.Close();​ 
 + 
 +                if (boundingBox.UpperLeftPoint.X < -180 || boundingBox.UpperLeftPoint.Y > 90 || boundingBox.LowerRightPoint.X > 180 || boundingBox.LowerRightPoint.Y ​-90) 
 +                { 
 +                    cmbGeographyUnit.SelectedIndex = 2; 
 +                } 
 +                else 
 +                { 
 +                    cmbGeographyUnit.SelectedIndex = 0; 
 +                } 
 + 
 +                InitCombColumns(cmbOnewayRoadColumn,​ columns, currentConfigModel.IdentifierColumnName);​ 
 +                InitCombColumns(cmbOnewayIndicatorColumn,​ columns, currentConfigModel.IndicatorColumnName);​ 
 +                InitCombColumns(cmbRoadClassColumn,​ columns, currentConfigModel.SpeedColumnName);​ 
 +                InitCombColumns(cmbSpeedColumn,​ columns, currentConfigModel.SpeedColumnName);​ 
 +                InitCombColumns(cmbClosedRoadColumn,​ columns, currentConfigModel.ClosedColumnName);​ 
 + 
 +                if (currentConfigModel.RoutingIndexType == 0) 
 +                { 
 +                    rbtnClassSpeed.Checked = true; 
 +                    tbOptions.Enabled = true; 
 +                } 
 + 
 +                cmbRouteIndexType.SelectedIndex = currentConfigModel.RoutingIndexType;​ 
 +                cmbSpeedUnit.SelectedIndex = currentConfigModel.SpeedUnit;​ 
 + 
 +                txtDefaultSpeed.Text = currentConfigModel.DefaultSpeed.ToString();​ 
 +                txtOneWayRoadValue.Text = currentConfigModel.IdentifierColumnValue;​ 
 +                txtFromToValue.Text = currentConfigModel.IndicatorStartEndValue;​ 
 + 
 +                btnGenerate.Enabled = true; 
 +            } 
 +        } 
 + 
 +        private void btnGenerate_Click(object sender, EventArgs e) 
 +        { 
 +            RoutingIndexBuilderParameters buildRoutingIndexParameters = GetIndexBuildingParameters();​ 
 +            if (buildRoutingIndexParameters == null) 
 +            { 
 +                return; 
 +            } 
 + 
 +            //create a new RoutingIndexFileBuilder. 
 +            routingIndexbuilder = new RoutingIndexBuilder(buildRoutingIndexParameters);​ 
 + 
 +            //Add an event to display refresh the ProgressBar. 
 +            routingIndexbuilder.ExtractingSqliteDatabase += routingIndexbuilder_ExtractingSqliteDatabase;​ 
 +            routingIndexbuilder.BuildingRoutableSegment += routingIndexbuilder_BuildingRoutableSegment;​ 
 +            routingIndexbuilder.BuildingRouteRTSegment += routingIndexbuilder_BuildingRouteSegment;​ 
 +            routingIndexbuilder.BuildingIndexFinished += routingIndexbuilder_BuildingIndexFinished;​ 
 +            routingIndexbuilder.BuildingShapeFileIndex += routingIndexbuilder_BuildingShapeFileIndex;​ 
 +            btnGenerate.Enabled = false; 
 + 
 +            //Start building index file(.rtg). 
 +            Task.Factory.StartNew(() => 
 +            { 
 +                routingIndexbuilder.ExtractRoadsFromSqliteToShapefileWithLowerMemory(currentConfigModel);​ 
 +                routingIndexbuilder.StartBuildingRoutableFile();​ 
 +                routingIndexbuilder.StartBuildingRtgFile();​ 
 +            }); 
 +        } 
 + 
 +        private void routingIndexbuilder_BuildingShapeFileIndex(object sender, RoutingIndexBuilderEventArgs e) 
 +        { 
 +            if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) 
 +            { 
 +                this.BeginInvoke(new Action(() => 
 +                { 
 +                    lblProcessingMessage.Text = string.Format("​Building shape file index: {0}/​{1}",​ e.ProcessedRecordCount,​ e.TotalRecordCount);​ 
 +                    pgbBuildProgress.Value = (int)(((double)e.ProcessedRecordCount / (double)e.TotalRecordCount) * 100); 
 +                })); 
 +            } 
 +        } 
 + 
 +        private void routingIndexbuilder_BuildingIndexFinished(object sender, EventArgs e) 
 +        { 
 +            this.BeginInvoke(new Action(() => 
 +            { 
 +                btnGenerate.Enabled = true; 
 +                MessageBox.Show(this,​ "​Generation Completed!",​ "​Completed"​);​ 
 +            })); 
 +        } 
 + 
 +        private void routingIndexbuilder_ExtractingSqliteDatabase(object sender, RoutingIndexBuilderEventArgs e) 
 +        { 
 +            if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) 
 +            { 
 +                this.BeginInvoke(new Action(() => 
 +                { 
 +                    lblProcessingMessage.Text = string.Format("​Generating Index (1/3): Extracting ​source ​file: {0}/​{1}",​ e.ProcessedRecordCount,​ e.TotalRecordCount);​ 
 +                    pgbBuildProgress.Value ​(int)(((double)e.ProcessedRecordCount / (double)e.TotalRecordCount) * 100); ; 
 +                })); 
 +            } 
 +        } 
 + 
 +        private void routingIndexbuilder_BuildingRoutableSegment(object sender, RoutingIndexBuilderEventArgs e) 
 +        { 
 +            if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) 
 +            { 
 +                this.BeginInvoke(new Action(() => 
 +                { 
 +                    lblProcessingMessage.Text = string.Format("Generating Index (2/3) Building Routable shape file: {0}/​{1}",​ e.ProcessedRecordCount,​ e.TotalRecordCount);​ 
 +                    pgbBuildProgress.Value = (int)(((double)e.ProcessedRecordCount / (double)e.TotalRecordCount) * 100); 
 +                })); 
 +            } 
 +        } 
 + 
 +        private void routingIndexbuilder_BuildingRouteSegment(object sender, RoutingIndexBuilderEventArgs e) 
 +        { 
 +            if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) 
 +            { 
 +                this.BeginInvoke(new Action(() => 
 +                { 
 +                    lblProcessingMessage.Text = string.Format("​Generating Index (3/3) Building rtg file: {0}/​{1}",​ e.ProcessedRecordCount,​ e.TotalRecordCount);​ 
 +                    pgbBuildProgress.Value = (int)(((double)e.ProcessedRecordCount / (double)e.TotalRecordCount) * 100); 
 +                })); 
 +            } 
 +        } 
 + 
 +        private void btnSaveRtgFile_Click(object sender, EventArgs e) 
 +        { 
 +            SaveFileDialog saveFileDialog = new SaveFileDialog();​ 
 +            saveFileDialog.FileName = Path.ChangeExtension(txtDataProviderFilePath.Text,​ "​.routable.rtg"​);​ ; 
 +            saveFileDialog.Filter = "​Routing Index File(*.rtg)|*.rtg";​ 
 +            saveFileDialog.DefaultExt = "​.rtg";​ 
 +            if (saveFileDialog.ShowDialog() == DialogResult.OK) 
 +            { 
 +                txtIndexFilePath.Text = saveFileDialog.FileName;​ 
 +            } 
 +        } 
 + 
 +        private void btnSaveRoutableFile_Click(object sender, EventArgs e) 
 +        { 
 +            SaveFileDialog saveFileDialog = new SaveFileDialog();​ 
 +            saveFileDialog.FileName = Path.ChangeExtension(txtDataProviderFilePath.Text,​ "​.Routable.shp"​);​ 
 + 
 +            saveFileDialog.Filter = "Shape File(*.shp)|*.shp";​ 
 +            saveFileDialog.DefaultExt = "​.shp";​ 
 +            if (saveFileDialog.ShowDialog() == DialogResult.OK) 
 +            { 
 +                this.txtRoutableFile.Text = saveFileDialog.FileName;​ 
 +            } 
 +        } 
 + 
 +        private void SpeedTypeRadioButton_CheckedChanged(object sender, EventArgs e) 
 +        { 
 +            lblRoadClassColumn.Enabled = rbtnClassSpeed.Checked;​ 
 +            cmbRoadClassColumn.Enabled = rbtnClassSpeed.Checked;​ 
 +            dgvRoadClassSpeed.Enabled = rbtnClassSpeed.Checked;​ 
 +            cmbSpeedColumn.Enabled = rbtnRoadSpeed.Checked;​ 
 +        } 
 + 
 +        private void cmbRouteIndexType_SelectedIndexChanged(object sender, EventArgs e) 
 +        { 
 +            bool considerringSpeedLimit = cmbRouteIndexType.SelectedItem.ToString() == "​Fastest";​ 
 +            panelRouteSpeedOptions.Enabled = considerringSpeedLimit;​ 
 +        } 
 + 
 +        private void cmbSpeedUnit_SelectedIndexChanged(object sender, EventArgs e) 
 +        { 
 +            if (cmbSpeedUnit.SelectedIndex == 0) 
 +            { 
 +                txtDefaultSpeed.Text = "​50";​ 
 +            } 
 +            else 
 +            { 
 +                txtDefaultSpeed.Text = "​30";​ 
 +            } 
 +            BindRoadClassSpeed();​ 
 +        } 
 + 
 +        private void cmbOnewayRoadColumn_SelectedIndexChanged(object sender, EventArgs e) 
 +        { 
 +            bool oneWayIdentifierIsNotNull = (cmbOnewayRoadColumn.SelectedItem.ToString() != string.Empty);​ 
 + 
 +            label8.Enabled = oneWayIdentifierIsNotNull;​ 
 +            txtOneWayRoadValue.Enabled = oneWayIdentifierIsNotNull;​ 
 +            panelOneWayIndicator.Enabled = oneWayIdentifierIsNotNull;​ 
 +        } 
 + 
 +        private void cmbOnewayIndicatorColumn_SelectedIndexChanged(object sender, EventArgs e) 
 +        { 
 +            bool oneWayIndicatorColumnNotNull = (cmbOnewayIndicatorColumn.SelectedItem.ToString() != string.Empty);​ 
 +            panelOneWayIndicatorDetail.Enabled = oneWayIndicatorColumnNotNull;​ 
 +        } 
 + 
 +        private void cmbClosedRoadColumn_SelectedIndexChanged(object sender, EventArgs e) 
 +        { 
 +            bool closedRoadColumnNotNull = (cmbClosedRoadColumn.SelectedItem.ToString() != string.Empty);​ 
 +            panelClosedRoad.Enabled = closedRoadColumnNotNull;​ 
 +        } 
 + 
 +        private void cmbRoadClassColumn_SelectedIndexChanged(object sender, EventArgs e) 
 +        { 
 +            BindRoadClassSpeed();​ 
 +        } 
 + 
 +        private void btnClose_Click(object sender, EventArgs e) 
 +        { 
 +            if (routingIndexbuilder != null) 
 +            { 
 +                routingIndexbuilder.CancelBuildingRtgFile();​ 
 +            } 
 +            this.Close();​ 
 +        } 
 + 
 +        private RoutingIndexBuilderParameters GetIndexBuildingParameters() 
 +        { 
 +            RoutingIndexBuilderParameters buildRoutingIndexParameters = new RoutingIndexBuilderParameters();​ 
 +            buildRoutingIndexParameters.SourceSqlitePathName = txtDataProviderFilePath.Text;​ 
 + 
 +            buildRoutingIndexParameters.GeographyUnit = (GeographyUnit)Enum.Parse(typeof(GeographyUnit),​ cmbGeographyUnit.SelectedItem.ToString());​ 
 +            buildRoutingIndexParameters.RouteIndexType = (RoutingIndexType)Enum.Parse(typeof(RoutingIndexType),​ cmbRouteIndexType.SelectedItem.ToString());​ 
 +            buildRoutingIndexParameters.RtgFilePathName = txtIndexFilePath.Text;​ 
 +            buildRoutingIndexParameters.RoutableShapeFilePathName = txtRoutableFile.Text;​ 
 +            buildRoutingIndexParameters.BuildRoutingDataMode = chkRebuildRtgFile.Checked ? BuildRoutingDataMode.Rebuild : BuildRoutingDataMode.DoNotRebuild;​ 
 +            buildRoutingIndexParameters.OverrideRoutableFile = chkRebuildRoutableFile.Checked ? true : false; 
 + 
 +            //Get restrict extent if specify. 
 +            if (this.txtUpperLeftX.Text.Split(','​).Length == 2 && this.txtUpperLeftX.Text.Split(','​).Length == 2) 
 +            { 
 +                buildRoutingIndexParameters.RestrictExtent = new RectangleShape(double.Parse(this.txtUpperLeftX.Text.Split(','​)[0]),​ double.Parse(this.txtUpperLeftX.Text.Split(','​)[1]),​ double.Parse(this.txtLowerRightX.Text.Split(','​)[0]),​ double.Parse(this.txtLowerRightX.Text.Split(','​)[1]));​ 
 +                // Check if restrict extent is too large and give it a warning if does. 
 +                if (buildRoutingIndexParameters.RestrictExtent.GetArea(buildRoutingIndexParameters.GeographyUnit,​ AreaUnit.SquareMiles) > warningAreaInSquareMiles) 
 +                { 
 +                    string routingAreaTooLargeWarning = "The selected area is too big and may take a long time, we suggest making the selected area smaller, do you want to continue anyway?";​ 
 +                    if (DialogResult.No == MessageBox.Show(routingAreaTooLargeWarning,​ "​Warning",​ MessageBoxButtons.YesNo,​ MessageBoxIcon.Warning)) 
 +                    { 
 +                        return null; 
 +                    } 
 +                } 
 +            } 
 +            else 
 +            { 
 +                MessageBox.Show("​Either Upper Left Point or Lower Right Point is not correctly"​);​ 
 +                return null; 
 +            } 
 + 
 +            // Get the Speed Options.  
 +            if (cmbRouteIndexType.SelectedItem.ToString() == "​Fastest"​) 
 +            { 
 +                buildRoutingIndexParameters.SpeedOption.SpeedUnit = (SpeedUnit)Enum.Parse(typeof(SpeedUnit),​ cmbSpeedUnit.SelectedIndex.ToString());​ 
 +                buildRoutingIndexParameters.SpeedOption.DefaultSpeed = Convert.ToSingle(txtDefaultSpeed.Text);​ 
 +                buildRoutingIndexParameters.SpeedOption.SpeedSourceType = rbtnClassSpeed.Checked ? RoadSpeedSourceType.BasedOnRoadType : RoadSpeedSourceType.DefinedInAttribution;​ 
 +                buildRoutingIndexParameters.SpeedOption.SpeedColumnName = cmbSpeedColumn.Text;​ 
 +                buildRoutingIndexParameters.SpeedOption.RoadTypeColumnName = cmbRoadClassColumn.Text;​ 
 +                DataTable dataTable = (DataTable)dgvRoadClassSpeed.DataSource;​ 
 +                buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Clear();​ 
 +                foreach (DataRow dataRow in dataTable.Rows) 
 +                { 
 +                    buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Add(dataRow[0].ToString(),​ Convert.ToDouble(dataRow[1]));​ 
 +                } 
 +            } 
 + 
 +            // Get the One way Road Options.  
 +            buildRoutingIndexParameters.OneWayRoadOption.OneWayColumnName = cmbOnewayRoadColumn.Text;​ 
 +            if (buildRoutingIndexParameters.OneWayRoadOption.OneWayColumnName != string.Empty) 
 +            { 
 +                buildRoutingIndexParameters.IncludeOnewayOptions = true; 
 +                buildRoutingIndexParameters.OneWayRoadOption.IndicatorColumnName = cmbOnewayIndicatorColumn.Text;​ 
 +                buildRoutingIndexParameters.OneWayRoadOption.OneWayIdentifier = txtOneWayRoadValue.Text;​ 
 +                buildRoutingIndexParameters.OneWayRoadOption.StartToEnd = txtFromToValue.Text;​ 
 +                buildRoutingIndexParameters.OneWayRoadOption.EndToStart = txtToFromValue.Text;​ 
 +            } 
 + 
 +            // Get the closed Road Options. 
 +            buildRoutingIndexParameters.ClosedRoadOption.ClosedColumnName = cmbClosedRoadColumn.Text;​ 
 +            buildRoutingIndexParameters.ClosedRoadOption.ClosedRoadValue = txtColsedRoad.Text;​ 
 + 
 +            return buildRoutingIndexParameters;​ 
 +        } 
 + 
 +        private void ShowErrorMessageBox() 
 +        { 
 +            MessageBox.Show(this, ​"The chosen data doesn'​t include ​line shapes. Please choose another one.", "​Invalid data", MessageBoxButtons.OK,​ MessageBoxIcon.Error);​ 
 +        } 
 + 
 +        private string GetSelectFileFilter() 
 +        { 
 +            string filter = string.Empty;​ 
 +            string allExName = string.Empty;​ 
 +            List<​string>​ fileExNames = new List<​string>​();​ 
 + 
 +            foreach (var item in configModelsDictionary) 
 +            { 
 +                if (string.IsNullOrEmpty(filter)) filter += item.Value.FileType;​ 
 +                else 
 +                { 
 +                    filter += "|" + item.Value.FileType;​ 
 +                } 
 + 
 +                if (string.IsNullOrEmpty(allExName)) allExName += item.Key; 
 +                else 
 +                { 
 +                    allExName += ";"​ + item.Key; 
 +                } 
 + 
 +                fileExNames.Add(item.Value.FileType.Split('​|'​).Last());​ 
 +            } 
 + 
 +            filter += string.Format("​|All Surpported Files({0})|{0}",​ allExName);​ 
 + 
 +            return filter; 
 +        } 
 + 
 +        private void BindRoadClassSpeed() 
 +        { 
 +            DataTable dataTable = new DataTable();​ 
 +            dataTable.Columns.Add("​RoadClass"​);​ 
 +            dataTable.Columns.Add("​Speed"​);​ 
 + 
 +            Dictionary<​string,​ float> roadSpeed = currentConfigModel.RoadSpeedForKPH;​ 
 +            if (cmbSpeedUnit.SelectedIndex == 1
 +            { 
 +                roadSpeed = currentConfigModel.RoadSpeedForMPH;​ 
 +            } 
 +            foreach (var item in roadSpeed) 
 +            { 
 +                DataRow dr = dataTable.NewRow();​ 
 +                dr[0] = item.Key; 
 +                dr[1] = item.Value;​ 
 +                dataTable.Rows.Add(dr);​ 
 +            } 
 +            dgvRoadClassSpeed.DataSource = dataTable;​ 
 +        } 
 + 
 +        private void InitCombColumns(ComboBox comboBox, Collection<​FeatureSourceColumn>​ columns, string defaultValue) 
 +        { 
 +            comboBox.Items.Clear();​ 
 +            comboBox.Items.Add(""); 
 +            foreach (FeatureSourceColumn item in columns) 
 +            { 
 +                comboBox.Items.Add(item.ColumnName);​ 
 +                if (item.ColumnName.Equals(defaultValue,​ StringComparison.InvariantCultureIgnoreCase)) 
 +                { 
 +                    comboBox.SelectedIndex = comboBox.Items.Count - 1; 
 +                } 
 +            } 
 +        } 
 +    } 
 +
 +  
 + </​code> 
 + 
 + 
 +====RoutingIndexBuilder.cs==== 
 + 
 +<code csharp> ​   
 +   
 +using System; 
 +using System.Collections.ObjectModel;​ 
 +using System.IO; 
 +using System.Text; 
 +using ThinkGeo.MapSuite.Core;​ 
 +using ThinkGeo.MapSuite.Routing;​ 
 + 
 +namespace RoutingIndexGenerator 
 +{ 
 +    ​public class RoutingIndexBuilder 
 +    ​{ 
 +        public event EventHandler<​RoutingIndexBuilderEventArgs>​ BuildingShapeFileIndex;​ 
 +        public event EventHandler<​RoutingIndexBuilderEventArgs>​ ExtractingSqliteDatabase;​ 
 +        public event EventHandler<​RoutingIndexBuilderEventArgs>​ BuildingRoutableSegment;​ 
 +        public event EventHandler<​RoutingIndexBuilderEventArgs>​ BuildingRouteRTSegment;​ 
 +        ​public event EventHandler<​EventArgs> ​BuildingIndexFinished; 
 + 
 +        ​private bool cancelBuilding;​ 
 +        ​private ​int totalRecordCount; 
 +        ​private int processedRecordCount;​ 
 +        ​private ​Feature previousFeature; 
 +        ​private Collection<​string>​ requiredColumns;​ 
 +        private ShapeFileFeatureSource routableFeatureSource;​ 
 +        private RoutingIndexBuilderParameters buildRtgParameter;​ 
 + 
 +        ​public ​RoutingIndexBuilder() 
 +            ​: this(new ​RoutingIndexBuilderParameters()) 
 +        ​{ } 
 + 
 +        ​public ​RoutingIndexBuilder(RoutingIndexBuilderParameters ​buildRtgParameter) 
 +        ​{ 
 +            ​this.buildRtgParameter = buildRtgParameter;​ 
 +            this.buildRtgParameter.ClosedRoadOption.InitRegexes();​ 
 +            this.buildRtgParameter.OneWayRoadOption.InitRegexes();​ 
 +            RtgRoutingSource.GeneratingRoutableShapeFile += RtgRoutingSource_GeneratingRoutableShapeFile;​ 
 +            RtgRoutingSource.BuildingRoutingData += RtgRoutingSource_BuildingRoutingData;​ 
 +        ​} 
 + 
 +        //This method uses lower memory than the other method, but only works with .sqlite files 
 +        ​public ​void ExtractRoadsFromSqliteToShapefileWithLowerMemory(ConfigModel config) 
 +        ​{ 
 +            // If don't override routable file, let's skip this step. 
 +            if (buildRtgParameter.OverrideRoutableFile || !File.Exists(buildRtgParameter.RoutableShapeFilePathName)) 
 +            ​{ 
 +                SqliteFeatureSource source = new SqliteFeatureSource(string.Format("​Data Source={0};Version=3;",​ buildRtgParameter.SourceSqlitePathName),​ config.TableName,​ config.FeatureIdColumn,​ config.GeometryColumnName);​ 
 +                source.Open();​ 
 + 
 +                RectangleShape restrictExtent = buildRtgParameter.RestrictExtent == null ? source.GetBoundingBox() : buildRtgParameter.RestrictExtent;​ 
 +                Collection<​string>​ ids = new Collection<​string>​();​ 
 +                ids = source.GetFeatureIdsInsideBoundingBox(restrictExtent);​ 
 + 
 +                Collection<​DbfColumn>​ dbfColumns = new Collection<​DbfColumn>​();​ 
 +                foreach (string columnName in config.ExtractRequiredColumns) 
 +                { 
 +                    dbfColumns.Add(new DbfColumn(columnName,​ DbfColumnType.Character,​ 255, 0)); 
 +                ​} 
 +                ShapeFileFeatureSource.CreateShapeFile(ShapeFileType.Polyline,​ buildRtgParameter.SourceShapefilePathName,​ dbfColumns, Encoding.UTF8,​ OverwriteMode.Overwrite);​ 
 + 
 +                ShapeFileFeatureSource target = new ShapeFileFeatureSource(buildRtgParameter.SourceShapefilePathName,​ ShapeFileReadWriteMode.ReadWrite);​ 
 +                target.Open();​ 
 + 
 +                ​int processedRecordCount = 0; 
 +                int totalRecordCount = ids.Count;​ 
 +                target.BeginTransaction();​ 
 + 
 +                //load 10,000 features into memory at a time from the sqlite database 
 +                int loadingFeatureCount = 10000; 
 +                int startIndex = 0; 
 +                int length = 0; 
 + 
 +                string[] totalIds = new string[ids.Count];​ 
 +                ids.CopyTo(totalIds,​ 0); 
 + 
 +                while (startIndex + length < ids.Count) 
 +                ​{ 
 +                    startIndex = startIndex + length; 
 +                    length = Math.Min(ids.Count - startIndex, loadingFeatureCount);​ 
 + 
 +                    string[] fetchIds = new string[length];​ 
 +                    Array.Copy(totalIds,​ startIndex, fetchIds, 0, length); 
 + 
 +                    Collection<​Feature>​ features = source.GetFeaturesByIds(fetchIds,​ config.ExtractRequiredColumns);​ 
 + 
 +                    foreach (Feature feature in features) 
 +                    ​{ 
 +                        target.AddFeature(feature);​ 
 +                        processedRecordCount++;​ 
 + 
 +                        //write 100,000 features to shapefile at a time 
 +                        if (processedRecordCount % 100000 == 0) 
 +                        { 
 +                            target.CommitTransaction();​ 
 +                            target.BeginTransaction();​ 
 +                        } 
 +                        OnExtractingSqliteDatabase(new RoutingIndexBuilderEventArgs(totalRecordCount, processedRecordCount)); 
 +                    ​} 
 + 
 +                ​} 
 +                target.CommitTransaction();​ 
 +                target.Close();​ 
 +                source.Close();​ 
 +            } 
 +        } 
 + 
 +        ​public ​void ExtractRoadsFromSqliteToShapefile(ConfigModel config) 
 +        ​{ 
 +            // If don't override routable file, let's skip this step. 
 +            if (buildRtgParameter.OverrideRoutableFile || !File.Exists(buildRtgParameter.RoutableShapeFilePathName)) 
 +            ​{ 
 +                FeatureSource source = null; 
 +                if (config.FileType.EndsWith("​.sqlite",​ StringComparison.InvariantCultureIgnoreCase)) 
 +                { 
 +                    source = new SqliteFeatureSource(string.Format("​Data Source={0};​Version=3;", ​buildRtgParameter.SourceSqlitePathName),​ config.TableName,​ config.FeatureIdColumn,​ config.GeometryColumnName); 
 +                ​} 
 +                else if (config.FileType.EndsWith("​.shp",​ StringComparison.InvariantCultureIgnoreCase)) 
 +                { 
 +                    ShapeFileFeatureSource.BuildingIndex += ShapeFileFeatureSource_BuildingIndex;​ 
 +                    ShapeFileFeatureSource.BuildIndexFile(buildRtgParameter.SourceSqlitePathName,​ BuildIndexMode.DoNotRebuild);​ 
 +                    source = new ShapeFileFeatureSource(buildRtgParameter.SourceSqlitePathName);​ 
 +                ​} 
 +                else if (config.FileType.EndsWith("​.wkb",​ StringComparison.InvariantCultureIgnoreCase)
 +                ​{ 
 +                    source = new WkbFileFeatureSource(buildRtgParameter.SourceSqlitePathName);​ 
 +                } 
 + 
 +                source.Open();​ 
 + 
 +                RectangleShape restrictExtent = buildRtgParameter.RestrictExtent == null ? source.GetBoundingBox() : buildRtgParameter.RestrictExtent;​ 
 +                Collection<​Feature>​ features = new Collection<​Feature>​();​ 
 +                Collection<​DbfColumn>​ dbfColumns = new Collection<​DbfColumn>​();​ 
 +                ​if (config.ExtractRequiredColumns.Count == 0) 
 +                { 
 +                    features = source.GetFeaturesInsideBoundingBox(restrictExtent,​ ReturningColumnsType.AllColumns);​ 
 +                    foreach (var column in source.GetColumns()) 
 +                    { 
 +                        dbfColumns.Add(new DbfColumn(column.ColumnName,​ DbfColumnType.Character,​ column.MaxLength,​ 0)); 
 +                    } 
 +                } 
 +                else 
 +                { 
 +                    features = source.GetFeaturesInsideBoundingBox(restrictExtent,​ config.ExtractRequiredColumns);​ 
 +                    foreach (string columnName in config.ExtractRequiredColumns) 
 +                    { 
 +                        dbfColumns.Add(new DbfColumn(columnName,​ DbfColumnType.Character,​ 255, 0)); 
 +                    } 
 +                } 
 + 
 +                ShapeFileFeatureSource.CreateShapeFile(ShapeFileType.Polyline, ​buildRtgParameter.SourceShapefilePathName,​ dbfColumns, Encoding.UTF8,​ OverwriteMode.Overwrite);​ 
 + 
 +                ShapeFileFeatureSource target = new ShapeFileFeatureSource(buildRtgParameter.SourceShapefilePathName,​ ShapeFileReadWriteMode.ReadWrite)
 +                target.Open()
 + 
 +                int processedRecordCount = 0; 
 +                int totalRecordCount = features.Count;​ 
 +                target.BeginTransaction();​ 
 +                foreach (Feature feature in features) 
 +                ​{ 
 + 
 +                    target.AddFeature(feature);​ 
 +                    processedRecordCount++;​ 
 + 
 +                    if (processedRecordCount % 100000 == 0) 
 +                    { 
 +                        target.CommitTransaction();​ 
 +                        target.BeginTransaction();​ 
 +                    } 
 +                    OnExtractingSqliteDatabase(new RoutingIndexBuilderEventArgs(totalRecordCount,​ processedRecordCount));​ 
 +                } 
 + 
 +                target.CommitTransaction(); 
 +                target.Close();​ 
 +                source.Close();​ 
 +            ​} 
 +        } 
 + 
 +        public void StartBuildingRoutableFile() 
 +        { 
 +            if (buildRtgParameter.OverrideRoutableFile) 
 +            { 
 +                ShapeFileFeatureSource sourceFeatureSource = new ShapeFileFeatureSource(buildRtgParameter.SourceShapefilePathName);​ 
 +                sourceFeatureSource.Open();​ 
 + 
 +                // reset the process status. 
 +                this.processedRecordCount = 0; 
 +                this.totalRecordCount = sourceFeatureSource.GetCount();​ 
 +                RtgRoutingSource.GenerateRoutableShapeFile(buildRtgParameter.SourceShapefilePathName,​ buildRtgParameter.RoutableShapeFilePathName,​ buildRtgParameter.OverrideRoutableFile ? OverwriteMode.Overwrite : OverwriteMode.DoNotOverwrite,​ buildRtgParameter.GeographyUnit,​ 2); 
 + 
 +                sourceFeatureSource.Close();​ 
 +            } 
 +        } 
 + 
 +        public void StartBuildingRtgFile() 
 +        { 
 +            ​routableFeatureSource = new ShapeFileFeatureSource(buildRtgParameter.RoutableShapeFilePathName); 
 +            ​routableFeatureSource.Open();​ 
 + 
 +            // reset the process status. 
 +            this.processedRecordCount = 0; 
 +            this.totalRecordCount = routableFeatureSource.GetCount();​ 
 +            ​RtgRoutingSource.GenerateRoutingData(buildRtgParameter.RtgFilePathName,​ buildRtgParameter.SourceShapefilePathName, buildRtgParameter.RoutableShapeFilePathName, buildRtgParameter.BuildRoutingDataMode,​ buildRtgParameter.GeographyUnit, ​DistanceUnit.Meter); 
 + 
 +            ​routableFeatureSource.Close();​ 
 + 
 +            ​if (cancelBuilding == true) 
 +            ​{ 
 +                ​File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName,​ "​.rtg"​));​ 
 +                ​File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName,​ "​.rtx"​));​ 
 +            ​} 
 + 
 +            // clear up the temporary shape files extracted from sqlite. 
 +            if (File.Exists(buildRtgParameter.SourceSqlitePathName) && File.Exists(buildRtgParameter.SourceShapefilePathName)) 
 +            { 
 +                string tempShapefile = Path.GetFileNameWithoutExtension(buildRtgParameter.SourceShapefilePathName);​ 
 +                string[] files = Directory.GetFiles(Path.GetDirectoryName(buildRtgParameter.SourceShapefilePathName));​ 
 +                foreach (string file in files) 
 +                { 
 +                    if (Path.GetFileNameWithoutExtension(file).Equals(tempShapefile,​ StringComparison.InvariantCultureIgnoreCase)) 
 +                    { 
 +                        File.Delete(file);​ 
 +                    ​} 
 +                } 
 +            } 
 +            OnBuildingIndexFinished(new EventArgs());​ 
 +        } 
 + 
 +        ​public void CancelBuildingRtgFile() 
 +        ​{ 
 +            ​cancelBuilding = true; 
 +        ​} 
 + 
 +        private void ShapeFileFeatureSource_BuildingIndex(object sender, BuildingIndexShapeFileFeatureSourceEventArgs e) 
 +        { 
 +            var handler = BuildingShapeFileIndex;​ 
 +            if (handler != null) 
 +            { 
 +                handler(this,​ new RoutingIndexBuilderEventArgs(e.RecordCount,​ e.CurrentRecordIndex));​ 
 +            } 
 +        } 
 + 
 +        private void RtgRoutingSource_GeneratingRoutableShapeFile(object sender, GeneratingRoutableShapeFileRoutingSourceEventArgs e) 
 +        { 
 +            if (previousFeature == null) 
 +            { 
 +                previousFeature = e.PreviousFeature;​ 
 +            } 
 + 
 +            // we add the previous feature is because this event may be triggered multi times in one feature. 
 +            if (previousFeature.Id != e.PreviousFeature.Id) 
 +            { 
 +                previousFeature = e.PreviousFeature;​ 
 +                this.processedRecordCount++;​ 
 +                OnBuildingRoutableSegment(new RoutingIndexBuilderEventArgs(this.totalRecordCount,​ this.processedRecordCount));​ 
 +            } 
 +        } 
 + 
 +        ​private void RtgRoutingSource_BuildingRoutingData(object sender, BuildingRoutingDataRtgRoutingSourceEventArgs e) 
 +        ​{ 
 +            ​// Make progressBar move forward a step 
 +            this.processedRecordCount++;​ 
 +            OnBuildingRouteRTSegment(new RoutingIndexBuilderEventArgs(this.totalRecordCount,​ this.processedRecordCount)); 
 + 
 +            ​// Get the processing Feature 
 +            ​if (requiredColumns == null) 
 +            ​{ 
 +                ​requiredColumns = GetRequiredColumns();​ 
 +            ​} 
 + 
 +            ​Feature feature = routableFeatureSource.GetFeatureById(e.RouteSegment.FeatureId,​ requiredColumns);​ 
 +            ​if (buildRtgParameter.IncludeOnewayOptions) 
 +            ​{ 
 +                ​ProcessOneWayRoad(e,​ feature, requiredColumns);​ 
 +            ​} 
 + 
 +            ​if (buildRtgParameter.RouteIndexType == RoutingIndexType.Fastest) 
 +            ​{ 
 +                ​if (buildRtgParameter.SpeedOption.SpeedSourceType ​== RoadSpeedSourceType.BasedOnRoadType ​&& !string.IsNullOrEmpty(buildRtgParameter.SpeedOption.RoadTypeColumnName)) 
 +                ​{ 
 +                    ​string featureRoadClassValue = feature.ColumnValues[buildRtgParameter.SpeedOption.RoadTypeColumnName]; 
 +                    ​e.RouteSegment.Weight = GetDistance(e.RouteSegment.Distance/ GetSpeed(featureRoadClassValue);​ 
 +                ​} 
 +                ​else if (buildRtgParameter.SpeedOption.SpeedSourceType ​== RoadSpeedSourceType.DefinedInAttribution ​&& !string.IsNullOrEmpty(buildRtgParameter.SpeedOption.SpeedColumnName)) 
 +                ​{ 
 +                    ​string speedString = feature.ColumnValues[buildRtgParameter.SpeedOption.SpeedColumnName];​ 
 +                    float speed = float.TryParse(speedString,​ out speed) ? speed : buildRtgParameter.SpeedOption.DefaultSpeed;​ 
 +                    ​e.RouteSegment.Weight = GetDistance(e.RouteSegment.Distance/ speed; 
 +                ​} 
 +                ​else 
 +                ​{ 
 +                    ​e.RouteSegment.Weight = GetDistance(e.RouteSegment.Distance/ buildRtgParameter.SpeedOption.DefaultSpeed;​ 
 +                ​} 
 +            ​} 
 + 
 +            ​e.Cancel = cancelBuilding;​ 
 +        ​} 
 + 
 +        ​private Collection<​string>​ GetRequiredColumns() 
 +        ​{ 
 +            ​Collection<​string>​ requiredColumns = new Collection<​string>​();​ 
 +            ​if (buildRtgParameter.IncludeOnewayOptions) 
 +            ​{ 
 +                ​if (!string.IsNullOrEmpty(buildRtgParameter.OneWayRoadOption.OneWayColumnName)) 
 +                ​{ 
 +                    ​requiredColumns.Add(buildRtgParameter.OneWayRoadOption.OneWayColumnName);​ 
 +                ​} 
 +                ​if (!string.IsNullOrEmpty(buildRtgParameter.OneWayRoadOption.IndicatorColumnName)) 
 +                ​{ 
 +                    ​requiredColumns.Add(buildRtgParameter.OneWayRoadOption.IndicatorColumnName);​ 
 +                ​} 
 +            ​} 
 + 
 +            ​string speedColumn = string.Empty;​ 
 +            ​switch (buildRtgParameter.SpeedOption.SpeedSourceType) 
 +            ​{ 
 +                ​case RoadSpeedSourceType.BasedOnRoadType: 
 +                    ​speedColumn = buildRtgParameter.SpeedOption.RoadTypeColumnName; 
 +                    ​break; 
 +                ​case RoadSpeedSourceType.DefinedInAttribution: 
 +                    ​speedColumn = buildRtgParameter.SpeedOption.SpeedColumnName;​ 
 +                    ​break; 
 +                ​default: 
 +                    ​break; 
 +            ​} 
 +            ​if (!string.IsNullOrEmpty(speedColumn)) 
 +            ​{ 
 +                ​requiredColumns.Add(speedColumn);​ 
 +            ​} 
 + 
 +            ​return requiredColumns;​ 
 +        ​} 
 + 
 +        ​private void ProcessOneWayRoad(BuildingRoutingDataRtgRoutingSourceEventArgs e, Feature roadFeature,​ Collection<​string>​ oneWayColumns) 
 +        ​{ 
 +            ​LineShape lineShape = GetLineShape(roadFeature);​ 
 + 
 +            ​// handled feature is one-way road 
 +            ​if (buildRtgParameter.OneWayRoadOption.MatchOneWayIdentifier(roadFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.OneWayColumnName])) 
 +            { 
 +                if (buildRtgParameter.OneWayRoadOption.MatchStartToEnd(roadFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName])) 
 +                ​{ 
 +                    ​e.RouteSegment.StartPointAdjacentIds.Clear();​ 
 +                ​} 
 +                ​else if (buildRtgParameter.OneWayRoadOption.MatchEndToStart(roadFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName])) 
 +                ​{ 
 +                    ​e.RouteSegment.EndPointAdjacentIds.Clear();​ 
 +                ​} 
 +                ​else if (buildRtgParameter.ClosedRoadOption.MatchClosedRoadValue(roadFeature.ColumnValues[buildRtgParameter.ClosedRoadOption.ClosedColumnName])) 
 +                ​{ 
 +                    ​e.RouteSegment.StartPointAdjacentIds.Clear();​ 
 +                    ​e.RouteSegment.EndPointAdjacentIds.Clear();​ 
 +                ​} 
 +            ​} 
 + 
 +            ​// analysis adjacent one-way road features 
 +            ​Collection<​string>​ removedStartPointAdjacentIds = GetRemovedAdjacentIds(e.RouteSegment.StartPointAdjacentIds,​ new PointShape(lineShape.Vertices[0]),​ oneWayColumns);​ 
 +            ​foreach (string id in removedStartPointAdjacentIds) 
 +            ​{ 
 +                ​e.RouteSegment.StartPointAdjacentIds.Remove(id);​ 
 +            ​} 
 +            ​Collection<​string>​ removedEndPointAdjacentIds = GetRemovedAdjacentIds(e.RouteSegment.EndPointAdjacentIds,​ new PointShape(lineShape.Vertices[lineShape.Vertices.Count - 1]), oneWayColumns);​ 
 +            ​foreach (string id in removedEndPointAdjacentIds) 
 +            ​{ 
 +                ​e.RouteSegment.EndPointAdjacentIds.Remove(id);​ 
 +            ​} 
 +        ​} 
 + 
 +        ​private Collection<​string>​ GetRemovedAdjacentIds(Collection<​string>​ adjacentIds,​ PointShape intersectingPoint,​ Collection<​string>​ oneWayColumns) 
 +        ​{ 
 +            ​Collection<​string>​ removedIds = new Collection<​string>​();​ 
 +            ​foreach (string id in adjacentIds) 
 +            ​{ 
 +                ​Feature adjacentFeature = routableFeatureSource.GetFeatureById(id,​ oneWayColumns);​ 
 +                ​if (buildRtgParameter.OneWayRoadOption.MatchOneWayIdentifier(adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.OneWayColumnName])) 
 +                //if (adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.OneWayColumnName].Equals(buildRtgParameter.OneWayRoadOption.OneWayIdentifier, StringComparison.InvariantCultureIgnoreCase)) 
 +                ​{ 
 +                    ​LineShape adjacentLineShape = GetLineShape(adjacentFeature);​ 
 +                    ​double distanceFromAdjacentStartToIntersecting = new PointShape(adjacentLineShape.Vertices[0]).GetDistanceTo(intersectingPoint,​ buildRtgParameter.GeographyUnit,​ DistanceUnit.Meter); 
 +                    ​double distanceFromAdjacentEndToIntersecting = new PointShape(adjacentLineShape.Vertices[adjacentLineShape.Vertices.Count - 1]).GetDistanceTo(intersectingPoint,​ buildRtgParameter.GeographyUnit,​ DistanceUnit.Meter); 
 +                    ​if (distanceFromAdjacentStartToIntersecting <= distanceFromAdjacentEndToIntersecting && ​buildRtgParameter.OneWayRoadOption.MatchEndToStart(adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName])) 
 +                    //if (distanceFromAdjacentStartToIntersecting <= distanceFromAdjacentEndToIntersecting && adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.EndToStart)) 
 +                    ​{ 
 +                        ​removedIds.Add(id);​ 
 +                    ​} 
 +                    ​else if (distanceFromAdjacentEndToIntersecting <= distanceFromAdjacentStartToIntersecting 
 +                        ​&& ​buildRtgParameter.OneWayRoadOption.MatchStartToEnd(adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName])) 
 +                    //&&​ adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.StartToEnd)) 
 +                    ​{ 
 +                        ​removedIds.Add(id);​ 
 +                    ​} 
 +                    ​else if (buildRtgParameter.ClosedRoadOption.ClosedColumnName != string.Empty && buildRtgParameter.ClosedRoadOption.MatchClosedRoadValue(adjacentFeature.ColumnValues[buildRtgParameter.ClosedRoadOption.ClosedColumnName])) 
 +                    //else if (buildRtgParameter.ClosedRoadOption.ClosedColumnName != string.Empty && adjacentFeature.ColumnValues[buildRtgParameter.ClosedRoadOption.ClosedColumnName].Equals(buildRtgParameter.ClosedRoadOption.ClosedRoadValue)) 
 +                    ​{ 
 +                        ​removedIds.Add(id);​ 
 +                    ​} 
 +                ​} 
 +            ​} 
 +            ​return removedIds; 
 +        ​} 
 + 
 +        ​private float GetSpeed(String featureRoadSpeedClassValue) 
 +        ​{ 
 +            ​float result = buildRtgParameter.SpeedOption.DefaultSpeed;​ 
 +            ​foreach (var item in buildRtgParameter.SpeedOption.RoadSpeeds) 
 +            ​{ 
 +                ​if (item.Key.Equals(featureRoadSpeedClassValue,​ StringComparison.OrdinalIgnoreCase)) 
 +                ​{ 
 +                    ​result = (float)item.Value;​ 
 +                    ​break; 
 +                ​} 
 +            ​} 
 + 
 +            ​return result; 
 +        ​} 
 + 
 +        private float GetDistance(float distanceMeter) 
 +        { 
 +            switch (buildRtgParameter.SpeedOption.SpeedUnit) 
 +            { 
 +                case SpeedUnit.KilometersPerHour:​ 
 +                    return (float)(distanceMeter * 0.001); 
 +                case SpeedUnit.MilesPerHour:​ 
 +                    return (float)(distanceMeter * 0.00062137);​ 
 +            } 
 +            return distanceMeter;​ 
 +        } 
 + 
 +        ​private static LineShape GetLineShape(Feature lineFeature) 
 +        ​{ 
 +            ​BaseShape baseShape = lineFeature.GetShape();​ 
 + 
 +            ​LineShape lineShape = baseShape as LineShape; 
 +            ​if (lineShape == null) 
 +            ​{ 
 +                ​MultilineShape lineShapes = ((MultilineShape)baseShape);​ 
 +                ​Collection<​Vertex>​ vertices = new Collection<​Vertex>​();​ 
 + 
 +                ​foreach (LineShape line in lineShapes.Lines) 
 +                ​{ 
 +                    ​for (int i = 0; i < line.Vertices.Count;​ i++) 
 +                    ​{ 
 +                        ​vertices.Add(line.Vertices[i]);​ 
 +                    ​} 
 +                ​} 
 + 
 +                ​lineShape = new LineShape(vertices);​ 
 +                ​lineShape.Id = baseShape.Id;​ 
 +                ​lineShape.Tag = baseShape.Tag;​ 
 +            ​} 
 + 
 +            ​return lineShape; 
 +        ​} 
 + 
 +        ​protected virtual void OnBuildingRouteRTSegment(RoutingIndexBuilderEventArgs e) 
 +        ​{ 
 +            var handler = BuildingRouteRTSegment;​ 
 +            ​if (handler ​!= null) 
 +            ​{ 
 +                handler(this, ​e); 
 +            } 
 +        } 
 + 
 +        protected virtual void OnBuildingRoutableSegment(RoutingIndexBuilderEventArgs e) 
 +        { 
 +            var handler = BuildingRoutableSegment;​ 
 +            if (handler != null) 
 +            { 
 +                handler(this,​ e); 
 +            } 
 +        } 
 + 
 +        protected virtual void OnExtractingSqliteDatabase(RoutingIndexBuilderEventArgs e) 
 +        { 
 +            var handler = ExtractingSqliteDatabase;​ 
 +            if (handler != null) 
 +            { 
 +                handler(this,​ e); 
 +            } 
 +        } 
 + 
 +        protected virtual void OnBuildingIndexFinished(EventArgs ​e) 
 +        { 
 +            var handler = BuildingIndexFinished;​ 
 +            if (handler != null) 
 +            { 
 +                handler(this,​ e); 
 +            ​} 
 +        ​} 
 +    ​} 
 +} 
 +   
 + </code>
  
  
 ====Program.cs==== ====Program.cs====
-^ Code ^ 
-| <source lang="​csharp"​ line="​1"> ​ \\ using System; ​ \\ using System.Collections.Generic; ​ \\ using System.Linq; ​ \\ using System.Windows.Forms; ​ \\  \\ namespace RoutingIndexGenerator ​ \\ {  \\     ​static class Program ​ \\     ​{ ​ \\         <​nowiki>//</​nowiki>/​ <​summary> ​ \\         <​nowiki>//</​nowiki>/​ The main entry point for the application. ​ \\         <​nowiki>//</​nowiki>/​ </​summary> ​ \\         ​[[STAThread]] ​ \\         ​static void Main() ​ \\         ​{ ​ \\             ​Application.EnableVisualStyles(); ​ \\             ​Application.SetCompatibleTextRenderingDefault(false); ​ \\             ​Application.Run(new RoutingIndexGenerator()); ​ \\         ​} ​ \\     ​} ​ \\ }  \\  \\ </​source> ​  | 
  
 +<code csharp>
 +   
 +using System;
 +using System.Collections.Generic;​
 +using System.Linq;​
 +using System.Windows.Forms;​
  
-====SpeedUnit.cs==== +namespace RoutingIndexGenerator 
-^ Code ^ +{ 
-<source lang="​csharp"​ line="​1"​ ​\\ ​ \\ namespace RoutingIndexGenerator ​ \\  ​\\ ​    ​public enum SpeedUnit ​ \\     ​{ ​ \\         ​kilometer_hour = 0,  \\         ​mile_hour = 1  \\      ​\\ ​}  ​\\  \\ </source  |+    ​static class Program 
 +    { 
 +        /// <summary> 
 +        /// The main entry point for the application. 
 +        /// </​summary>​ 
 +        [STAThread] 
 +        static void Main() 
 +        ​{ 
 +            Application.EnableVisualStyles();​ 
 +            Application.SetCompatibleTextRenderingDefault(false);​ 
 +            Application.Run(new RoutingIndexGenerator());​ 
 +        ​} 
 +    } 
 +}  ​ 
 +   
 + </code>
  
  
 +====SpeedUnit.cs====
  
-====SpeedType.cs==== +<code csharp> ​  
-^ Code ^ +
-<source lang="csharp" line="​1"> ​ \\  \\  \\ namespace RoutingIndexGenerator ​ \\ {  \\     ​public enum SpeedType ​ \\     ​{ ​ \\         ​RoadClass = 0,  \\         ​RoadSpeed = 1,  \\         ​DefaultSpeed = 2  \\     ​} ​ \\ }  \\  \\ </source>   |+
  
 +namespace RoutingIndexGenerator
 +{
 +    public enum SpeedUnit
 +    {
 +        KilometersPerHour = 0,
 +        MilesPerHour = 1
 +    }
 +}
 +  ​
 +</​code>​
  
-====RouteIndexType.cs==== +====RoutingIndexType.cs====
-^ Code ^ +
-| <source lang="​csharp"​ line="​1"> ​ \\  \\  \\ namespace RoutingIndexGenerator ​ \\ {  \\     ​public enum RouteIndexType ​ \\     ​{ ​ \\         ​Fastest = 0,  \\         ​Shortest = 1  \\     ​} ​ \\ }  \\  \\  \\ </​source> ​  |+
  
 +<code csharp> ​  
 +  ​
 +namespace RoutingIndexGenerator
 +{
 +    public enum RoutingIndexType
 +    {
 +        Fastest = 0,
 +        Shortest = 1
 +    }
 +}
 +  ​
 + </​code>​
  
 ====RoadSpeedOption.cs==== ====RoadSpeedOption.cs====
-^ Code ^ + 
-<source lang="csharp" line="​1"​>  ​\\  \\ using System.Collections.Generic; ​ ​\\ ​ \\ namespace RoutingIndexGenerator ​ ​\\ ​ ​\\ ​    public class RoadSpeedOption ​ ​\\ ​     ​\\ ​        private SpeedUnit speedUnit; ​ ​\\ ​        private float defaultSpeed; ​ ​\\ ​        private ​SpeedType speedType ​\\ ​        private string ​speedColumnName ​\\ ​        private string ​roadClassColumnName ​\\ ​        private Dictionary<​string,​ double> roadSpeeds; ​ ​\\ ​ \\         public RoadSpeedOption() ​ ​\\ ​         ​\\ ​            DefaultSpeed = 60 ​\\ ​            ​SpeedType = SpeedType.DefaultSpeed; ​ \\             SpeedUnit = SpeedUnit.kilometer_hour ​\\ ​         ​\\ ​ \\         public SpeedUnit SpeedUnit ​ ​\\ ​         ​\\ ​            get { return speedUnit; }  ​\\ ​            set { speedUnit = value; }  ​\\ ​         ​\\ ​ \\         public float DefaultSpeed ​ ​\\ ​         ​\\ ​            get { return defaultSpeed;​ }  ​\\ ​            set { defaultSpeed = value; }  ​\\ ​         ​\\ ​ \\         public ​SpeedType SpeedType ​ \\          ​\\ ​            get { return ​speedType; }  ​\\ ​            set { speedType ​= value; }  ​\\ ​         ​\\ ​ \\         public string SpeedColumnName ​ ​\\ ​         ​\\ ​            get { return ​speedColumnName; }  ​\\ ​            set { speedColumnName ​= value; }  ​\\ ​         ​\\ ​ \\         public string ​RoadClassColumnName ​ \\          ​\\ ​            get { return ​roadClassColumnName; }  ​\\ ​            set { roadClassColumnName ​= value; }  ​\\ ​         ​\\ ​ \\         public Dictionary<​string,​ double> RoadSpeeds ​ ​\\ ​         ​\\ ​            get  ​\\ ​             ​\\ ​                if (roadSpeeds == null)  ​\\ ​                 ​\\ ​                    roadSpeeds = new Dictionary<​string,​ double>​(); ​ ​\\ ​                 ​\\ ​                return roadSpeeds; ​ ​\\ ​             ​\\ ​         ​\\ ​     ​\\ ​}  ​\\  \\  \\ </source  |+<code csharp> ​   
 +   
 + using System.Collections.Generic;​ 
 + 
 +namespace RoutingIndexGenerator 
 +{ 
 +    ​public class RoadSpeedOption 
 +    ​{ 
 +        ​private SpeedUnit speedUnit; 
 +        ​private float defaultSpeed;​ 
 +        ​private ​RoadSpeedSourceType roadSpeedSourceType; 
 +        ​private string ​roadSpeedColumnName; 
 +        ​private string ​roadTypeColumnName; 
 +        ​private Dictionary<​string,​ double> roadSpeeds; 
 + 
 +        ​public RoadSpeedOption() 
 +        ​{ 
 +            ​DefaultSpeed = 50; 
 +            ​SpeedUnit = SpeedUnit.KilometersPerHour; 
 +        ​} 
 + 
 +        ​public SpeedUnit SpeedUnit 
 +        ​{ 
 +            ​get { return speedUnit; } 
 +            ​set { speedUnit = value; } 
 +        ​} 
 + 
 +        ​public float DefaultSpeed 
 +        ​{ 
 +            ​get { return defaultSpeed;​ } 
 +            ​set { defaultSpeed = value; } 
 +        ​} 
 + 
 +        ​public ​RoadSpeedSourceType SpeedSourceType 
 +        ​{ 
 +            ​get { return ​roadSpeedSourceType; } 
 +            ​set { roadSpeedSourceType ​= value; } 
 +        ​} 
 + 
 +        ​public string SpeedColumnName 
 +        ​{ 
 +            ​get { return ​roadSpeedColumnName; } 
 +            ​set { roadSpeedColumnName ​= value; } 
 +        ​} 
 + 
 +        ​public string ​RoadTypeColumnName 
 +        ​{ 
 +            ​get { return ​roadTypeColumnName; } 
 +            ​set { roadTypeColumnName ​= value; } 
 +        ​} 
 + 
 +        ​public Dictionary<​string,​ double> RoadSpeeds 
 +        ​{ 
 +            ​get 
 +            ​{ 
 +                ​if (roadSpeeds == null) 
 +                ​{ 
 +                    ​roadSpeeds = new Dictionary<​string,​ double>​();​ 
 +                ​} 
 +                ​return roadSpeeds; 
 +            ​} 
 +        ​} 
 +    ​} 
 +}  ​ 
 +   
 + </code>
  
  
  
 ====OneWayRoadOption.cs==== ====OneWayRoadOption.cs====
-^ Code ^ 
-| <source lang="​csharp"​ line="​1"> ​ \\  \\  \\ namespace RoutingIndexGenerator ​ \\ {  \\     ​public class OneWayRoadOption ​ \\     ​{ ​ \\         ​private string oneWayColumnName; ​ \\         ​private string bothWayRoadValue; ​ \\         ​private string indicatorColumnName; ​ \\         ​private string fromToValue; ​ \\         ​private string toFromValue; ​ \\         ​private string closedRoad; ​ \\  \\         ​public OneWayRoadOption() ​ \\         { }  \\  \\         ​public string OneWayColumnName ​ \\         ​{ ​ \\             get { return oneWayColumnName;​ }  \\             set { oneWayColumnName = value; }  \\         ​} ​ \\  \\         ​public string BothWayRoadValue ​ \\         ​{ ​ \\             get { return bothWayRoadValue;​ }  \\             set { bothWayRoadValue = value; }  \\         ​} ​ \\  \\         ​public string IndicatorColumnName ​ \\         ​{ ​ \\             get { return indicatorColumnName;​ }  \\             set { indicatorColumnName = value; }  \\         ​} ​ \\  \\         ​public string FromToValue ​ \\         ​{ ​ \\             get { return fromToValue;​ }  \\             set { fromToValue = value; }  \\         ​} ​ \\  \\         ​public string ToFromValue ​ \\         ​{ ​ \\             get { return toFromValue;​ }  \\             set { toFromValue = value; }  \\         ​} ​ \\  \\         ​public string ClosedRoad ​ \\         ​{ ​ \\             get { return closedRoad; }  \\             set { closedRoad = value; }  \\         ​} ​ \\     ​} ​ \\ }  \\  \\  \\ </​source> ​  | 
  
 +<code csharp> ​  
 +  ​
 + using System;
 +using System.Text.RegularExpressions;​
 +
 +namespace RoutingIndexGenerator
 +{
 +    public class OneWayRoadOption
 +    {
 +        private string oneWayColumnName;​
 +        private string oneWayIdentifier;​
 +        private string indicatorColumnName;​
 +        private string startToEnd;
 +        private string endToStart;
 +
 +        private Regex startToEndRegex;​
 +        private Regex endToStartRegex;​
 +        private Regex oneWayIdentifierRegex;​
 +
 +        public OneWayRoadOption()
 +        { }
 +
 +        public string OneWayColumnName
 +        {
 +            get { return oneWayColumnName;​ }
 +            set { oneWayColumnName = value; }
 +        }
 +
 +        public string IndicatorColumnName
 +        {
 +            get { return indicatorColumnName;​ }
 +            set { indicatorColumnName = value; }
 +        }
 +
 +        public string OneWayIdentifier
 +        {
 +            get { return oneWayIdentifier;​ }
 +            set { oneWayIdentifier = value; }
 +        }
 +
 +        public string StartToEnd
 +        {
 +            get { return startToEnd; }
 +            set { startToEnd = value; }
 +        }
 +
 +        public string EndToStart
 +        {
 +            get { return endToStart; }
 +            set { endToStart = value; }
 +        }
 +
 +        private Regex GetRegex(string stringToMatch)
 +        {
 +            if (String.IsNullOrEmpty(stringToMatch))
 +            {
 +                return null;
 +            }
 +
 +            Regex regex = null;
 +
 +            if (stringToMatch.StartsWith("​["​) && stringToMatch.EndsWith("​]"​))
 +            {
 +                string regexString = stringToMatch.Substring(1,​ stringToMatch.Length - 2);
 +                regex = new Regex(regexString,​ RegexOptions.Compiled);​
 +            }
 +
 +            return regex;
 +        }
 +
 +        public void InitRegexes()
 +        {
 +            this.endToStartRegex = GetRegex(this.endToStart);​
 +            this.startToEndRegex = GetRegex(this.startToEnd);​
 +            this.oneWayIdentifierRegex = GetRegex(this.oneWayIdentifier);​
 +        }
 +
 +        public bool MatchEndToStart(string endToStart)
 +        {
 +            bool match = false;
 +            if (endToStartRegex == null)
 +            {
 +                match = endToStart.Equals(this.endToStart,​ StringComparison.InvariantCultureIgnoreCase);​
 +            }
 +            else
 +            {
 +                match = endToStartRegex.Match(endToStart).Success;​
 +            }
 +            return match;
 +        }
 +
 +        public bool MatchStartToEnd(string startToEnd)
 +        {
 +            bool match = false;
 +            if (startToEndRegex == null)
 +            {
 +                match = startToEnd.Equals(this.startToEnd,​ StringComparison.InvariantCultureIgnoreCase);​
 +            }
 +            else
 +            {
 +                match = startToEndRegex.Match(startToEnd).Success;​
 +            }
 +            return match;
 +        }
 +
 +        public bool MatchOneWayIdentifier(string oneWayIdentifier)
 +        {
 +            bool match = false;
 +            if (oneWayIdentifierRegex == null)
 +            {
 +                match = oneWayIdentifier.Equals(this.oneWayIdentifier,​ StringComparison.InvariantCultureIgnoreCase);​
 +            }
 +            else
 +            {
 +                match = oneWayIdentifierRegex.Match(oneWayIdentifier).Success;​
 +            }
 +            return match;
 +        }
 +    }
 +}
 +
 + </​code>​
 +
 +====RoutingIndexBuilderParameters.cs====
 +
 +<code csharp> ​  
 +  ​
 +using System.IO;
 +using ThinkGeo.MapSuite.Core;​
 +using ThinkGeo.MapSuite.Routing;​
 +
 +namespace RoutingIndexGenerator
 +{
 +    public class RoutingIndexBuilderParameters
 +    {
 +        private BuildRoutingDataMode buildRoutingDataMode;​
 +        private GeographyUnit geographyUnit;​
 +        private OneWayRoadOption oneWayRoadOption;​
 +        private ClosedRoadOption closedRoadOption;​
 +        private RoadSpeedOption speedOption;​
 +        private RoutingIndexType routeIndexType;​
 +        private RectangleShape restrictExtent;​
 +        private string routableShapeFilePathName;​
 +        private string rtgFilePathName;​
 +        private string sourceSqlitePathName;​
 +        private bool includeOnewayOptions;​
 +        private bool overrideRoutableFile;​
 +
 +        public RoutingIndexBuilderParameters()
 +        {
 +            RouteIndexType = RoutingIndexType.Fastest;​
 +            GeographyUnit = GeographyUnit.Meter;​
 +            BuildRoutingDataMode = BuildRoutingDataMode.Rebuild;​
 +
 +            OneWayRoadOption = new OneWayRoadOption();​
 +            closedRoadOption = new ClosedRoadOption();​
 +            SpeedOption = new RoadSpeedOption();​
 +            overrideRoutableFile = true;
 +        }
 +
 +        public RectangleShape RestrictExtent
 +        {
 +            get { return restrictExtent;​ }
 +            set { restrictExtent = value; }
 +        }
 +
 +        public BuildRoutingDataMode BuildRoutingDataMode
 +        {
 +            get { return buildRoutingDataMode;​ }
 +            set { buildRoutingDataMode = value; }
 +        }
 +
 +        public GeographyUnit GeographyUnit
 +        {
 +            get { return geographyUnit;​ }
 +            set { geographyUnit = value; }
 +        }
 +
 +        public OneWayRoadOption OneWayRoadOption
 +        {
 +            get { return oneWayRoadOption;​ }
 +            set { oneWayRoadOption = value; }
 +        }
 +
 +        public RoadSpeedOption SpeedOption
 +        {
 +            get { return speedOption;​ }
 +            set { speedOption = value; }
 +        }
 +
 +        public ClosedRoadOption ClosedRoadOption
 +        {
 +            get { return closedRoadOption;​ }
 +            set { closedRoadOption = value; }
 +        }
 +
 +        public RoutingIndexType RouteIndexType
 +        {
 +            get { return routeIndexType;​ }
 +            set { routeIndexType = value; }
 +        }
 +
 +        public string RtgFilePathName
 +        {
 +            get { return rtgFilePathName;​ }
 +            set { rtgFilePathName = value; }
 +        }
 +
 +        public string RoutableShapeFilePathName
 +        {
 +            get { return routableShapeFilePathName;​ }
 +            set { routableShapeFilePathName = value; }
 +        }
 +
 +        public string SourceSqlitePathName
 +        {
 +            get { return sourceSqlitePathName;​ }
 +            set { sourceSqlitePathName = value; }
 +        }
 +
 +        public string SourceShapefilePathName
 +        {
 +           get { return Path.ChangeExtension(sourceSqlitePathName,​ "​.source.shp"​);​ ; }
 +        }
 +
 +        public bool IncludeOnewayOptions
 +        {
 +            get { return includeOnewayOptions;​ }
 +            set { includeOnewayOptions = value; }
 +        }
 +
 +        public bool OverrideRoutableFile
 +        {
 +            get { return overrideRoutableFile;​ }
 +            set { overrideRoutableFile = value; }
 +        }
 +    }
 +}  ​
 +  ​
 + </​code>​
 +
 +====RoutingIndexBuilderEventArgs.cs====
 +
 +<code csharp> ​  
 +
 +using System;
 +
 +namespace RoutingIndexGenerator
 +{
 +    public class RoutingIndexBuilderEventArgs : EventArgs
 +    {
 +        private int totalRecordAccount;​
 +        private int processedRecordAccount;​
 +
 +        public RoutingIndexBuilderEventArgs()
 +        { }
 +
 +        public RoutingIndexBuilderEventArgs(int totalRecordAccount,​ int processedRecordAccount)
 +        {
 +            this.totalRecordAccount = totalRecordAccount;​
 +            this.processedRecordAccount = processedRecordAccount;​
 +        }
 +
 +        public int TotalRecordCount
 +        {
 +            get { return totalRecordAccount;​ }
 +            set { totalRecordAccount = value; }
 +        }
 +
 +        public int ProcessedRecordCount
 +        {
 +            get { return processedRecordAccount;​ }
 +            set { processedRecordAccount = value; }
 +        }
 +    }
 +}
 +
 +</​code>​
 +
 +====ClosedRoadOptions.cs====
 +
 +<code csharp> ​  
 +  ​
 +  using System;
 +using System.Text.RegularExpressions;​
 +namespace RoutingIndexGenerator
 +{
 +    public class ClosedRoadOption
 +    {
 +        private string closedRoadValue;​
 +        private string closedColumnName;​
 +        private Regex closedRoadValueRegex;​
 +
 +        public string ClosedColumnName
 +        {
 +            get { return closedColumnName;​ }
 +            set { closedColumnName = value; }
 +        }
 +
 +        public string ClosedRoadValue
 +        {
 +            get { return closedRoadValue;​ }
 +            set { closedRoadValue = value; }
 +        }
 +
 +        private Regex GetRegex(string stringToMatch)
 +        {
 +            if (String.IsNullOrEmpty(stringToMatch))
 +            {
 +                return null;
 +            }
 +
 +            Regex regex = null;
 +
 +            if (stringToMatch.StartsWith("​["​) && stringToMatch.EndsWith("​]"​))
 +            {
 +                string regexString = stringToMatch.Substring(1,​ stringToMatch.Length - 2);
 +                regex = new Regex(regexString,​ RegexOptions.Compiled);​
 +            }
 +
 +            return regex;
 +        }
  
 +        public void InitRegexes()
 +        {
 +            this.closedRoadValueRegex = GetRegex(this.closedRoadValue);​
 +        }
  
-====BuildRoutingIndexParameters.cs==== +        ​public bool MatchClosedRoadValue(string ​closedRoadValue) 
-^ Code ^ +        ​{ 
-| <source lang="​csharp"​ line="​1"> ​ \\  \\ using System.IO; ​ \\ using ThinkGeo.MapSuite.Core; ​ \\ using ThinkGeo.MapSuite.Routing; ​ \\  \\ namespace RoutingIndexGenerator ​ \\ {  \\     public ​class BuildRoutingIndexParameters ​ \\     ​{ ​ \\         ​private BuildRoutingDataMode buildRoutingDataMode; ​ \\         ​private DistanceUnit distanceUnit; ​ \\         ​private GeographyUnit geographyUnit; ​ \\         ​private OneWayRoadOption oneWayRoadOption; ​ \\         ​private RouteIndexType routeIndexType; ​ \\         ​private string rtgFilePathName; ​ \\         ​private string shapefilePathName; ​ \\         ​private ​bool skipOnewayOptions; ​ \\         ​private RoadSpeedOption speedOption; ​ \\  \\         ​public BuildRoutingIndexParameters()  \\         ​{ ​ \\             ​DistanceUnit = DistanceUnit.Meter; ​ \\             ​RouteIndexType = RouteIndexType.Shortest; ​ \\             ​GeographyUnit = GeographyUnit.DecimalDegree; ​ \\             ​BuildRoutingDataMode = BuildRoutingDataMode.Rebuild; ​ \\  \\             ​OneWayRoadOption = new OneWayRoadOption(); ​ \\             ​SpeedOption = new RoadSpeedOption(); ​ \\         ​} ​ \\  \\         ​public BuildRoutingDataMode BuildRoutingDataMode ​ \\         ​{ ​ \\             get { return buildRoutingDataMode;​ }  \\             set { buildRoutingDataMode = value; }  \\         ​} ​ \\  \\         ​public DistanceUnit DistanceUnit ​ \\         ​{ ​ \\             get { return distanceUnit;​ }  \\             set { distanceUnit = value; }  \\         ​} ​ \\  \\         ​public GeographyUnit GeographyUnit ​ \\         ​{ ​ \\             get { return geographyUnit;​ }  \\             set { geographyUnit = value; }  \\         ​} ​ \\  \\         ​public OneWayRoadOption OneWayRoadOption ​ \\         ​{ ​ \\             get { return oneWayRoadOption;​ }  \\             set { oneWayRoadOption = value; }  \\         ​} ​ \\  \\         ​public RouteIndexType RouteIndexType ​ \\         ​{ ​ \\             get { return routeIndexType;​ }  \\             set { routeIndexType = value; }  \\         ​} ​ \\  \\         ​public ​string ​RtgFilePathName ​ \\         ​{ ​ \\             get { return rtgFilePathName;​ }  \\             ​set ​ \\             ​{ ​ \\                 ​rtgFilePathName = !string.IsNullOrEmpty(value? Path.ChangeExtension(value,​ "​.rtg"​) : string.Empty; ​ \\             ​} ​ \\         ​} ​ \\  \\         ​public string ShapefilePathName ​ \\          ​\\ ​            get { return shapefilePathName;​ }  \\             ​set ​ \\             ​{ ​ \\                 ​shapefilePathName = value; ​ \\                 ​RtgFilePathName = Path.ChangeExtension(shapefilePathName,​ "​.rtg"​); ​ \\             ​} ​ \\         ​} ​ \\  \\         ​public ​bool SkipOnewayOptions ​ \\         ​{ ​ \\             get { return skipOnewayOptions;​ }  \\             set { skipOnewayOptions ​value}  \\         ​} ​ \\  \\         ​public RoadSpeedOption SpeedOption ​ \\         ​{ ​ \\             get { return speedOption;​ }  \\             set { speedOption = value; }  \\         ​} ​ \\  \\         ​public bool CheckCanBuildIndexFile() ​ \\         ​{ ​ \\             bool result = SpeedOption.DefaultSpeed != 0;  \\             ​try ​ \\             ​{ ​ \\                 ​ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(ShapefilePathName); ​ \\                 ​layer.Open(); ​ \\                 ​ShapeFileType fileType = layer.GetShapeFileType(); ​ \\                 ​layer.Close(); ​ \\  \\                 if (fileType !ShapeFileType.Polyline) ​ \\                 ​{ ​ \\                     ​result ​false; ​ \\                 ​} ​ \\             ​} ​ \\             ​catch ​ \\             ​{ ​ \\                 ​result = false; ​ \\             ​} ​ \\  \\             if (result && string.IsNullOrEmpty(rtgFilePathName))  \\              ​\\ ​                ​result ​false; ​ \\             ​} ​ \\             else if (result && !SkipOnewayOptions && (string.IsNullOrEmpty(OneWayRoadOption.BothWayRoadValue) ​ \\                 || string.IsNullOrEmpty(OneWayRoadOption.FromToValue|| string.IsNullOrEmpty(OneWayRoadOption.ToFromValue) ​ \\                 || string.IsNullOrEmpty(OneWayRoadOption.IndicatorColumnName) || string.IsNullOrEmpty(OneWayRoadOption.OneWayColumnName))) ​ \\             ​{ ​ \\                 ​result = false ​\\ ​             ​\\ ​            else if ((result && SpeedOption.SpeedType ​== SpeedType.RoadClass) ​ \\                 && ​(string.IsNullOrEmpty(SpeedOption.RoadClassColumnName|| SpeedOption.RoadSpeeds.Count == 0))  \\             ​{ ​ \\                 ​result = false ​\\ ​             ​\\ ​            else if (result && SpeedOption.SpeedType == SpeedType.RoadSpeed ​ \\                 &&​ string.IsNullOrEmpty(SpeedOption.SpeedColumnName)) ​ \\             ​{ ​ \\                 ​result = false; ​ \\             ​} ​ \\  \\             return ​result ​\\ ​        ​} ​ \\     ​} ​ \\  ​\\ ​ \\ </​source> ​  |+            ​bool match false; 
 +            ​if (closedRoadValue ​== null) 
 +            ​{ 
 +                match closedRoadValue.Equals(this.closedRoadValue,​ StringComparison.InvariantCultureIgnoreCase); 
 +            ​} 
 +            ​else 
 +            { 
 +                match closedRoadValueRegex.Match(closedRoadValue).Success; 
 +            ​} 
 +            ​return ​match; 
 +        ​}
  
 +    }
 +}
  
 +</​code>​
source_code_routing_index_generator_cs_100325.zip.1440040125.txt.gz · Last modified: 2015/09/09 03:33 (external edit)