/// <summary> /// Physically split features on the GIS layer. /// </summary> private bool PerformPhysicalSplit() { bool success = true; _viewModelMain.DataBase.BeginTransaction(true, IsolationLevel.ReadCommitted); try { // find next available toid_fragment_id for selected toid string lastToidFragmentID = _viewModelMain.RecIDs.MaxToidFragmentId(_viewModelMain.ToidsSelectedMap.ElementAt(0)); // get a filter from the GIS selection List <List <SqlFilterCondition> > featuresFilter = ViewModelWindowMainHelpers.GisSelectionToWhereClause( _viewModelMain.GisSelection.AsEnumerable().Skip(1).ToArray(), _viewModelMain.GisIDColumnOrdinals, ViewModelWindowMain.IncidPageSize, _viewModelMain.HluDataset.incid_mm_polygons); if (featuresFilter.Count != 1) { throw new Exception("Error finding features in database."); } // update records in GIS and collect new features resulting from split DataTable newFeatures = _viewModelMain.GISApplication.SplitFeature(lastToidFragmentID, featuresFilter[0], _viewModelMain.HluDataset.incid_mm_polygons.Columns.Cast <DataColumn>().Where(c => c.ColumnName != _viewModelMain.HluDataset.incid_mm_polygons.shape_lengthColumn.ColumnName && c.ColumnName != _viewModelMain.HluDataset.incid_mm_polygons.shape_areaColumn.ColumnName).ToArray()); if ((newFeatures == null) || (newFeatures.Rows.Count < 2)) { throw new Exception("Failed to update GIS layer."); } ViewModelWindowMainHistory vmHist = new ViewModelWindowMainHistory(_viewModelMain); vmHist.HistoryRenameGeometryPropertyColumns( _viewModelMain.HluDataset.incid_mm_polygons.shape_lengthColumn.ColumnName, _viewModelMain.HluDataset.incid_mm_polygons.shape_areaColumn.ColumnName, ref newFeatures); // get a where clause for the original split feature List <List <SqlFilterCondition> > originalFeatureWhereClause = ViewModelWindowMainHelpers.GisSelectionToWhereClause( _viewModelMain.GisSelection.AsEnumerable().Take(1).ToArray(), _viewModelMain.GisIDColumnOrdinals, ViewModelWindowMain.IncidPageSize, _viewModelMain.HluDataset.incid_mm_polygons); if (originalFeatureWhereClause.Count != 1) { throw new Exception("Error finding features in database."); } // get the attributes of the split feature HluDataSet.incid_mm_polygonsDataTable updTable = new HluDataSet.incid_mm_polygonsDataTable(); _viewModelMain.GetIncidMMPolygonRows(originalFeatureWhereClause, ref updTable); if ((updTable == null) || (updTable.Rows.Count != 1)) { throw new Exception("Failed to fetch incid_mm_polygon rows."); } // insert attributes of original split feature into history DataTable history = updTable.Copy(); history.Columns[updTable.shape_lengthColumn.ColumnName].ColumnName = ViewModelWindowMain.HistoryGeometry1ColumnName; history.Columns[updTable.shape_areaColumn.ColumnName].ColumnName = ViewModelWindowMain.HistoryGeometry2ColumnName; string[] historyColNames = (new string[] { ViewModelWindowMain.HistoryGeometry1ColumnName, ViewModelWindowMain.HistoryGeometry2ColumnName } .Concat(_viewModelMain.HistoryColumns.Select(c => c.ColumnName)).ToArray()); DataColumn[] delCols = history.Columns.Cast <DataColumn>().Where(c => !historyColNames.Contains(c.ColumnName)).ToArray(); foreach (DataColumn c in delCols) { history.Columns.Remove(c); } vmHist.HistoryWrite(null, history, ViewModelWindowMain.Operations.PhysicalSplit); // update the original row if (_viewModelMain.DataBase.ExecuteNonQuery(String.Format("UPDATE {0} SET {1} WHERE {2}", _viewModelMain.DataBase.QualifyTableName(_viewModelMain.HluDataset.incid_mm_polygons.TableName), String.Join(",", newFeatures.Rows[0].ItemArray.Select((i, index) => new { ColumnName = newFeatures.Columns[index].ColumnName, value = i }) .Where(a => _viewModelMain.GisIDColumns.Count(c => c.ColumnName == a.ColumnName) == 0) .Select(a => String.Format("{0} = {1}", _viewModelMain.DataBase.QuoteIdentifier(a.ColumnName), _viewModelMain.DataBase.QuoteValue(a.value))).ToArray()), _viewModelMain.DataBase.WhereClause(false, true, true, originalFeatureWhereClause[0])), _viewModelMain.DataBase.Connection.ConnectionTimeout, CommandType.Text) == -1) { throw new Exception("Failed to update original row in database copy of GIS layer."); } // build an insert statement for DB shadow copy of GIS layer string insertStatement = String.Format("INSERT INTO {0} ({1}) VALUES (", _viewModelMain.DataBase.QualifyTableName(_viewModelMain.HluDataset.incid_mm_polygons.TableName), String.Join(",", newFeatures.Columns.Cast <DataColumn>().Select(c => _viewModelMain.DataBase.QuoteIdentifier(c.ColumnName)).ToArray())) + "{0})"; int toidFragID = Int32.Parse(lastToidFragmentID); string numFormat = String.Format("D{0}", updTable.toid_fragment_idColumn.MaxLength); // insert new features returned from GIS into DB shadow copy of GIS layer for (int i = 1; i < newFeatures.Rows.Count; i++) { if (_viewModelMain.DataBase.ExecuteNonQuery(String.Format(insertStatement, String.Join(",", newFeatures.Rows[i].ItemArray.Select((item, index) => _viewModelMain.DataBase.QuoteValue(newFeatures.Columns[index].ColumnName == updTable.toid_fragment_idColumn.ColumnName ? (toidFragID + i).ToString(numFormat) : item)).ToArray())), _viewModelMain.DataBase.Connection.ConnectionTimeout, CommandType.Text) == -1) { throw new Exception("Failed to insert new rows into database copy of GIS layer."); } } _viewModelMain.ViewModelUpdate.UpdateIncidModifiedColumns(_viewModelMain.IncidsSelectedMap.ElementAt(0)); _viewModelMain.DataBase.CommitTransaction(); _viewModelMain.HluDataset.AcceptChanges(); } catch (Exception ex) { _viewModelMain.DataBase.RollbackTransaction(); success = false; MessageBox.Show("Split operation failed. The error message returned was:\n\n" + ex.Message, "HLU Split Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { if (success) { _viewModelMain.IncidRowCount(true); _viewModelMain.ClearFilter(); _viewModelMain.ReadMapSelection(true); } } return(success); }