public void CanSortByStringField()
        {
            IFeatureWorkspace featureWs =
                WorkspaceUtils.OpenFileGdbFeatureWorkspace(TestData.GetArealeFileGdbPath());

            ITable table = DatasetUtils.OpenTable(featureWs, "TLM_NUTZUNGSAREAL");

            const string operatorFieldName = "OPERATEUR";
            ICursor      cursor            = TableSortUtils.GetSortedTableCursor(table, operatorFieldName);

            int fieldIndex = cursor.FindField(operatorFieldName);

            Assert.True(fieldIndex >= 0, "Field not found");

            string lastValue = null;
            IRow   row;

            while ((row = cursor.NextRow()) != null)
            {
                object value = row.get_Value(fieldIndex);

                Assert.False(value == DBNull.Value, "Empty field");

                var currentValue = (string)value;
                Console.WriteLine(currentValue);

                if (lastValue != null)
                {
                    Assert.False(currentValue.CompareTo(lastValue) < 0, "Not sorted");
                }

                lastValue = currentValue;
            }
        }
        public void CanGetExistingRowsFastEnough()
        {
            IFeatureWorkspace ws = OpenTestWorkspace();
            ITable            fc = ws.OpenTable("TOPGIS_TLM.TLM_WANDERWEG");

            const int max = 100;
            IDictionary <int, IRow> rows = GetFirstNRows(fc, max);

            var watch = new Stopwatch();

            watch.Start();

            foreach (int oid in rows.Keys)
            {
                Assert.NotNull(GdbQueryUtils.GetRow(fc, oid));
                _msg.Info($"Oid {oid} time: {watch.ElapsedMilliseconds}");
            }

            watch.Stop();

            double msPerIteration = watch.ElapsedMilliseconds / (double)rows.Count;

            _msg.InfoFormat(@"GetRow() per iteration: {0} ms", msPerIteration);

            Assert.True(msPerIteration < 50,
                        "GetFeature with existing feature takes too long ({0} ms, {1} rows)",
                        msPerIteration, rows.Count);
        }
        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");
        }
        public void CanGetNullForNonExistingFeatureFastEnough()
        {
            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

            const int iterations = 200;

            var watch = new Stopwatch();

            watch.Start();

            for (var iteration = 0; iteration < iterations; iteration++)
            {
                int oid = 999999999 + iteration;
                Assert.Null(GdbQueryUtils.GetFeature(fc, oid));
            }

            watch.Stop();

            double msPerIteration = watch.ElapsedMilliseconds / (double)iterations;

            _msg.InfoFormat(@"GetFeature() per iteration: {0} ms", msPerIteration);

            const int maxMilliseconds = 35;

            Assert.True(msPerIteration < maxMilliseconds,
                        "GetFeature with non-existing feature takes too long ({0} ms)",
                        msPerIteration);
        }
        public void CanCreateSpatialFilterWithSubResolutionEnvelope()
        {
            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

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

            ISpatialReference spatialReference = DatasetUtils.GetSpatialReference(fc);

            subResolutionEnv.SpatialReference = spatialReference;

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

            IGeometry validGeometry;
            string    message;

            Assert.False(GdbQueryUtils.IsValidFilterGeometry(
                             subResolutionEnv, xyResolution, out validGeometry, out message),
                         "Sub-resolution polygon should not be valid");
            Assert.NotNull(validGeometry);
            Assert.False(subResolutionEnv == validGeometry,
                         "Corrected geometry must be different to input");

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

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

            IFeatureCursor cursor = fc.Search(filter, true);

            Marshal.ReleaseComObject(cursor);

            IEnvelope linearEnv = GeometryFactory.CreateEnvelope(2600000, 1200000,
                                                                 2600000.0001, 1201010);

            linearEnv.SpatialReference = ((IGeoDataset)fc).SpatialReference;

            filter = GdbQueryUtils.CreateSpatialFilter(
                fc, linearEnv, esriSpatialRelEnum.esriSpatialRelIntersects, true,
                null);

            cursor = fc.Search(filter, true);

            Marshal.ReleaseComObject(cursor);
        }
        private static void LoopAndWrite(ICursor cursor, string uuidFieldName)
        {
            int fieldIndex = cursor.FindField(uuidFieldName);

            Assert.True(fieldIndex >= 0, "Field not found");

            IRow row;

            while ((row = cursor.NextRow()) != null)
            {
                object value = row.get_Value(fieldIndex);

                Assert.False(value == DBNull.Value, "Empty UUID field");

                var         currentGuid  = new Guid((string)value);
                IComparable currentValue = currentGuid;                 // value as IComparable; // currentGuid;

                Console.WriteLine(currentValue);
            }
        }
        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.");
        }
        public void CanSortOnFgdbGuids()
        {
            IFeatureWorkspace featureWs =
                WorkspaceUtils.OpenFileGdbFeatureWorkspace(TestData.GetArealeFileGdbPath());
            //IFeatureWorkspace featureWs = OpenTestWorkspace();

            ITable table = DatasetUtils.OpenTable(featureWs, "TLM_NUTZUNGSAREAL");
            //ITable table = DatasetUtils.OpenTable(featureWs, "TOPGIS_TLM.TLM_NUTZUNGSAREAL");

            const string uuidFieldName = "UUID";

            ICursor cursor = TableSortUtils.GetGuidFieldSortedCursor(table, uuidFieldName);

            int fieldIndex = cursor.FindField(uuidFieldName);

            Assert.True(fieldIndex >= 0, "Field not found");

            Guid lastGuid = Guid.Empty;
            IRow row;

            while ((row = cursor.NextRow()) != null)
            {
                object value = row.get_Value(fieldIndex);

                Assert.False(value == DBNull.Value, "Empty UUID field");

                var currentGuid = new Guid((string)value);
                Console.WriteLine(currentGuid);

                if (lastGuid != Guid.Empty)
                {
                    Assert.False(currentGuid.CompareTo(lastGuid) < 0, "Not sorted");
                }

                lastGuid = currentGuid;
            }
        }
        public void CanQueryDateField()
        {
            const string featureClassName = "points";
            const string fieldName        = "date";
            var          equalDateTime    = new DateTime(2012, 03, 22, 12, 00, 00);
            var          greaterDateTime  = new DateTime(2012, 03, 22, 12, 00, 01);
            var          lowerDateTime    = new DateTime(2012, 03, 22, 11, 59, 59);

            IFeatureWorkspace workspace =
                WorkspaceUtils.OpenFileGdbFeatureWorkspace(TestData.GetFileGdb93Path());
            IFeatureClass fc = DatasetUtils.OpenFeatureClass(workspace,
                                                             featureClassName);
            int    fieldIndex = fc.Fields.FindField(fieldName);
            IField dateField  = fc.Fields.get_Field(fieldIndex);

            Assert.True(dateField.Type == esriFieldType.esriFieldTypeDate,
                        "Wrong FieldType in test data");

            IList <IFeature> rows = GdbQueryUtils.FindList(fc, "OBJECTID = 1");

            Assert.True(rows.Count == 1, "Expected object not in test data");

            DateTime dateTime = Convert.ToDateTime(rows[0].get_Value(fieldIndex));

            _msg.InfoFormat(@"Testing with dateTime: {0}", dateTime);

            Assert.True(dateTime == equalDateTime, "Expected DateTime = DateTime failed.");
            Assert.True(dateTime <= greaterDateTime, "Expected DateTime <= DateTime failed.");
            Assert.True(dateTime < greaterDateTime, "Expected DateTime < DateTime failed.");
            Assert.True(dateTime >= lowerDateTime, "Expected DateTime >= DateTime failed.");
            Assert.True(dateTime > lowerDateTime, "Expected DateTime > DateTime failed.");

            //Test query logic for date field
            const string equals          = "=";
            const string lowerOrEquals   = "<=";
            const string lower           = "<";
            const string greaterOrEquals = ">=";
            const string greater         = ">";

            string where = string.Format("{0} {1} {2}", fieldName, equals,
                                         GdbSqlUtils.GetFGDBDateLiteral(equalDateTime));
            Assert.True(GdbQueryUtils.Count(fc, where) == 1, "Query '{0}' fails.", equals);

            where = string.Format("{0} {1} {2}", fieldName, lowerOrEquals,
                                  GdbSqlUtils.GetFGDBDateLiteral(greaterDateTime));
            Assert.True(GdbQueryUtils.Count(fc, where) == 1, "Query '{0}' fails.",
                        lowerOrEquals);

            where = string.Format("{0} {1} {2}", fieldName, lower,
                                  GdbSqlUtils.GetFGDBDateLiteral(greaterDateTime));
            Assert.True(GdbQueryUtils.Count(fc, where) == 1, "Query '{0}' fails.", lower);

            where = string.Format("{0} {1} {2}", fieldName, greaterOrEquals,
                                  GdbSqlUtils.GetFGDBDateLiteral(lowerDateTime));
            Assert.True(GdbQueryUtils.Count(fc, where) == 1, "Query '{0}' fails.",
                        greaterOrEquals);

            where = string.Format("{0} {1} {2}", fieldName, greater,
                                  GdbSqlUtils.GetFGDBDateLiteral(lowerDateTime));
            Assert.True(GdbQueryUtils.Count(fc, where) == 1, "Query '{0}' fails.", greater);
        }
        public void CanCreateSpatialFilterWithSubResolutionPolyline()
        {
            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

            IPolyline subResolutionPolyline = GeometryFactory.CreatePolyline(2600000, 1200000,
                                                                             2600000.0001,
                                                                             1200000.0001);

            subResolutionPolyline.SpatialReference = ((IGeoDataset)fc).SpatialReference;

            Exception expectedEx = null;

            try
            {
                ISpatialFilter standardFilter = new SpatialFilterClass();
                standardFilter.Geometry   = subResolutionPolyline;
                standardFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIndexIntersects;
                // ReSharper disable once UnusedVariable
                IFeatureCursor failingCursor = fc.Search(standardFilter, true);
            }
            catch (Exception ex)
            {
                expectedEx = ex;
            }

            if (RuntimeUtils.Is10_2 || RuntimeUtils.Is10_3 || RuntimeUtils.Is10_4orHigher)
            {
                Assert.Null(expectedEx);
            }
            else
            {
                Assert.NotNull(expectedEx);
            }

            IQueryFilter filter = GdbQueryUtils.CreateSpatialFilter(
                fc, subResolutionPolyline, esriSpatialRelEnum.esriSpatialRelIntersects, false,
                null);

            Assert.True(((ISpatialFilter)filter).FilterOwnsGeometry,
                        "Filter should own geometry due to cloned geometry in GetValidSearchGeometry.");
            Assert.AreEqual(((ISpatialFilter)filter).SearchOrder,
                            esriSearchOrder.esriSearchOrderSpatial,
                            "Default should be spatial.");
            Assert.AreEqual(((ISpatialFilter)filter).SpatialRel,
                            esriSpatialRelEnum.esriSpatialRelIntersects,
                            "Default should be spatial.");

            IFeatureCursor cursor = fc.Search(filter, true);

            Marshal.ReleaseComObject(cursor);

            // test the exact half of the resolution - which is the limit
            double resolution = GeometryUtils.GetXyResolution(fc);

            subResolutionPolyline = GeometryFactory.CreatePolyline(2600000 - 0.00001,
                                                                   1200000 - 0.00001,
                                                                   2600000 + resolution -
                                                                   0.00001,
                                                                   1200000 + resolution -
                                                                   0.00001);

            filter = GdbQueryUtils.CreateSpatialFilter(
                fc, subResolutionPolyline, esriSpatialRelEnum.esriSpatialRelIntersects, false,
                null);

            cursor = fc.Search(filter, true);
            Marshal.ReleaseComObject(cursor);
        }
        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");
        }