コード例 #1
0
        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;
                }
            }
        }
コード例 #2
0
        async private Task <BinaryTree2Builder> SpatialIndex2(IFeatureDatabase fdb, IFeatureClass fc, ISpatialIndexDef def, List <IQueryFilter> filters)
        {
            if (fc == null)
            {
                return(null);
            }

            IEnvelope bounds = null;

            if (fc.Envelope != null)
            {
                bounds = fc.Envelope;
            }
            else if (fc.Dataset is IFeatureDataset && await((IFeatureDataset)fc.Dataset).Envelope() != null)
            {
                bounds = await((IFeatureDataset)fc.Dataset).Envelope();
            }
            if (bounds == null)
            {
                return(null);
            }
            if (_transformer != null)
            {
                IGeometry transBounds = _transformer.Transform2D(bounds) as IGeometry;
                if (transBounds != null)
                {
                    bounds = transBounds.Envelope;
                }
            }
            int maxAllowedLevel            = ((fdb is SqlFDB) ? 62 : 30);
            BinaryTree2Builder treeBuilder =
                ((Envelope.IsNull(def.SpatialIndexBounds)) ?
                 new BinaryTree2Builder(bounds,
                                        ((def.Levels != 0) ? def.Levels : maxAllowedLevel),
                                        ((def.MaxPerNode != 0) ? def.MaxPerNode : 500),
                                        ((def.SplitRatio != 0.0) ? def.SplitRatio : 0.55)) :
                 new BinaryTree2Builder2(def.SpatialIndexBounds, def.Levels, def.MaxPerNode, def.SplitRatio));

            if (filters == null)
            {
                QueryFilter filter = new QueryFilter();
                filter.AddField(fc.ShapeFieldName);
                filters = new List <IQueryFilter>();
                filters.Add(filter);
            }
            foreach (IQueryFilter filter in filters)
            {
                using (IFeatureCursor fCursor = await fc.GetFeatures(filter))
                {
                    if (fCursor == null)
                    {
                        _errMsg = "Fatal error: sourcedb query failed...";
                        return(null);
                    }

                    if (ReportAction != null)
                    {
                        ReportAction(this, "Calculate spatial index");
                    }

                    IEnvelope fcEnvelope = bounds;
                    if (_transformer != null)
                    {
                        IGeometry geom = _transformer.Transform2D(fcEnvelope) as IGeometry;
                        if (geom == null)
                        {
                            _errMsg = "SpatialIndex: Can't project featureclass extent!";
                            return(null);
                        }
                        fcEnvelope = geom.Envelope;
                    }
                    //treeBuilder = new BinaryTree2Builder(fcEnvelope, maxLevels, maxPerNode);

                    int      counter = 0;
                    IFeature feat;
                    while ((feat = await fCursor.NextFeature()) != null)
                    {
                        if (!_cancelTracker.Continue)
                        {
                            break;
                        }

                        IGeometry shape = feat.Shape;
                        if (_transformer != null)
                        {
                            shape = _transformer.Transform2D(shape) as IGeometry;
                        }

                        feat.Shape = shape;
                        treeBuilder.AddFeature(feat);

                        if ((counter % 1000) == 0 && ReportProgress != null)
                        {
                            ReportProgress(this, counter);
                        }
                        counter++;
                    }
                    fCursor.Dispose();
                }
            }

            treeBuilder.Trim();
            return(treeBuilder);
        }
