コード例 #1
0
        private static IEnumerable <Feature> GetFeatures([CanBeNull] BasicFeatureLayer layer,
                                                         [NotNull] List <long> oids,
                                                         bool recycling = false)
        {
            if (layer == null)
            {
                yield break;
            }

            // TODO: Use layer search (there might habe been an issue with recycling?!)
            var featureClass = layer.GetTable();

            var filter = new QueryFilter
            {
                WhereClause =
                    $"{featureClass.GetDefinition().GetObjectIDField()} IN ({StringUtils.Concatenate(oids, ", ")})"
            };

            filter.OutputSpatialReference = layer.GetSpatialReference();

            foreach (var feature in GdbQueryUtils.GetFeatures(featureClass, filter, recycling))
            {
                yield return(feature);
            }
        }
コード例 #2
0
        public void CanCreateSpatialFilterWithNonZSimpleGeometry()
        {
            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

            IEnvelope nonZSimpleEnvelope = GeometryFactory.CreateEnvelope(2600000, 1200000,
                                                                          2700000, 1300000);

            GeometryUtils.MakeZAware(nonZSimpleEnvelope);

            Assert.False(((IZAware)nonZSimpleEnvelope).ZSimple, "Must be non-Z-simple");

            ISpatialReference spatialReference =
                Assert.NotNull(DatasetUtils.GetSpatialReference(fc));

            IGeometry validGeometry;
            string    message;

            Assert.False(GdbQueryUtils.IsValidFilterGeometry(
                             nonZSimpleEnvelope,
                             SpatialReferenceUtils.GetXyResolution(spatialReference),
                             out validGeometry, out message),
                         "Search geometry should not be valid");

            Assert.NotNull(validGeometry);

            IQueryFilter filter = GdbQueryUtils.CreateSpatialFilter(fc, nonZSimpleEnvelope);

            Assert.True(GdbQueryUtils.GetFeatures(fc, filter, true).Any(), "No features found");
        }
コード例 #3
0
        public void CanConvertMultipatchesSpecialCasesWithInnerRings()
        {
            IWorkspace workspace = TestUtils.OpenSDEWorkspaceOracle();

            IFeatureClass featureClass = DatasetUtils.OpenFeatureClass(
                workspace, "TOPGIS_TLM.TLM_GEBAEUDE");

            const int    rolexLearningCenter      = 321430;
            const int    mediamarktMuriBB         = 565844;
            const int    hintermBahnhofGraenichen = 2269631;
            IQueryFilter qf = new QueryFilterClass()
            {
                WhereClause = "OBJECTID IN (" +
                              $"{hintermBahnhofGraenichen}, " +
                              $"{mediamarktMuriBB}, " +
                              $"{rolexLearningCenter})"
            };
            int count = 0;

            foreach (IFeature feature in GdbQueryUtils.GetFeatures(featureClass, qf, true))
            {
                count++;

                AssertWkbSerialization(feature, false);
                AssertWkbSerialization(feature, true);
            }

            Assert.AreEqual(3, count);
        }
コード例 #4
0
        public void Learning_CanFindFeaturesWithNonZSimpleSearchGeometry()
        {
            // 10.2.1: Test fails (correct) with COM Exception on OpenCursor
            // 10.4.1: Test fails (correct) with COM Exception on OpenCursor
            // 10.6.1: Test passes (incorrectly!), no features found

            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

            IEnvelope nonZSimpleEnvelope = GeometryFactory.CreateEnvelope(2600000, 1200000,
                                                                          2700000, 1300000);

            GeometryUtils.MakeZAware(nonZSimpleEnvelope);

            Assert.False(((IZAware)nonZSimpleEnvelope).ZSimple, "Must be non-Z-simple");

            ISpatialReference spatialReference = DatasetUtils.GetSpatialReference(fc);

            nonZSimpleEnvelope.SpatialReference = spatialReference;

            ISpatialFilter spatialFilter = new SpatialFilterClass();

            spatialFilter.GeometryField = fc.ShapeFieldName;
            spatialFilter.set_GeometryEx(nonZSimpleEnvelope, true);
            spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

            Assert.AreEqual(0, GdbQueryUtils.GetFeatures(fc, spatialFilter, true).Count(),
                            "Behaviour changed: Now features are found even with non-Z-simple search geometry.");
        }
