This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | |||
source_code_routing_index_generator_cs_100325.zip [2015/09/09 03:33] admin |
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 ====== |
====RoutingIndexGenerator.cs==== | ====RoutingIndexGenerator.cs==== | ||
Line 6: | Line 5: | ||
<code csharp> | <code csharp> | ||
| | ||
- | using System; | + | using System; |
- | using System.Collections.ObjectModel; | + | using System.Collections.Generic; |
- | using System.IO; | + | using System.Collections.ObjectModel; |
- | using System.Linq; | + | using System.Data; |
- | using System.Threading.Tasks; | + | using System.IO; |
- | using System.Windows.Forms; | + | using System.Linq; |
- | using RoutingIndexGenerator.Properties; | + | using System.Threading.Tasks; |
- | using ThinkGeo.MapSuite.Core; | + | using System.Windows.Forms; |
- | using ThinkGeo.MapSuite.Routing; | + | using System.Xml.Linq; |
- | + | using ThinkGeo.MapSuite.Core; | |
- | namespace RoutingIndexGenerator | + | using ThinkGeo.MapSuite.Routing; |
- | { | + | |
- | public partial class RoutingIndexGenerator : Form | + | namespace RoutingIndexGenerator |
- | { | + | { |
- | private bool isBuildingRtgFile; | + | public partial class RoutingIndexGenerator : Form |
- | private RoutingIndexFileBuilder builder; | + | { |
- | private BuildRoutingIndexParameters buildRoutingIndexParameters; | + | // 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; | |
- | public RoutingIndexGenerator() | + | private ConfigModel currentConfigModel; |
- | { | + | private RoutingIndexBuilder routingIndexbuilder; |
- | InitializeComponent(); | + | private Dictionary<string, ConfigModel> configModelsDictionary; |
- | + | ||
- | //initialization parameters. | + | public RoutingIndexGenerator() |
- | buildRoutingIndexParameters = new BuildRoutingIndexParameters(); | + | { |
- | + | InitializeComponent(); | |
- | //read the options for parameter and refresh the Uis | + | |
- | cmbGeographyUnit.SelectedIndex = (int)buildRoutingIndexParameters.GeographyUnit; | + | configModelsDictionary = new Dictionary<string, ConfigModel>(); |
- | cmbDistanceUnit.SelectedIndex = (int)buildRoutingIndexParameters.DistanceUnit; | + | |
- | cmbRouteIndexType.SelectedIndex = (int)buildRoutingIndexParameters.RouteIndexType; | + | if (File.Exists("InitConfig.xml")) |
- | cmbSpeedUnit.SelectedIndex = (int)buildRoutingIndexParameters.SpeedOption.SpeedUnit; | + | { |
- | } | + | ConfigModel model = new ConfigModel("InitConfig.xml"); |
- | + | string key = model.FileType.Split('|').Last(); | |
- | private void btnGenerate_Click(object sender, EventArgs e) | + | configModelsDictionary.Add(key, model); |
- | { | + | } |
- | isBuildingRtgFile = true; | + | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | if (File.Exists("WkbConfig.xml")) |
- | + | { | |
- | //display the ProgressBar. | + | ConfigModel model = new ConfigModel("WkbConfig.xml"); |
- | pnlProgress.Visible = true; | + | string key = model.FileType.Split('|').Last(); |
- | + | configModelsDictionary.Add(key, model); | |
- | //create a new RoutingIndexFileBuilder. | + | } |
- | builder = new RoutingIndexFileBuilder(buildRoutingIndexParameters); | + | |
- | + | // We will always load shapefile configuration by default, even there is no configuration file. | |
- | //Add a event to display refresh the ProgressBar. | + | if (!configModelsDictionary.Any(i => i.Value.FileType.Contains("*.shp"))) |
- | builder.BuildingRouteSegment += new EventHandler<EventArgs>(builder_BuildingRouteSegment); | + | { |
- | + | ConfigModel model = new ConfigModel(XDocument.Parse(Properties.Resources.DefaultConfig)); | |
- | //Start build index file(.rtg). | + | string key = model.FileType.Split('|').Last(); |
- | Task.Factory.StartNew(() => | + | configModelsDictionary.Add(key, model); |
- | { | + | } |
- | builder.StartBuildingRtgFile(); | + | } |
- | }); | + | |
- | } | + | private void btnBrowseSqliteFile_Click(object sender, EventArgs e) |
- | + | { | |
- | private void builder_BuildingRouteSegment(object sender, EventArgs e) | + | OpenFileDialog fileDialog = new OpenFileDialog(); |
- | { | + | fileDialog.Filter = GetSelectFileFilter(); |
- | this.BeginInvoke(new Action(() => | + | |
- | { | + | if (fileDialog.ShowDialog() == DialogResult.OK) |
- | //refresh the progress and display the total record count. | + | { |
- | lblSegmentCount.Text = builder.TotalRecordCount.ToString(); | + | string currentKey = string.Format("*.{0}", fileDialog.FileName.Split('.').Last()); |
- | pgbBuildProgress.Value = builder.ProcessedRecordCount * 100 / builder.TotalRecordCount; | + | currentConfigModel = configModelsDictionary[currentKey]; |
- | + | ||
- | if (pgbBuildProgress.Value == 100) | + | // Get the bounding box of the feature source. |
- | { | + | |
- | isBuildingRtgFile = false; | + | FeatureSource featureSource = null; |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | if (currentConfigModel.FileType.EndsWith(".sqlite", StringComparison.InvariantCultureIgnoreCase)) |
- | MessageBox.Show(this, Resources.FinishBuildIndexFile, "Completed"); | + | { |
- | } | + | 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)) |
- | + | { | |
- | private void btnBrowseShapeFile_Click(object sender, EventArgs e) | + | featureSource = new ShapeFileFeatureSource(fileDialog.FileName); |
- | { | + | ((ShapeFileFeatureSource)featureSource).RequireIndex = false; |
- | //create dialog to select the shape file. | + | } |
- | OpenFileDialog fileDialog = new OpenFileDialog(); | + | if (currentConfigModel.FileType.EndsWith(".wkb", StringComparison.InvariantCultureIgnoreCase)) |
- | fileDialog.Multiselect = false; | + | { |
- | fileDialog.Filter = Resources.ShapeFileFilterString; | + | featureSource = new WkbFileFeatureSource(fileDialog.FileName); |
- | + | } | |
- | if (fileDialog.ShowDialog() == DialogResult.OK) | + | |
- | { | + | featureSource.Open(); |
- | CheckFileIsRequirement(fileDialog.FileName); | + | WellKnownType wellKnownType = featureSource.GetFirstFeaturesWellKnownType(); |
- | + | if (wellKnownType != WellKnownType.Line && wellKnownType != WellKnownType.Multiline) | |
- | txtShapeFilePath.Text = buildRoutingIndexParameters.ShapefilePathName; | + | { |
- | txtIndexFilePath.Text = buildRoutingIndexParameters.RtgFilePathName; | + | ShowErrorMessageBox(); |
- | } | + | return; |
- | + | } | |
- | //check can build index file. | + | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | txtDataProviderFilePath.Text = fileDialog.FileName; |
- | } | + | txtRoutableFile.Text = Path.ChangeExtension(fileDialog.FileName, ".routable.shp"); |
- | + | txtIndexFilePath.Text = Path.ChangeExtension(fileDialog.FileName, ".routable.rtg"); | |
- | private void btnSaveRtgFile_Click(object sender, EventArgs e) | + | |
- | { | + | RectangleShape boundingBox = featureSource.GetBoundingBox(); |
- | //create dialog to save the .rtg file. | + | txtUpperLeftX.Text = string.Format("{0},{1}", boundingBox.UpperLeftPoint.X, boundingBox.UpperLeftPoint.Y); |
- | SaveFileDialog saveFileDialog = new SaveFileDialog(); | + | txtLowerRightX.Text = string.Format("{0},{1}", boundingBox.LowerRightPoint.X, boundingBox.LowerRightPoint.Y); |
- | saveFileDialog.FileName = buildRoutingIndexParameters.RtgFilePathName; | + | |
- | saveFileDialog.Filter = Resources.RoutingIndexFileFilterString; | + | // Get the columns of the feature source. |
- | saveFileDialog.DefaultExt = ".rtg"; | + | Collection<FeatureSourceColumn> columns = featureSource.GetColumns(); |
- | if (saveFileDialog.ShowDialog() == DialogResult.OK) | + | featureSource.Close(); |
- | { | + | |
- | txtIndexFilePath.Text = saveFileDialog.FileName; | + | if (boundingBox.UpperLeftPoint.X < -180 || boundingBox.UpperLeftPoint.Y > 90 || boundingBox.LowerRightPoint.X > 180 || boundingBox.LowerRightPoint.Y < -90) |
- | } | + | { |
- | + | cmbGeographyUnit.SelectedIndex = 2; | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | } |
- | } | + | else |
- | + | { | |
- | private void txtIndexFilePath_TextChanged(object sender, EventArgs e) | + | cmbGeographyUnit.SelectedIndex = 0; |
- | { | + | } |
- | buildRoutingIndexParameters.RtgFilePathName = txtIndexFilePath.Text; | + | |
- | txtIndexFilePath.Text = buildRoutingIndexParameters.RtgFilePathName; | + | InitCombColumns(cmbOnewayRoadColumn, columns, currentConfigModel.IdentifierColumnName); |
- | + | InitCombColumns(cmbOnewayIndicatorColumn, columns, currentConfigModel.IndicatorColumnName); | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | InitCombColumns(cmbRoadClassColumn, columns, currentConfigModel.SpeedColumnName); |
- | } | + | InitCombColumns(cmbSpeedColumn, columns, currentConfigModel.SpeedColumnName); |
- | + | InitCombColumns(cmbClosedRoadColumn, columns, currentConfigModel.ClosedColumnName); | |
- | private void txtDefaultSpeed_TextChanged(object sender, EventArgs e) | + | |
- | { | + | if (currentConfigModel.RoutingIndexType == 0) |
- | float speed = buildRoutingIndexParameters.SpeedOption.DefaultSpeed; | + | { |
- | buildRoutingIndexParameters.SpeedOption.DefaultSpeed = float.TryParse(txtDefaultSpeed.Text, out speed) ? speed : 0; | + | rbtnClassSpeed.Checked = true; |
- | + | tbOptions.Enabled = true; | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | } |
- | } | + | |
- | + | cmbRouteIndexType.SelectedIndex = currentConfigModel.RoutingIndexType; | |
- | private void chkSkipOnewayOptions_CheckedChanged(object sender, EventArgs e) | + | cmbSpeedUnit.SelectedIndex = currentConfigModel.SpeedUnit; |
- | { | + | |
- | buildRoutingIndexParameters.SkipOnewayOptions = chkSkipOnewayOptions.Checked; | + | txtDefaultSpeed.Text = currentConfigModel.DefaultSpeed.ToString(); |
- | pnlOnewayOptions.Enabled = !chkSkipOnewayOptions.Checked; | + | txtOneWayRoadValue.Text = currentConfigModel.IdentifierColumnValue; |
- | + | txtFromToValue.Text = currentConfigModel.IndicatorStartEndValue; | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | |
- | } | + | btnGenerate.Enabled = true; |
- | + | } | |
- | private void chkRebuildRtgFile_CheckedChanged(object sender, EventArgs e) | + | } |
- | { | + | |
- | buildRoutingIndexParameters.BuildRoutingDataMode = chkRebuildRtgFile.Checked ? BuildRoutingDataMode.Rebuild : BuildRoutingDataMode.DoNotRebuild; | + | private void btnGenerate_Click(object sender, EventArgs e) |
- | } | + | { |
- | + | RoutingIndexBuilderParameters buildRoutingIndexParameters = GetIndexBuildingParameters(); | |
- | private void RouteOptionComboBox_SelectedIndexChanged(object sender, EventArgs e) | + | if (buildRoutingIndexParameters == null) |
- | { | + | { |
- | buildRoutingIndexParameters.GeographyUnit = cmbGeographyUnit.SelectedIndex != -1 ? (GeographyUnit)cmbGeographyUnit.SelectedIndex | + | return; |
- | : buildRoutingIndexParameters.GeographyUnit; | + | } |
- | + | ||
- | buildRoutingIndexParameters.DistanceUnit = cmbDistanceUnit.SelectedIndex != -1 ? (DistanceUnit)cmbDistanceUnit.SelectedIndex | + | //create a new RoutingIndexFileBuilder. |
- | : buildRoutingIndexParameters.DistanceUnit; | + | routingIndexbuilder = new RoutingIndexBuilder(buildRoutingIndexParameters); |
- | + | ||
- | buildRoutingIndexParameters.RouteIndexType = cmbRouteIndexType.SelectedIndex != -1 ? (RouteIndexType)cmbRouteIndexType.SelectedIndex | + | //Add an event to display refresh the ProgressBar. |
- | : buildRoutingIndexParameters.RouteIndexType; | + | routingIndexbuilder.ExtractingSqliteDatabase += routingIndexbuilder_ExtractingSqliteDatabase; |
- | + | routingIndexbuilder.BuildingRoutableSegment += routingIndexbuilder_BuildingRoutableSegment; | |
- | buildRoutingIndexParameters.SpeedOption.SpeedUnit = cmbSpeedUnit.SelectedIndex != -1 ? (SpeedUnit)cmbSpeedUnit.SelectedIndex | + | routingIndexbuilder.BuildingRouteRTSegment += routingIndexbuilder_BuildingRouteSegment; |
- | : buildRoutingIndexParameters.SpeedOption.SpeedUnit; | + | routingIndexbuilder.BuildingIndexFinished += routingIndexbuilder_BuildingIndexFinished; |
- | } | + | routingIndexbuilder.BuildingShapeFileIndex += routingIndexbuilder_BuildingShapeFileIndex; |
- | + | btnGenerate.Enabled = false; | |
- | private void chkRouteSpeedOptions_CheckedChanged(object sender, EventArgs e) | + | |
- | { | + | //Start building index file(.rtg). |
- | if (!chkRouteSpeedOptions.Checked) | + | Task.Factory.StartNew(() => |
- | { | + | { |
- | buildRoutingIndexParameters.SpeedOption.SpeedType = SpeedType.DefaultSpeed; | + | routingIndexbuilder.ExtractRoadsFromSqliteToShapefileWithLowerMemory(currentConfigModel); |
- | } | + | routingIndexbuilder.StartBuildingRoutableFile(); |
- | else | + | routingIndexbuilder.StartBuildingRtgFile(); |
- | { | + | }); |
- | buildRoutingIndexParameters.SpeedOption.SpeedType = rbtnClassSpeed.Checked ? SpeedType.RoadClass : SpeedType.RoadSpeed; | + | } |
- | } | + | |
- | + | private void routingIndexbuilder_BuildingShapeFileIndex(object sender, RoutingIndexBuilderEventArgs e) | |
- | pnlRouteSpeedOptions.Enabled = chkRouteSpeedOptions.Checked; | + | { |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) |
- | } | + | { |
- | + | this.BeginInvoke(new Action(() => | |
- | private void ShapeFileColumnComboBox_SelectedValueChanged(object sender, EventArgs e) | + | { |
- | { | + | lblProcessingMessage.Text = string.Format("Building shape file index: {0}/{1}", e.ProcessedRecordCount, e.TotalRecordCount); |
- | buildRoutingIndexParameters.OneWayRoadOption.IndicatorColumnName = cmbOnewayIndicatorColumn.Text; | + | pgbBuildProgress.Value = (int)(((double)e.ProcessedRecordCount / (double)e.TotalRecordCount) * 100); |
- | buildRoutingIndexParameters.OneWayRoadOption.OneWayColumnName = cmbOnewayRoadColumn.Text; | + | })); |
- | buildRoutingIndexParameters.SpeedOption.SpeedColumnName = cmbSpeedColumn.Text; | + | } |
- | buildRoutingIndexParameters.SpeedOption.RoadClassColumnName = cmbRoadClassColumn.Text; | + | } |
- | + | ||
- | if (sender.Equals(cmbRoadClassColumn)) | + | private void routingIndexbuilder_BuildingIndexFinished(object sender, EventArgs e) |
- | { | + | { |
- | colRoadClass.Items.Clear(); | + | this.BeginInvoke(new Action(() => |
- | dgvRoadClassSpeed.Rows.Clear(); | + | { |
- | buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Clear(); | + | btnGenerate.Enabled = true; |
- | + | MessageBox.Show(this, "Generation Completed!", "Completed"); | |
- | ShapeFileFeatureSource source = new ShapeFileFeatureSource(buildRoutingIndexParameters.ShapefilePathName); | + | })); |
- | source.Open(); | + | } |
- | Collection<Feature> features = source.GetAllFeatures(new string[] { cmbRoadClassColumn.Text }); | + | |
- | source.Close(); | + | private void routingIndexbuilder_ExtractingSqliteDatabase(object sender, RoutingIndexBuilderEventArgs e) |
- | + | { | |
- | foreach (Feature feature in features) | + | if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) |
- | { | + | { |
- | if (!colRoadClass.Items.Contains(feature.ColumnValues[cmbRoadClassColumn.Text])) | + | this.BeginInvoke(new Action(() => |
- | { | + | { |
- | colRoadClass.Items.Add(feature.ColumnValues[cmbRoadClassColumn.Text]); | + | 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); ; |
- | } | + | })); |
- | colRoadClass.Items.Remove(string.Empty); | + | } |
- | } | + | } |
- | + | ||
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | private void routingIndexbuilder_BuildingRoutableSegment(object sender, RoutingIndexBuilderEventArgs e) |
- | } | + | { |
- | + | if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) | |
- | private void SpeedTypeRadioButton_CheckedChanged(object sender, EventArgs e) | + | { |
- | { | + | this.BeginInvoke(new Action(() => |
- | buildRoutingIndexParameters.SpeedOption.SpeedType = rbtnClassSpeed.Checked ? SpeedType.RoadClass : SpeedType.RoadSpeed; | + | { |
- | + | lblProcessingMessage.Text = string.Format("Generating Index (2/3) Building Routable shape file: {0}/{1}", e.ProcessedRecordCount, e.TotalRecordCount); | |
- | lblSpeedColumn.Enabled = false; | + | pgbBuildProgress.Value = (int)(((double)e.ProcessedRecordCount / (double)e.TotalRecordCount) * 100); |
- | cmbSpeedColumn.Enabled = false; | + | })); |
- | lblRoadClassColumn.Enabled = false; | + | } |
- | cmbRoadClassColumn.Enabled = false; | + | } |
- | dgvRoadClassSpeed.Enabled = false; | + | |
- | + | private void routingIndexbuilder_BuildingRouteSegment(object sender, RoutingIndexBuilderEventArgs e) | |
- | if (rbtnClassSpeed.Checked) | + | { |
- | { | + | if (e.ProcessedRecordCount % 100 == 0 || e.ProcessedRecordCount == e.TotalRecordCount) |
- | lblRoadClassColumn.Enabled = true; | + | { |
- | cmbRoadClassColumn.Enabled = true; | + | this.BeginInvoke(new Action(() => |
- | dgvRoadClassSpeed.Enabled = true; | + | { |
- | } | + | lblProcessingMessage.Text = string.Format("Generating Index (3/3) Building rtg file: {0}/{1}", e.ProcessedRecordCount, e.TotalRecordCount); |
- | else if (rbtnRoadSpeed.Checked) | + | pgbBuildProgress.Value = (int)(((double)e.ProcessedRecordCount / (double)e.TotalRecordCount) * 100); |
- | { | + | })); |
- | lblSpeedColumn.Enabled = true; | + | } |
- | cmbSpeedColumn.Enabled = true; | + | } |
- | } | + | |
- | + | private void btnSaveRtgFile_Click(object sender, EventArgs e) | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | { |
- | } | + | SaveFileDialog saveFileDialog = new SaveFileDialog(); |
- | | + | saveFileDialog.FileName = Path.ChangeExtension(txtDataProviderFilePath.Text, ".routable.rtg"); ; |
- | private void RouteOptionTextBox_TextChanged(object sender, EventArgs e) | + | saveFileDialog.Filter = "Routing Index File(*.rtg)|*.rtg"; |
- | { | + | saveFileDialog.DefaultExt = ".rtg"; |
- | buildRoutingIndexParameters.OneWayRoadOption.BothWayRoadValue = txtBothWayRoadValue.Text; | + | if (saveFileDialog.ShowDialog() == DialogResult.OK) |
- | buildRoutingIndexParameters.OneWayRoadOption.FromToValue = txtFromToValue.Text; | + | { |
- | buildRoutingIndexParameters.OneWayRoadOption.ToFromValue = txtToFromValue.Text; | + | txtIndexFilePath.Text = saveFileDialog.FileName; |
- | buildRoutingIndexParameters.OneWayRoadOption.ClosedRoad = txtColsedRoad.Text; | + | } |
- | + | } | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | |
- | } | + | private void btnSaveRoutableFile_Click(object sender, EventArgs e) |
- | + | { | |
- | private void dgvRoadClassSpeed_CellEndEdit(object sender, DataGridViewCellEventArgs e) | + | SaveFileDialog saveFileDialog = new SaveFileDialog(); |
- | { | + | saveFileDialog.FileName = Path.ChangeExtension(txtDataProviderFilePath.Text, ".Routable.shp"); |
- | buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Clear(); | + | |
- | + | saveFileDialog.Filter = "Shape File(*.shp)|*.shp"; | |
- | foreach (DataGridViewRow row in dgvRoadClassSpeed.Rows) | + | saveFileDialog.DefaultExt = ".shp"; |
- | { | + | if (saveFileDialog.ShowDialog() == DialogResult.OK) |
- | 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(); | + | this.txtRoutableFile.Text = saveFileDialog.FileName; |
- | + | } | |
- | double speed = 0; | + | } |
- | + | ||
- | if (!buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Keys.Contains(key) && double.TryParse(value, out speed) && speed > 0) | + | private void SpeedTypeRadioButton_CheckedChanged(object sender, EventArgs e) |
- | { | + | { |
- | buildRoutingIndexParameters.SpeedOption.RoadSpeeds.Add(key, speed); | + | lblRoadClassColumn.Enabled = rbtnClassSpeed.Checked; |
- | } | + | cmbRoadClassColumn.Enabled = rbtnClassSpeed.Checked; |
- | } | + | dgvRoadClassSpeed.Enabled = rbtnClassSpeed.Checked; |
- | + | cmbSpeedColumn.Enabled = rbtnRoadSpeed.Checked; | |
- | btnGenerate.Enabled = buildRoutingIndexParameters.CheckCanBuildIndexFile() && !isBuildingRtgFile; | + | } |
- | } | + | |
- | + | private void cmbRouteIndexType_SelectedIndexChanged(object sender, EventArgs e) | |
- | private void btnCancel_Click(object sender, EventArgs e) | + | { |
- | { | + | bool considerringSpeedLimit = cmbRouteIndexType.SelectedItem.ToString() == "Fastest"; |
- | if (builder != null) | + | panelRouteSpeedOptions.Enabled = considerringSpeedLimit; |
- | { | + | } |
- | builder.CancelBuildingRtgFile(); | + | |
- | } | + | private void cmbSpeedUnit_SelectedIndexChanged(object sender, EventArgs e) |
- | this.Close(); | + | { |
- | } | + | if (cmbSpeedUnit.SelectedIndex == 0) |
- | + | { | |
- | private void CheckFileIsRequirement(string shapeFile) | + | txtDefaultSpeed.Text = "50"; |
- | { | + | } |
- | string errorMessage = string.Empty; | + | else |
- | try | + | { |
- | { | + | txtDefaultSpeed.Text = "30"; |
- | //read ShapeFileType and ShapeFileColumns from ShapeFile. | + | } |
- | ShapeFileType fileType; | + | BindRoadClassSpeed(); |
- | Collection<FeatureSourceColumn> columns = ReadShapeFileTypeAndColumns(shapeFile, out fileType); | + | } |
- | + | ||
- | //check if ShapeFileType is Polyline. | + | private void cmbOnewayRoadColumn_SelectedIndexChanged(object sender, EventArgs e) |
- | if (fileType == ShapeFileType.Polyline) | + | { |
- | { | + | bool oneWayIdentifierIsNotNull = (cmbOnewayRoadColumn.SelectedItem.ToString() != string.Empty); |
- | AddColumnItemsToComboBox(columns); | + | |
- | buildRoutingIndexParameters.ShapefilePathName = shapeFile; | + | label8.Enabled = oneWayIdentifierIsNotNull; |
- | } | + | txtOneWayRoadValue.Enabled = oneWayIdentifierIsNotNull; |
- | else | + | panelOneWayIndicator.Enabled = oneWayIdentifierIsNotNull; |
- | { | + | } |
- | errorMessage = Resources.ShapeFileTypeError; | + | |
- | } | + | private void cmbOnewayIndicatorColumn_SelectedIndexChanged(object sender, EventArgs e) |
- | } | + | { |
- | catch | + | bool oneWayIndicatorColumnNotNull = (cmbOnewayIndicatorColumn.SelectedItem.ToString() != string.Empty); |
- | { | + | panelOneWayIndicatorDetail.Enabled = oneWayIndicatorColumnNotNull; |
- | errorMessage = Resources.ShapeFileFormatError; | + | } |
- | } | + | |
- | + | private void cmbClosedRoadColumn_SelectedIndexChanged(object sender, EventArgs e) | |
- | //Display the ErrorMessage. | + | { |
- | if (!string.IsNullOrEmpty(errorMessage)) | + | bool closedRoadColumnNotNull = (cmbClosedRoadColumn.SelectedItem.ToString() != string.Empty); |
- | { | + | panelClosedRoad.Enabled = closedRoadColumnNotNull; |
- | MessageBox.Show(errorMessage, "Error"); | + | } |
- | } | + | |
- | } | + | private void cmbRoadClassColumn_SelectedIndexChanged(object sender, EventArgs e) |
- | + | { | |
- | private Collection<FeatureSourceColumn> ReadShapeFileTypeAndColumns(string shapeFilePath, out ShapeFileType fileType) | + | BindRoadClassSpeed(); |
- | { | + | } |
- | Collection<FeatureSourceColumn> columns; | + | |
- | + | private void btnClose_Click(object sender, EventArgs e) | |
- | ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(shapeFilePath); | + | { |
- | layer.Open(); | + | if (routingIndexbuilder != null) |
- | fileType = layer.GetShapeFileType(); | + | { |
- | columns = layer.FeatureSource.GetColumns(); | + | routingIndexbuilder.CancelBuildingRtgFile(); |
- | layer.Close(); | + | } |
- | + | this.Close(); | |
- | return columns; | + | } |
- | } | + | |
- | + | private RoutingIndexBuilderParameters GetIndexBuildingParameters() | |
- | private void AddColumnItemsToComboBox(Collection<FeatureSourceColumn> columns) | + | { |
- | { | + | RoutingIndexBuilderParameters buildRoutingIndexParameters = new RoutingIndexBuilderParameters(); |
- | cmbOnewayIndicatorColumn.Items.Clear(); | + | buildRoutingIndexParameters.SourceSqlitePathName = txtDataProviderFilePath.Text; |
- | cmbOnewayRoadColumn.Items.Clear(); | + | |
- | cmbRoadClassColumn.Items.Clear(); | + | buildRoutingIndexParameters.GeographyUnit = (GeographyUnit)Enum.Parse(typeof(GeographyUnit), cmbGeographyUnit.SelectedItem.ToString()); |
- | cmbSpeedColumn.Items.Clear(); | + | buildRoutingIndexParameters.RouteIndexType = (RoutingIndexType)Enum.Parse(typeof(RoutingIndexType), cmbRouteIndexType.SelectedItem.ToString()); |
- | + | buildRoutingIndexParameters.RtgFilePathName = txtIndexFilePath.Text; | |
- | foreach (FeatureSourceColumn column in columns) | + | buildRoutingIndexParameters.RoutableShapeFilePathName = txtRoutableFile.Text; |
- | { | + | buildRoutingIndexParameters.BuildRoutingDataMode = chkRebuildRtgFile.Checked ? BuildRoutingDataMode.Rebuild : BuildRoutingDataMode.DoNotRebuild; |
- | cmbOnewayIndicatorColumn.Items.Add(column); | + | buildRoutingIndexParameters.OverrideRoutableFile = chkRebuildRoutableFile.Checked ? true : false; |
- | cmbOnewayRoadColumn.Items.Add(column); | + | |
- | cmbRoadClassColumn.Items.Add(column); | + | //Get restrict extent if specify. |
- | cmbSpeedColumn.Items.Add(column); | + | 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> | </code> | ||
- | ====RoutingIndexFileBuilder.cs==== | + | ====RoutingIndexBuilder.cs==== |
<code csharp> | <code csharp> | ||
| | ||
- | using System; | + | using System; |
- | using System.Collections.ObjectModel; | + | using System.Collections.ObjectModel; |
- | using System.IO; | + | using System.IO; |
- | using RoutingIndexGenerator.Properties; | + | using System.Text; |
- | using ThinkGeo.MapSuite.Core; | + | using ThinkGeo.MapSuite.Core; |
- | using ThinkGeo.MapSuite.Routing; | + | using ThinkGeo.MapSuite.Routing; |
- | + | ||
- | namespace RoutingIndexGenerator | + | namespace RoutingIndexGenerator |
- | { | + | { |
- | public class RoutingIndexFileBuilder | + | public class RoutingIndexBuilder |
- | { | + | { |
- | public event EventHandler<EventArgs> BuildingRouteSegment; | + | public event EventHandler<RoutingIndexBuilderEventArgs> BuildingShapeFileIndex; |
- | + | public event EventHandler<RoutingIndexBuilderEventArgs> ExtractingSqliteDatabase; | |
- | private BuildRoutingIndexParameters buildRtgParameter; | + | public event EventHandler<RoutingIndexBuilderEventArgs> BuildingRoutableSegment; |
- | private bool cancelBuilding; | + | public event EventHandler<RoutingIndexBuilderEventArgs> BuildingRouteRTSegment; |
- | private ShapeFileFeatureSource routableFeatureSource; | + | public event EventHandler<EventArgs> BuildingIndexFinished; |
- | + | ||
- | private int processedRecordCount; | + | private bool cancelBuilding; |
- | private int totalRecordCount; | + | private int totalRecordCount; |
- | private Collection<string> requiredColumns; | + | private int processedRecordCount; |
- | + | private Feature previousFeature; | |
- | public RoutingIndexFileBuilder() | + | private Collection<string> requiredColumns; |
- | : this(new BuildRoutingIndexParameters()) | + | private ShapeFileFeatureSource routableFeatureSource; |
- | { } | + | private RoutingIndexBuilderParameters buildRtgParameter; |
- | + | ||
- | public RoutingIndexFileBuilder(BuildRoutingIndexParameters buildRtgParameter) | + | public RoutingIndexBuilder() |
- | { | + | : this(new RoutingIndexBuilderParameters()) |
- | this.buildRtgParameter = buildRtgParameter; | + | { } |
- | } | + | |
- | + | public RoutingIndexBuilder(RoutingIndexBuilderParameters buildRtgParameter) | |
- | public int ProcessedRecordCount | + | { |
- | { | + | this.buildRtgParameter = buildRtgParameter; |
- | get { return processedRecordCount; } | + | this.buildRtgParameter.ClosedRoadOption.InitRegexes(); |
- | } | + | this.buildRtgParameter.OneWayRoadOption.InitRegexes(); |
- | + | RtgRoutingSource.GeneratingRoutableShapeFile += RtgRoutingSource_GeneratingRoutableShapeFile; | |
- | public int TotalRecordCount | + | RtgRoutingSource.BuildingRoutingData += RtgRoutingSource_BuildingRoutingData; |
- | { | + | } |
- | get { return totalRecordCount; } | + | |
- | } | + | //This method uses lower memory than the other method, but only works with .sqlite files |
- | + | public void ExtractRoadsFromSqliteToShapefileWithLowerMemory(ConfigModel config) | |
- | public BuildRoutingIndexParameters BuildRtgParameter | + | { |
- | { | + | // If don't override routable file, let's skip this step. |
- | get { return buildRtgParameter; } | + | 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); | |
- | public void StartBuildingRtgFile() | + | source.Open(); |
- | { | + | |
- | if (!buildRtgParameter.CheckCanBuildIndexFile()) | + | RectangleShape restrictExtent = buildRtgParameter.RestrictExtent == null ? source.GetBoundingBox() : buildRtgParameter.RestrictExtent; |
- | { | + | Collection<string> ids = new Collection<string>(); |
- | throw new NotSupportedException(Resources.ParametersNotSuppertBuildingIndex); | + | ids = source.GetFeatureIdsInsideBoundingBox(restrictExtent); |
- | } | + | |
- | + | Collection<DbfColumn> dbfColumns = new Collection<DbfColumn>(); | |
- | processedRecordCount = 0; | + | foreach (string columnName in config.ExtractRequiredColumns) |
- | + | { | |
- | routableFeatureSource = new ShapeFileFeatureSource(buildRtgParameter.ShapefilePathName); | + | dbfColumns.Add(new DbfColumn(columnName, DbfColumnType.Character, 255, 0)); |
- | routableFeatureSource.Open(); | + | } |
- | + | ShapeFileFeatureSource.CreateShapeFile(ShapeFileType.Polyline, buildRtgParameter.SourceShapefilePathName, dbfColumns, Encoding.UTF8, OverwriteMode.Overwrite); | |
- | totalRecordCount = routableFeatureSource.GetCount(); | + | |
- | + | ShapeFileFeatureSource target = new ShapeFileFeatureSource(buildRtgParameter.SourceShapefilePathName, ShapeFileReadWriteMode.ReadWrite); | |
- | RtgRoutingSource.BuildingRoutingData += RtgRoutingSource_BuildingRoutingData; | + | target.Open(); |
- | RtgRoutingSource.GenerateRoutingData(buildRtgParameter.RtgFilePathName, buildRtgParameter.ShapefilePathName, buildRtgParameter.ShapefilePathName, buildRtgParameter.BuildRoutingDataMode, buildRtgParameter.GeographyUnit, buildRtgParameter.DistanceUnit); | + | |
- | RtgRoutingSource.BuildingRoutingData -= RtgRoutingSource_BuildingRoutingData; | + | int processedRecordCount = 0; |
- | + | int totalRecordCount = ids.Count; | |
- | routableFeatureSource.Close(); | + | target.BeginTransaction(); |
- | + | ||
- | if (cancelBuilding == true) | + | //load 10,000 features into memory at a time from the sqlite database |
- | { | + | int loadingFeatureCount = 10000; |
- | File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName, ".rtg")); | + | int startIndex = 0; |
- | File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName, ".rtx")); | + | int length = 0; |
- | } | + | |
- | } | + | string[] totalIds = new string[ids.Count]; |
- | + | ids.CopyTo(totalIds, 0); | |
- | public void CancelBuildingRtgFile() | + | |
- | { | + | while (startIndex + length < ids.Count) |
- | cancelBuilding = true; | + | { |
- | } | + | startIndex = startIndex + length; |
- | + | length = Math.Min(ids.Count - startIndex, loadingFeatureCount); | |
- | private void RtgRoutingSource_BuildingRoutingData(object sender, BuildingRoutingDataRtgRoutingSourceEventArgs e) | + | |
- | { | + | string[] fetchIds = new string[length]; |
- | // Make progressBar move forward a step | + | Array.Copy(totalIds, startIndex, fetchIds, 0, length); |
- | processedRecordCount++; | + | |
- | OnBuildingRouteSegment(); | + | Collection<Feature> features = source.GetFeaturesByIds(fetchIds, config.ExtractRequiredColumns); |
- | + | ||
- | // Get the processing Feature | + | foreach (Feature feature in features) |
- | if (requiredColumns == null) | + | { |
- | { | + | target.AddFeature(feature); |
- | requiredColumns = GetRequiredColumns(); | + | processedRecordCount++; |
- | } | + | |
- | + | //write 100,000 features to shapefile at a time | |
- | Feature feature = routableFeatureSource.GetFeatureById(e.RouteSegment.FeatureId, requiredColumns); | + | if (processedRecordCount % 100000 == 0) |
- | if (!buildRtgParameter.SkipOnewayOptions) | + | { |
- | { | + | target.CommitTransaction(); |
- | ProcessOneWayRoad(e, feature, requiredColumns); | + | target.BeginTransaction(); |
- | } | + | } |
- | + | OnExtractingSqliteDatabase(new RoutingIndexBuilderEventArgs(totalRecordCount, processedRecordCount)); | |
- | if (buildRtgParameter.RouteIndexType == RouteIndexType.Fastest) | + | } |
- | { | + | |
- | if (buildRtgParameter.SpeedOption.SpeedType == SpeedType.RoadClass && !string.IsNullOrEmpty(buildRtgParameter.SpeedOption.RoadClassColumnName)) | + | } |
- | { | + | target.CommitTransaction(); |
- | string featureRoadClassValue = feature.ColumnValues[buildRtgParameter.SpeedOption.RoadClassColumnName]; | + | target.Close(); |
- | e.RouteSegment.Weight = e.RouteSegment.Distance / GetSpeed(featureRoadClassValue); | + | source.Close(); |
- | } | + | } |
- | else if (buildRtgParameter.SpeedOption.SpeedType == SpeedType.RoadSpeed && !string.IsNullOrEmpty(buildRtgParameter.SpeedOption.SpeedColumnName)) | + | } |
- | { | + | |
- | float speed = 0; | + | public void ExtractRoadsFromSqliteToShapefile(ConfigModel config) |
- | string speedString = feature.ColumnValues[buildRtgParameter.SpeedOption.SpeedColumnName]; | + | { |
- | speed = float.TryParse(speedString, out speed) ? speed : buildRtgParameter.SpeedOption.DefaultSpeed; | + | // If don't override routable file, let's skip this step. |
- | e.RouteSegment.Weight = e.RouteSegment.Distance / speed; | + | if (buildRtgParameter.OverrideRoutableFile || !File.Exists(buildRtgParameter.RoutableShapeFilePathName)) |
- | } | + | { |
- | else | + | FeatureSource source = null; |
- | { | + | if (config.FileType.EndsWith(".sqlite", StringComparison.InvariantCultureIgnoreCase)) |
- | e.RouteSegment.Weight = e.RouteSegment.Distance / buildRtgParameter.SpeedOption.DefaultSpeed; | + | { |
- | } | + | 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)) | |
- | e.Cancel = cancelBuilding; | + | { |
- | } | + | ShapeFileFeatureSource.BuildingIndex += ShapeFileFeatureSource_BuildingIndex; |
- | + | ShapeFileFeatureSource.BuildIndexFile(buildRtgParameter.SourceSqlitePathName, BuildIndexMode.DoNotRebuild); | |
- | private Collection<string> GetRequiredColumns() | + | source = new ShapeFileFeatureSource(buildRtgParameter.SourceSqlitePathName); |
- | { | + | } |
- | Collection<string> requiredColumns = new Collection<string>(); | + | else if (config.FileType.EndsWith(".wkb", StringComparison.InvariantCultureIgnoreCase)) |
- | if (!buildRtgParameter.SkipOnewayOptions) | + | { |
- | { | + | source = new WkbFileFeatureSource(buildRtgParameter.SourceSqlitePathName); |
- | if (!string.IsNullOrEmpty(buildRtgParameter.OneWayRoadOption.OneWayColumnName)) | + | } |
- | { | + | |
- | requiredColumns.Add(buildRtgParameter.OneWayRoadOption.OneWayColumnName); | + | source.Open(); |
- | } | + | |
- | if (!string.IsNullOrEmpty(buildRtgParameter.OneWayRoadOption.IndicatorColumnName)) | + | RectangleShape restrictExtent = buildRtgParameter.RestrictExtent == null ? source.GetBoundingBox() : buildRtgParameter.RestrictExtent; |
- | { | + | Collection<Feature> features = new Collection<Feature>(); |
- | requiredColumns.Add(buildRtgParameter.OneWayRoadOption.IndicatorColumnName); | + | Collection<DbfColumn> dbfColumns = new Collection<DbfColumn>(); |
- | } | + | if (config.ExtractRequiredColumns.Count == 0) |
- | } | + | { |
- | + | features = source.GetFeaturesInsideBoundingBox(restrictExtent, ReturningColumnsType.AllColumns); | |
- | string speedColumn = string.Empty; | + | foreach (var column in source.GetColumns()) |
- | switch (buildRtgParameter.SpeedOption.SpeedType) | + | { |
- | { | + | dbfColumns.Add(new DbfColumn(column.ColumnName, DbfColumnType.Character, column.MaxLength, 0)); |
- | case SpeedType.RoadClass: | + | } |
- | speedColumn = buildRtgParameter.SpeedOption.RoadClassColumnName; | + | } |
- | break; | + | else |
- | case SpeedType.RoadSpeed: | + | { |
- | speedColumn = buildRtgParameter.SpeedOption.SpeedColumnName; | + | features = source.GetFeaturesInsideBoundingBox(restrictExtent, config.ExtractRequiredColumns); |
- | break; | + | foreach (string columnName in config.ExtractRequiredColumns) |
- | default: | + | { |
- | break; | + | dbfColumns.Add(new DbfColumn(columnName, DbfColumnType.Character, 255, 0)); |
- | } | + | } |
- | if (!string.IsNullOrEmpty(speedColumn)) | + | } |
- | { | + | |
- | requiredColumns.Add(speedColumn); | + | ShapeFileFeatureSource.CreateShapeFile(ShapeFileType.Polyline, buildRtgParameter.SourceShapefilePathName, dbfColumns, Encoding.UTF8, OverwriteMode.Overwrite); |
- | } | + | |
- | + | ShapeFileFeatureSource target = new ShapeFileFeatureSource(buildRtgParameter.SourceShapefilePathName, ShapeFileReadWriteMode.ReadWrite); | |
- | return requiredColumns; | + | target.Open(); |
- | } | + | |
- | + | int processedRecordCount = 0; | |
- | private void ProcessOneWayRoad(BuildingRoutingDataRtgRoutingSourceEventArgs e, Feature roadFeature, Collection<string> oneWayColumns) | + | int totalRecordCount = features.Count; |
- | { | + | target.BeginTransaction(); |
- | LineShape lineShape = GetLineShape(roadFeature); | + | foreach (Feature feature in features) |
- | + | { | |
- | // handled feature is one-way road | + | |
- | if (!roadFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.OneWayColumnName].Equals(buildRtgParameter.OneWayRoadOption.BothWayRoadValue, StringComparison.InvariantCultureIgnoreCase)) | + | target.AddFeature(feature); |
- | { | + | processedRecordCount++; |
- | if (roadFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.FromToValue)) | + | |
- | { | + | if (processedRecordCount % 100000 == 0) |
- | e.RouteSegment.StartPointAdjacentIds.Clear(); | + | { |
- | } | + | target.CommitTransaction(); |
- | else if (roadFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.ToFromValue)) | + | target.BeginTransaction(); |
- | { | + | } |
- | e.RouteSegment.EndPointAdjacentIds.Clear(); | + | OnExtractingSqliteDatabase(new RoutingIndexBuilderEventArgs(totalRecordCount, processedRecordCount)); |
- | } | + | } |
- | else if (roadFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.ClosedRoad)) | + | |
- | { | + | target.CommitTransaction(); |
- | e.RouteSegment.StartPointAdjacentIds.Clear(); | + | target.Close(); |
- | e.RouteSegment.EndPointAdjacentIds.Clear(); | + | source.Close(); |
- | } | + | } |
- | } | + | } |
- | + | ||
- | // analysis adjacent one-way road features | + | public void StartBuildingRoutableFile() |
- | Collection<string> removedStartPointAdjacentIds = GetRemovedAdjacentIds(e.RouteSegment.StartPointAdjacentIds, new PointShape(lineShape.Vertices[0]), oneWayColumns); | + | { |
- | foreach (string id in removedStartPointAdjacentIds) | + | if (buildRtgParameter.OverrideRoutableFile) |
- | { | + | { |
- | e.RouteSegment.StartPointAdjacentIds.Remove(id); | + | ShapeFileFeatureSource sourceFeatureSource = new ShapeFileFeatureSource(buildRtgParameter.SourceShapefilePathName); |
- | } | + | sourceFeatureSource.Open(); |
- | Collection<string> removedEndPointAdjacentIds = GetRemovedAdjacentIds(e.RouteSegment.EndPointAdjacentIds, new PointShape(lineShape.Vertices[lineShape.Vertices.Count|- 1]), oneWayColumns); | + | |
- | foreach (string id in removedEndPointAdjacentIds) | + | // reset the process status. |
- | { | + | this.processedRecordCount = 0; |
- | e.RouteSegment.EndPointAdjacentIds.Remove(id); | + | this.totalRecordCount = sourceFeatureSource.GetCount(); |
- | } | + | RtgRoutingSource.GenerateRoutableShapeFile(buildRtgParameter.SourceShapefilePathName, buildRtgParameter.RoutableShapeFilePathName, buildRtgParameter.OverrideRoutableFile ? OverwriteMode.Overwrite : OverwriteMode.DoNotOverwrite, buildRtgParameter.GeographyUnit, 2); |
- | } | + | |
- | + | sourceFeatureSource.Close(); | |
- | private Collection<string> GetRemovedAdjacentIds(Collection<string> adjacentIds, PointShape intersectingPoint, Collection<string> oneWayColumns) | + | } |
- | { | + | } |
- | Collection<string> removedIds = new Collection<string>(); | + | |
- | foreach (string id in adjacentIds) | + | public void StartBuildingRtgFile() |
- | { | + | { |
- | Feature adjacentFeature = routableFeatureSource.GetFeatureById(id, oneWayColumns); | + | routableFeatureSource = new ShapeFileFeatureSource(buildRtgParameter.RoutableShapeFilePathName); |
- | if (!adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.OneWayColumnName].Equals(buildRtgParameter.OneWayRoadOption.BothWayRoadValue, StringComparison.InvariantCultureIgnoreCase)) | + | routableFeatureSource.Open(); |
- | { | + | |
- | LineShape adjacentLineShape = GetLineShape(adjacentFeature); | + | // reset the process status. |
- | double distanceFromAdjacentStartToIntersecting = new PointShape(adjacentLineShape.Vertices[0]).GetDistanceTo(intersectingPoint, buildRtgParameter.GeographyUnit, buildRtgParameter.DistanceUnit); | + | this.processedRecordCount = 0; |
- | double distanceFromAdjacentEndToIntersecting = new PointShape(adjacentLineShape.Vertices[adjacentLineShape.Vertices.Count|- 1]).GetDistanceTo(intersectingPoint, buildRtgParameter.GeographyUnit, buildRtgParameter.DistanceUnit); | + | this.totalRecordCount = routableFeatureSource.GetCount(); |
- | if (distanceFromAdjacentStartToIntersecting <= distanceFromAdjacentEndToIntersecting | + | RtgRoutingSource.GenerateRoutingData(buildRtgParameter.RtgFilePathName, buildRtgParameter.SourceShapefilePathName, buildRtgParameter.RoutableShapeFilePathName, buildRtgParameter.BuildRoutingDataMode, buildRtgParameter.GeographyUnit, DistanceUnit.Meter); |
- | && adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.ToFromValue)) | + | |
- | { | + | routableFeatureSource.Close(); |
- | removedIds.Add(id); | + | |
- | } | + | if (cancelBuilding == true) |
- | else if (distanceFromAdjacentEndToIntersecting <= distanceFromAdjacentStartToIntersecting | + | { |
- | && adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.FromToValue)) | + | File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName, ".rtg")); |
- | { | + | File.Delete(Path.ChangeExtension(buildRtgParameter.RtgFilePathName, ".rtx")); |
- | removedIds.Add(id); | + | } |
- | } | + | |
- | else if (adjacentFeature.ColumnValues[buildRtgParameter.OneWayRoadOption.IndicatorColumnName].Equals(buildRtgParameter.OneWayRoadOption.ClosedRoad)) | + | // clear up the temporary shape files extracted from sqlite. |
- | { | + | if (File.Exists(buildRtgParameter.SourceSqlitePathName) && File.Exists(buildRtgParameter.SourceShapefilePathName)) |
- | removedIds.Add(id); | + | { |
- | } | + | string tempShapefile = Path.GetFileNameWithoutExtension(buildRtgParameter.SourceShapefilePathName); |
- | } | + | string[] files = Directory.GetFiles(Path.GetDirectoryName(buildRtgParameter.SourceShapefilePathName)); |
- | } | + | foreach (string file in files) |
- | return removedIds; | + | { |
- | } | + | if (Path.GetFileNameWithoutExtension(file).Equals(tempShapefile, StringComparison.InvariantCultureIgnoreCase)) |
- | + | { | |
- | private float GetSpeed(String featureRoadSpeedClassValue) | + | File.Delete(file); |
- | { | + | } |
- | float result = buildRtgParameter.SpeedOption.DefaultSpeed; | + | } |
- | foreach (var item in buildRtgParameter.SpeedOption.RoadSpeeds) | + | } |
- | { | + | OnBuildingIndexFinished(new EventArgs()); |
- | if (item.Key.Equals(featureRoadSpeedClassValue, StringComparison.OrdinalIgnoreCase)) | + | } |
- | { | + | |
- | result = (float)item.Value; | + | public void CancelBuildingRtgFile() |
- | break; | + | { |
- | } | + | cancelBuilding = true; |
- | } | + | } |
- | + | ||
- | return result; | + | private void ShapeFileFeatureSource_BuildingIndex(object sender, BuildingIndexShapeFileFeatureSourceEventArgs e) |
- | } | + | { |
- | + | var handler = BuildingShapeFileIndex; | |
- | private static LineShape GetLineShape(Feature lineFeature) | + | if (handler != null) |
- | { | + | { |
- | BaseShape baseShape = lineFeature.GetShape(); | + | handler(this, new RoutingIndexBuilderEventArgs(e.RecordCount, e.CurrentRecordIndex)); |
- | + | } | |
- | LineShape lineShape = baseShape as LineShape; | + | } |
- | if (lineShape == null) | + | |
- | { | + | private void RtgRoutingSource_GeneratingRoutableShapeFile(object sender, GeneratingRoutableShapeFileRoutingSourceEventArgs e) |
- | MultilineShape lineShapes = ((MultilineShape)baseShape); | + | { |
- | Collection<Vertex> vertices = new Collection<Vertex>(); | + | if (previousFeature == null) |
- | + | { | |
- | foreach (LineShape line in lineShapes.Lines) | + | previousFeature = e.PreviousFeature; |
- | { | + | } |
- | for (int i = 0; i < line.Vertices.Count; i++) | + | |
- | { | + | // we add the previous feature is because this event may be triggered multi times in one feature. |
- | vertices.Add(line.Vertices[i]); | + | if (previousFeature.Id != e.PreviousFeature.Id) |
- | } | + | { |
- | } | + | previousFeature = e.PreviousFeature; |
- | + | this.processedRecordCount++; | |
- | lineShape = new LineShape(vertices); | + | OnBuildingRoutableSegment(new RoutingIndexBuilderEventArgs(this.totalRecordCount, this.processedRecordCount)); |
- | lineShape.Id = baseShape.Id; | + | } |
- | lineShape.Tag = baseShape.Tag; | + | } |
- | } | + | |
- | + | private void RtgRoutingSource_BuildingRoutingData(object sender, BuildingRoutingDataRtgRoutingSourceEventArgs e) | |
- | return lineShape; | + | { |
- | } | + | // Make progressBar move forward a step |
- | + | this.processedRecordCount++; | |
- | protected virtual void OnBuildingRouteSegment() | + | OnBuildingRouteRTSegment(new RoutingIndexBuilderEventArgs(this.totalRecordCount, this.processedRecordCount)); |
- | { | + | |
- | if (BuildingRouteSegment != null) | + | // Get the processing Feature |
- | { | + | if (requiredColumns == null) |
- | BuildingRouteSegment(this, new EventArgs()); | + | { |
- | } | + | 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> | </code> | ||
Line 610: | Line 944: | ||
====Program.cs==== | ====Program.cs==== | ||
- | <code csharp> | + | <code csharp> |
- | using System; | + | |
- | using System.Collections.Generic; | + | using System; |
- | using System.Linq; | + | using System.Collections.Generic; |
- | using System.Windows.Forms; | + | using System.Linq; |
- | + | using System.Windows.Forms; | |
- | namespace RoutingIndexGenerator | + | |
- | { | + | namespace RoutingIndexGenerator |
- | static class Program | + | { |
- | { | + | static class Program |
- | /// <summary> | + | { |
- | /// The main entry point for the application. | + | /// <summary> |
- | /// </summary> | + | /// The main entry point for the application. |
- | [STAThread] | + | /// </summary> |
- | static void Main() | + | [STAThread] |
- | { | + | static void Main() |
- | Application.EnableVisualStyles(); | + | { |
- | Application.SetCompatibleTextRenderingDefault(false); | + | Application.EnableVisualStyles(); |
- | Application.Run(new RoutingIndexGenerator()); | + | Application.SetCompatibleTextRenderingDefault(false); |
- | } | + | Application.Run(new RoutingIndexGenerator()); |
- | } | + | } |
- | } | + | } |
+ | } | ||
| | ||
</code> | </code> | ||
Line 639: | Line 974: | ||
<code csharp> | <code csharp> | ||
+ | |||
+ | namespace RoutingIndexGenerator | ||
+ | { | ||
+ | public enum SpeedUnit | ||
+ | { | ||
+ | KilometersPerHour = 0, | ||
+ | MilesPerHour = 1 | ||
+ | } | ||
+ | } | ||
| | ||
- | namespace RoutingIndexGenerator | + | </code> |
- | { | + | |
- | public enum SpeedUnit | + | |
- | { | + | |
- | kilometer_hour = 0, | + | |
- | mile_hour = 1 | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | </code> | + | |
- | + | ====RoutingIndexType.cs==== | |
- | + | ||
- | ====SpeedType.cs==== | + | |
<code csharp> | <code csharp> | ||
| | ||
- | + | namespace RoutingIndexGenerator | |
- | namespace RoutingIndexGenerator | + | { |
- | { | + | public enum RoutingIndexType |
- | public enum SpeedType | + | { |
- | { | + | Fastest = 0, |
- | RoadClass = 0, | + | Shortest = 1 |
- | RoadSpeed = 1, | + | } |
- | DefaultSpeed = 2 | + | } |
- | } | + | |
- | } | + | |
| | ||
</code> | </code> | ||
- | + | ====RoadSpeedOption.cs==== | |
- | ====RouteIndexType.cs==== | + | |
<code csharp> | <code csharp> | ||
| | ||
- | | + | using System.Collections.Generic; |
- | namespace RoutingIndexGenerator | + | |
- | { | + | namespace RoutingIndexGenerator |
- | public enum RouteIndexType | + | { |
- | { | + | public class RoadSpeedOption |
- | Fastest = 0, | + | { |
- | Shortest = 1 | + | 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> | </code> | ||
- | ====RoadSpeedOption.cs==== | + | |
+ | ====OneWayRoadOption.cs==== | ||
<code csharp> | <code csharp> | ||
| | ||
- | using System.Collections.Generic; | + | using System; |
- | + | using System.Text.RegularExpressions; | |
- | 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; | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | + | ||
- | </code> | + | |
+ | 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; | ||
- | ====OneWayRoadOption.cs==== | + | 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> | <code csharp> | ||
| | ||
- | | + | using System.IO; |
- | namespace RoutingIndexGenerator | + | using ThinkGeo.MapSuite.Core; |
- | { | + | using ThinkGeo.MapSuite.Routing; |
- | public class OneWayRoadOption | + | |
- | { | + | namespace RoutingIndexGenerator |
- | private string oneWayColumnName; | + | { |
- | private string bothWayRoadValue; | + | public class RoutingIndexBuilderParameters |
- | private string indicatorColumnName; | + | { |
- | private string fromToValue; | + | private BuildRoutingDataMode buildRoutingDataMode; |
- | private string toFromValue; | + | private GeographyUnit geographyUnit; |
- | private string closedRoad; | + | private OneWayRoadOption oneWayRoadOption; |
- | + | private ClosedRoadOption closedRoadOption; | |
- | public OneWayRoadOption() | + | private RoadSpeedOption speedOption; |
- | { } | + | private RoutingIndexType routeIndexType; |
- | + | private RectangleShape restrictExtent; | |
- | public string OneWayColumnName | + | private string routableShapeFilePathName; |
- | { | + | private string rtgFilePathName; |
- | get { return oneWayColumnName; } | + | private string sourceSqlitePathName; |
- | set { oneWayColumnName = value; } | + | private bool includeOnewayOptions; |
- | } | + | private bool overrideRoutableFile; |
- | + | ||
- | public string BothWayRoadValue | + | public RoutingIndexBuilderParameters() |
- | { | + | { |
- | get { return bothWayRoadValue; } | + | RouteIndexType = RoutingIndexType.Fastest; |
- | set { bothWayRoadValue = value; } | + | GeographyUnit = GeographyUnit.Meter; |
- | } | + | BuildRoutingDataMode = BuildRoutingDataMode.Rebuild; |
- | + | ||
- | public string IndicatorColumnName | + | OneWayRoadOption = new OneWayRoadOption(); |
- | { | + | closedRoadOption = new ClosedRoadOption(); |
- | get { return indicatorColumnName; } | + | SpeedOption = new RoadSpeedOption(); |
- | set { indicatorColumnName = value; } | + | overrideRoutableFile = true; |
- | } | + | } |
- | + | ||
- | public string FromToValue | + | public RectangleShape RestrictExtent |
- | { | + | { |
- | get { return fromToValue; } | + | get { return restrictExtent; } |
- | set { fromToValue = value; } | + | set { restrictExtent = value; } |
- | } | + | } |
- | + | ||
- | public string ToFromValue | + | public BuildRoutingDataMode BuildRoutingDataMode |
- | { | + | { |
- | get { return toFromValue; } | + | get { return buildRoutingDataMode; } |
- | set { toFromValue = value; } | + | set { buildRoutingDataMode = value; } |
- | } | + | } |
- | + | ||
- | public string ClosedRoad | + | public GeographyUnit GeographyUnit |
- | { | + | { |
- | get { return closedRoad; } | + | get { return geographyUnit; } |
- | set { closedRoad = value; } | + | 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> | </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> | ||
- | ====BuildRoutingIndexParameters.cs==== | + | ====ClosedRoadOptions.cs==== |
<code csharp> | <code csharp> | ||
| | ||
- | using System.IO; | + | using System; |
- | using ThinkGeo.MapSuite.Core; | + | using System.Text.RegularExpressions; |
- | using ThinkGeo.MapSuite.Routing; | + | namespace RoutingIndexGenerator |
- | | + | { |
- | namespace RoutingIndexGenerator | + | public class ClosedRoadOption |
- | { | + | { |
- | public class BuildRoutingIndexParameters | + | private string closedRoadValue; |
- | { | + | private string closedColumnName; |
- | private BuildRoutingDataMode buildRoutingDataMode; | + | private Regex closedRoadValueRegex; |
- | private DistanceUnit distanceUnit; | + | |
- | private GeographyUnit geographyUnit; | + | public string ClosedColumnName |
- | private OneWayRoadOption oneWayRoadOption; | + | { |
- | private RouteIndexType routeIndexType; | + | get { return closedColumnName; } |
- | private string rtgFilePathName; | + | set { closedColumnName = value; } |
- | private string shapefilePathName; | + | } |
- | private bool skipOnewayOptions; | + | |
- | private RoadSpeedOption speedOption; | + | public string ClosedRoadValue |
- | + | { | |
- | public BuildRoutingIndexParameters() | + | get { return closedRoadValue; } |
- | { | + | set { closedRoadValue = value; } |
- | DistanceUnit = DistanceUnit.Meter; | + | } |
- | RouteIndexType = RouteIndexType.Shortest; | + | |
- | GeographyUnit = GeographyUnit.DecimalDegree; | + | private Regex GetRegex(string stringToMatch) |
- | BuildRoutingDataMode = BuildRoutingDataMode.Rebuild; | + | { |
- | + | if (String.IsNullOrEmpty(stringToMatch)) | |
- | OneWayRoadOption = new OneWayRoadOption(); | + | { |
- | SpeedOption = new RoadSpeedOption(); | + | return null; |
- | } | + | } |
- | + | ||
- | public BuildRoutingDataMode BuildRoutingDataMode | + | Regex regex = null; |
- | { | + | |
- | get { return buildRoutingDataMode; } | + | if (stringToMatch.StartsWith("[") && stringToMatch.EndsWith("]")) |
- | set { buildRoutingDataMode = value; } | + | { |
- | } | + | string regexString = stringToMatch.Substring(1, stringToMatch.Length - 2); |
- | + | regex = new Regex(regexString, RegexOptions.Compiled); | |
- | public DistanceUnit DistanceUnit | + | } |
- | { | + | |
- | get { return distanceUnit; } | + | return regex; |
- | set { distanceUnit = value; } | + | } |
- | } | + | |
- | + | public void InitRegexes() | |
- | public GeographyUnit GeographyUnit | + | { |
- | { | + | this.closedRoadValueRegex = GetRegex(this.closedRoadValue); |
- | get { return geographyUnit; } | + | } |
- | set { geographyUnit = value; } | + | |
- | } | + | public bool MatchClosedRoadValue(string closedRoadValue) |
- | + | { | |
- | public OneWayRoadOption OneWayRoadOption | + | bool match = false; |
- | { | + | if (closedRoadValue == null) |
- | get { return oneWayRoadOption; } | + | { |
- | set { oneWayRoadOption = value; } | + | match = closedRoadValue.Equals(this.closedRoadValue, StringComparison.InvariantCultureIgnoreCase); |
- | } | + | } |
- | + | else | |
- | public RouteIndexType RouteIndexType | + | { |
- | { | + | match = closedRoadValueRegex.Match(closedRoadValue).Success; |
- | get { return routeIndexType; } | + | } |
- | set { routeIndexType = value; } | + | return match; |
- | } | + | } |
- | + | ||
- | public string RtgFilePathName | + | } |
- | { | + | } |
- | get { return rtgFilePathName; } | + | |
- | set | + | </code> |
- | { | + | |
- | 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; | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | </code> | + |