public static IList <esriSegmentInfo> CalculateShortSegments( [NotNull] FeatureVertexInfo forFeatureVertexInfo, bool use2DLengthOnly, [CanBeNull] IGeometry perimeter) { _msg.VerboseDebugFormat("Getting short segments for {0}", GdbObjectUtils.ToString(forFeatureVertexInfo.Feature)); var minimumSegmentLength = (double)Assert.NotNull(forFeatureVertexInfo.MinimumSegmentLength); IList <esriSegmentInfo> shortSegments = GetShortSegments( forFeatureVertexInfo.Feature, perimeter, minimumSegmentLength, use2DLengthOnly); IList <esriSegmentInfo> protectedSegments = GetProtectedSegments( shortSegments, forFeatureVertexInfo.CrackPointCollection); IList <esriSegmentInfo> removableSegments = shortSegments.Where(shortSegment => !protectedSegments.Contains(shortSegment)) .ToList(); forFeatureVertexInfo.ShortSegments = removableSegments; forFeatureVertexInfo.NonRemovableShortSegments = protectedSegments; return(removableSegments); }
public void RestoreSelection( [NotNull] BoundDataGridSelectionState <ROW> selectionState) { Assert.ArgumentNotNull(selectionState, nameof(selectionState)); if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat("Restoring selection ({0} row(s))", selectionState.SelectionCount); } DataGridViewUtils.RestoreSelection(_dataGridView, selectionState); }
public CodedDomainValueProvider([NotNull] ITable table, [NotNull] string codedDomainField, [CanBeNull] IFormatProvider formatProvider) { _codedFieldIndex = table.FindField(codedDomainField); IField field = table.Fields.Field[_codedFieldIndex]; var domain = (ICodedValueDomain)field.Domain; _valueDict = new Dictionary <object, T?>(); foreach (CodedValue codedValue in DomainUtils.GetCodedValueList(domain)) { object code = codedValue.Value; string name = codedValue.Name; try { var value = (T)Assert.NotNull(Convert.ChangeType(name, typeof(T), formatProvider)); _valueDict.Add(code, value); } catch (Exception e) { _msg.VerboseDebugFormat("Unable to convert '{0}' to type {1}: {2}", name, typeof(T).Name, e.Message); _valueDict.Add(code, null); } } }
private void ProlongThirdEdge([NotNull] IFeature thirdEdge, [NotNull] IPolyline cutOffLine) { Assert.ArgumentNotNull(thirdEdge, nameof(thirdEdge)); if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat( "The third connected edge {0} is prolonged with cut-off line {1}", GdbObjectUtils.ToString(thirdEdge), GeometryUtils.ToString(cutOffLine)); } // add the cut off line to the third edge, take along the junction // (if using MaintainConnectivityStretchLastSegment here, it can result in // COM-exception 0x80044020) // TODO: Handle Z-differences according to some option (Union always merges and higher Z-value wins) var originalLine = (IPolyline)thirdEdge.ShapeCopy; var prolongedLine = (IPolyline)GeometryUtils.Union(originalLine, cutOffLine); // NOTE: The cutOffLine and the original thirdEdgeLine can have different orientation. // The union sometimes produces lines that use the cutOffLine's orientation // Maintaining the orientation of the third edge is crucial to avoid COM-exception 0x80044020 EnsureOrientation(originalLine, prolongedLine); StoreSingleFeatureShape(thirdEdge, prolongedLine); AddToRefreshArea(prolongedLine); }
private static bool TryGetVersion([CanBeNull] out string version) { try { // the following code fails in the 64bit background environment (see COM-221) RuntimeInfo runtime = RuntimeManager.ActiveRuntime; if (runtime == null) { // not bound yet? // There seems to be another scenario where this is null (observed // for background gp on a particular setup, which also includes server). _msg.Debug( "RuntimeInfo not available. Trying to get version from assembly"); if (TryGetVersionFromVersionAssembly(out version)) { return(true); } _msg.DebugFormat("Unable to get ArcGIS version from assembly"); version = null; return(false); } version = runtime.Version; return(true); } catch (DllNotFoundException e) { _msg.VerboseDebugFormat( "Error accessing RuntimeManager: {0}; trying to get version from assembly", e.Message); if (TryGetVersionFromVersionAssembly(out version)) { return(true); } _msg.DebugFormat("Unable to get ArcGIS version from assembly"); return(false); } }
public static Assembly LoadAssembly([NotNull] string assemblyName) { Assert.ArgumentNotNullOrEmpty(assemblyName, nameof(assemblyName)); AssemblyName name = GetAssemblyName(BinDirectory, assemblyName); if (string.IsNullOrEmpty(name.CodeBase)) { _msg.VerboseDebugFormat("Loading assembly from {0}", name); } else { _msg.VerboseDebugFormat("Loading assembly from {0} (codebase: {1})", name, name.CodeBase); } return(Assembly.Load(name)); }
public static Assembly LoadAssembly( [NotNull] string assemblyName, [CanBeNull] IReadOnlyDictionary <string, string> assemblySubstitutes = null) { IReadOnlyDictionary <string, string> substitutes = GetSubstitutes(assemblySubstitutes); bool throwOnError = !substitutes.TryGetValue(assemblyName, out string substituteAssembly); Assembly assembly; try { AssemblyName name = GetAssemblyName(BinDirectory, assemblyName); if (string.IsNullOrEmpty(name.CodeBase)) { _msg.VerboseDebugFormat("Loading assembly from {0}", name); } else { _msg.VerboseDebugFormat("Loading assembly from {0} (codebase: {1})", name, name.CodeBase); } assembly = Assembly.Load(name); } catch (Exception e) { _msg.Debug($"Loading {assemblyName} from {BinDirectory} failed.", e); if (throwOnError) { throw; } _msg.DebugFormat("Trying assembly substitute {0}...", substituteAssembly); assembly = Assembly.Load(substituteAssembly); } return(assembly); }
public static bool UseCaseSensitiveSql([NotNull] ITable table, SqlCaseSensitivity caseSensitivity) { switch (caseSensitivity) { case SqlCaseSensitivity.CaseInsensitive: if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat("{0}: not case sensitive", DatasetUtils.GetName(table)); } return(false); case SqlCaseSensitivity.CaseSensitive: if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat("{0}: case sensitive", DatasetUtils.GetName(table)); } return(true); case SqlCaseSensitivity.SameAsDatabase: var sqlSyntax = DatasetUtils.GetWorkspace(table) as ISQLSyntax; bool result = sqlSyntax != null && sqlSyntax.GetStringComparisonCase(); if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat(sqlSyntax == null ? "{0}: database case sensitivity: UNKNOWN (use {1})" : "{0}: database case sensitivity: {1}", DatasetUtils.GetName(table), result); } return(result); default: throw new InvalidOperationException( string.Format("Unsupported SqlCaseSensitivity: {0}", caseSensitivity)); } }
public override async Task VerifyStandaloneXml( StandaloneVerificationRequest request, IServerStreamWriter <StandaloneVerificationResponse> responseStream, ServerCallContext context) { try { await StartRequest(context.Peer, request); _msg.InfoFormat("Starting stand-alone verification request from {0}", context.Peer); _msg.VerboseDebugFormat("Request details: {0}", request); Action <LoggingEvent> action = SendInfoLogAction(responseStream, ServiceCallStatus.Running); using (MessagingUtils.TemporaryRootAppender(new ActionAppender(action))) { Func <ITrackCancel, ServiceCallStatus> func = trackCancel => VerifyStandaloneXmlCore(request, responseStream, trackCancel); ServiceCallStatus result = await GrpcServerUtils.ExecuteServiceCall( func, context, _staThreadScheduler); _msg.InfoFormat("Verification {0}", result); } } catch (Exception e) { _msg.Error($"Error verifying quality for request {request}", e); SendFatalException(e, responseStream); SetUnhealthy(); } finally { EndRequest(); } }
private void ApplyFormState([NotNull] T formState, FormStateRestoreOption restoreOption) { _msg.VerboseDebugFormat("Applying form state for {0}", Form.Name); using (_msg.IncrementIndentation()) { switch (restoreOption) { case FormStateRestoreOption.OnlyLocation: ApplyLocation(formState); ApplyTopMost(formState); // don't apply size // don't apply window state ApplyInternalFormState(formState); break; case FormStateRestoreOption.KeepLocation: // don't apply location ApplyTopMost(formState); ApplySize(formState); ApplyWindowState(formState); ApplyInternalFormState(formState); break; case FormStateRestoreOption.Normal: ApplyLocation(formState); ApplyTopMost(formState); ApplySize(formState); ApplyWindowState(formState); ApplyInternalFormState(formState); break; default: throw new ArgumentException( string.Format("Unknown restore option: {0}", restoreOption)); } } }
public int Compare(object value1, object value2, int fieldIndex, int fieldSortIndex) { // TODO: sometimes the OID gets provided (with fieldSortIndex == 1) -> we never asked for it! // test whether we can safely ignore it by if (fieldSortIndex > 0) return 0; try { if (fieldSortIndex > 0) { _msg.VerboseDebugFormat( "Assuming equal IDs: value1 {0}, value2 {1}, fieldIndex {2}, fieldSortIndex {3}", value1, value2, fieldIndex, fieldSortIndex); return(0); } if (Convert.IsDBNull(value1)) { _msg.WarnFormat("Sort field (fieldindex {0}) contains NULL (value1).", fieldIndex); return(Convert.IsDBNull(value2) ? 0 : -1); } if (Convert.IsDBNull(value2)) { _msg.WarnFormat("Sort field (fieldindex {0}) contains NULL (value2).", fieldIndex); return(Convert.IsDBNull(value1) ? 0 : 1); } // NOTE: To avoid exception with explicit cast // TODO: Check performance string value1String = Convert.ToString(value1); string value2String = Convert.ToString(value2); return(string.Compare(value1String, value2String, StringComparison.InvariantCultureIgnoreCase)); } catch (Exception e) { _msg.Debug( string.Format("Error comparing object values {0} and {1}", value1, value2), e); throw; } }
private static bool TryGetInstallDirForActiveRuntime(out string installDir) { installDir = null; try { // the following code fails in the 64bit background environment (see COM-221) RuntimeInfo runtime = RuntimeManager.ActiveRuntime; if (runtime == null) { // not bound yet? // There seems to be another scenario where this is null (observed // for background gp on a particular setup, which also includes server). _msg.Debug("RuntimeInfo not available."); return(false); } if (Process.GetCurrentProcess().ProcessName.Equals("python")) { // in x64-bit python the active runtime is Server (even if background GP is installed too). // However, the (contour) GP tool fails (E_FAIL, TOP-5169) unless the Desktop(!) toolbox is referenced. _msg.DebugFormat( "Called from python. The active runtime ({0}) might be incorrect -> using default implementation, favoring Desktop.", runtime.Product); return(false); } installDir = runtime.Path; return(true); } catch (DllNotFoundException e) { _msg.VerboseDebugFormat( "Error accessing RuntimeManager: {0}.", e.Message); return(false); } }
public bool TryWritePendingChanges() { try { if (!_hasPendingChanges) { _msg.VerboseDebug("no pending changes"); return(false); } if (AutoSave) { _canSave = true; } if (!CanHandlePendingChanges()) { _msg.VerboseDebugFormat( "Cannot handle pending changes. Reason: saving {0}, aborting {1}, can save {2}", _saving, _aborting, _canSave); return(false); } BeginWrite(); WriteChanges(); return(true); } catch (Exception e) { ErrorHandler.HandleError(e.Message, e, _msg, _owner); return(false); } finally { _canSave = false; EndWrite(); } }
public void Callback() { if (_pending) { _msg.VerboseDebug("Callback already pending - ignored"); return; } _expectedThreadId = Thread.CurrentThread.ManagedThreadId; if (_synchronizationContext == null) { // get the winforms synchronization context // NOTE: relying on the current synchronization context of the current thread is not sufficient, // as this gets changed depending on previous winforms actions: // - after showing a modal dialog, the synchronization context DOES NOT displatch back to the gui thread // - after opening/activating a modeless form, it DOES dispatch back to the gui thread // -> better to set the expected synchronization context explicitly // NOTE: this must be done on the gui thread, otherwise even this synchronization context will not dispatch back to it _synchronizationContext = new WindowsFormsSynchronizationContext(); } _msg.VerboseDebugFormat("Scheduling delayed processing (thread: {0})", Thread.CurrentThread.ManagedThreadId); try { _pending = true; _synchronizationContext.Post(delegate { TryExecuteProcedure(); }, null); } catch (Exception ex) { _pending = false; _msg.Error($"Error executing procedure via synchronization context: {ex.Message}", ex); } }
public void Add(T identifier, IEnumerable <TileIndex> intersectedTiles) { foreach (TileIndex intersectedTileIdx in intersectedTiles) { List <T> tileGeometryRefs; if (!_tiles.TryGetValue(intersectedTileIdx, out tileGeometryRefs)) { tileGeometryRefs = new List <T>(_estimatedItemsPerTile); _tiles.Add(intersectedTileIdx, tileGeometryRefs); } if (_msg.IsVerboseDebugEnabled && tileGeometryRefs.Count >= _estimatedItemsPerTile) { _msg.VerboseDebugFormat( "Numer of items in tile {0} is exceeding the estimated maximum and now contains {1} items", intersectedTileIdx, tileGeometryRefs.Count + 1); } tileGeometryRefs.Add(identifier); } }
private static IEnumerable <CutSubcurve> GetIndividualGeometriesReshapeCurves( [NotNull] IList <IFeature> sourceFeatures, [NotNull] IPolyline targetPolyline, [NotNull] ISubcurveCalculator subcurveCalculator) { var result = new List <CutSubcurve>(); _msg.DebugFormat( "GetIndividualGeometriesReshapeCurves: calculating curves for {0} geometries..", sourceFeatures.Count); foreach (IFeature sourceFeature in sourceFeatures) { IGeometry sourceGeometry = sourceFeature.Shape; var individualResultList = new List <CutSubcurve>(); ReshapeAlongCurveUsability individualResult = subcurveCalculator.CalculateSubcurves( sourceGeometry, targetPolyline, individualResultList, null); foreach (CutSubcurve subcurve in individualResultList) { subcurve.Source = new GdbObjectReference(sourceFeature); } result.AddRange(individualResultList); _msg.VerboseDebugFormat( "Individual geometry's subcurve calculation result: {0}", individualResult); Marshal.ReleaseComObject(sourceGeometry); } return(result); }
private bool IsDisjoint([NotNull] IGeometry shape, [NotNull] ITable relatedTable, int relatedTableIndex, [NotNull] QueryFilterHelper relatedFilterHelper, [NotNull] IGeometry cacheShape) { ISpatialFilter intersectsFilter = _spatialFiltersIntersects[relatedTableIndex]; intersectsFilter.Geometry = shape; foreach ( IRow row in Search(relatedTable, intersectsFilter, relatedFilterHelper, cacheShape)) { if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat("not disjoint (row found: {0})", GdbObjectUtils.ToString(row)); } return(false); } return(true); }
public static IEnumerable <IGeometry> GetSelectableOverlaps( [NotNull] IFeature sourceFeature, [NotNull] SpatialHashSearcher <IFeature> overlappingFeatures, [CanBeNull] NotificationCollection notifications = null, [CanBeNull] ITrackCancel trackCancel = null) { IGeometry sourceGeometry = sourceFeature.Shape; if (sourceGeometry == null || sourceGeometry.IsEmpty) { yield break; } IEnvelope sourceEnvelope = sourceGeometry.Envelope; double tolerance = GeometryUtils.GetXyTolerance(sourceGeometry); foreach (IFeature targetFeature in overlappingFeatures.Search( sourceEnvelope.XMin, sourceEnvelope.YMin, sourceEnvelope.XMax, sourceEnvelope.YMax, tolerance)) { if (trackCancel != null && !trackCancel.Continue()) { yield break; } _msg.VerboseDebugFormat("Calculating overlap from {0}", GdbObjectUtils.ToString(targetFeature)); IGeometry targetGeometry = targetFeature.Shape; if (GeometryUtils.Disjoint(targetGeometry, sourceGeometry)) { continue; } if (GeometryUtils.Contains(targetGeometry, sourceGeometry)) { // Idea for the future: Optionally allow also deleting features (probably using a black display feedback) NotificationUtils.Add(notifications, "Source feature {0} is completely within target {1} and would become empty if the overlap was removed. The overlap is supressed.", RowFormat.Format(sourceFeature), RowFormat.Format(targetFeature)); continue; } if (sourceGeometry.GeometryType == esriGeometryType.esriGeometryMultiPatch) { sourceGeometry = GeometryFactory.CreatePolygon(sourceGeometry); } IGeometry intersection = TryGetIntersection(sourceGeometry, targetGeometry); if (intersection == null) { continue; } if (GeometryUtils.GetPartCount(intersection) > 1) { foreach (var part in GeometryUtils.Explode(intersection)) { yield return(part); } } else { yield return(intersection); } } }
private static IEnumerable <CutSubcurve> GetCutSubcurves( [NotNull] IGeometryCollection differences, int differencePathIndexToSplit, [NotNull] IGeometry cuttingGeometry, IDictionary <SubcurveNode, SubcurveNode> nodes, [NotNull] IPointCollection intersectionPoints, IPolyline target) { var curveToSplit = (IPath)differences.Geometry[differencePathIndexToSplit]; IGeometry highLevelCurveToSplit = GeometryUtils.GetHighLevelGeometry( curveToSplit, true); // Enlarge search tolerance to avoid missing points because the intersection points are // 'found' between the target vertex and the actual source-target intersection. // But when using minimum tolerance, make sure we're not searching with the normal tolerance // otherwise stitch points close to target vertices are missed and the result becomes unnecessarily // inaccurate by the two vertices being simplified (at data tolerance) into one intermediate. double searchToleranceFactor = 2 * Math.Sqrt(2); double stitchPointSearchTol = GeometryUtils.GetXyTolerance((IGeometry)differences) * searchToleranceFactor; if (intersectionPoints.PointCount == 0 || GeometryUtils.Disjoint(cuttingGeometry, highLevelCurveToSplit)) { _msg.VerboseDebugFormat( "GetCutSubcurves: No intersections / disjoint geometries"); yield return (CreateCutSubcurve(curveToSplit, null, nodes, null, target, stitchPointSearchTol)); } else { _msg.DebugFormat("GetCutSubcurves: Intersection Point Count: {0}.", intersectionPoints.PointCount); const bool projectPointsOntoPathToSplit = false; // NOTE: take tolerance from cutting geometry because the difference's spatial reference could // have been changed to minimum tolerance which sometimes results in missed points due to cutOffDistance being too small double cutOffDistance = GeometryUtils.GetXyTolerance(cuttingGeometry); // the original subdivision at start/end point is not needed any more: merge if it doesn't touch // any other difference part (to allow the other difference part to become a reshape candidate) IGeometryCollection subCurves = GeometryUtils.SplitPath( curveToSplit, intersectionPoints, projectPointsOntoPathToSplit, cutOffDistance, splittedCurves => UnlessTouchesOtherPart(splittedCurves, differences, differencePathIndexToSplit)); for (var i = 0; i < subCurves.GeometryCount; i++) { var subCurve = (IPath)subCurves.Geometry[i]; bool?curveTouchesDifferentParts = SubCurveTouchesDifferentParts( subCurve, cuttingGeometry); IPath subCurveClone = GeometryFactory.Clone(subCurve); yield return (CreateCutSubcurve(subCurveClone, intersectionPoints, nodes, curveTouchesDifferentParts, target, stitchPointSearchTol)); } Marshal.ReleaseComObject(subCurves); } }
internal static IKeySet ReadKeySet([NotNull] ITable table, [NotNull] string keyField, [CanBeNull] string whereClause, esriFieldType keyFieldType, int keyFieldIndex) { Assert.ArgumentNotNull(table, nameof(table)); Assert.ArgumentNotNullOrEmpty(keyField, nameof(keyField)); Stopwatch watch = null; MemoryUsageInfo memoryUsage = null; if (_msg.IsVerboseDebugEnabled) { watch = _msg.DebugStartTiming(); memoryUsage = new MemoryUsageInfo(); memoryUsage.Refresh(); } IKeySet result = CreateKeySet(keyFieldType); var queryFilter = new QueryFilterClass { SubFields = keyField, WhereClause = whereClause }; string tableName = DatasetUtils.GetName(table); const bool recycle = true; foreach (IRow row in GdbQueryUtils.GetRows(table, queryFilter, recycle)) { object key = row.Value[keyFieldIndex]; if (key == DBNull.Value || key == null) { continue; } // TODO handle errors (e.g. invalid guid strings) bool added = result.Add(key); if (!added) { _msg.VerboseDebugFormat( "Ignored duplicate key found in field '{0}' in table '{1}': {2}", keyField, tableName, key); } } if (watch != null) { _msg.DebugStopTiming(watch, "Reading {0:N0} {1} keys from field '{2}' in table '{3}'", result.Count, keyFieldType, keyField, DatasetUtils.GetName(table)); _msg.DebugFormat("Memory usage of keys: {0}", memoryUsage); } return(result); }