コード例 #5
0
        private int CheckPolygonPoints(
            [NotNull] IEnumerable <PolygonPoints> polygonPointsToCheck)
        {
            Assert.ArgumentNotNull(polygonPointsToCheck, nameof(polygonPointsToCheck));

            Dictionary <int, List <PolygonPointsError> > errorsByTable =
                GetErrorsByTable(polygonPointsToCheck);

            int errorCount = 0;

            foreach (KeyValuePair <int, List <PolygonPointsError> > pair in errorsByTable)
            {
                int tableIndex = pair.Key;
                List <PolygonPointsError> errors = pair.Value;

                var featureClass = (IFeatureClass)InvolvedTables[tableIndex];
                Dictionary <int, PolygonPointsError> errorsByOid = GetErrorsByOid(errors);

                const bool recycle = true;
                foreach (
                    IFeature polygonFeature in
                    GdbQueryUtils.GetFeatures(featureClass, errorsByOid.Keys, recycle))
                {
                    IGeometry errorGeometry = polygonFeature.ShapeCopy;

                    PolygonPointsError error = errorsByOid[polygonFeature.OID];

                    errorCount += ReportError(error.ErrorDescription, errorGeometry,
                                              error.IssueCode, null,
                                              GetInvolvedRows(polygonFeature, error));
                }
            }

            return(errorCount);
        }
コード例 #6
0
        private int ExecuteGeometry([CanBeNull] IGeometry geometry)
        {
            if (!_canHaveNonLinearSegments)
            {
                return(NoError);
            }

            IQueryFilter filter = TestUtils.CreateFilter(geometry, AreaOfInterest,
                                                         GetConstraint(0),
                                                         (ITable)_featureClass,
                                                         null);

            GdbQueryUtils.SetSubFields(filter,
                                       _featureClass.OIDFieldName,
                                       _featureClass.ShapeFieldName);

            int errorCount = 0;

            const bool recycle = true;

            foreach (IFeature feature in
                     GdbQueryUtils.GetFeatures(_featureClass, filter, recycle))
            {
                errorCount += VerifyFeature(feature);
            }

            return(errorCount);
        }
