protected override void LogDerivedGeometriesCalculated(CancelableProgressor progressor)
        {
            if (_overlaps != null && _overlaps.Notifications.Count > 0)
            {
                _msg.Info(_overlaps.Notifications.Concatenate(Environment.NewLine));

                if (!_overlaps.HasOverlaps())
                {
                    _msg.InfoFormat("Select one or more different features.");
                }
            }
            else if (_overlaps == null || !_overlaps.HasOverlaps())
            {
                _msg.Info(
                    "No overlap of other polygons with current selection found. Select one or more different features.");
            }

            if (_overlaps != null && _overlaps.HasOverlaps())
            {
                string msg = _overlaps.OverlapGeometries.Count == 1
                                                     ? "Select the overlap to subtract from the selection"
                                                     : "Select one or more overlaps to subtract from the selection. Draw a box to select overlaps completely within the box.";

                _msg.InfoFormat(LocalizableStrings.RemoveOverlapsTool_AfterSelection, msg);
            }
        }
Example #2
0
        public override async Task VerifyQuality(
            VerificationRequest request,
            IServerStreamWriter <VerificationResponse> responseStream,
            ServerCallContext context)
        {
            try
            {
                await StartRequest(request);

                Func <ITrackCancel, ServiceCallStatus> func =
                    trackCancel => VerifyQualityCore(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();
            }
        }
Example #3
0
        private static void AddOrUpdateAttribute(
            [NotNull] AttributedAssociation attributedAssociation,
            [NotNull] IField field,
            int fieldIndex)
        {
            Assert.ArgumentNotNull(field, nameof(field));

            const bool           includeDeleted = true;
            AssociationAttribute attribute      =
                attributedAssociation.GetAttribute(field.Name, includeDeleted);

            if (attribute == null)
            {
                _msg.InfoFormat("Adding attribute {0}", field.Name);

                attribute = attributedAssociation.AddAttribute(field.Name, (FieldType)field.Type);
            }
            else
            {
                // attribute already registered
                if (attribute.Deleted)
                {
                    _msg.WarnFormat(
                        "Attribute {0} was registered as deleted, but exists now. " +
                        "Resurrecting it...", attribute.Name);

                    attribute.RegisterExisting();
                }

                attribute.FieldType = (FieldType)field.Type;
            }

            // configure the attribute
            attribute.SortOrder = fieldIndex;
        }
Example #4
0
        public void CanGetExistingFeaturesFastEnough()
        {
            IFeatureWorkspace ws = OpenTestWorkspace();
            IFeatureClass     fc = ws.OpenFeatureClass("TOPGIS_TLM.TLM_STRASSE");

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

            var watch = new Stopwatch();

            watch.Start();

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

            watch.Stop();

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

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

            Assert.True(msPerIteration < 50,
                        "GetFeature with existing feature takes too long ({0} ms)",
                        msPerIteration);
        }
Example #5
0
        protected override void LogPromptForSelection()
        {
            //string enterMsg = CanUseSelection()
            //		  ? "- To re-use the existing selection, press Enter"
            //		  : string.Empty;

            _msg.InfoFormat(
                "Select one or more polygon features.<br>- Press and hold SHIFT to add or remove features from the existing selection.<br>- Press and hold P to draw a polygon that completely contains the features to be selected. Finish the polygon with double-click.");
        }
Example #6
0
        private static Grpc.Core.Server Run(string[] args,
                                            out IServiceHealth health)
        {
            Grpc.Core.Server server;

            try
            {
                MicroserverArguments arguments;
                string configFilePath;
                if (!TryGetArgumentsFromConfigFile(args, _configFileName, out arguments,
                                                   out configFilePath))
                {
                    var parsedArgs = Parser.Default.ParseArguments <MicroserverArguments>(args);

                    parsedArgs.WithParsed(a => { arguments = a; });
                }

                ConfigureLogging(arguments.VerboseLogging, _logConfigFileName);

                // Read the RuntimeUtils.Version to initialize it and use fall-back implementation
                // to avoid subsequent hang once the license has been initialized (this is probably
                // only relevant for 10.x).
                _msg.DebugFormat("Installed ArcGIS Version: {0}.", RuntimeUtils.Version);

                if (configFilePath != null)
                {
                    _msg.InfoFormat("Using service configuration defined in {0}", configFilePath);
                }
                else
                {
                    _msg.DebugFormat(
                        "Program was called with the following command line arguments: {0}{1}",
                        Environment.NewLine, arguments);
                }

                _msg.DebugFormat("Host: {0}", arguments.HostName);
                _msg.DebugFormat("Port: {0}", arguments.Port);

                _msg.InfoFormat("Checking out ArcGIS license...");

                ComUtils.ExecuteInStaThread(CheckoutLicense);

                EnvironmentUtils.SetConfigurationDirectoryProvider(
                    ConfigurationUtils.GetAppDataConfigDirectoryProvider());

                server = StartServer(arguments, out health);
            }
            catch (Exception ex)
            {
                _msg.Error("An error occurred in QA microservice startup.", ex);
                throw;
            }

            return(server);
        }
Example #7
0
        /// <summary>
        /// Starts the grpc server, binds the <see cref="QualityVerificationGrpcImpl"/> together
        /// with the <see cref="IServiceHealth"/> implementation and returns a handle for both.
        /// </summary>
        /// <param name="arguments">The microserver command line / config arguments.</param>
        /// <param name="inputsFactoryMethod">The factory method that creates the
        /// <see cref="IBackgroundVerificationInputs"/> instance. If no factory is proveded, only
        /// stand-alone verification (such as XML) can be used.</param>
        /// <param name="checkout3dAnalyst"></param>
        /// <param name="markUnhealthyOnExceptions"></param>
        /// <returns></returns>
        public static StartedGrpcServer StartVerificationServer(
            [NotNull] MicroserverArguments arguments,
            [CanBeNull]
            Func <VerificationRequest, IBackgroundVerificationInputs> inputsFactoryMethod,
            bool checkout3dAnalyst,
            bool markUnhealthyOnExceptions)
        {
            var healthService = new HealthServiceImpl();

            IServiceHealth health = new ServiceHealth(healthService);

            var wuVerificationServiceImpl =
                new QualityVerificationGrpcImpl(inputsFactoryMethod,
                                                arguments.MaxParallel)
            {
                Checkout3DAnalyst = checkout3dAnalyst
            };

            if (markUnhealthyOnExceptions)
            {
                wuVerificationServiceImpl.Health = health;
            }

            health.SetStatus(wuVerificationServiceImpl.GetType(), true);

            ServerCredentials serverCredentials =
                GrpcServerUtils.GetServerCredentials(arguments.Certificate,
                                                     arguments.PrivateKeyFile,
                                                     arguments.EnforceMutualTls);

            var oneGb = (int)Math.Pow(1024, 3);

            IList <ChannelOption> channelOptions = GrpcServerUtils.CreateChannelOptions(oneGb);

            var server =
                new Grpc.Core.Server(channelOptions)
            {
                Services =
                {
                    QualityVerificationGrpc.BindService(wuVerificationServiceImpl),
                    Health.BindService(healthService)
                },
                Ports =
                {
                    new ServerPort(arguments.HostName, arguments.Port, serverCredentials)
                }
            };

            server.Start();

            _msg.InfoFormat("Service is listening on host {0}, port {1}.", arguments.HostName,
                            arguments.Port);

            return(new StartedGrpcServer(server, health));
        }
Example #8
0
        private static void AddOrUpdateObjectType([NotNull] ObjectDataset objectDataset,
                                                  [NotNull] Subtype subtype,
                                                  int subtypeIndex,
                                                  [NotNull] IEnumerable <Subtype> allSubtypes)
        {
            Assert.ArgumentNotNull(subtype, nameof(subtype));
            Assert.ArgumentNotNull(allSubtypes, nameof(allSubtypes));

            ObjectType objectType = GetObjectType(objectDataset, subtype, allSubtypes);

            if (objectType == null)
            {
                objectType = new ObjectType(objectDataset, subtype.Code, subtype.Name);

                _msg.InfoFormat("Adding object type {0}", objectType.Name);

                objectDataset.AddObjectType(subtype.Code, subtype.Name);
            }
            else
            {
                // object type already registered

                if (objectType.Deleted)
                {
                    _msg.WarnFormat(
                        "Object type {0} ({1}) was registered as deleted, but exists now. " +
                        "Resurrecting it...",
                        objectType.Name, objectType.SubtypeCode);

                    objectType.RegisterExisting();
                }

                // update properties
                if (!Equals(objectType.Name, subtype.Name))
                {
                    _msg.InfoFormat("Updating name of object type {0} to {1}",
                                    objectType.Name, subtype.Name);

                    objectType.UpdateName(subtype.Name);
                }

                if (!Equals(objectType.SubtypeCode, subtype.Code))
                {
                    _msg.InfoFormat("Updating subtype code of object type {0} from {1} to {2}",
                                    objectType.Name, objectType.SubtypeCode, subtype.Code);

                    objectType.UpdateSubtypeCode(subtype.Code);
                }
            }

            // configure the object type
            objectType.SortOrder = subtypeIndex;
        }
Example #9
0
        private static Grpc.Core.Server Run(string[] args,
                                            out IServiceHealth health)
        {
            Grpc.Core.Server server;

            try
            {
                MicroserverArguments arguments;
                string configFilePath;
                if (!ConfigurationUtils.TryGetArgumentsFromConfigFile(
                        args, _configFileName, out arguments, out configFilePath))
                {
                    var parsedArgs = Parser.Default.ParseArguments <MicroserverArguments>(args);

                    parsedArgs.WithParsed(a => { arguments = a; });
                }

                ConfigureLogging(arguments.VerboseLogging, _logConfigFileName);

                if (configFilePath != null)
                {
                    _msg.InfoFormat("Using service configuration defined in {0}", configFilePath);
                }
                else
                {
                    _msg.DebugFormat(
                        "Program was called with the following command line arguments: {0}{1}",
                        Environment.NewLine, arguments);
                }

                _msg.DebugFormat("Host: {0}", arguments.HostName);
                _msg.DebugFormat("Port: {0}", arguments.Port);

                _msg.InfoFormat("Checking out ArcGIS license...");

                ArcGISLicenses.InitializeAo11();

                EnvironmentUtils.SetConfigurationDirectoryProvider(
                    ConfigurationUtils.GetAppDataConfigDirectoryProvider());

                server = StartServer(arguments, out health);
            }
            catch (Exception ex)
            {
                _msg.Error("An error occurred in QA microservice startup.", ex);
                throw;
            }

            return(server);
        }
Example #10
0
 public void LogSuccessfulCut()
 {
     if (ResultGeometriesByFeature.Count == 1)
     {
         _msg.InfoFormat("The selected feature was cut into {0} features",
                         GetResultPolygonCount(ResultGeometriesByFeature));
     }
     else
     {
         _msg.InfoFormat("{0} features were cut into {1} features",
                         ResultGeometriesByFeature.Count,
                         GetResultPolygonCount(ResultGeometriesByFeature));
     }
 }
Example #11
0
        /// <summary>
        /// Creates the server credentials using either two PEM files or a certificate from the
        /// Certificate Store.
        /// </summary>
        /// <param name="certificate">The certificate store's certificate (subject or thumbprint)
        /// or the PEM file containing the certificate chain.</param>
        /// <param name="privateKeyFilePath">The PEM file containing the private key (only if the
        /// certificate was provided by a PEM file</param>
        /// <param name="enforceMutualTls">Enforce client authentication.</param>
        /// <returns></returns>
        public static ServerCredentials GetServerCredentials(
            [CanBeNull] string certificate,
            [CanBeNull] string privateKeyFilePath,
            bool enforceMutualTls = false)
        {
            if (string.IsNullOrEmpty(certificate))
            {
                _msg.InfoFormat("Certificate was not provided. Using insecure credentials.");

                return(ServerCredentials.Insecure);
            }

            KeyPair certificateKeyPair =
                TryGetServerCertificateKeyPair(certificate, privateKeyFilePath);

            if (certificateKeyPair == null)
            {
                return(ServerCredentials.Insecure);
            }

            List <KeyCertificatePair> keyCertificatePairs =
                new List <KeyCertificatePair>
            {
                new KeyCertificatePair(
                    certificateKeyPair.PublicKey, certificateKeyPair.PrivateKey)
            };

            string rootCertificatesAsPem =
                CertificateUtils.GetUserRootCertificatesInPemFormat();

            if (_msg.IsVerboseDebugEnabled)
            {
                _msg.DebugFormat("Trusted root credentials provided: {0}",
                                 rootCertificatesAsPem);
            }

            // If not required, still verify the client certificate, if presented
            var clientCertificates =
                enforceMutualTls
                                        ? SslClientCertificateRequestType.RequestAndRequireAndVerify
                                        : SslClientCertificateRequestType.RequestAndVerify;

            ServerCredentials result = new SslServerCredentials(
                keyCertificatePairs, rootCertificatesAsPem,
                clientCertificates);

            return(result);
        }
Example #12
0
        private static void ValidateConnectLines([NotNull] ICurve sourcePart,
                                                 [CanBeNull] ref IPath startSourceConnection,
                                                 [CanBeNull] ref IPath endSourceConnection,
                                                 [CanBeNull] IPath startFallback,
                                                 [CanBeNull] IPath endFallback)
        {
            startSourceConnection = startSourceConnection ?? startFallback;
            endSourceConnection   = endSourceConnection ?? endFallback;

            var fallbackAssigned = false;

            // crossing source connections
            if (startSourceConnection != null && startSourceConnection.Length > 0 &&
                endSourceConnection != null && endSourceConnection.Length > 0 &&
                InteriorIntersects(startSourceConnection, endSourceConnection))
            {
                // can happen if one (or both) is (are) prolongated
                _msg.InfoFormat(
                    "Unable to use adjust line with source prolongation. Resulting line would cross.");

                if (TryAssignFallback(ref startSourceConnection, startFallback))
                {
                    fallbackAssigned = true;
                }

                if (TryAssignFallback(ref endSourceConnection, endFallback))
                {
                    fallbackAssigned = true;
                }
            }

            if (startSourceConnection != null && endSourceConnection != null)
            {
                if (EnsureMinimumSourceReplacementLength(sourcePart, ref startSourceConnection,
                                                         ref endSourceConnection, startFallback,
                                                         endFallback))
                {
                    fallbackAssigned = true;
                }
            }

            if (fallbackAssigned)
            {
                // validate again -> fall backs could cross too
                ValidateConnectLines(sourcePart, ref startSourceConnection,
                                     ref endSourceConnection, startFallback, endFallback);
            }
        }
        public static string RenderHtmlQualitySpecification(
            [NotNull] HtmlQualitySpecification qualitySpecification,
            [NotNull] string templateFilePath,
            [NotNull] string reportFilePath,
            bool throwTemplateErrors = false)
        {
            Assert.ArgumentNotNull(qualitySpecification, nameof(qualitySpecification));
            Assert.ArgumentNotNullOrEmpty(templateFilePath, nameof(templateFilePath));
            Assert.ArgumentNotNullOrEmpty(reportFilePath, nameof(reportFilePath));
            Assert.ArgumentCondition(File.Exists(templateFilePath),
                                     "template file does not exist: {0}",
                                     (object)templateFilePath);

            _msg.DebugFormat(
                "Rendering quality specification documentation based on template {0}",
                templateFilePath);

            LiquidUtils.RegisterSafeType <HtmlQualitySpecification>();
            LiquidUtils.RegisterSafeType <HtmlTexts>();

            const string rootName = "specification";

            string output = LiquidUtils.Render(
                templateFilePath,
                throwTemplateErrors,
                new KeyValuePair <string, object>(rootName, qualitySpecification),
                new KeyValuePair <string, object>("text", new HtmlTexts()));

            _msg.DebugFormat("Writing quality specification report to {0}", reportFilePath);

            FileSystemUtils.WriteTextFile(output, reportFilePath);

            _msg.InfoFormat("Quality specification report written to {0}", reportFilePath);
            return(reportFilePath);
        }
Example #14
0
        private void ProcessSelection([NotNull] MapView activeMapView,
                                      [CanBeNull] CancelableProgressor progressor = null)
        {
            Dictionary <MapMember, List <long> > selectionByLayer = activeMapView.Map.GetSelection();

            NotificationCollection notifications       = new NotificationCollection();
            List <Feature>         applicableSelection =
                GetApplicableSelectedFeatures(selectionByLayer, notifications).ToList();

            int selectionCount = selectionByLayer.Sum(kvp => kvp.Value.Count);

            if (applicableSelection.Count > 0 &&
                (AllowNotApplicableFeaturesInSelection ||
                 applicableSelection.Count == selectionCount))
            {
                LogUsingCurrentSelection();

                AfterSelection(applicableSelection, progressor);
            }
            else
            {
                if (selectionCount > 0)
                {
                    _msg.InfoFormat(notifications.Concatenate(Environment.NewLine));
                }

                LogPromptForSelection();
                StartSelectionPhase();
            }
        }
Example #15
0
        public static bool TryGetArgumentsFromConfigFile(string[] args, string configFileName,
                                                         out MicroserverArguments arguments,
                                                         out string configFilePath)
        {
            arguments      = null;
            configFilePath = null;

            if (args.Length == 0)
            {
                _msg.InfoFormat("Getting server host/port parameters from configuration file.");

                configFilePath = GetConfigFilePath(configFileName, false);

                if (configFilePath != null)
                {
                    XmlSerializationHelper <MicroserverArguments> helper =
                        new XmlSerializationHelper <MicroserverArguments>();

                    arguments = helper.ReadFromFile(configFilePath);
                    return(true);
                }
            }

            return(false);
        }
Example #16
0
        private static void CreateIndex([NotNull] IssueFeatureWriter writer,
                                        [CanBeNull] ITrackCancel trackCancel,
                                        bool ignoreErrors)
        {
            _msg.InfoFormat(writer.WriteCount == 1
                                                ? "Creating spatial index for {0} issue feature in '{1}'"
                                                : "Creating spatial index for {0} issue features in '{1}'",
                            writer.WriteCount, writer.Name);

            try
            {
                writer.CreateSpatialIndex(trackCancel);
            }
            catch (Exception e)
            {
                if (!ignoreErrors)
                {
                    throw;
                }

                _msg.Debug("Error creating spatial index", e);
                _msg.WarnFormat("Error creating spatial index for feature class {0}: {1}",
                                writer.Name, e.Message);
            }
        }
Example #17
0
        public static async Task <bool> FlashResultPolygonsAsync(
            [NotNull] MapView activeView,
            [NotNull] IDictionary <Feature, Geometry> resultFeatures,
            int maxFeatureCountThreshold = 5)
        {
            if (resultFeatures.Count > maxFeatureCountThreshold)
            {
                _msg.InfoFormat("{0} have been updated (no feature flashing).",
                                resultFeatures.Count);
                return(false);
            }

            var polySymbol = SymbolFactory.Instance.DefaultPolygonSymbol;

            foreach (Geometry resultGeometry in resultFeatures.Values)
            {
                if (!(resultGeometry is Polygon poly))
                {
                    continue;
                }

                using (await activeView.AddOverlayAsync(poly,
                                                        polySymbol.MakeSymbolReference()))
                {
                    await Task.Delay(400);
                }
            }

            return(true);
        }
        private static void LogBeginVerification(
            [NotNull] QualitySpecification qualitySpecification,
            double tileSize,
            [CanBeNull] AreaOfInterest areaOfInterest)
        {
            using (_msg.IncrementIndentation("Begin quality verification"))
            {
                _msg.InfoFormat("Quality specification: {0}", qualitySpecification.Name);
                _msg.InfoFormat("Verification tile size: {0}", tileSize);

                if (areaOfInterest != null)
                {
                    IGeometry testPerimeter = areaOfInterest.Geometry;

                    if (testPerimeter.IsEmpty)
                    {
                        _msg.Warn("Test perimeter is empty");
                    }
                    else
                    {
                        var envelope = testPerimeter as IEnvelope;

                        string message;
                        if (envelope == null)
                        {
                            Assert.ArgumentCondition(testPerimeter is IPolygon,
                                                     "Unexpected test perimeter type: {0}; must be polygon or envelope",
                                                     testPerimeter.GeometryType);

                            envelope = testPerimeter.Envelope;
                            message  = string.Format("Polygon extent: {0} x {1}",
                                                     envelope.Width, envelope.Height);
                        }
                        else
                        {
                            message = string.Format("Extent: {0} x {1}",
                                                    envelope.Width, envelope.Height);
                        }

                        using (_msg.IncrementIndentation(message))
                        {
                            _msg.InfoFormat("X-Min: {0}", envelope.XMin);
                            _msg.InfoFormat("Y-Min: {0}", envelope.YMin);
                            _msg.InfoFormat("X-Max: {0}", envelope.XMax);
                            _msg.InfoFormat("Y-Max: {0}", envelope.YMax);
                        }
                    }
                }
            }
        }
Example #19
0
 protected override void LogPromptForSelection()
 {
     _msg.InfoFormat(
         "Select one or more features by clicking or dragging a box. Options: " +
         "<br>-Press and hold SHIFT to add or remove features from the existing selection." +
         "<br>-Press CTRL and drag a box to show a list of selectable feature classes." +
         "<br>-Press CTRL and click on overlapping features to select a single feature." +
         "<br>-Press ALT and click to select all features at the click point.");
 }
        private static void EnsuresZsAreNonNan([NotNull] IGeometry inGeometry,
                                               [NotNull] IGeometry originalGeometry,
                                               [NotNull] IFeature feature)
        {
            bool zSimple = GeometryUtils.TrySimplifyZ(inGeometry);

            if (zSimple)
            {
                return;
            }

            _msg.Debug(
                "Geometry has undefined Zs, even after calculating non-simple Zs.");

            // Remaining NaNs cannot be interpolated -> e.g. because there is only 1 Z value in a part

            // make sure each part has at least some Z values, otherwise CalculateNonSimpleZs fails:
            int geometryCount = ((IGeometryCollection)inGeometry).GeometryCount;

            for (var i = 0; i < geometryCount; i++)
            {
                IGeometry part = ((IGeometryCollection)inGeometry).Geometry[i];

                if (!GeometryUtils.HasUndefinedZValues(part))
                {
                    continue;
                }

                _msg.DebugFormat("Geometry part <index> {0} has no Zs. Extrapolating...",
                                 i);

                IGeometry originalGeoInDataSpatialRef;

                // NOTE: same SR needed because ExtrapolateZs / QueryPointAndDistance does not honor different spatial refs
                if (GeometryUtils.EnsureSpatialReference(originalGeometry, feature,
                                                         out originalGeoInDataSpatialRef))
                {
                    _msg.DebugFormat(
                        "The original shape of {0} was projected from map coordinates back to the feature class' spatial reference.",
                        GdbObjectUtils.ToString(feature));
                }

                IGeometry extrapolatedPart = GeometryUtils.ExtrapolateZ(
                    part, (IPolycurve)originalGeoInDataSpatialRef);

                GeometryUtils.ReplaceGeometryPart(inGeometry, i, extrapolatedPart);

                if (originalGeoInDataSpatialRef != originalGeometry)
                {
                    Marshal.ReleaseComObject(originalGeoInDataSpatialRef);
                }

                _msg.InfoFormat(
                    "Z values for {0} were extrapolated from source geometry.",
                    GdbObjectUtils.ToString(feature));
            }
        }
        public static bool StoreTx(
            EditOperation.IEditContext editContext,
            [CanBeNull] IDictionary <Feature, Geometry> updates,
            [CanBeNull] IDictionary <Feature, IList <Geometry> > copies = null)
        {
            _msg.DebugFormat("Saving {0} updates and {1} inserts...", updates?.Count ?? 0,
                             copies?.Count ?? 0);

            if (updates != null && updates.Count > 0)
            {
                foreach (KeyValuePair <Feature, Geometry> keyValuePair in updates)
                {
                    StoreShape(keyValuePair, editContext);
                }

                _msg.InfoFormat("Successfully stored {0} updated feature(s).", updates.Count);
            }

            if (copies != null && copies.Count > 0)
            {
                foreach (KeyValuePair <Feature, IList <Geometry> > keyValuePair in copies)
                {
                    Feature          originalFeature = keyValuePair.Key;
                    IList <Geometry> newGeometries   = keyValuePair.Value;

                    FeatureClass featureClass = originalFeature.GetTable();

                    foreach (Geometry newGeometry in newGeometries)
                    {
                        RowBuffer rowBuffer = DuplicateRow(originalFeature);

                        SetShape(rowBuffer, newGeometry, featureClass);

                        Feature newFeature = featureClass.CreateRow(rowBuffer);

                        StoreShape(newFeature, newGeometry, editContext);
                    }
                }

                _msg.InfoFormat("Successfully created {0} new feature(s).", copies.Count);
            }

            return(true);
        }
Example #22
0
        private static bool ValidateFlowDirection(
            [NotNull] IFeature feature,
            [NotNull] ILinearNetworkFeatureFinder featureFinder,
            [NotNull] NotificationCollection notifications)
        {
            if (((IFeatureClass)feature.Class).ShapeType != esriGeometryType.esriGeometryPolyline)
            {
                return(true);
            }

            IGeometry newGeometry = feature.Shape;

            IPolyline polyline = (IPolyline)newGeometry;

            bool hasCorrectOrientation = false;
            bool hasWrongOrientation   = false;
            int  fromEdgeCount         = ValidateConnections(feature, LineEnd.From, featureFinder,
                                                             ref hasCorrectOrientation,
                                                             ref hasWrongOrientation);

            int toEdgeCount = ValidateConnections(feature, LineEnd.To, featureFinder,
                                                  ref hasCorrectOrientation,
                                                  ref hasWrongOrientation);

            if (!hasWrongOrientation)
            {
                return(true);
            }

            if (!hasCorrectOrientation)
            {
                // all other connections are different -> flip
                polyline.ReverseOrientation();
                feature.Shape = polyline;
                feature.Store();

                _msg.InfoFormat("Feature {0} was flipped to enforce flow direction",
                                GdbObjectUtils.ToString(feature));
                return(true);
            }

            // Mixed situation:
            if (fromEdgeCount <= 1 && toEdgeCount <= 1)
            {
                // No bifurcation or confluence but still incorrect at one end -> error?
                NotificationUtils.Add(notifications,
                                      "Feature {0} does not have a consistent flow direction with respect to its connected edges",
                                      GdbObjectUtils.ToString(feature));
                return(false);
            }

            // Confluence or bifurcation -> probably ok
            return(true);
        }
        public override async Task VerifyQuality(
            VerificationRequest request,
            IServerStreamWriter <VerificationResponse> responseStream,
            ServerCallContext context)
        {
            try
            {
                _msg.InfoFormat("Starting verification request from {0}", request.UserName);
                _msg.DebugFormat("Request details: {0}", request);

                if (Checkout3DAnalyst)
                {
                    // It must be re-checked out (but somehow it's enough to do it
                    // on the calling thread-pool thread!?)
                    Ensure3dAnalyst();
                }

                Func <ITrackCancel, ServiceCallStatus> func =
                    trackCancel => VerifyQualityCore(request, responseStream, trackCancel);

                ServiceCallStatus result =
                    await GrpcServerUtils.ExecuteServiceCall(
                        func, context, _singleStaThreadScheduler);

                _msg.InfoFormat("Verification {0}", result);
            }
            catch (Exception e)
            {
                _msg.Error($"Error verifying quality for request {request}", e);

                SendFatalException(e, responseStream);
                SetUnhealthy();
            }
        }
Example #24
0
        protected override void LogPromptForSelection()
        {
            // TODO: Only usable selection
            bool hasSelection = ActiveMapView.Map.SelectionCount > 0;

            // If the last reshape was just finished and the feature is still selected, Enter is entering the sketch mode again using the same selection
            string enterMsg =
                hasSelection
                                        ? LocalizableStrings.AdvancedReshapeTool_LogPromptForSelection_Enter
                                        : string.Empty;

            _msg.InfoFormat(LocalizableStrings.AdvancedReshapeTool_LogPromptForSelection,
                            enterMsg);
        }
        private static void WriteHtmlReport(
            [NotNull] QualitySpecification qualitySpecification,
            [NotNull] string directory,
            [NotNull] HtmlReportDefinition reportDefinition,
            [NotNull] IssueStatistics issueStatistics,
            [NotNull] XmlVerificationReport verificationReport,
            [NotNull] string verificationReportFileName,
            [CanBeNull] string issueGdbPath,
            [CanBeNull] IEnumerable <string> issueMapFilePaths,
            [NotNull] IEnumerable <string> htmlReportFileNames,
            [CanBeNull] IEnumerable <string> qualitySpecificationReportFilePaths)
        {
            Assert.ArgumentNotNull(reportDefinition, nameof(reportDefinition));
            Assert.ArgumentCondition(File.Exists(reportDefinition.TemplatePath),
                                     "Template file does not exist: {0}",
                                     reportDefinition.TemplatePath);

            string reportFilePath = Path.Combine(directory, reportDefinition.FileName);

            _msg.DebugFormat("Preparing html report model");
            var reportModel = new HtmlReportModel(qualitySpecification,
                                                  issueStatistics,
                                                  verificationReport,
                                                  directory,
                                                  verificationReportFileName,
                                                  issueGdbPath,
                                                  issueMapFilePaths,
                                                  htmlReportFileNames,
                                                  qualitySpecificationReportFilePaths,
                                                  reportDefinition);

            _msg.DebugFormat("Rendering html report based on template {0}",
                             reportDefinition.TemplatePath);

            LiquidUtils.RegisterSafeType <HtmlReportModel>();
            LiquidUtils.RegisterSafeType <HtmlTexts>();

            string output = LiquidUtils.Render(
                reportDefinition.TemplatePath,
                new KeyValuePair <string, object>("report", reportModel),
                new KeyValuePair <string, object>("text", new HtmlTexts()));

            _msg.DebugFormat("Writing html report to {0}", reportFilePath);
            FileSystemUtils.WriteTextFile(output, reportFilePath);

            _msg.InfoFormat("Html report written to {0}", reportFilePath);
        }
Example #26
0
        /// <summary>
        /// Starts the grpc server, binds the <see cref="QualityVerificationGrpcImpl"/> together
        /// with the <see cref="IServiceHealth"/> implementation and returns a handle for both.
        /// </summary>
        /// <param name="arguments">The microserver command line / config arguments.</param>
        /// <param name="inputsFactory">The factory method that creates the
        /// <see cref="IBackgroundVerificationInputs"/> instance. If no factory is proveded, only
        /// stand-alone verification (such as XML) can be used.</param>
        /// <param name="markUnhealthyOnExceptions"></param>
        /// <returns></returns>
        public static StartedGrpcServer <QualityVerificationGrpcImpl> StartVerificationServer(
            [NotNull] MicroserverArguments arguments,
            [CanBeNull] Func <VerificationRequest, IBackgroundVerificationInputs> inputsFactory,
            bool markUnhealthyOnExceptions)
        {
            var healthService = new HealthServiceImpl();

            IServiceHealth health = new ServiceHealth(healthService);

            LoadReportingGrpcImpl loadReporting = new LoadReportingGrpcImpl();

            ServiceLoad serviceLoad = new ServiceLoad(arguments.MaxParallel);

            loadReporting.AllowMonitoring(nameof(QualityVerificationGrpc), serviceLoad);

            var verificationServiceImpl =
                new QualityVerificationGrpcImpl(inputsFactory,
                                                arguments.MaxParallel)
            {
                CurrentLoad = serviceLoad
            };

            if (markUnhealthyOnExceptions)
            {
                verificationServiceImpl.Health = health;
            }

            health.SetStatus(verificationServiceImpl.GetType(), true);

            Grpc.Core.Server server =
                StartGrpcServer(arguments, verificationServiceImpl, healthService, loadReporting);

            _msg.InfoFormat("Service is listening on host {0}, port {1}.", arguments.HostName,
                            arguments.Port);

            return(new StartedGrpcServer <QualityVerificationGrpcImpl>(
                       server, verificationServiceImpl, health));
        }
        internal static void LogQualityVerification(
            [NotNull] QualityVerification verification)
        {
            try
            {
                var sb = new StringBuilder();

                sb.AppendLine(verification.Cancelled
                                                      ? "The quality verification was cancelled"
                                                      : "Quality verified");

                int conditionCount = verification.ConditionVerifications.Count;

                sb.AppendFormat("- {0:N0} quality condition{1} verified",
                                conditionCount, conditionCount == 1
                                                                        ? ""
                                                                        : "s");
                sb.AppendLine();

                int issueCount = verification.IssueCount;
                if (issueCount == 0)
                {
                    sb.AppendLine("- No issues found");
                }
                else
                {
                    sb.AppendFormat(issueCount == 1
                                                                ? "- {0:N0} issue found"
                                                                : "- {0:N0} issues found",
                                    issueCount);
                    sb.AppendLine();

                    sb.AppendFormat("  - Errors: {0:N0}", verification.ErrorCount);
                    sb.AppendLine();

                    sb.AppendFormat("  - Warnings: {0:N0}", verification.WarningCount);
                    sb.AppendLine();

                    if (verification.RowsWithStopConditions > 0)
                    {
                        sb.AppendFormat("  - Number of rows with a stop condition error: {0:N0}",
                                        verification.RowsWithStopConditions);
                        sb.AppendLine();
                    }
                }

                if (!verification.Cancelled)
                {
                    sb.AppendLine(verification.Fulfilled
                                                              ? "- The quality specification is fulfilled"
                                                              : "- The quality specification is not fulfilled");
                }

                if (verification.Fulfilled)
                {
                    _msg.InfoFormat(sb.ToString());
                }
                else
                {
                    _msg.WarnFormat(sb.ToString());
                }

                LogVerificationDetails(verification);
            }
            catch (Exception e)
            {
                _msg.Warn("Error writing report to log", e);
                // continue
            }
        }
Example #28
0
        public static void Import(
            [CanBeNull] string importWhereClause,
            [NotNull] IList <IObjectClass> targetExceptionClasses,
            [NotNull] IList <IObjectClass> importExceptionClasses,
            [NotNull] string importOriginValue,
            DateTime importDate)
        {
            IIssueTableFields importFields = GetImportFields(importExceptionClasses);
            IIssueTableFields targetFields = GetTargetFields(targetExceptionClasses);

            IDictionary <Guid, QualityConditionExceptions> targetExceptionsByConditionVersion;

            using (_msg.IncrementIndentation(
                       "Reading existing exceptions in target workspace"))
            {
                targetExceptionsByConditionVersion = ReadTargetExceptions(targetExceptionClasses,
                                                                          targetFields);
            }

            var replacedExceptionObjects = new Dictionary <esriGeometryType, HashSet <int> >();

            using (_msg.IncrementIndentation("Importing new exceptions from issue datasets...")
                   )
            {
                foreach (ITable importTable in importExceptionClasses.Cast <ITable>())
                {
                    using (_msg.IncrementIndentation("from {0}...",
                                                     DatasetUtils.GetName(importTable)))
                    {
                        ITable targetTable = GetTargetTable(importTable, targetExceptionClasses);
                        if (targetTable == null)
                        {
                            _msg.Warn(
                                "No matching table in target workspace, ignoring import table");
                            continue;
                        }

                        var factory = new ExceptionObjectFactory(
                            importTable, importFields,
                            defaultStatus: ExceptionObjectStatus.Inactive);

                        var newCount     = 0;
                        var updateCount  = 0;
                        var ignoredCount = 0;

                        using (var writer = new ExceptionWriter(importTable, importFields,
                                                                targetTable, targetFields))
                        {
                            foreach (IRow row in GdbQueryUtils.GetRows(importTable,
                                                                       GetQueryFilter(
                                                                           importWhereClause),
                                                                       recycle: true))
                            {
                                int  matchCount;
                                bool added = ImportException(row, importOriginValue, importDate,
                                                             factory,
                                                             targetExceptionsByConditionVersion,
                                                             replacedExceptionObjects,
                                                             writer,
                                                             out matchCount);
                                if (!added)
                                {
                                    ignoredCount++;
                                }
                                else if (matchCount == 0)
                                {
                                    newCount++;
                                }
                                else
                                {
                                    updateCount++;
                                }
                            }
                        }

                        _msg.InfoFormat("{0:N0} exception(s) imported as new", newCount);
                        _msg.InfoFormat("{0:N0} exception(s) imported as updates", updateCount);
                        if (ignoredCount > 0)
                        {
                            _msg.InfoFormat("{0:N0} exception(s) ignored", ignoredCount);
                        }
                    }
                }
            }

            using (_msg.IncrementIndentation("Processing replaced exceptions..."))
            {
                foreach (ITable targetTable in targetExceptionClasses.Cast <ITable>())
                {
                    using (_msg.IncrementIndentation("Target table {0}...",
                                                     DatasetUtils.GetName(targetTable)))
                    {
                        int fixedStatusCount;
                        int updateCount = ProcessReplacedExceptions(targetTable, targetFields,
                                                                    replacedExceptionObjects,
                                                                    importDate,
                                                                    out fixedStatusCount);

                        _msg.InfoFormat("{0:N0} replaced exception(s) updated", updateCount);
                        if (fixedStatusCount > 0)
                        {
                            _msg.InfoFormat("Status value of {0:N0} old exception version(s) fixed",
                                            fixedStatusCount);
                        }
                    }
                }
            }
        }
Example #29
0
        public static IEnvelope GetFullExtent(
            [NotNull] IEnumerable <IGeoDataset> geoDatasets)
        {
            IEnvelope extentUnion    = null;
            double    maxXyTolerance = 0;

            foreach (IGeoDataset geoDataset in geoDatasets)
            {
                if (geoDataset == null)
                {
                    continue;
                }

                IEnvelope datasetExtent = geoDataset.Extent;

                if (datasetExtent == null || datasetExtent.IsEmpty)
                {
                    continue;
                }

                string datasetName = geoDataset is IDataset
                                                             ? ((IDataset)geoDataset).Name
                                                             : "raster";
                _msg.DebugFormat("Adding extent of {0}: {1}",
                                 datasetName,
                                 GeometryUtils.Format(datasetExtent));

                var featureClass = geoDataset as IFeatureClass;
                if (featureClass != null)
                {
                    double xyTolerance;
                    if (DatasetUtils.TryGetXyTolerance(featureClass, out xyTolerance))
                    {
                        maxXyTolerance = Math.Max(maxXyTolerance, xyTolerance);
                    }
                }

                if (extentUnion == null)
                {
                    extentUnion = datasetExtent;
                }
                else
                {
                    double previousArea = ((IArea)extentUnion).Area;

                    extentUnion.Union(datasetExtent);

                    double area = ((IArea)extentUnion).Area;

                    if ((area - previousArea) / area > 0.5)
                    {
                        _msg.DebugFormat("Enlarged test extent by more than half: {0}",
                                         datasetName);
                    }
                }
            }

            if (extentUnion != null)
            {
                _msg.InfoFormat("Full test extent of all datasets: {0}",
                                GeometryUtils.Format(extentUnion));

                extentUnion = EnsureMinimumSize(extentUnion, maxXyTolerance * 10);
            }

            return(extentUnion);
        }
Example #30
0
 public void ReportInfo(string format, params object[] args)
 {
     _msg.InfoFormat(format, args);
 }