This shows you the differences between two versions of the page.
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> |