コード例 #7
0
ファイル: MapUtils.cs プロジェクト: ProSuite/ProSuite
        /// <summary>
        /// Finds the features in the map by the specified criteria, grouped by feature class
        /// </summary>
        /// <param name="mapView">The map view containing the layers to search</param>
        /// <param name="searchGeometry">The search geometry</param>
        /// <param name="spatialRelationship">The spatial relationship between the found features
        /// and the search geometry.</param>
        /// <param name="targetSelectionType">The target selection type that determines which layers
        /// are searched.</param>
        /// <param name="layerPredicate">An extra layer predicate that allows for a more
        /// fine-granular determination of the layers to be searched.</param>
        /// <param name="featurePredicate">An extra feature predicate that allows to determine
        /// criteria on the feature level.</param>
        /// <param name="selectedFeatures">The selected features, relevant only for
        /// <see cref="targetSelectionType"/> with value <see cref="TargetFeatureSelection.SameClass"/>. </param>
        /// <param name="cancelableProgressor"></param>
        /// <returns></returns>
        public static IEnumerable <KeyValuePair <FeatureClass, List <Feature> > > FindFeatures(
            [NotNull] MapView mapView,
            [NotNull] ArcGIS.Core.Geometry.Geometry searchGeometry,
            SpatialRelationship spatialRelationship,
            TargetFeatureSelection targetSelectionType,
            [CanBeNull] Predicate <FeatureLayer> layerPredicate,
            [CanBeNull] Predicate <Feature> featurePredicate,
            List <Feature> selectedFeatures,
            CancelableProgressor cancelableProgressor = null)
        {
            // NOTE: FeatureLayer.Search is quite useless, as we cannot control recyclability and as soon as the cursor
            //       is disposed, the feature's geometry is wrong!

            // -> Get the distinct feature classes (TODO: include layer definition queries)

            IEnumerable <FeatureLayer> featureLayers =
                GetLayers <FeatureLayer>(
                    mapView, fl => IsLayerApplicable(fl, targetSelectionType, layerPredicate,
                                                     selectedFeatures));

            IEnumerable <IGrouping <IntPtr, FeatureLayer> > layersGroupedByClass =
                featureLayers.GroupBy(fl => fl.GetFeatureClass().Handle);

            foreach (var layersInClass in layersGroupedByClass)
            {
                // One query per distinct definition query, then make OIDs distinct

                FeatureClass   featureClass = null;
                List <Feature> features     = new List <Feature>();
                foreach (IGrouping <string, FeatureLayer> layers in layersInClass.GroupBy(
                             fl => fl.DefinitionQuery))
                {
                    if (cancelableProgressor != null &&
                        cancelableProgressor.CancellationToken.IsCancellationRequested)
                    {
                        yield break;
                    }

                    featureClass = layers.First().GetFeatureClass();

                    QueryFilter filter =
                        GdbQueryUtils.CreateSpatialFilter(searchGeometry, spatialRelationship);
                    filter.WhereClause = layers.Key;

                    IEnumerable <Feature> foundFeatures = GdbQueryUtils
                                                          .GetFeatures(featureClass, filter, false)
                                                          .Where(f => featurePredicate == null ||
                                                                 featurePredicate(f));
                    features.AddRange(foundFeatures);
                }

                if (featureClass != null && features.Count > 0)
                {
                    yield return(new KeyValuePair <FeatureClass, List <Feature> >(
                                     featureClass, features.DistinctBy(f => f.GetObjectID()).ToList()));
                }
            }
        }
コード例 #8
0
        public void CanGetRasterFileFromMosaicDatasetUsingSpatialQuery()
        {
            IWorkspace workspace = TestUtils.OpenUserWorkspaceOracle();

            IMosaicDataset mosaicDataset = DatasetUtils.OpenMosaicDataset(workspace,
                                                                          "TOPGIS_TLM.TLM_DTM_MOSAIC");

            IFeatureClass rasterCatalog = mosaicDataset.Catalog;

            IEnvelope winterthur = GeometryFactory.CreateEnvelope(
                2690000, 1254000, 2707500, 1266000,
                SpatialReferenceUtils.CreateSpatialReference(WellKnownHorizontalCS.LV95));

            winterthur.Expand(-0.1, -0.1, false);

            IQueryFilter spatialFilter =
                GdbQueryUtils.CreateSpatialFilter(rasterCatalog, winterthur);

            IStringArray stringArray;
            Stopwatch    watch = Stopwatch.StartNew();

            int count = 0;

            foreach (IFeature catalogFeature in GdbQueryUtils.GetFeatures(
                         rasterCatalog, spatialFilter, false))
            {
                // Method 1 (slow):
                var rasterCatalogItem = (IRasterCatalogItem)catalogFeature;

                IRasterDataset rasterDataset = rasterCatalogItem.RasterDataset;
                var            itemPaths     = (IItemPaths)rasterDataset;
                stringArray = itemPaths.GetPaths();
                Marshal.ReleaseComObject(rasterDataset);

                Assert.AreEqual(1, stringArray.Count);

                string resultPathViaRasterDataset = stringArray.Element[0];

                // Method 2 (fast):
                var itemPathsQuery = (IItemPathsQuery)mosaicDataset;

                if (itemPathsQuery.QueryPathsParameters == null)
                {
                    itemPathsQuery.QueryPathsParameters = new QueryPathsParametersClass();
                }

                stringArray = itemPathsQuery.GetItemPaths(catalogFeature);
                Assert.AreEqual(1, stringArray.Count);

                string resultPathViaItemPathsQuery = stringArray.Element[0];
                Assert.AreEqual(resultPathViaRasterDataset, resultPathViaItemPathsQuery);
                count++;
            }

            Console.WriteLine("Successfully extracted {0} raster paths in {1}s", count,
                              watch.Elapsed.TotalSeconds);
        }
