// $Id: PopulateRoadwaySegmentsFromDisplayLinks.cs,v 1.2 2013-01-03 21:04:52 jonesk Exp $ // Copyright TransCore 2012, All Rights Reserved // // PROPRIETARY // THIS SOURCE CODE IS THE PROPERTY OF TRANSCORE. IT MAY BE USED BY RECIPIENT // ONLY FOR THE PURPOSE FOR WHICH IT WAS TRANSMITTED AND MUST BE RETURNED UPON // REQUEST OR WHEN NO LONGER NEEDED BY RECIPIENT. IT MAY NOT BE COPIED OR // COMMUNICATED WITHOUT THE WRITTEN CONSENT OF TRANSCORE. // //----------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Linq; using Microsoft.SqlServer.Server; public partial class StoredProcedures { /// /// Loads WebMap_RoadwaySegment and WebMap_RoadwaySegmentDetectorStation /// using data in FMS_DetectorStation, FMS_ComponentConnect, and FMSDisplayLink /// [Microsoft.SqlServer.Server.SqlProcedure] public static void PopulateRoadwaySegmentsFromDisplayLinks() { using (SqlConnection sqlConnection = new SqlConnection("context connection=true")) { sqlConnection.Open(); try { #region Delete any existing RoadwaySegments string sqlDelete = @"DELETE FROM WebMap_RoadwaySegmentDisplayLink " + "DELETE FROM WebMap_RoadwaySegmentDetectorStation " + "DELETE FROM WebMap_RoadwaySegment"; using (SqlTransaction deleteTransaction = sqlConnection.BeginTransaction("txnRoadwaySegmentDelete")) using (SqlCommand deleteCommand = new SqlCommand(sqlDelete, sqlConnection, deleteTransaction)) { deleteCommand.ExecuteNonQuery(); deleteTransaction.Commit(); } #endregion List> segmentsDsData = new List>(); #region Populate segmentsDsData from FMS_ComponentConnect and FMS_DetectorStation string sqlDsConnects = @"SELECT FMS_DetectorStation.IntId, RoadwayName, TmddLinkDirection, " + "FMS_DetectorStation.LinearReference, FMS_ComponentConnect.Distance " + "FROM FMS_DetectorStation " + "JOIN FMS_ComponentConnect ON FMS_DetectorStation.IntId = FMS_ComponentConnect.DSIntId " + "ORDER BY FMS_ComponentConnect.DSIntId, DSIntIdDownstream"; using (SqlCommand sqlCommand = new SqlCommand(sqlDsConnects, sqlConnection)) using (SqlDataReader sqlDsConnectsReader = sqlCommand.ExecuteReader()) { string lastRoadway = string.Empty; int lastDirection = -1; float lastLinearReference = -1; List thisSegmentData = new List(); while (sqlDsConnectsReader.Read()) { Object[] dsConnectValues = new Object[sqlDsConnectsReader.FieldCount]; sqlDsConnectsReader.GetValues(dsConnectValues); int dsIntId = (int)dsConnectValues[0]; string roadwayName = dsConnectValues[1].ToString(); int tmddLinkDirection = int.Parse(dsConnectValues[2].ToString()); float linearReference = float.Parse(dsConnectValues[3].ToString()); float distance = float.Parse(dsConnectValues[4].ToString()); if (roadwayName != lastRoadway || tmddLinkDirection != lastDirection || linearReference < lastLinearReference) { if (thisSegmentData.Count > 0) { segmentsDsData.Add(thisSegmentData); } thisSegmentData = new List(); thisSegmentData.Add(new SegmentDetectorStationData(dsIntId, distance)); } else { thisSegmentData.Add(new SegmentDetectorStationData(dsIntId, distance)); } lastRoadway = roadwayName; lastDirection = tmddLinkDirection; lastLinearReference = linearReference; } if (thisSegmentData.Count > 0) { segmentsDsData.Add(thisSegmentData); } } #endregion string roadwaySegmentInsertValues = string.Empty; string roadwaySegmentDlInsertValues = string.Empty; string roadwaySegmentDsInsertValues = string.Empty; #region Build values portions of insert statements int segmentId = 0; foreach (List thisSegmentData in segmentsDsData) { bool segmentDisplayLinkFound = false; int dlSequence = 0; foreach (SegmentDetectorStationData segmentDsData in thisSegmentData) { int dsSequence = 0; int dlIntId = -1; int vertexCount = -1; #region roadwaySegmentDsInsertValues = FMS_DisplayLinks.Where(DsIntId = dsIntId) with greatest amount of verticies string sqlDisplayLinks = @"SELECT VertexData, FMS_DisplayLink.IntId " + "FROM FMS_DisplayLinkDetStation " + "JOIN FMS_DisplayLink ON FMS_DisplayLinkDetStation.DLIntId = FMS_DisplayLink.IntId " + "WHERE DSIntId = " + segmentDsData.DsIntId; using (SqlCommand sqlCommand2 = new SqlCommand(sqlDisplayLinks, sqlConnection)) using (SqlDataReader sqlDisplayLinksReader = sqlCommand2.ExecuteReader()) { while (sqlDisplayLinksReader.Read()) { Object[] dsDisplayLinkValues = new Object[sqlDisplayLinksReader.FieldCount]; sqlDisplayLinksReader.GetValues(dsDisplayLinkValues); string vertexData = dsDisplayLinkValues[0].ToString(); int countDataSeperatorIdx = vertexData.IndexOf(' '); int thisCount = int.Parse(vertexData.Substring(0, countDataSeperatorIdx)); if (thisCount > vertexCount) { dlIntId = Int32.Parse(dsDisplayLinkValues[1].ToString()); vertexCount = thisCount; } } } #endregion if (vertexCount > 0) { segmentDisplayLinkFound = true; if (roadwaySegmentDsInsertValues.Length > 0) { roadwaySegmentDsInsertValues += ","; } ++dsSequence; roadwaySegmentDsInsertValues += string.Format("((SELECT IntId FROM WebMap_RoadwaySegment WHERE ExtId={0}),{1},{2},{3})", segmentId + 1, segmentDsData.DsIntId, segmentDsData.Distance, dsSequence); if (roadwaySegmentDlInsertValues.Length > 0) { roadwaySegmentDlInsertValues += ","; } ++dlSequence; roadwaySegmentDlInsertValues += string.Format("((SELECT IntId FROM WebMap_RoadwaySegment WHERE ExtId={0}),{1},{2})", segmentId + 1, dlIntId, dlSequence); } } if (segmentDisplayLinkFound) { ++segmentId; if (roadwaySegmentInsertValues.Length > 0) { roadwaySegmentInsertValues += ","; } roadwaySegmentInsertValues += string.Format("({0},'Roadway Segment {0}')", segmentId); } } #endregion #region Insert all rows using (SqlTransaction insertTransaction = sqlConnection.BeginTransaction("txnRoadwaySegmentInsert")) { string sqlInsert = @"INSERT INTO WebMap_RoadwaySegment (ExtId, Name) VALUES " + roadwaySegmentInsertValues + " "; using (SqlCommand insertCommand = new SqlCommand(sqlInsert, sqlConnection, insertTransaction)) { insertCommand.ExecuteNonQuery(); } sqlInsert = @"INSERT INTO WebMap_RoadwaySegmentDisplayLink (RoadwaySegmentIntId, DLIntId, Sequence) VALUES " + roadwaySegmentDlInsertValues; using (SqlCommand insertCommand = new SqlCommand(sqlInsert, sqlConnection, insertTransaction)) { insertCommand.ExecuteNonQuery(); } sqlInsert = @"INSERT INTO WebMap_RoadwaySegmentDetectorStation (RoadwaySegmentIntId, DsIntId, Distance, Sequence) VALUES " + roadwaySegmentDsInsertValues; using (SqlCommand insertCommand = new SqlCommand(sqlInsert, sqlConnection, insertTransaction)) { insertCommand.ExecuteNonQuery(); } insertTransaction.Commit(); } #endregion } catch (Exception ex) { SqlContext.Pipe.Send(ex.Message); } finally { sqlConnection.Close(); } } } private class SegmentDetectorStationData { public SegmentDetectorStationData(int dsIntId, float distance) { DsIntId = dsIntId; Distance = distance; } public int DsIntId { get; private set; } public float Distance { get; private set; } } };