コード例 #3
0
        async private Task <bool> CopyFeatures2(IFeatureClass source, IFeatureUpdater fdb, IFeatureClass dest, FieldTranslation fTrans, BinaryTree2Builder treeBuilder)
        {
            List <BinaryTree2BuilderNode> nodes;

            if (treeBuilder == null || (nodes = treeBuilder.Nodes) == null)
            {
                _errMsg = "Spatial Index is not defined...";
                return(false);
            }

            if (ReportAction != null)
            {
                ReportAction(this, "Copy Features (" + dest.Name + ")");
            }
            int featcounter = 0;

            foreach (BinaryTree2BuilderNode node in nodes)
            {
                if (!_cancelTracker.Continue)
                {
                    break;
                }

                RowIDFilter filter = new RowIDFilter(source.IDFieldName);
                filter.IDs       = node.OIDs;
                filter.SubFields = "*";

                using (IFeatureCursor fCursor = await source.GetFeatures(filter))
                {
                    if (fCursor == null)
                    {
                        _errMsg = "Fatal error: sourcedb query failed...";
                        return(false);
                    }

                    int copycounter = await CopyFeatures(fCursor, node.Number, fdb, dest, fTrans, featcounter);

                    if (copycounter < 0)
                    {
                        fCursor.Dispose();
                        return(false);
                    }
                    featcounter = copycounter;

                    fCursor.Dispose();
                }
            }
            if (ReportProgress != null)
            {
                ReportProgress(this, featcounter);
            }
            return(true);
        }
コード例 #4
0
        async static private Task <BinaryTree2Builder> SpatialIndex2(IFeatureDatabase fdb, IFeatureClass fc, ISpatialIndexDef def, List <IQueryFilter> filters = null)
        {
            if (fc == null)
            {
                return(null);
            }

            IEnvelope bounds = null;

            if (fc.Envelope != null)
            {
                bounds = fc.Envelope;
            }
            else if (fc.Dataset is IFeatureDataset && await((IFeatureDataset)fc.Dataset).Envelope() != null)
            {
                bounds = await((IFeatureDataset)fc.Dataset).Envelope();
            }

            if (bounds == null)
            {
                return(null);
            }
            //if (_transformer != null)
            //{
            //    IGeometry transBounds = _transformer.Transform2D(bounds) as IGeometry;
            //    if (transBounds != null)
            //        bounds = transBounds.Envelope;
            //}
            int maxAllowedLevel            = ((fdb is SqlFDB) ? 62 : 30);
            BinaryTree2Builder treeBuilder =
                ((Envelope.IsNull(def.SpatialIndexBounds)) ?
                 new BinaryTree2Builder(bounds,
                                        ((def.Levels != 0) ? def.Levels : maxAllowedLevel),
                                        ((def.MaxPerNode != 0) ? def.MaxPerNode : 500),
                                        ((def.SplitRatio != 0.0) ? def.SplitRatio : 0.55),
                                        maxVerticesPerNode: 500 * 50) :
                 new BinaryTree2Builder2(def.SpatialIndexBounds, def.Levels, def.MaxPerNode, def.SplitRatio));

            if (filters == null)
            {
                QueryFilter filter = new QueryFilter()
                {
                    WhereClause = "1=1"
                };
                filter.AddField(fc.ShapeFieldName);
                filters = new List <IQueryFilter>();
                filters.Add(filter);
            }
            foreach (IQueryFilter filter in filters)
            {
                using (IFeatureCursor fCursor = await fc.GetFeatures(filter))
                {
                    if (fCursor == null)
                    {
                        throw new Exception("Fatal error: sourcedb query failed...");
                    }

                    Console.WriteLine("Calculate spatial index:");

                    IEnvelope fcEnvelope = bounds;
                    //if (_transformer != null)
                    //{
                    //    IGeometry geom = _transformer.Transform2D(fcEnvelope) as IGeometry;
                    //    if (geom == null)
                    //    {
                    //        _errMsg = "SpatialIndex: Can't project featureclass extent!";
                    //        return null;
                    //    }
                    //    fcEnvelope = geom.Envelope;
                    //}

                    int      counter = 0;
                    IFeature feat;
                    while ((feat = await fCursor.NextFeature()) != null)
                    {
                        IGeometry shape = feat.Shape;
                        //if (_transformer != null)
                        //{
                        //    shape = _transformer.Transform2D(shape) as IGeometry;
                        //}

                        feat.Shape = shape;
                        treeBuilder.AddFeature(feat);

                        counter++;
                        if (counter % 10000 == 0)
                        {
                            Console.Write($"...{ counter }");
                        }
                    }
                    Console.Write($"...{ counter }");
                }
            }

            treeBuilder.Trim();
            Console.WriteLine();

            return(treeBuilder);
        }