コード例 #9
0
        private static IFeature GetFeatureUsingGetFeatures(
            [NotNull] IFeatureClass featureClass, int oid)
        {
            var singleOidList = new List <int> {
                oid
            };

            IList <IFeature> features = new List <IFeature>(
                GdbQueryUtils.GetFeatures(featureClass, singleOidList, false));

            Assert.AreEqual(1, features.Count, "unexpected feature count");
            return(features[0]);
        }
コード例 #10
0
        public void CanConvertMultipatchesAllBuildingsGroupedByPointId()
        {
            IWorkspace workspace = TestUtils.OpenSDEWorkspaceOracle();

            IFeatureClass featureClass = DatasetUtils.OpenFeatureClass(
                workspace, "TOPGIS_TLM.TLM_GEBAEUDE");

            int count = 0;

            foreach (IFeature feature in GdbQueryUtils.GetFeatures(featureClass, true))
            {
                count++;

                AssertWkbSerialization(feature, true);
            }
        }
コード例 #11
0
        private IEnumerable <KeyValuePair <int, IFeature> > GetFeatures(
            [CanBeNull] IGeometry geometry)
        {
            for (var tableIndex = 0; tableIndex < _totalClassCount; tableIndex++)
            {
                IFeatureClass featureClass = _polylineClasses[tableIndex];

                IQueryFilter queryFilter = GetQueryFilter(featureClass, tableIndex, geometry);

                const bool recycle = true;
                foreach (IFeature feature in
                         GdbQueryUtils.GetFeatures(featureClass, queryFilter, recycle))
                {
                    yield return(new KeyValuePair <int, IFeature>(tableIndex, feature));
                }
            }
        }
コード例 #12
0
        private int ReportErrors(int tableIndex,
                                 [NotNull] ICollection <T> errorFeatures)
        {
            if (errorFeatures.Count == 0)
            {
                return(NoError);
            }

            var featureClass = (IFeatureClass)InvolvedTables[tableIndex];

            List <int>          oids = errorFeatures.Select(feature => feature.OID).ToList();
            Dictionary <int, T> errorFeaturesByOid =
                errorFeatures.ToDictionary(errorFeature => errorFeature.OID);

            const bool recycling = true;

            return(GdbQueryUtils.GetFeatures(featureClass, oids, recycling)
                   .Sum(
                       feature =>
                       ReportError(feature, tableIndex,
                                   errorFeaturesByOid[feature.OID])));
        }
コード例 #13
0
        public void CanCreateSpatialFilterWithMultipatch()
        {
            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

            ISpatialReference spatialReference = DatasetUtils.GetSpatialReference(fc);

            IEnvelope largeEnvelope = GeometryFactory.CreateEnvelope(2600000, 1200000,
                                                                     2601000, 1201000,
                                                                     445, spatialReference);

            IMultiPatch multiPatch =
                GeometryFactory.CreateMultiPatch(GeometryFactory.CreatePolygon(largeEnvelope));

            double xyResolution =
                SpatialReferenceUtils.GetXyResolution(Assert.NotNull(spatialReference));

            // NOTE: Multipatch implements IRelationalOperator since a while!
            IGeometry validGeometry;
            string    message;

            Assert.True(GdbQueryUtils.IsValidFilterGeometry(
                            multiPatch, xyResolution, out validGeometry, out message),
                        "Multipatch should be valid");
            Assert.NotNull(validGeometry);
            Assert.True(multiPatch == validGeometry,
                        "Multipatch should be valid");

            Assert.True(GdbQueryUtils.IsValidFilterGeometry(
                            validGeometry, xyResolution, out validGeometry, out message),
                        "Corrected geometry should be valid");

            IQueryFilter filter = GdbQueryUtils.CreateSpatialFilter(
                fc, multiPatch, esriSpatialRelEnum.esriSpatialRelIntersects, false,
                spatialReference);

            Assert.True(GdbQueryUtils.GetFeatures(fc, filter, true).Any(), "No features found.");
        }
