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); } }
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 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); }
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."); }
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); }
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); }
/// <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())); } } }
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); }
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]); }
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); } }
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)); } } }
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]))); }
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."); }
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)))); }
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); }
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); }
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); }
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); }
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"); }
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); } }
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; } } }