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 dbfColumns = new Dictionary(); Collection addedColumns = featureLayerStructureParameters.AddedColumns; Dictionary oldNewNames = new Dictionary(); bool truncateLongColumn = featureLayerStructureParameters.CustomData.ContainsKey("LongColumnNameMode") && (LongColumnTruncateMode)featureLayerStructureParameters.CustomData["LongColumnNameMode"] == LongColumnTruncateMode.Truncate; bool convertMemoToCharacter = featureLayerStructureParameters.CustomData.ContainsKey("MemoColumnMode") && (MemoColumnConvertMode)featureLayerStructureParameters.CustomData["MemoColumnMode"] == MemoColumnConvertMode.ToCharacter; if (truncateLongColumn) { addedColumns = TruncateLongColumnNames(featureLayerStructureParameters.AddedColumns, oldNewNames); } 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 "NUMBERIC": 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": columnLenght = columnLenght == 0 ? characterTypeLength : columnLenght; decimalLength = 0; break; } dbfColumn = new DbfColumn(column.ColumnName, (DbfColumnType)Enum.Parse(typeof(DbfColumnType), column.TypeName, true), 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. if (firstFeature != null && firstFeature.LinkColumnValues.ContainsKey(column.ColumnName)) { if (dbfColumn.ColumnType != DbfColumnType.Memo) { dbfColumn.ColumnType = DbfColumnType.Character; dbfColumn.Length = characterTypeLength; dbfColumn.DecimalLength = 0; } } dbfColumns[dbfColumn.ColumnName] = dbfColumn; } } Collection addedFeatures = featureLayerStructureParameters.AddedFeatures; if (truncateLongColumn) { 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 { if (oldNewNames.ContainsKey(linkColumnValue.Key)) feature.ColumnValues[oldNewNames[linkColumnValue.Key]] = string.Join(",", values); else feature.ColumnValues[linkColumnValue.Key] = string.Join(",", values); } } } 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; } } } } } else { 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))) { feature.ColumnValues[linkColumnValue.Key] = string.Empty; } else { feature.ColumnValues[linkColumnValue.Key] = string.Join(",", values); } } } if (!convertMemoToCharacter) { foreach (var item in feature.ColumnValues) { if (item.Value.Length > characterTypeLength && dbfColumns.ContainsKey(item.Key) && dbfColumns[item.Key].ColumnType != DbfColumnType.Memo) { dbfColumns[item.Key].ColumnType = DbfColumnType.Memo; dbfColumns[item.Key].Length = 4; dbfColumns[item.Key].DecimalLength = 0; } } } } } 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, ShapeFileReadWriteMode.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); } } } resultLayer.EditTools.Add(feature); } resultLayer.EditTools.CommitTransaction(); resultLayer.Close(); } return resultLayer; } private Collection TruncateLongColumnNames(IEnumerable addedColumns, Dictionary oldNewNames) { Collection fixedColumns = new Collection(); foreach (FeatureSourceColumn column in addedColumns) { if (column.ColumnName.Length > 10) { string oldName = column.ColumnName; column.ColumnName = column.ColumnName.Substring(0, 10); int i = 1; while (fixedColumns.Select(a => a.ColumnName).Contains(column.ColumnName)) { int length = i.ToString(CultureInfo.InvariantCulture).Length; column.ColumnName = column.ColumnName.Substring(0, 10 - length) + i; i++; } oldNewNames[oldName] = column.ColumnName; } fixedColumns.Add(column); } return fixedColumns; }