コード例 #14
0
        private int ReportErrors(int tableIndex,
                                 [NotNull] ICollection <PendingFeature> errorFeatures)
        {
            if (errorFeatures.Count == 0)
            {
                return(NoError);
            }

            var        featureClass = (IFeatureClass)InvolvedTables[tableIndex];
            List <int> oids         = errorFeatures.Select(feature => feature.OID).ToList();

            // TODO extract base class (QaRequiredSpatialRelationSelf)
            // TODO use issue code NoTouchingFeature_WithFulfilledConstraint
            const bool recycling = true;

            return(GdbQueryUtils.GetFeatures(featureClass, oids, recycling)
                   .Sum(feature => ReportError(
                            "Feature is not touched by another feature",
                            feature.ShapeCopy,
                            Codes[MustTouchIssueCodes.NoTouchingFeature],
                            TestUtils.GetShapeFieldName(feature),
                            GetInvolvedRows(feature))));
        }
コード例 #15
0
        protected override int CompleteTileCore(TileInfo args)
        {
            if (!_reportSingleErrorPerDuplicateSet)
            {
                return(NoError);
            }

            if (args.State != TileState.Final)
            {
                return(NoError);
            }

            int errorCount = 0;

            Dictionary <int, HashSet <int> > duplicatesByFirstOid =
                GetDuplicatesByFirstOid(_duplicateSets);

            string     tableName = DatasetUtils.GetName(_featureClass);
            const bool recycle   = true;

            foreach (IFeature feature in GdbQueryUtils.GetFeatures(
                         _featureClass, duplicatesByFirstOid.Keys, recycle))
            {
                HashSet <int> duplicates = duplicatesByFirstOid[feature.OID];

                string errorDescription = _validRelationConstraintSql == null
                                                                  ? "Geometries are equal"
                                                                  : "Geometries are equal and constraint is not fulfilled";

                IGeometry errorGeometry = feature.ShapeCopy;
                errorCount += ReportError(errorDescription, errorGeometry,
                                          GetIssueCode(), _shapeFieldName,
                                          GetInvolvedRows(tableName, duplicates));
            }

            return(errorCount);
        }
コード例 #16
0
        protected static List <IFeature> SearchFeatureClasses(
            [NotNull] IEnumerable <LinearNetworkClassDef> linearNetworkClasses,
            [NotNull] IGeometry searchGeometry,
            [NotNull] ICollection <esriGeometryType> geometryTypes,
            [CanBeNull] IWorkspace alternateVersion = null)
        {
            var foundFeatures = new List <IFeature>();

            foreach (LinearNetworkClassDef networkClassDef in linearNetworkClasses)
            {
                IFeatureClass featureClass = networkClassDef.FeatureClass;

                if (alternateVersion != null &&
                    !WorkspaceUtils.IsSameVersion(alternateVersion,
                                                  DatasetUtils.GetWorkspace(featureClass)))
                {
                    featureClass =
                        DatasetUtils.OpenFeatureClass(alternateVersion,
                                                      DatasetUtils.GetName(featureClass));
                }

                if (!geometryTypes.Contains(featureClass.ShapeType))
                {
                    continue;
                }

                IQueryFilter filter =
                    GdbQueryUtils.CreateSpatialFilter(featureClass, searchGeometry);

                filter.WhereClause = networkClassDef.WhereClause;

                foundFeatures.AddRange(GdbQueryUtils.GetFeatures(featureClass, filter, false));
            }

            return(foundFeatures);
        }
コード例 #17
0
        private static IList <int> GetFeatureIDs([NotNull] IFeatureClass featureClass,
                                                 int count)
        {
            var result  = new List <int>();
            int current = 0;

            IQueryFilter filter = new QueryFilterClass();

            filter.SubFields = featureClass.OIDFieldName;

            foreach (IFeature feature in GdbQueryUtils.GetFeatures(featureClass, filter, true))
            {
                current++;

                if (current > count)
                {
                    break;
                }

                result.Add(feature.OID);
            }

            return(result);
        }
