async public Task <bool> ImportToNewFeatureclass(IFeatureDatabase fdb, string dsname, string fcname, IFeatureClass sourceFC, FieldTranslation fieldTranslation, bool project, List <IQueryFilter> filters, ISpatialIndexDef sIndexDef, geometryType?sourceGeometryType = null) { if (!_cancelTracker.Continue) { return(true); } if (fdb is AccessFDB) { ISpatialIndexDef dsSpatialIndexDef = await((AccessFDB)fdb).SpatialIndexDef(dsname); if (sIndexDef == null) { sIndexDef = dsSpatialIndexDef; } else if (sIndexDef.GeometryType != dsSpatialIndexDef.GeometryType) { _errMsg = "Spatial-Index-Definition-GeometryTypes are not compatible!"; return(false); } } if (sIndexDef == null) { sIndexDef = new gViewSpatialIndexDef(); } bool msSpatial = false; if (fdb is SqlFDB && (sIndexDef.GeometryType == GeometryFieldType.MsGeography || sIndexDef.GeometryType == GeometryFieldType.MsGeometry)) { msSpatial = true; } else { int maxAllowedLevel = ((fdb is SqlFDB || fdb is pgFDB) ? 62 : 30); if (sIndexDef.Levels > maxAllowedLevel) { ISpatialReference defSRef = sIndexDef.SpatialReference; sIndexDef = new gViewSpatialIndexDef( sIndexDef.SpatialIndexBounds, Math.Min(sIndexDef.Levels, maxAllowedLevel), sIndexDef.MaxPerNode, sIndexDef.SplitRatio); ((gViewSpatialIndexDef)sIndexDef).SpatialReference = defSRef; } } try { fcname = fcname.Replace(".", "_"); IFeatureDataset destDS = await fdb.GetDataset(dsname); if (destDS == null) { _errMsg = fdb.LastErrorMessage; return(false); } IDatasetElement destLayer = await destDS.Element(fcname); if (destLayer != null) { if (ReportRequest != null) { RequestArgs args = new RequestArgs( "Featureclass " + fcname + " already exists in " + dsname + "\nDo want to replace it?", MessageBoxButtons.YesNoCancel, DialogResult.Cancel); ReportRequest(this, args); switch (args.Result) { case DialogResult.No: return(true); case DialogResult.Cancel: _errMsg = "Import is canceled by the user..."; return(false); } } } GeometryDef geomDef = new GeometryDef(sourceFC); if (geomDef.GeometryType == geometryType.Unknown && sourceGeometryType != null) { geomDef.GeometryType = sourceGeometryType.Value; } int fcID = -1; if (destLayer != null) { if (fdb is AccessFDB) { fcID = await((AccessFDB)fdb).ReplaceFeatureClass(destDS.DatasetName, fcname, geomDef, (fieldTranslation == null) ? ((sourceFC.Fields != null) ? (IFields)sourceFC.Fields.Clone() : new Fields()) : fieldTranslation.DestinationFields); if (fcID < 0) { _errMsg = "Can't replace featureclass " + fcname + "...\r\n" + fdb.LastErrorMessage; destDS.Dispose(); return(false); } } else { await fdb.DeleteFeatureClass(fcname); } } if (fcID < 0) { fcID = await fdb.CreateFeatureClass(destDS.DatasetName, fcname, geomDef, (fieldTranslation == null)? ((sourceFC.Fields != null) ? (IFields)sourceFC.Fields.Clone() : new Fields()) : fieldTranslation.DestinationFields); } if (fcID < 0) { _errMsg = "Can't create featureclass " + fcname + "...\r\n" + fdb.LastErrorMessage; destDS.Dispose(); return(false); } destLayer = await destDS.Element(fcname); if (destLayer == null || !(destLayer.Class is IFeatureClass)) { _errMsg = "Can't load featureclass " + fcname + "...\r\n" + destDS.LastErrorMessage; destDS.Dispose(); return(false); } IFeatureClass destFC = destLayer.Class as IFeatureClass; if (project && destFC.SpatialReference != null && !destFC.SpatialReference.Equals(sourceFC.SpatialReference)) { _transformer = GeometricTransformerFactory.Create(); //_transformer.FromSpatialReference = sourceFC.SpatialReference; //_transformer.ToSpatialReference = destFC.SpatialReference; _transformer.SetSpatialReferences(sourceFC.SpatialReference, destFC.SpatialReference); } if (!Envelope.IsNull(sIndexDef.SpatialIndexBounds) && sIndexDef.SpatialReference != null && !sIndexDef.SpatialReference.Equals(destFC.SpatialReference)) { if (!sIndexDef.ProjectTo(destFC.SpatialReference)) { _errMsg = "Can't project SpatialIndex Boundaries..."; destDS.Dispose(); return(false); } } DualTree tree = null; BinaryTree2Builder tree2 = null; if (msSpatial) { ((SqlFDB)fdb).SetMSSpatialIndex((MSSpatialIndex)sIndexDef, destFC.Name); await((SqlFDB)fdb).SetFeatureclassExtent(destFC.Name, sIndexDef.SpatialIndexBounds); } else { if (_treeVersion == TreeVersion.BinaryTree) { tree = await SpatialIndex(sourceFC, sIndexDef.MaxPerNode, filters); if (tree == null) { return(false); } } else if (_treeVersion == TreeVersion.BinaryTree2) { if (_schemaOnly && sourceFC.Dataset.Database is IImplementsBinarayTreeDef) { BinaryTreeDef tDef = await((IImplementsBinarayTreeDef)sourceFC.Dataset.Database).BinaryTreeDef(sourceFC.Name); tree2 = new BinaryTree2Builder(tDef.Bounds, tDef.MaxLevel, tDef.MaxPerNode, tDef.SplitRatio); } else { tree2 = await SpatialIndex2(fdb, sourceFC, sIndexDef, filters); if (tree2 == null) { return(false); } } } // Vorab einmal alle "Bounds" festlegen, damit auch // ein aufzubauender Layer geviewt werden kann if (_treeVersion == TreeVersion.BinaryTree2 && fdb is AccessFDB) { if (ReportAction != null) { ReportAction(this, "Insert spatial index nodes"); } List <long> nids = new List <long>(); foreach (BinaryTree2BuilderNode node in tree2.Nodes) { nids.Add(node.Number); } await((AccessFDB)fdb).ShrinkSpatialIndex(fcname, nids); if (ReportAction != null) { ReportAction(this, "Set spatial index bounds"); } //((AccessFDB)fdb).SetSpatialIndexBounds(fcname, "BinaryTree2", tree2.Bounds, sIndexDef.SplitRatio, sIndexDef.MaxPerNode, tree2.maxLevels); await((AccessFDB)fdb).SetSpatialIndexBounds(fcname, "BinaryTree2", tree2.Bounds, tree2.SplitRatio, tree2.MaxPerNode, tree2.maxLevels); await((AccessFDB)fdb).SetFeatureclassExtent(fcname, tree2.Bounds); } } if (_cancelTracker.Continue) { bool result = true; if (!_schemaOnly) { if (msSpatial) { result = await CopyFeatures(sourceFC, fdb, destFC, fieldTranslation, filters); } else if (_treeVersion == TreeVersion.BinaryTree) { if (String.IsNullOrEmpty(sourceFC.IDFieldName)) // SDE Views haben keine ID -> Tree enthält keine Features { result = await CopyFeatures(sourceFC, fdb, destFC, fieldTranslation, filters); } else { result = await CopyFeatures(sourceFC, fdb, destFC, fieldTranslation, tree); } } else if (_treeVersion == TreeVersion.BinaryTree2) { if (String.IsNullOrEmpty(sourceFC.IDFieldName)) // SDE Views haben keine ID -> Tree enthält keine Features { result = await CopyFeatures(sourceFC, fdb, destFC, fieldTranslation, filters); } else { result = await CopyFeatures2(sourceFC, fdb, destFC, fieldTranslation, tree2); } } if (!result) { await fdb.DeleteFeatureClass(fcname); destDS.Dispose(); return(false); } } } destDS.Dispose(); if (_cancelTracker.Continue && fdb is AccessFDB) { if (ReportAction != null) { ReportAction(this, "Calculate extent"); } await((AccessFDB)fdb).CalculateExtent(destFC); if (msSpatial == false) { if (_treeVersion == TreeVersion.BinaryTree) { if (ReportAction != null) { ReportAction(this, "Set spatial index bounds"); } await((AccessFDB)fdb).SetSpatialIndexBounds(fcname, "BinaryTree", tree.Bounds, sIndexDef.SplitRatio, sIndexDef.MaxPerNode, 0); if (ReportAction != null) { ReportAction(this, "Insert spatial index nodes"); } await((AccessFDB)fdb).__intInsertSpatialIndexNodes2(fcname, tree.Nodes); } } return(true); } else { await fdb.DeleteFeatureClass(fcname); _errMsg = "Import is canceled by the user..."; return(false); } } finally { if (_transformer != null) { _transformer.Release(); _transformer = null; } } }
static int Main(string[] args) { string server = "", database = "", uid = "", pwd = "", dataset = "", imageSpace = "database"; string connectionString = ""; bool delExisting = true; bool imagedataset = false; for (int i = 0; i < args.Length; i++) { if (args[i] == "-server") { server = args[++i]; } if (args[i] == "-uid") { uid = args[++i]; } if (args[i] == "-pwd") { pwd = args[++i]; } if (args[i] == "-database") { database = args[++i]; } if (args[i] == "-ds") { dataset = args[++i]; } if (args[i] == "-imagedataset") { imagedataset = true; } if (args[i] == "-imagespace") { imageSpace = args[++i]; } if (args[i] == "-connectionstring") { connectionString = args[++i]; } } if (((server == "" && database == "") && connectionString == "") || dataset == "") { Console.WriteLine("USAGE:"); Console.WriteLine("gView.Cmd.CreateSqlFDBDataset -server <Filename> -database <Database> OR -connectionstring <ConnectionString>"); Console.WriteLine(" -ds <Datasetname>"); Console.WriteLine(" [-uid <User> -pwd <Password> -imagedataset -imagespace <Image Space Directory (Database)>]"); return(1); } try { if (connectionString == "") { connectionString = "server=" + server + ";database=" + database; if (uid != "") { connectionString += ";uid=" + uid + ";pwd=" + pwd; } else { connectionString += ";Trusted_Connection=True"; } } SqlFDB fdb = new SqlFDB(); if (!fdb.Open(connectionString)) { Console.WriteLine("\n\nERROR: " + fdb.lastErrorMsg); return(1); } //SpatialReference sRef = new SpatialReference(); ISpatialIndexDef sIndexDef = new gViewSpatialIndexDef(); if (imagedataset) { if (fdb.CreateImageDataset(dataset, null, sIndexDef, imageSpace, null) < 1) { fdb.Dispose(); Console.WriteLine("\n\nERROR: " + fdb.lastErrorMsg); return(1); } } else { if (fdb.CreateDataset(dataset, null, sIndexDef) < 1) { fdb.Dispose(); Console.WriteLine("\n\nERROR: " + fdb.lastErrorMsg); return(1); } } fdb.Dispose(); Console.WriteLine(server + @"\" + database + ": Dataset " + dataset + " created..."); return(0); } catch (Exception ex) { Console.WriteLine("\n\nERROR: " + ex.Message); return(1); } }
async public Task Run(string[] args) { string inFile = String.Empty; string outFile = String.Empty; string targetConnectionString = String.Empty; IEnumerable <string> dontCopyFeatues = null; Guid targetGuid = new Guid(); for (int i = 1; i < args.Length - 1; i++) { switch (args[i].ToLower()) { case "-mxl": inFile = args[++i]; break; case "-target-connectionstring": targetConnectionString = args[++i]; break; case "-target-guid": var guid = args[++i]; switch (guid.ToLower()) { case "sqlserver": targetGuid = new Guid("3B870AB5-8BE0-4a00-911D-ECC6C83DD6B4"); break; case "postgres": targetGuid = new Guid("33254063-133D-4b17-AAE2-46AF7A7DA733"); break; case "sqlite": targetGuid = new Guid("36DEB6AC-EA0C-4B37-91F1-B2E397351555"); break; default: targetGuid = new Guid(guid); break; } break; case "-out-mxl": outFile = args[++i]; break; case "-dont-copy-features-from": dontCopyFeatues = args[++i].Split(',').Select(n => n.Trim().ToLower()); break; } } if (String.IsNullOrEmpty(inFile) || String.IsNullOrEmpty(targetConnectionString) || targetGuid.Equals(new Guid())) { throw new IncompleteArgumentsException(); } if (String.IsNullOrEmpty(outFile)) { outFile = String.IsNullOrEmpty(inFile) ? String.Empty : inFile.Substring(0, inFile.LastIndexOf(".")) + "_fdb.mxl"; } XmlStream stream = new XmlStream(""); stream.ReadStream(inFile); MxlDocument doc = new MxlDocument(); await stream.LoadAsync("MapDocument", doc); var pluginManager = new PlugInManager(); #region Destination Dataset IFeatureDataset targetFeatureDataset = pluginManager.CreateInstance(targetGuid) as IFeatureDataset; if (targetFeatureDataset == null) { throw new Exception("Plugin with GUID '" + targetGuid.ToString() + "' is not a feature dataset..."); } await targetFeatureDataset.SetConnectionString(targetConnectionString); await targetFeatureDataset.Open(); var targetDatabase = (IFDBDatabase)targetFeatureDataset.Database; #endregion Destination Dataset var map = doc.Maps.FirstOrDefault() as Map; var featureLayers = map.TOC.Layers.Where(l => l is IFeatureLayer) .Select(l => (IFeatureLayer)l); if (map.Datasets != null) { int datasetId = 0; foreach (var dataset in map.Datasets.ToArray()) { Console.WriteLine(); Console.WriteLine($"Dataset: { dataset.DatasetName }"); Console.WriteLine($" { dataset.GetType() }"); Console.WriteLine("-------------------------------------------------------"); foreach (var dsElement in map.MapElements.Where(e => e.DatasetID == datasetId)) { if (dsElement?.Class == null) { continue; } var featureLayer = featureLayers.Where(l => l.DatasetID == datasetId && l.Class == dsElement.Class) .FirstOrDefault(); if (featureLayer == null) { continue; } Console.WriteLine(); Console.WriteLine($"FeatureLayer: { featureLayer.Title }"); Console.WriteLine($" Class: { dsElement.Class.Name }"); Console.WriteLine($" { dsElement.Class.GetType() }"); Console.WriteLine(); var sourceFc = dsElement.Class as IFeatureClass; if (sourceFc == null) { Console.WriteLine("Class is not a FeatureClass"); continue; } #region Create Target Featureclass (if not exists) string targetFcName = dsElement.Class.Name; if (targetFcName.Contains(".")) { targetFcName = targetFcName.Substring(targetFcName.LastIndexOf(".") + 1); } var targetFc = (await targetFeatureDataset.Element(targetFcName))?.Class as IFeatureClass; if (targetFc != null) { var count = await targetFc.CountFeatures(); if (count > 0) { Console.Write($"Already exists in target fdb ({ count } features)"); } else { if (!await targetDatabase.DeleteFeatureClass(targetFcName)) { throw new Exception($"Can't delete existing (empty) featureclass { targetFcName }"); } } } else { var fcId = await targetDatabase.CreateFeatureClass( targetFeatureDataset.DatasetName, targetFcName, new GeometryDef() { GeometryType = sourceFc.GeometryType, HasM = sourceFc.HasM, HasZ = sourceFc.HasZ, SpatialReference = sourceFc.SpatialReference }, new Fields(sourceFc.Fields.ToEnumerable().Select(f => { if (f != null && f.type == FieldType.ID && f.name.ToUpper().Equals("FDB_OID") == false) // also include original ID Column { return(new Field(f.name, FieldType.integer)); } return(f); }))); if (fcId <= 0) { throw new Exception($"Can't create featureclass { targetFcName }: { targetDatabase.LastErrorMessage }"); } targetFc = (await targetFeatureDataset.Element(targetFcName)).Class as IFeatureClass; if (targetFc == null) { throw new Exception($"Can't load target FeatureClass { targetFcName }"); } var copyFeatures = dontCopyFeatues == null || (!dontCopyFeatues.Contains(sourceFc.Name.ToLower()) && !dontCopyFeatues.Contains(targetFc.Name.ToLower())); if (copyFeatures) { var sIndexDef = new gViewSpatialIndexDef(null, 62); var tree2 = await SpatialIndex2( targetDatabase, sourceFc, sIndexDef); tree2.Trim(); List <long> nids = new List <long>(); foreach (BinaryTree2BuilderNode node in tree2.Nodes) { nids.Add(node.Number); } await((AccessFDB)targetDatabase).ShrinkSpatialIndex(targetFcName, nids); await((AccessFDB)targetDatabase).SetSpatialIndexBounds(targetFcName, "BinaryTree2", tree2.Bounds, tree2.SplitRatio, tree2.MaxPerNode, tree2.maxLevels); await((AccessFDB)targetDatabase).SetFeatureclassExtent(targetFcName, tree2.Bounds); #endregion Create Target Featureclass (if not exists) var featureBag = new List <IFeature>(); IFeature feature = null; int counter = 0; Console.WriteLine("Copy features:"); if (sourceFc is IFeatureClassPerformanceInfo && ((IFeatureClassPerformanceInfo)sourceFc).SupportsHighperformanceOidQueries == false) { using (var memoryFeatureBag = new FeatureBag()) { #region Read all Features to FeatureBag (Memory) // // eg. SDE Multiversion Views are very slow, queiried win OID Filter!! // Console.WriteLine("Source feature class do not support high performance oid quries!"); QueryFilter filter = new QueryFilter() { WhereClause = "1=1" }; filter.AddField("*"); Console.WriteLine("Read all features to memory feature bag..."); using (var featureCursor = await sourceFc.GetFeatures(filter)) { if (featureCursor == null) { throw new Exception($"Can't query features from soure featureclass: { (sourceFc is IDebugging ? ((IDebugging)sourceFc).LastException?.Message : "") }"); } while ((feature = await featureCursor.NextFeature()) != null) { memoryFeatureBag.AddFeature(feature); counter++; if (counter % 10000 == 0) { Console.Write($"...{ counter }"); } } } #endregion Read all Features to FeatureBag (Memory) #region Write to target featureclass Console.WriteLine($"...{ counter }"); Console.WriteLine("copy feature to target feature class"); counter = 0; foreach (BinaryTree2BuilderNode node in tree2.Nodes) { foreach (var memoryFeature in memoryFeatureBag.GetFeatures(node.OIDs)) { memoryFeature.Fields.Add(new FieldValue("$FDB_NID", node.Number)); featureBag.Add(memoryFeature); counter++; if (counter % 10000 == 0) { await Store(targetDatabase, targetFc, featureBag, counter); } } } #endregion Write to target featureclass } GC.Collect(); } else { #region Query all per Oid and Node foreach (BinaryTree2BuilderNode node in tree2.Nodes) { RowIDFilter filter = new RowIDFilter(sourceFc.IDFieldName); filter.IDs = node.OIDs; filter.SubFields = "*"; using (var featureCursor = await sourceFc.GetFeatures(filter)) { if (featureCursor == null) { throw new Exception($"Can't query features from soure featureclass: { (sourceFc is IDebugging ? ((IDebugging)sourceFc).LastException?.Message : "") }"); } while ((feature = await featureCursor.NextFeature()) != null) { feature.Fields.Add(new FieldValue("$FDB_NID", node.Number)); featureBag.Add(feature); counter++; if (counter % 10000 == 0) { await Store(targetDatabase, targetFc, featureBag, counter); } } } } #endregion Query all per Oid and Node } await Store(targetDatabase, targetFc, featureBag, counter); await((AccessFDB)targetDatabase).CalculateExtent(targetFcName); } } dsElement.Title = targetFc.Name; ((DatasetElement)dsElement).Class = targetFc; } ((MapPersist)map).SetDataset(datasetId, targetFeatureDataset); datasetId++; } } map.Compress(); stream = new XmlStream(""); stream.Save("MapDocument", doc); Console.WriteLine($"Write: { outFile }"); stream.WriteStream(outFile); Console.WriteLine("succeeded..."); }