private void Initialize(ShapeFileType shapeFileType, string pathFileName, IEnumerable <DbfColumn> columns, string projectionWkt) { string[] suffixes = { ".shp", ".shx", ".ids", ".idx", ".dbf", ".prj" }; foreach (var suffix in suffixes) { string fileToRemove = Path.ChangeExtension(pathFileName, suffix); if (File.Exists(fileToRemove)) { File.Delete(fileToRemove); } } if (!string.IsNullOrEmpty(projectionWkt)) { File.WriteAllText(Path.ChangeExtension(pathFileName, ".prj"), projectionWkt); } ShapeFileFeatureLayer.CreateShapeFile(shapeFileType, pathFileName, columns); featureLayer = new ShapeFileFeatureLayer(pathFileName, GeoFileReadWriteMode.ReadWrite); }
private void CreateShapeFile(ObservableCollection <FeatureSourceColumn> includedColumnsList , string OutputPath, Encoding ShapeFileEncoding, string csvFilePath , List <Feature> features , bool isIncludeAllFeatures , IEnumerable <MatchCondition> matchConditions , Action <UpdatingTaskProgressEventArgs> updateAction , Dictionary <string, string> invalidColumns) { Collection <DbfColumn> includeColumns = new Collection <DbfColumn>(); RemoveUnduplicateColumn(includedColumnsList); foreach (var column in includedColumnsList) { DbfColumnType tmpDbfColumnType = DbfColumnType.Character; if (Enum.TryParse(column.TypeName, out tmpDbfColumnType)) { DbfColumn dbfColumn = new DbfColumn(column.ColumnName, tmpDbfColumnType, column.MaxLength, 0); includeColumns.Add(dbfColumn); } } ShapeFileType shapeFileType = GetShapeFileType(features.FirstOrDefault()); if (shapeFileType != ShapeFileType.Null) { ShapeFileFeatureLayer.CreateShapeFile(shapeFileType, OutputPath, includeColumns, ShapeFileEncoding, OverwriteMode.Overwrite); var dataTable = DataJoinAdapter.ReadDataToDataGrid(csvFilePath, Delimiter); var featureRows = dataTable.Rows; var index = 0; var count = features.Count; ShapeFileFeatureLayer newShapeFileFeatureLayer = new ShapeFileFeatureLayer(OutputPath, GeoFileReadWriteMode.ReadWrite); newShapeFileFeatureLayer.SafeProcess(() => { newShapeFileFeatureLayer.EditTools.BeginTransaction(); foreach (var feature in features) { index++; try { var matchedDataRow = featureRows.Cast <DataRow>().FirstOrDefault(r => matchConditions.All(tmpCondition => feature.ColumnValues[tmpCondition.SelectedLayerColumn.ColumnName] == r[tmpCondition.SelectedDelimitedColumn.ColumnName].ToString())); if (matchedDataRow != null) { SetFeatureColumnValues(feature, matchedDataRow, includedColumnsList, invalidColumns); newShapeFileFeatureLayer.EditTools.Add(feature); } else if (isIncludeAllFeatures) { newShapeFileFeatureLayer.EditTools.Add(feature); } if (UpdateProgress(updateAction, index, count)) { break; } } catch (Exception ex) { var errorEventArgs = new UpdatingTaskProgressEventArgs(TaskState.Error); errorEventArgs.Error = new ExceptionInfo(string.Format(CultureInfo.InvariantCulture, "Feature id: {0}, {1}" , feature.Id, ex.Message) , ex.StackTrace , ex.Source); GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); errorEventArgs.Message = feature.Id; updateAction(errorEventArgs); } } newShapeFileFeatureLayer.EditTools.CommitTransaction(); }); SavePrjFile(OutputPath, DisplayProjectionParameters); } }
protected override FeatureLayer CreateFeatureLayerCore(ConfigureFeatureLayerParameters featureLayerStructureParameters) { string layerPath = LayerPluginHelper.GetLayerUriToSave(featureLayerStructureParameters.LayerUri, ExtensionFilterCore); if (string.IsNullOrEmpty(layerPath)) { return(null); } featureLayerStructureParameters.LayerUri = new Uri(layerPath); ShapeFileType shapeFileType = ShapeFileType.Null; switch (featureLayerStructureParameters.WellKnownType) { case WellKnownType.Multipoint: shapeFileType = ShapeFileType.Multipoint; break; case WellKnownType.Point: shapeFileType = ShapeFileType.Point; break; case WellKnownType.Line: case WellKnownType.Multiline: shapeFileType = ShapeFileType.Polyline; break; case WellKnownType.Polygon: case WellKnownType.Multipolygon: shapeFileType = ShapeFileType.Polygon; break; } Dictionary <string, DbfColumn> dbfColumns = new Dictionary <string, DbfColumn>(); Collection <FeatureSourceColumn> addedColumns = featureLayerStructureParameters.AddedColumns; Dictionary <string, string> oldNewNames = new Dictionary <string, string>(); Collection <Feature> addedFeatures = featureLayerStructureParameters.AddedFeatures; bool truncateLongColumn = featureLayerStructureParameters.LongColumnTruncateMode == LongColumnTruncateMode.Truncate; if (truncateLongColumn) { Dictionary <string, string> editColumns = new Dictionary <string, string>(); if (featureLayerStructureParameters.CustomData.ContainsKey("EditedColumns")) { editColumns = featureLayerStructureParameters.CustomData["EditedColumns"] as Dictionary <string, string>; } addedColumns = TruncateLongColumnNames(featureLayerStructureParameters.AddedColumns, oldNewNames, editColumns); } foreach (var column in addedColumns) { if (!string.IsNullOrEmpty(column.ColumnName)) { DbfColumn dbfColumn = column as DbfColumn; if (dbfColumn != null) { if (dbfColumn.ColumnType == DbfColumnType.DoubleInBinary || dbfColumn.ColumnType == DbfColumnType.DateTime) { dbfColumn.Length = 8; dbfColumn.DecimalLength = 0; } else if (dbfColumn.ColumnType == DbfColumnType.IntegerInBinary) { dbfColumn.Length = 4; dbfColumn.DecimalLength = 0; } } else { int columnLenght = column.MaxLength; int decimalLength = 0; switch (column.TypeName.ToUpperInvariant()) { case "DOUBLE": case "NUMERIC": columnLenght = columnLenght == 0 ? 10 : columnLenght; if (columnLenght < 4) { columnLenght = 10; } decimalLength = 4; break; case "DATE": case "DATETIME": columnLenght = columnLenght == 0 ? 10 : columnLenght; decimalLength = 0; break; case "INTEGER": case "INT": columnLenght = columnLenght == 0 ? 10 : columnLenght; decimalLength = 0; break; case "STRING": case "CHARACTER": columnLenght = columnLenght == 0 ? characterTypeLength : columnLenght; decimalLength = 0; break; case "LOGICAL": columnLenght = 5; decimalLength = 0; break; } DbfColumnType type = DbfColumnType.Character; if (column.TypeName.Equals("DOUBLE", StringComparison.InvariantCultureIgnoreCase)) { column.TypeName = DbfColumnType.Float.ToString(); } if (column.TypeName.Equals("INT", StringComparison.InvariantCultureIgnoreCase)) { column.TypeName = DbfColumnType.Numeric.ToString(); } bool isSuccess = Enum.TryParse <DbfColumnType>(column.TypeName, true, out type); if (!isSuccess) { type = DbfColumnType.Character; } dbfColumn = new DbfColumn(column.ColumnName, type, columnLenght, decimalLength); dbfColumn.TypeName = column.TypeName; dbfColumn.MaxLength = column.MaxLength; } //Feature firstFeature = featureLayerStructureParameters.AddedFeatures.FirstOrDefault(); ////This is to fix that fox pro columns cannot write to dbf, convert all linked columns to character column type. //string tempColumnName = column.ColumnName; //if (oldNewNames.ContainsValue(column.ColumnName)) //{ // tempColumnName = oldNewNames.FirstOrDefault(f => f.Value == column.ColumnName).Key; //} //if (tempColumnName.Contains(".") && firstFeature != null && firstFeature.LinkColumnValues.ContainsKey(tempColumnName)) //{ // if (dbfColumn.ColumnType != DbfColumnType.Memo) // { // dbfColumn.ColumnType = DbfColumnType.Character; // dbfColumn.Length = characterTypeLength; // dbfColumn.DecimalLength = 0; // } //} dbfColumns[dbfColumn.ColumnName] = dbfColumn; } } bool convertMemoToCharacter = featureLayerStructureParameters.MemoColumnConvertMode == MemoColumnConvertMode.ToCharacter; Dictionary <string, int> columnLength = new Dictionary <string, int>(); foreach (var feature in addedFeatures) { //foreach (var linkColumnValue in feature.LinkColumnValues) //{ // if (!feature.ColumnValues.ContainsKey(linkColumnValue.Key)) // { // string[] values = linkColumnValue.Value.Select(v => // { // if (v.Value == null) // { // return string.Empty; // } // if (v.Value is DateTime) // { // return ((DateTime)v.Value).ToShortDateString(); // } // return v.Value.ToString(); // }).ToArray(); // if (values.All(v => string.IsNullOrEmpty(v) || string.IsNullOrWhiteSpace(v))) // { // if (oldNewNames.ContainsKey(linkColumnValue.Key)) // feature.ColumnValues[oldNewNames[linkColumnValue.Key]] = string.Empty; // else // feature.ColumnValues[linkColumnValue.Key] = string.Empty; // } // else // { // string tempColumName = linkColumnValue.Key; // if (oldNewNames.ContainsKey(linkColumnValue.Key)) // { // tempColumName = oldNewNames[linkColumnValue.Key]; // } // string linkValue = string.Join(",", values); // feature.ColumnValues[tempColumName] = linkValue; // //Choose the max length // if (columnLength.ContainsKey(tempColumName)) // { // if (columnLength[tempColumName] < linkValue.Length) // { // columnLength[tempColumName] = linkValue.Length; // } // } // else // { // columnLength[tempColumName] = linkValue.Length > 254 ? 254 : linkValue.Length; // } // } // } //} foreach (var item in oldNewNames) { if (feature.ColumnValues.ContainsKey(item.Key)) { feature.ColumnValues[oldNewNames[item.Key]] = feature.ColumnValues[item.Key]; feature.ColumnValues.Remove(item.Key); } } if (!convertMemoToCharacter) { foreach (var item in feature.ColumnValues) { if (item.Value.Length > characterTypeLength && dbfColumns[item.Key].ColumnType != DbfColumnType.Memo) { dbfColumns[item.Key].ColumnType = DbfColumnType.Memo; dbfColumns[item.Key].Length = 4; dbfColumns[item.Key].DecimalLength = 0; } } } } foreach (var column in dbfColumns) { Feature firstFeature = featureLayerStructureParameters.AddedFeatures.FirstOrDefault(); //This is to fix that fox pro columns cannot write to dbf, convert all linked columns to character column type. string tempColumnName = column.Key; if (oldNewNames.ContainsValue(column.Key)) { tempColumnName = oldNewNames.FirstOrDefault(f => f.Value == column.Key).Key; } //if (tempColumnName.Contains(".") && firstFeature != null && firstFeature.LinkColumnValues.ContainsKey(tempColumnName)) //{ // if (column.Value.ColumnType != DbfColumnType.Memo) // { // column.Value.ColumnType = DbfColumnType.Character; // //column.Value.Length = characterTypeLength; // column.Value.DecimalLength = 0; // if (columnLength.ContainsKey(tempColumnName) && column.Value.Length < columnLength[tempColumnName]) // { // column.Value.Length = columnLength[tempColumnName]; // } // } //} } ShapeFileFeatureLayer.CreateShapeFile(shapeFileType, featureLayerStructureParameters.LayerUri.OriginalString, dbfColumns.Values, DefaultEncoding, OverwriteMode.Overwrite); string encodingPathFileName = Path.ChangeExtension(featureLayerStructureParameters.LayerUri.OriginalString, ".cpg"); if (File.Exists(encodingPathFileName)) { File.Delete(encodingPathFileName); } File.WriteAllText(encodingPathFileName, DefaultEncoding.CodePage.ToString(CultureInfo.InvariantCulture)); string prjPath = Path.ChangeExtension(featureLayerStructureParameters.LayerUri.OriginalString, "prj"); File.WriteAllText(prjPath, Proj4Projection.ConvertProj4ToPrj(featureLayerStructureParameters.Proj4ProjectionParametersString)); ShapeFileFeatureLayer resultLayer = new ShapeFileFeatureLayer(featureLayerStructureParameters.LayerUri.LocalPath, GeoFileReadWriteMode.ReadWrite); if (addedFeatures.Count > 0) { resultLayer.Open(); resultLayer.EditTools.BeginTransaction(); foreach (var feature in addedFeatures) { if (convertMemoToCharacter) { foreach (var item in dbfColumns) { if (feature.ColumnValues.ContainsKey(item.Key) && feature.ColumnValues[item.Key].Length > 254) { feature.ColumnValues[item.Key] = feature.ColumnValues[item.Key].Substring(0, 254); } if (feature.ColumnValues.ContainsKey(item.Key) && feature.ColumnValues[item.Key].Length > item.Value.MaxLength) { feature.ColumnValues[item.Key] = feature.ColumnValues[item.Key].Substring(0, item.Value.MaxLength); } } } resultLayer.EditTools.Add(feature); } resultLayer.EditTools.CommitTransaction(); resultLayer.Close(); } return(resultLayer); }
private void Export(IGrouping <ShapeFileType, Feature> group, FileExportInfo info) { string path = info.Path; if (File.Exists(path)) { if (info.Overwrite) { string[] suffixes = { ".shp", ".shx", ".ids", ".idx", ".dbf", ".prj" }; foreach (var suffix in suffixes) { string fileToRemove = Path.ChangeExtension(path, suffix); if (File.Exists(fileToRemove)) { File.Delete(fileToRemove); } } } else { string dir = Path.GetDirectoryName(path); string fileName = Path.GetFileNameWithoutExtension(path); string extension = Path.GetExtension(path); path = Path.Combine(dir, fileName + group.Key.ToString() + extension); } } var dbfColumns = info.Columns.Select(column => { DbfColumnType columnType = (DbfColumnType)Enum.Parse(typeof(DbfColumnType), column.TypeName); DbfColumn dbfColumn = new DbfColumn(column.ColumnName, columnType, column.MaxLength, GetDecimalLength(columnType, column.MaxLength)); return(dbfColumn); }); ShapeFileFeatureLayer.CreateShapeFile(group.Key, path, dbfColumns); ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(path, GeoFileReadWriteMode.ReadWrite); try { layer.Open(); layer.EditTools.BeginTransaction(); foreach (var feature in group) { bool isValid = true; var newFeature = feature; if (!feature.IsValid()) { if (feature.CanMakeValid) { newFeature = feature.MakeValid(); } else { isValid = false; } } if (isValid) { var featureSourceColumns = layer.FeatureSource.GetColumns(); var tempColumnNames = featureSourceColumns.Select(column => column.ColumnName); var validColumns = GeoDbf.GetValidColumnNames(tempColumnNames); Dictionary <string, string> columnValues = new Dictionary <string, string>(); for (int i = 0; i < validColumns.Count(); i++) { var columnName = dbfColumns.ElementAt(i).ColumnName; if (newFeature.ColumnValues.ContainsKey(columnName)) { columnValues.Add(validColumns.ElementAt(i), newFeature.ColumnValues[columnName]); } } Feature validFeature = new Feature(newFeature.GetWellKnownBinary(), newFeature.Id, columnValues); layer.EditTools.Add(validFeature); } } layer.EditTools.CommitTransaction(); layer.Close(); SavePrjFile(path, info.ProjectionWkt); RebuildDbf(path); } catch (Exception ex) { GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); if (layer.EditTools.IsInTransaction) { layer.EditTools.CommitTransaction(); } if (layer.IsOpen) { layer.Close(); } string[] suffixes = { ".shp", ".shx", ".ids", ".idx", ".dbf", ".prj" }; foreach (var suffix in suffixes) { string fileToRemove = Path.ChangeExtension(path, suffix); if (File.Exists(fileToRemove)) { File.Delete(fileToRemove); } } throw new OperationCanceledException("Shapefile generates failed.", ex); } }