コード例 #18
0
        private int TestFeatures([NotNull] IFeatureClass featureClass)
        {
            Assert.ArgumentNotNull(featureClass, nameof(featureClass));

            var errorCount = 0;

            const bool   recycling = true;
            IQueryFilter filter    = CreateFilter(featureClass, GetConstraint(0));

            int  previousOid = -1;
            bool tryFallbackImplementation = false;

            // New with 12.5 (probably 10.8.1 x64 too?) for multipatch features:
            // COMException (errorCode -2147220959) with various messages, such as
            // - Insufficient permissions [ORA-00942: table or view does not exist]
            // - The operation was attempted on an empty geometry (when in SDE schema/user)
            // when an empty geometry is encountered!

            try
            {
                foreach (IFeature feature in
                         GdbQueryUtils.GetFeatures(featureClass, filter, recycling))
                {
                    errorCount += TestFeature(feature);
                    previousOid = feature.OID;
                }
            }
            catch (COMException e)
            {
                _msg.Debug($"Error getting feature from {DatasetUtils.GetName(featureClass)}. " +
                           $"Previous successful object id: {previousOid}", e);

                if (e.ErrorCode == -2147220959)
                {
                    _msg.Debug(
                        "Error getting feature with presumably empty geometry. Using fall-back implementation (slow) to identify object id.");
                    tryFallbackImplementation = true;
                }
                else
                {
                    throw;
                }
            }

            if (!tryFallbackImplementation)
            {
                return(errorCount);
            }

            // Read all features without geometry, get geometry separately for each feature:
            filter.SubFields = featureClass.OIDFieldName;

            foreach (IFeature feature in
                     GdbQueryUtils.GetFeatures(featureClass, filter, recycling))
            {
                try
                {
                    IFeature featureWithGeometry = featureClass.GetFeature(feature.OID);
                    Marshal.ReleaseComObject(featureWithGeometry);
                }
                catch (Exception e)
                {
                    errorCount += ReportError($"Feature geometry cannot be loaded ({e.Message})",
                                              null,
                                              Codes[Code.GeometryEmpty], _shapeFieldName,
                                              feature);
                }
            }

            return(errorCount);
        }
コード例 #19
0
        public void Learning_CanFindFeaturesWithSubResolutionEnvelope()
        {
            // TODO: This used to fail (in 2011) ("The number of points is less than required")
            // TEST if it now works on all supported versions!

            // 10.2.1: Test passes, Features are found
            // 10.4.1: Test passes, Features are found
            // 10.6.1: Test passes, Features are found

            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

            IEnvelope subResolutionEnv = GeometryFactory.CreateEnvelope(2600000, 1200000,
                                                                        2600000.0001,
                                                                        1200000.0001);

            ISpatialReference spatialReference =
                Assert.NotNull(DatasetUtils.GetSpatialReference(fc));

            subResolutionEnv.SpatialReference = spatialReference;

            IPoint point = null;

            foreach (var feature in GdbQueryUtils.GetFeatures(fc, true))
            {
                point = ((IPolyline)feature.Shape).FromPoint;
                break;
            }

            Assert.NotNull(point);
            IEnvelope envelope = point.Envelope;

            ISpatialFilter spatialFilter = new SpatialFilterClass();

            spatialFilter.GeometryField = fc.ShapeFieldName;

            spatialFilter.set_GeometryEx(envelope, true);

            spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

            var srClone =
                (ISpatialReferenceResolution)((IClone)spatialReference).Clone();

            srClone.set_XYResolution(true, 0.00001);

            spatialFilter.set_OutputSpatialReference(fc.ShapeFieldName,
                                                     (ISpatialReference)srClone);

            int found = GdbQueryUtils.GetFeatures(fc, spatialFilter, true).Count();

            Assert.True(found > 0, "No features found with mini-envelope");

            envelope.Expand(0.0001, 0.0001, false);
            IPolygon miniPoly = GeometryFactory.CreatePolygon(envelope);

            spatialFilter.set_GeometryEx(miniPoly, true);

            found = GdbQueryUtils.GetFeatures(fc, spatialFilter, true).Count();

            Assert.True(found > 0, "No features found with mini-polygon");
        }
コード例 #20
0
        public void CanOpenRasterFileFromMosaicDatasetUsingSpatialQueryGdal_Learning()
        {
            // TODO: Corrext GDAL native reference. Work-around: copy the x64 directory to the output dir
            IWorkspace workspace = TestUtils.OpenUserWorkspaceOracle();

            IMosaicDataset mosaicDataset = DatasetUtils.OpenMosaicDataset(workspace,
                                                                          "TOPGIS_TLM.TLM_DTM_MOSAIC");

            IFeatureClass rasterCatalog = mosaicDataset.Catalog;

            IPoint winterthurLL = GeometryFactory.CreatePoint(
                2690021, 1254011,
                SpatialReferenceUtils.CreateSpatialReference(WellKnownHorizontalCS.LV95));

            IQueryFilter spatialFilter =
                GdbQueryUtils.CreateSpatialFilter(rasterCatalog, winterthurLL);

            Gdal.AllRegister();

            IStringArray stringArray;
            Stopwatch    watch = Stopwatch.StartNew();

            List <IFeature> features = GdbQueryUtils.GetFeatures(
                rasterCatalog, spatialFilter, false).ToList();

            Assert.True(features.Count > 0);

            var itemPathsQuery = (IItemPathsQuery)mosaicDataset;

            itemPathsQuery.QueryPathsParameters = new QueryPathsParametersClass();

            stringArray = itemPathsQuery.GetItemPaths(features[0]);

            string rasterPath = stringArray.Element[0];

            Dataset ds = Gdal.Open(rasterPath, Access.GA_ReadOnly);

            if (ds == null)
            {
                Console.WriteLine("Can't open " + rasterPath);
                return;
            }

            Console.WriteLine("Raster dataset parameters:");
            Console.WriteLine("  Projection: " + ds.GetProjectionRef());
            Console.WriteLine("  RasterCount: " + ds.RasterCount);
            Console.WriteLine("  RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")");

            double[] adfGeoTransform = new double[6];
            ds.GetGeoTransform(adfGeoTransform);

            double originX = adfGeoTransform[0];
            double originY = adfGeoTransform[3];

            Console.WriteLine($"Origin: {originX} | {originY}");

            double pixelSizeX = adfGeoTransform[1];
            double pixelSizeY = adfGeoTransform[5];

            Console.WriteLine($"Pixel Size: {pixelSizeX} | {pixelSizeY}");

            /* -------------------------------------------------------------------- */
            /*      Get driver                                                      */
            /* -------------------------------------------------------------------- */
            Driver drv = ds.GetDriver();

            if (drv == null)
            {
                Console.WriteLine("Can't get driver.");
                Environment.Exit(-1);
            }

            Console.WriteLine("Using driver " + drv.LongName);

            /* -------------------------------------------------------------------- */
            /*      Get raster band                                                 */
            /* -------------------------------------------------------------------- */
            for (int iBand = 1; iBand <= ds.RasterCount; iBand++)
            {
                Band band = ds.GetRasterBand(iBand);
                Console.WriteLine("Band " + iBand + " :");
                Console.WriteLine("   DataType: " + band.DataType);
                Console.WriteLine("   Size (" + band.XSize + "," + band.YSize + ")");
                Console.WriteLine("   PaletteInterp: " +
                                  band.GetRasterColorInterpretation().ToString());

                band.GetBlockSize(out int blockSizeX, out int blockSizeY);

                Console.WriteLine("   Block Size (" + blockSizeX + "," + blockSizeY + ")");

                for (int iOver = 0; iOver < band.GetOverviewCount(); iOver++)
                {
                    Band over = band.GetOverview(iOver);
                    Console.WriteLine("      OverView " + iOver + " :");
                    Console.WriteLine("         DataType: " + over.DataType);
                    Console.WriteLine("         Size (" + over.XSize + "," + over.YSize + ")");
                    Console.WriteLine("         PaletteInterp: " +
                                      over.GetRasterColorInterpretation());
                }

                // Get the value at winterthurLL:
                int pxlOffsetX = (int)Math.Floor((winterthurLL.X - originX) / pixelSizeX);
                int pxlOffsetY = (int)Math.Floor((winterthurLL.Y - originY) / pixelSizeY);

                double[] buffer = new double[1];
                band.ReadRaster(pxlOffsetX, pxlOffsetY, 1, 1, buffer, 1, 1, 0, 0);

                double z = buffer[0];

                // TODO: Theoretically there is an underlying block cache which would make subsequent
                //       reads in a similar area very fast (TEST!) - probably the same as IRaster behaviour.
                // TODO: Bilinear interpolation if it's not the middle of a pixel!
                Console.WriteLine("Z value at {0}, {1}: {2}", winterthurLL.X, winterthurLL.Y, z);
            }
        }
コード例 #21
0
        public void CanCreateGdbRowFromRealData()
        {
            IWorkspace ws = TestUtils.OpenUserWorkspaceOracle();

            const string tlmStrasse = "TOPGIS_TLM.TLM_STRASSE";

            IFeatureClass realFeatureClass = DatasetUtils.OpenFeatureClass(ws, tlmStrasse);

            var objectClassMsg = ProtobufGdbUtils.ToObjectClassMsg(realFeatureClass, true);

            GdbTableContainer gdbTableContainer =
                ProtobufConversionUtils.CreateGdbTableContainer(
                    new[] { objectClassMsg }, null, out GdbWorkspace _);

            var virtualFeatureClass = (IFeatureClass)gdbTableContainer.OpenTable(tlmStrasse);

            Assert.AreEqual(realFeatureClass.ObjectClassID, virtualFeatureClass.ObjectClassID);
            Assert.AreEqual(DatasetUtils.GetName(realFeatureClass),
                            DatasetUtils.GetName(virtualFeatureClass));
            Assert.AreEqual(realFeatureClass.AliasName, virtualFeatureClass.AliasName);
            Assert.AreEqual(realFeatureClass.ShapeFieldName, virtualFeatureClass.ShapeFieldName);
            Assert.AreEqual(realFeatureClass.OIDFieldName, virtualFeatureClass.OIDFieldName);
            Assert.AreEqual(realFeatureClass.FeatureClassID, virtualFeatureClass.FeatureClassID);
            Assert.AreEqual(realFeatureClass.FeatureType, virtualFeatureClass.FeatureType);
            Assert.AreEqual(realFeatureClass.HasOID, virtualFeatureClass.HasOID);
            Assert.AreEqual(realFeatureClass.ShapeType, virtualFeatureClass.ShapeType);
            Assert.AreEqual(realFeatureClass.ShapeFieldName, virtualFeatureClass.ShapeFieldName);

            Assert.IsTrue(SpatialReferenceUtils.AreEqual(
                              DatasetUtils.GetSpatialReference(realFeatureClass),
                              DatasetUtils.GetSpatialReference(virtualFeatureClass), true, true));

            Assert.AreEqual(realFeatureClass.Fields.FieldCount,
                            virtualFeatureClass.Fields.FieldCount);

            int featureCount = 0;

            foreach (var feature in GdbQueryUtils.GetFeatures(realFeatureClass, true))
            {
                // TODO: Move all this to separate project referenced by both client and server
                GdbObjectMsg gdbObjectMsg =
                    ProtobufGdbUtils.ToGdbObjectMsg(feature, false, true);

                GdbRow gdbRow =
                    ProtobufConversionUtils.FromGdbObjectMsg(
                        gdbObjectMsg, (ITable)realFeatureClass);

                for (int i = 0; i < feature.Fields.FieldCount; i++)
                {
                    object expected = feature.get_Value(i);
                    object actual   = gdbRow.get_Value(i);

                    if (expected is IGeometry shape)
                    {
                        Assert.IsTrue(
                            GeometryUtils.AreEqual(shape, (IGeometry)actual));
                    }
                    else
                    {
                        Assert.AreEqual(expected, actual);
                    }
                }

                featureCount++;

                if (featureCount > 250)
                {
                    return;
                }
            }
        }