Exemple #1
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                // Retrieve the parameter in which the list of MXDs will be stored
                WmauParameterMap  paramMap  = new WmauParameterMap(paramValues);
                IGPParameter3     param     = paramMap.GetParam(C_PARAM_MAP_DOCUMENT_LIST);
                IGPParameterEdit3 paramEdit = paramMap.GetParamEdit(C_PARAM_MAP_DOCUMENT_LIST);

                // Set up the multi-value objects
                IGPMultiValue mvValue = new GPMultiValueClass();
                mvValue.MemberDataType = param.DataType;

                // Get the list of MXD names and add them all to the multivalue
                SortedList <string, string> mapDocuments = this.ListMapDocumentsInDatabase();
                foreach (string mapDocName in mapDocuments.Keys)
                {
                    IGPString strVal = new GPStringClass();
                    strVal.Value = mapDocName;
                    mvValue.AddValue(strVal as IGPValue);
                    msgs.AddMessage("Map Document: " + mapDocName);
                }

                paramEdit.Value = (IGPValue)mvValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Close the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXJob3           job        = jobManager.GetJob(m_jobToClose) as IJTXJob3;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;

                if (job.Stage != jtxJobStage.jtxJobStageClosed && !job.CanClose())
                {
                    throw new WmauException(WmauErrorCodes.C_CANNOT_CLOSE_JOB_ERROR);
                }

                msgs.AddMessage("Closing job " + m_jobToClose + " (" + job.Name + ")");
                job.Close();

                // Once the job is closed, do the other things that still need to be handled
                // separately (status updates, notifications, ...)
                Common.WmauHelperFunctions.UpdateJobStatus(this.WmxDatabase, job);
                job.Store();

                job.LogJobAction(
                    configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_CLOSE_JOB),
                    null,
                    string.Empty);
                Common.WmauHelperFunctions.SendNotification(
                    ESRI.ArcGIS.JTX.Utilities.Constants.NOTIF_JOB_CLOSED,
                    this.WmxDatabase,
                    job);

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_JOB_CLOSED);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobToClose;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                WmauParameterMap   paramMap  = new WmauParameterMap(paramValues);
                IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;

                // Determine which query the user has selected
                SortedList <string, IJTXJobQuery> queryMap = new SortedList <string, IJTXJobQuery>();
                AddQueriesFromContainer(configMgr.GetPublicQueryContainer(), string.Empty, queryMap);
                if (!queryMap.Keys.Contains(m_queryName))
                {
                    throw new WmauException(WmauErrorCodes.C_UNKNOWN_QUERY_ERROR);
                }

                // Run the selected job query
                IJTXJobQuery tempQuery = queryMap[m_queryName];

                // TODO: Change this to use ".Evaluate()" once it's fixed
                List <int> jobIds = ParseJobIdsFromXml(tempQuery.EvaluateXML());
                jobIds.Sort();

                // Store the job IDs from the query into the output GP param
                IGPMultiValue outputValues = new GPMultiValueClass();
                outputValues.MemberDataType = paramMap.GetParam(C_PARAM_OUT_JOB_ID_LIST).DataType;
                for (int i = 0; i < jobIds.Count; i++)
                {
                    IGPLong jobIdVal = new GPLongClass();
                    jobIdVal.Value = jobIds[i];
                    outputValues.AddValue(jobIdVal as IGPValue);
                    msgs.AddMessage("Found job: " + jobIds[i]);
                }

                paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID_LIST).Value = (IGPValue)outputValues;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                WmauParameterMap paramMap = new WmauParameterMap(paramValues);

                // Retrieve the parameter in which the list of workbook names will be stored
                IGPParameter3     param       = paramMap.GetParam(C_PARAM_JOB_ID_LIST);
                IGPParameterEdit3 paramEdit   = paramMap.GetParamEdit(C_PARAM_JOB_ID_LIST);
                IGPParameter3     filterParam = paramMap.GetParam(C_PARAM_SQL_QUERY_FILTER);

                // Get the multivalue object into which the output will be stored
                IGPMultiValue outputValues = new GPMultiValueClass();
                outputValues.MemberDataType = param.DataType;
                for (int i = 0; i < outputValues.Count; i++)
                {
                    outputValues.Remove(i);
                }

                // Get the list of job IDs and add them all to the multivalue
                SortedList <int, string> jobs = this.ListJobsInDatabase(filterParam.Value.GetAsText());
                msgs.AddMessage("Jobs matching query:");
                foreach (KeyValuePair <int, string> item in jobs)
                {
                    IGPLong value = new GPLongClass();
                    value.Value = item.Key;
                    outputValues.AddValue(value as IGPValue);
                    msgs.AddMessage("  " + value.Value.ToString() + " (" + item.Value + ")");
                }

                paramEdit.Value = (IGPValue)outputValues;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
Exemple #5
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Retrieve the parameter in which the list of workbook names will be stored
                WmauParameterMap  paramMap  = new WmauParameterMap(paramValues);
                IGPParameter3     param     = paramMap.GetParam(C_PARAM_TAM_WORKBOOK_LIST);
                IGPParameterEdit3 paramEdit = paramMap.GetParamEdit(C_PARAM_TAM_WORKBOOK_LIST);

                // Set up the multi-value objects
                IGPMultiValue mvValue = new GPMultiValueClass();
                mvValue.MemberDataType = param.DataType;

                // Get the list of TA workbook names and add them all to the multivalue
                SortedList <string, string> tamWorkbooks = this.ListTamWorkbooksInDatabase();
                foreach (string workbookAlias in tamWorkbooks.Keys)
                {
                    IGPString strVal = new GPStringClass();
                    strVal.Value = workbookAlias;
                    mvValue.AddValue(strVal as IGPValue);
                    msgs.AddMessage("Workbook: " + workbookAlias);
                }

                paramEdit.Value = (IGPValue)mvValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Update the internal parameters used by this GP tool
                string styleFileName = this.DetermineStyleFileName(this.m_xmlFilePath);

                // Retrieve the TA workbook
                IJTXConfiguration3 defaultDbReadonly      = WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXTaskAssistantWorkflowRecord tamRecord = defaultDbReadonly.GetTaskAssistantWorkflowRecord(this.m_sourceName);

                // Delete any existing workflow or style files that we're going to replace
                this.DeleteFile(this.m_xmlFilePath);
                this.DeleteFile(styleFileName);

                // Save the TAM workbook data out to file
                this.SaveStringToXmlFile(tamRecord.WorkflowXML, this.m_xmlFilePath);
                this.SaveStringToXmlFile(tamRecord.StyleXML, styleFileName);

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (System.IO.IOException ioEx)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_FILE_ACCESS_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ioEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_TAM_DOWNLOAD_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
        }
        public static void WriteBuildErrorsToTurnFC(string outputFileGdbPath, string fdsName, string turnFCName,
                                                    IGPMessages messages, ITrackCancel trackcancel)
        {
            messages.AddMessage("Writing build errors to the turn feature class...");

            // Create a new field on the turn feature class for the build errors

            Geoprocessor gp = new Geoprocessor();

            gp.AddOutputsToMap = false;
            AddField addFieldTool = new AddField();

            addFieldTool.in_table   = outputFileGdbPath + "\\" + fdsName + "\\" + turnFCName;
            addFieldTool.field_name = "BuildError";
            addFieldTool.field_type = "SHORT";
            gp.Execute(addFieldTool, trackcancel);

            // Open the turn feature class in the file geodatabase and find the BuildError field on it

            Type          factoryType     = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var           wsf             = Activator.CreateInstance(factoryType) as IWorkspaceFactory;
            var           fws             = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            IFeatureClass turnFC          = fws.OpenFeatureClass(turnFCName);
            int           buildErrorField = turnFC.FindField("BuildError");

            // Open the BuildErrors.txt file generated from building the network dataset

            string   s, leftTrimmedString, oidString;
            int      leftTrimAmt = 24 + turnFCName.Length;
            IFeature feat        = null;

            string[] buildErrorsFiles = System.IO.Directory.GetFiles(Environment.GetEnvironmentVariable("TEMP"), "BuildErrors.txt", System.IO.SearchOption.AllDirectories);
            string   buildErrorsFile  = buildErrorsFiles[0];

            System.IO.StreamReader f = new System.IO.StreamReader(buildErrorsFile);

            // Loop through the BuildErrors.txt file and write the value 1 for each entry found.

            while ((s = f.ReadLine()) != null)
            {
                // ignore blank lines
                if (s.Length == 0)
                {
                    continue;
                }

                // ignore build errors not dealing with the turn source
                if (s.Remove(leftTrimAmt) != ("SourceName: " + turnFCName + ", ObjectID: "))
                {
                    continue;
                }

                leftTrimmedString = s.Substring(leftTrimAmt);
                oidString         = leftTrimmedString.Remove(leftTrimmedString.IndexOf(", "));
                feat = turnFC.GetFeature(Convert.ToInt32(oidString, System.Globalization.CultureInfo.InvariantCulture));
                feat.set_Value(buildErrorField, 1);
                feat.Store();
            }
            f.Close();
        }
        private void DumpIt(string label, string idt, object o, IGPMessages ms, bool recurse)
        {
            if (o == null)
            {
                ms.AddMessage(label + ": null.");
                return;
            }

            AOIntrospector ir = new AOIntrospector(o);

            ms.AddMessage(label + ":");
            foreach (System.Type t in ir.GetImplementedInterfaces())
            {
                ms.AddMessage(idt + "(" + t.Name + "):");
                foreach (PropertyInfo pi in t.GetProperties())
                {
                    if (pi.CanRead)
                    {
                        try {
                            if (pi.GetIndexParameters().Length == 0)
                            {
                                object propv = pi.GetValue(o, null);
                                if (propv != null)
                                {
                                    if (pi.PropertyType.IsValueType || typeof(string).IsAssignableFrom(pi.PropertyType))
                                    {
                                        ms.AddMessage(idt + idt + "." + pi.Name + " = " + propv.ToString());
                                    }
                                    else if (recurse)
                                    {
                                        DumpIt(idt + idt + "." + pi.Name, idt + idt + idt, propv, ms, false);
                                    }
                                    else
                                    {
                                        ms.AddMessage(idt + idt + "." + pi.Name + " = {{" + propv.ToString() + "}}");
                                    }
                                }
                                else
                                {
                                    ms.AddMessage(idt + idt + "." + pi.Name + " = (null)");
                                }
                            }
                            else
                            {
                                ms.AddMessage(idt + idt + "." + pi.Name + " = []");
                            }
                        } catch (Exception e) {
                            ms.AddMessage(idt + idt + "." + pi.Name + " = E{" + e.GetType().Name + ":" + e.Message + "}");
                        }
                    }
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                // Retrieve the MXD and delete it
                IJTXConfiguration3 configMgr = WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXMap            map       = configMgr.GetJTXMap(m_mxdName);
                configMgr.DeleteJTXMap(map.ID);

                // Update the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_MXD_NAME);
                IGPString         outValue     = new GPStringClass();
                outValue.Value     = m_mxdName;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_DELETE_MXD_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            finally
            {
                // Release any COM objects here!
            }
        }
 /// <summary>
 /// Writes a message both to the GP messages object and to a log file (if
 /// one has been specified)
 /// </summary>
 /// <param name="message">The message to be written</param>
 /// <param name="msgs">The IGPMessages object to which the string will be written</param>
 /// <param name="writer">
 /// An optional StreamWriter object (opened log file) to which the messages will
 /// be written
 /// </param>
 private void RecordMessage(string message, IGPMessages msgs, StreamWriter writer)
 {
     if (msgs != null)
     {
         msgs.AddMessage("  " + message);
     }
     if (writer != null)
     {
         writer.WriteLine(message);
     }
 }
Exemple #11
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Assign the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXJob3           job        = jobManager.GetJob(m_jobId) as IJTXJob3;

                // As of Jan. 2011, the core Workflow Manager libraries do not
                // seem to check if the user has the privilege to add a comment
                // if a job as a hold on it.  So run the check here.
                IJTXJobHolds jobHolds = job as IJTXJobHolds;
                if (jobHolds.Holds != null &&
                    jobHolds.Holds.Count > 0 &&
                    !CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_CAN_ADD_COMMENTS_FOR_HELD_JOBS))
                {
                    throw new WmauException(WmauErrorCodes.C_NO_ADD_COMMENTS_HELD_JOBS_ERROR);
                }

                // If we get this far, then add the comment to the job.
                IJTXActivityType commentType = configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_COMMENT);
                job.LogJobAction(commentType, null, m_comment);
                job.Store();

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Assign the requested job
            try
            {
                IJTXJobManager         jobManager = this.WmxDatabase.JobManager;
                IJTXWorkflowExecution3 jobExec    = jobManager.GetJob(m_jobId) as IJTXWorkflowExecution3;

                // Don't try to deal with the case of multiple active steps
                int[] currentStepIds = jobExec.GetCurrentSteps();
                if (currentStepIds.Length != 1)
                {
                    throw new WmauException(WmauErrorCodes.C_NO_OR_MULTIPLE_STEPS_ERROR);
                }

                jobExec.RunStepChecks(currentStepIds[0], true);
                IJTXExecuteInfo execInfo = jobExec.RunStep(currentStepIds[0], false, true, false, this);
                if (execInfo.ThrewError)
                {
                    throw new WmauException(
                              WmauErrorCodes.C_JOB_EXECUTION_ERROR,
                              new Exception(execInfo.ErrorCode.ToString() + ": " + execInfo.ErrorDescription));
                }

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        public static void WriteBuildErrorsToTurnFC(string outputFileGdbPath, string fdsName, string turnFCName,
                                                    IGPMessages messages, ITrackCancel trackcancel)
        {
            messages.AddMessage("Writing build errors to the turn feature class...");

            // Create a new field on the turn feature class for the build errors

            Geoprocessor gp = new Geoprocessor();
            gp.AddOutputsToMap = false;
            AddField addFieldTool = new AddField();
            addFieldTool.in_table = outputFileGdbPath + "\\" + fdsName + "\\" + turnFCName;
            addFieldTool.field_name = "BuildError";
            addFieldTool.field_type = "SHORT";
            gp.Execute(addFieldTool, trackcancel);

            // Open the turn feature class in the file geodatabase and find the BuildError field on it

            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var wsf = Activator.CreateInstance(factoryType) as IWorkspaceFactory;
            var fws = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            IFeatureClass turnFC = fws.OpenFeatureClass(turnFCName);
            int buildErrorField = turnFC.FindField("BuildError");

            // Open the BuildErrors.txt file generated from building the network dataset

            string s, leftTrimmedString, oidString;
            int leftTrimAmt = 24 + turnFCName.Length;
            IFeature feat = null;
            string[] buildErrorsFiles = System.IO.Directory.GetFiles(Environment.GetEnvironmentVariable("TEMP"), "BuildErrors.txt", System.IO.SearchOption.AllDirectories);
            string buildErrorsFile = buildErrorsFiles[0];
            System.IO.StreamReader f = new System.IO.StreamReader(buildErrorsFile);

            // Loop through the BuildErrors.txt file and write the value 1 for each entry found.

            while ((s = f.ReadLine()) != null)
            {
                // ignore blank lines
                if (s.Length == 0)
                    continue;

                // ignore build errors not dealing with the turn source
                if (s.Remove(leftTrimAmt) != ("SourceName: " + turnFCName + ", ObjectID: "))
                    continue;

                leftTrimmedString = s.Substring(leftTrimAmt);
                oidString = leftTrimmedString.Remove(leftTrimmedString.IndexOf(", "));
                feat = turnFC.GetFeature(Convert.ToInt32(oidString, System.Globalization.CultureInfo.InvariantCulture));
                feat.set_Value(buildErrorField, 1);
                feat.Store();
            }
            f.Close();
        }
Exemple #14
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Send the notification
                IJTXJobManager jobManager = this.WmxDatabase.JobManager;
                Common.WmauHelperFunctions.SendNotification(
                    m_notificationName, this.WmxDatabase, jobManager.GetJob(m_jobId));

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Back up the database
            IJTXTransfer transfer = WmxDatabase as IJTXTransfer;

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                msgs.AddMessage("Retrieving data from Workflow Manager database...");
                string xml = transfer.ExportConfiguration();

                // Pretty-print the JXL file, if the user has selected that option
                if (this.m_prettyPrint)
                {
                    msgs.AddMessage("Making the data more easily human-readable...");
                    XmlDocument   xmlDoc        = new XmlDocument();
                    XmlTextReader xmlTextReader = new XmlTextReader(xml, XmlNodeType.Document, null);
                    xmlTextReader.WhitespaceHandling = WhitespaceHandling.None;
                    xmlDoc.Load(xmlTextReader);
                    xmlTextReader.Close();

                    msgs.AddMessage("Saving data to file...");
                    System.IO.TextWriter textWriter    = new System.IO.StreamWriter(this.m_jxlFilePath, false, System.Text.Encoding.UTF8, xml.Length);
                    XmlTextWriter        xmlTextWriter = new XmlTextWriter(textWriter);
                    xmlTextWriter.Formatting = Formatting.Indented;
                    xmlDoc.Save(xmlTextWriter);
                    xmlTextWriter.Close();
                    textWriter.Close();
                }
                else
                {
                    msgs.AddMessage("Saving data to file...");
                    System.IO.TextWriter textWriter = new System.IO.StreamWriter(this.m_jxlFilePath, false, System.Text.Encoding.UTF8, xml.Length);
                    textWriter.Write(xml);
                    textWriter.Close();
                }

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_JXL_BACKUP_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens }
                }
            }
        }
        private void CreateSignposts(string inputSignsTablePath, string outputFileGdbPath, IGPMessages messages, ITrackCancel trackcancel)
        {
            // Open the input Signs table

            ITable inputSignsTable = m_gpUtils.OpenTableFromString(inputSignsTablePath);

            // Open the Streets feature class

            Type gdbFactoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var gdbWSF = Activator.CreateInstance(gdbFactoryType) as IWorkspaceFactory;
            var gdbFWS = gdbWSF.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            IFeatureClass inputLineFeatures = gdbFWS.OpenFeatureClass(StreetsFCName);

            // Create the signpost feature class and table

            IFeatureClass outputSignFeatures = SignpostUtilities.CreateSignsFeatureClass(inputLineFeatures, SignpostFCName);
            ITable outputSignDetailTable = SignpostUtilities.CreateSignsDetailTable(inputLineFeatures, SignpostJoinTableName);

            #region Find fields
            //(Validate checked that these exist)
            IFields inputTableFields = inputSignsTable.Fields;
            int inSequenceFI = inputTableFields.FindField("SEQ_NUM");
            int inExitNumFI = inputTableFields.FindField("EXIT_NUM");
            int inFromIDFI = inputTableFields.FindField("SRC_LINKID");
            int inToIDFI = inputTableFields.FindField("DST_LINKID");
            int inLangFI = inputTableFields.FindField("LANG_CODE");
            int inBranchRteIDFI = inputTableFields.FindField("BR_RTEID");
            int inDirectionFI = inputTableFields.FindField("BR_RTEDIR");
            int inToNameFI = inputTableFields.FindField("SIGN_TEXT");
            int inAccessFI = inputTableFields.FindField("SIGN_TXTTP");
            int inToLocaleFI = inputTableFields.FindField("TOW_RTEID");

            // Find output fields (we just made these)

            IFields outputSignFeatureFields = outputSignFeatures.Fields;
            int outExitNameFI = outputSignFeatureFields.FindField("ExitName");

            int[] outBranchXFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outBranchXDirFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outBranchXLngFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outTowardXFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outTowardXLngFI = new int[SignpostUtilities.MaxBranchCount];

            string indexString;

            for (int i = 0; i < SignpostUtilities.MaxBranchCount; i++)
            {
                indexString = Convert.ToString(i, System.Globalization.CultureInfo.InvariantCulture);

                outBranchXFI[i] = outputSignFeatureFields.FindField("Branch" + indexString);
                outBranchXDirFI[i] = outputSignFeatureFields.FindField("Branch" + indexString + "Dir");
                outBranchXLngFI[i] = outputSignFeatureFields.FindField("Branch" + indexString + "Lng");
                outTowardXFI[i] = outputSignFeatureFields.FindField("Toward" + indexString);
                outTowardXLngFI[i] = outputSignFeatureFields.FindField("Toward" + indexString + "Lng");
            }

            IFields outputTableFields = outputSignDetailTable.Fields;
            int outTblSignpostIDFI = outputTableFields.FindField("SignpostID");
            int outTblSequenceFI = outputTableFields.FindField("Sequence");
            int outTblEdgeFCIDFI = outputTableFields.FindField("EdgeFCID");
            int outTblEdgeFIDFI = outputTableFields.FindField("EdgeFID");
            int outTblEdgeFrmPosFI = outputTableFields.FindField("EdgeFrmPos");
            int outTblEdgeToPosFI = outputTableFields.FindField("EdgeToPos");

            // Find ID fields on referenced lines

            int inLinesOIDFI = inputLineFeatures.FindField(inputLineFeatures.OIDFieldName);
            int inLinesUserIDFI = inputLineFeatures.FindField("LINK_ID");
            int inLinesShapeFI = inputLineFeatures.FindField(inputLineFeatures.ShapeFieldName);

            #endregion

            // Get the language lookup hash

            System.Collections.Hashtable langLookup = CreateLanguageLookup();

            // Fetch all line features referenced by the input signs table.  We do the
            // "join" this hard way to support all data sources in the sample.
            // Also, for large numbers of sign records, this strategy of fetching all
            // related features and holding them in RAM could be a problem.  To fix
            // this, one could process the input sign records in batches.

            System.Collections.Hashtable lineFeaturesList = SignpostUtilities.FillFeatureCache(inputSignsTable, inFromIDFI, inToIDFI, inputLineFeatures, "LINK_ID", trackcancel);

            // Create output feature/row buffers

            IFeatureBuffer featureBuffer = outputSignFeatures.CreateFeatureBuffer();
            IFeature feature = featureBuffer as IFeature;
            IRowBuffer featureRowBuffer = featureBuffer as IRowBuffer;

            IRowBuffer tableBuffer = outputSignDetailTable.CreateRowBuffer();
            IRow row = tableBuffer as IRow;
            IRowBuffer tableRowBuffer = tableBuffer as IRowBuffer;

            // Create insert cursors.

            IFeatureCursor featureInsertCursor = outputSignFeatures.Insert(true);
            ICursor tableInsertCursor = outputSignDetailTable.Insert(true);

            // Create input cursor for the signs table we are importing

            ITableSort tableSort = new TableSortClass();
            tableSort.Fields = "SRC_LINKID, DST_LINKID, SEQ_NUM";
            tableSort.set_Ascending("SRC_LINKID", true);
            tableSort.set_Ascending("DST_LINKID", true);
            tableSort.set_Ascending("SEQ_NUM", true);
            tableSort.QueryFilter = null;
            tableSort.Table = inputSignsTable;
            tableSort.Sort(null);
            ICursor inputCursor = tableSort.Rows;

            IRow inputTableRow;
            int numOutput = 0;
            int numInput = 0;
            short inSequenceValue;
            long fromIDVal, toIDVal;

            int nextBranchNum = -1, nextTowardNum = -1;

            // these are initialized to prevent uninitialized variable compiler error

            SignpostUtilities.FeatureData fromFeatureData = new SignpostUtilities.FeatureData(-1, null);
            SignpostUtilities.FeatureData toFeatureData = new SignpostUtilities.FeatureData(-1, null);

            object newOID;
            string branchText, towardText, signText, accessText;
            string langText, langValue;

            ICurve fromEdgeCurve, toEdgeCurve;
            IPoint fromEdgeStart, fromEdgeEnd, toEdgeStart, toEdgeEnd;

            int refLinesFCID = inputLineFeatures.ObjectClassID;
            IGeometry outputSignGeometry;

            double lastSrcLinkID = -1.0, currentSrcLinkID = -1.0;
            double lastDstLinkID = -1.0, currentDstLinkID = -1.0;
            double fromEdgeFromPos = 0.0;
            double fromEdgeToPos = 1.0;
            double toEdgeFromPos = 0.0;
            double toEdgeToPos = 1.0;

            while ((inputTableRow = inputCursor.NextRow()) != null)
            {
                currentSrcLinkID = Convert.ToInt32(inputTableRow.get_Value(inFromIDFI));
                currentDstLinkID = Convert.ToInt32(inputTableRow.get_Value(inToIDFI));

                // If we have a new source/destination link ID, we need to
                // insert the signpost feature in progress and write the detail records.
                // (identical code is also after the while loop for the last sign record)

                if (((currentSrcLinkID != lastSrcLinkID) || (currentDstLinkID != lastDstLinkID)) &&
                    ((lastSrcLinkID != -1) && (lastDstLinkID != -1)))
                {
                    // clean up unused parts of the row and pack toward/branch items

                    SignpostUtilities.CleanUpSignpostFeatureValues(featureBuffer, nextBranchNum - 1, nextTowardNum - 1,
                                                                   outBranchXFI, outBranchXDirFI, outBranchXLngFI,
                                                                   outTowardXFI, outTowardXLngFI);

                    // save sign feature record

                    newOID = featureInsertCursor.InsertFeature(featureBuffer);

                    // set streets table values

                    tableRowBuffer.set_Value(outTblSignpostIDFI, newOID);
                    tableRowBuffer.set_Value(outTblSequenceFI, 1);
                    tableRowBuffer.set_Value(outTblEdgeFCIDFI, refLinesFCID);
                    tableRowBuffer.set_Value(outTblEdgeFIDFI, fromFeatureData.OID);
                    tableRowBuffer.set_Value(outTblEdgeFrmPosFI, fromEdgeFromPos);
                    tableRowBuffer.set_Value(outTblEdgeToPosFI, fromEdgeToPos);

                    // insert first detail record

                    tableInsertCursor.InsertRow(tableRowBuffer);

                    tableRowBuffer.set_Value(outTblSequenceFI, 0);
                    tableRowBuffer.set_Value(outTblEdgeFIDFI, toFeatureData.OID);
                    tableRowBuffer.set_Value(outTblEdgeFrmPosFI, toEdgeFromPos);
                    tableRowBuffer.set_Value(outTblEdgeToPosFI, toEdgeToPos);

                    // insert second detail record

                    tableInsertCursor.InsertRow(tableRowBuffer);

                    numOutput++;
                    if ((numOutput % 100) == 0)
                    {
                        // check for user cancel

                        if (trackcancel != null && !trackcancel.Continue())
                            throw (new COMException("Function cancelled."));
                    }
                }

                lastSrcLinkID = currentSrcLinkID;
                lastDstLinkID = currentDstLinkID;

                inSequenceValue = Convert.ToInt16(inputTableRow.get_Value(inSequenceFI));
                if (inSequenceValue == 1)
                {
                    // We are starting a sequence of records for a new sign.
                    // nextBranchNum and nextTowardNum keep track of which branch and
                    // toward item numbers we have used and are not necessarily the same
                    // as inSequenceValue.

                    nextBranchNum = 0;
                    nextTowardNum = 0;

                    fromIDVal = Convert.ToInt64(inputTableRow.get_Value(inFromIDFI));
                    toIDVal = Convert.ToInt64(inputTableRow.get_Value(inToIDFI));

                    // If the signpost references a line feature that is not in the lines
                    // feature class, add a warning message and keep going.
                    // Only warn for the first 100 not found.

                    numInput++;

                    try
                    {
                        fromFeatureData = (SignpostUtilities.FeatureData)lineFeaturesList[fromIDVal];
                        toFeatureData = (SignpostUtilities.FeatureData)lineFeaturesList[toIDVal];
                    }
                    catch
                    {
                        if (numInput - numOutput < 100)
                        {
                            messages.AddWarning("Line feature not found for sign with FromID: " +
                                Convert.ToString(fromIDVal, System.Globalization.CultureInfo.InvariantCulture) +
                                ", ToID: " + Convert.ToString(toIDVal, System.Globalization.CultureInfo.InvariantCulture));
                        }
                        continue;
                    }

                    // To set from and to position in the detail table and to construct geometry
                    // for the output signs feature class, we need see where and
                    // if the two edge features connect to figure out their digitized direction.

                    fromEdgeCurve = fromFeatureData.feature as ICurve;
                    toEdgeCurve = toFeatureData.feature as ICurve;

                    fromEdgeStart = fromEdgeCurve.FromPoint;
                    fromEdgeEnd = fromEdgeCurve.ToPoint;
                    toEdgeStart = toEdgeCurve.FromPoint;
                    toEdgeEnd = toEdgeCurve.ToPoint;

                    fromEdgeFromPos = 0.0;
                    fromEdgeToPos = 1.0;
                    toEdgeFromPos = 0.0;
                    toEdgeToPos = 1.0;

                    // flip the from edge?

                    if (TurnGeometryUtilities.EqualPoints(fromEdgeStart, toEdgeStart) || TurnGeometryUtilities.EqualPoints(fromEdgeStart, toEdgeEnd))
                    {
                        fromEdgeFromPos = 1.0;
                        fromEdgeToPos = 0.0;
                    }

                    // flip the to edge?

                    if (TurnGeometryUtilities.EqualPoints(toEdgeEnd, fromEdgeStart) || TurnGeometryUtilities.EqualPoints(toEdgeEnd, fromEdgeEnd))
                    {
                        toEdgeFromPos = 1.0;
                        toEdgeToPos = 0.0;
                    }

                    // set sign feature values

                    // construct shape - the only purpose of the shape is visualization and it can be null

                    outputSignGeometry = MakeSignGeometry(fromEdgeCurve, toEdgeCurve, fromEdgeFromPos == 1.0, toEdgeFromPos == 1.0);

                    featureBuffer.Shape = outputSignGeometry;

                    featureBuffer.set_Value(outExitNameFI, inputTableRow.get_Value(inExitNumFI));
                }

                // Look up the language code

                langText = (inputTableRow.get_Value(inLangFI) as string).Trim();
                langValue = SignpostUtilities.GetLanguageValue(langText, langLookup);

                // Populate Branch items from BR_RTEID and BR_RTEDIR

                branchText = (inputTableRow.get_Value(inBranchRteIDFI) as string).Trim();

                if (branchText.Length > 0)
                {
                    // check for schema overflow
                    if (nextBranchNum > SignpostUtilities.MaxBranchCount - 1)
                        continue;

                    // set values
                    featureBuffer.set_Value(outBranchXFI[nextBranchNum], branchText);
                    featureBuffer.set_Value(outBranchXDirFI[nextBranchNum], inputTableRow.get_Value(inDirectionFI));
                    featureBuffer.set_Value(outBranchXLngFI[nextBranchNum], langValue);

                    // get ready for next branch
                    nextBranchNum++;
                }

                // Populate Branch or Toward items from SIGN_TEXT depending upon the value in the SIGN_TXTTP field:
                //  - if SIGN_TXTTP == "B" (direct), populate a branch
                //  - if SIGN_TXTTP == "T" (direct), populate a toward

                signText = (inputTableRow.get_Value(inToNameFI) as string).Trim();

                if (signText.Length > 0)
                {
                    accessText = (inputTableRow.get_Value(inAccessFI) as string);

                    if (accessText == "B")
                    {
                        // check for schema overflow
                        if (nextBranchNum > SignpostUtilities.MaxBranchCount - 1)
                            continue;

                        // set values
                        featureBuffer.set_Value(outBranchXFI[nextBranchNum], signText);
                        featureBuffer.set_Value(outBranchXDirFI[nextBranchNum], inputTableRow.get_Value(inDirectionFI));
                        featureBuffer.set_Value(outBranchXLngFI[nextBranchNum], langValue);

                        // get ready for next branch
                        nextBranchNum++;
                    }
                    else if (accessText == "T")
                    {
                        // check for schema overflow
                        if (nextTowardNum > SignpostUtilities.MaxBranchCount - 1)
                            continue;

                        // set values
                        featureBuffer.set_Value(outTowardXFI[nextTowardNum], signText);
                        featureBuffer.set_Value(outTowardXLngFI[nextTowardNum], langValue);

                        // get ready for next toward
                        nextTowardNum++;
                    }
                    else
                        continue;    // not expected
                }

                // Populate Toward items from TOW_RTEID

                towardText = (inputTableRow.get_Value(inToLocaleFI) as string).Trim();

                if (towardText.Length > 0)
                {
                    // check for schema overflow
                    if (nextTowardNum > SignpostUtilities.MaxBranchCount - 1)
                        continue;

                    // set values
                    featureBuffer.set_Value(outTowardXFI[nextTowardNum], towardText);
                    featureBuffer.set_Value(outTowardXLngFI[nextTowardNum], langValue);

                    // get ready for next toward
                    nextTowardNum++;
                }

            }  // each input table record

            // Assuming the table wasn't empty to begin with (detected by the Currents no longer being -1.0),
            // add the last signpost feature and detail records (same code as above)

            if (currentSrcLinkID != -1.0 && currentDstLinkID != -1.0)
            {
                // clean up unused parts of the row and pack toward/branch items

                SignpostUtilities.CleanUpSignpostFeatureValues(featureBuffer, nextBranchNum - 1, nextTowardNum - 1,
                                                               outBranchXFI, outBranchXDirFI, outBranchXLngFI,
                                                               outTowardXFI, outTowardXLngFI);

                // save sign feature record

                newOID = featureInsertCursor.InsertFeature(featureBuffer);

                // set streets table values

                tableRowBuffer.set_Value(outTblSignpostIDFI, newOID);
                tableRowBuffer.set_Value(outTblSequenceFI, 1);
                tableRowBuffer.set_Value(outTblEdgeFCIDFI, refLinesFCID);
                tableRowBuffer.set_Value(outTblEdgeFIDFI, fromFeatureData.OID);
                tableRowBuffer.set_Value(outTblEdgeFrmPosFI, fromEdgeFromPos);
                tableRowBuffer.set_Value(outTblEdgeToPosFI, fromEdgeToPos);

                // insert first detail record

                tableInsertCursor.InsertRow(tableRowBuffer);

                tableRowBuffer.set_Value(outTblSequenceFI, 0);
                tableRowBuffer.set_Value(outTblEdgeFIDFI, toFeatureData.OID);
                tableRowBuffer.set_Value(outTblEdgeFrmPosFI, toEdgeFromPos);
                tableRowBuffer.set_Value(outTblEdgeToPosFI, toEdgeToPos);

                // insert second detail record

                tableInsertCursor.InsertRow(tableRowBuffer);

                numOutput++;

                // Flush any outstanding writes to the feature class and table
                featureInsertCursor.Flush();
                tableInsertCursor.Flush();
            }

            // add a summary message

            messages.AddMessage(Convert.ToString(numOutput) + " of " + Convert.ToString(numInput) + " signposts added.");

            return;
        }
        internal List<string> loadOSMWays(string osmFileLocation, ref ITrackCancel TrackCancel, ref IGPMessages message, IGPValue targetGPValue, IFeatureClass osmPointFeatureClass, IFeatureClass osmLineFeatureClass, IFeatureClass osmPolygonFeatureClass, bool conserveMemory, bool fastLoad, int wayCapacity, ref Dictionary<string, simplePointRef> osmNodeDictionary, IFeatureWorkspace featureWorkspace, ISpatialReference downloadSpatialReference, OSMDomains availableDomains, bool checkForExisting)
        {
            if (osmLineFeatureClass == null)
            {
                throw new ArgumentNullException("osmLineFeatureClass");
            }

            if (osmPolygonFeatureClass == null)
            {
                throw new ArgumentNullException("osmPolygonFeatureClass");
            }

            XmlReader osmFileXmlReader = null;
            XmlSerializer waySerializer = null;
            List<string> missingWays = null;

            try
            {
                missingWays = new List<string>();

                int osmPointIDFieldIndex = osmPointFeatureClass.FindField("OSMID");
                int osmWayRefCountFieldIndex = osmPointFeatureClass.FindField("wayRefCount");

                int osmLineIDFieldIndex = osmLineFeatureClass.FindField("OSMID");
                Dictionary<string, int> osmLineDomainAttributeFieldIndices = new Dictionary<string, int>();
                Dictionary<string, int> osmLineDomainAttributeFieldLength = new Dictionary<string, int>();
                foreach (var domains in availableDomains.domain)
                {
                    int currentFieldIndex = osmLineFeatureClass.FindField(domains.name);

                    if (currentFieldIndex != -1)
                    {
                        osmLineDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex);
                        osmLineDomainAttributeFieldLength.Add(domains.name, osmLineFeatureClass.Fields.get_Field(currentFieldIndex).Length);
                    }
                }
                int tagCollectionPolylineFieldIndex = osmLineFeatureClass.FindField("osmTags");
                int osmUserPolylineFieldIndex = osmLineFeatureClass.FindField("osmuser");
                int osmUIDPolylineFieldIndex = osmLineFeatureClass.FindField("osmuid");
                int osmVisiblePolylineFieldIndex = osmLineFeatureClass.FindField("osmvisible");
                int osmVersionPolylineFieldIndex = osmLineFeatureClass.FindField("osmversion");
                int osmChangesetPolylineFieldIndex = osmLineFeatureClass.FindField("osmchangeset");
                int osmTimeStampPolylineFieldIndex = osmLineFeatureClass.FindField("osmtimestamp");
                int osmMemberOfPolylineFieldIndex = osmLineFeatureClass.FindField("osmMemberOf");
                int osmMembersPolylineFieldIndex = osmLineFeatureClass.FindField("osmMembers");
                int osmSupportingElementPolylineFieldIndex = osmLineFeatureClass.FindField("osmSupportingElement");

                int osmPolygonIDFieldIndex = osmPolygonFeatureClass.FindField("OSMID");
                Dictionary<string, int> osmPolygonDomainAttributeFieldIndices = new Dictionary<string, int>();
                Dictionary<string, int> osmPolygonDomainAttributeFieldLength = new Dictionary<string, int>();
                foreach (var domains in availableDomains.domain)
                {
                    int currentFieldIndex = osmPolygonFeatureClass.FindField(domains.name);

                    if (currentFieldIndex != -1)
                    {
                        osmPolygonDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex);
                        osmPolygonDomainAttributeFieldLength.Add(domains.name, osmPolygonFeatureClass.Fields.get_Field(currentFieldIndex).Length);
                    }
                }
                int tagCollectionPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmTags");
                int osmUserPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmuser");
                int osmUIDPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmuid");
                int osmVisiblePolygonFieldIndex = osmPolygonFeatureClass.FindField("osmvisible");
                int osmVersionPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmversion");
                int osmChangesetPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmchangeset");
                int osmTimeStampPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmtimestamp");
                int osmMemberOfPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmMemberOf");
                int osmMembersPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmMembers");
                int osmSupportingElementPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmSupportingElement");

                ISpatialReferenceFactory spatialRef = new SpatialReferenceEnvironmentClass();
                ISpatialReference wgs84 = spatialRef.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);

                bool shouldProject = !((IClone)wgs84).IsEqual((IClone)downloadSpatialReference);

                // set up the progress indicator
                IStepProgressor stepProgressor = TrackCancel as IStepProgressor;

                if (stepProgressor != null)
                {
                    stepProgressor.MinRange = 0;
                    stepProgressor.MaxRange = wayCapacity;
                    stepProgressor.Position = 0;
                    stepProgressor.Message = _resourceManager.GetString("GPTools_OSMGPFileReader_loadingWays");
                    stepProgressor.StepValue = 1;
                    stepProgressor.Show();
                }

                bool lineIndexRebuildRequired = false;
                bool polygonIndexRebuildRequired = false;

                int wayCount = 0;
                object missingValue = System.Reflection.Missing.Value;

                // enterprise GDB indicator -- supporting load only mode
                IFeatureClassLoad lineFeatureLoad = null;
                IFeatureClassLoad polygonFeatureLoad = null;

                using (SchemaLockManager lineLock = new SchemaLockManager(osmLineFeatureClass as ITable), polygonLock = new SchemaLockManager(osmPolygonFeatureClass as ITable))
                {
                    using (ComReleaser comReleaser = new ComReleaser())
                    {
                        IFeatureCursor insertLineCursor = osmLineFeatureClass.Insert(true);
                        comReleaser.ManageLifetime(insertLineCursor);

                        IFeatureBuffer featureLineBuffer = osmLineFeatureClass.CreateFeatureBuffer();
                        comReleaser.ManageLifetime(featureLineBuffer);

                        IFeatureCursor insertPolygonCursor = osmPolygonFeatureClass.Insert(true);
                        comReleaser.ManageLifetime(insertPolygonCursor);

                        IFeatureBuffer featurePolygonBuffer = osmPolygonFeatureClass.CreateFeatureBuffer();
                        comReleaser.ManageLifetime(featurePolygonBuffer);

                        if (((IWorkspace)featureWorkspace).WorkspaceFactory.WorkspaceType == esriWorkspaceType.esriRemoteDatabaseWorkspace)
                        {
                            lineFeatureLoad = osmLineFeatureClass as IFeatureClassLoad;
                            polygonFeatureLoad = osmPolygonFeatureClass as IFeatureClassLoad;
                        }

                        if (lineFeatureLoad != null)
                        {
                            lineFeatureLoad.LoadOnlyMode = true;
                        }

                        if (polygonFeatureLoad != null)
                        {
                            polygonFeatureLoad.LoadOnlyMode = true;
                        }

                        ISpatialReference nativeLineSpatialReference = ((IGeoDataset)osmLineFeatureClass).SpatialReference;
                        ISpatialReference nativePolygonSpatialReference = ((IGeoDataset)osmPolygonFeatureClass).SpatialReference;

                        IQueryFilter osmIDQueryFilter = new QueryFilterClass();
                        string sqlPointOSMID = osmPointFeatureClass.SqlIdentifier("OSMID");
                        IFeatureCursor updatePointCursor = null;

                        osmFileXmlReader = System.Xml.XmlReader.Create(osmFileLocation);
                        waySerializer = new XmlSerializer(typeof(way));

                        // the point query filter for updates will not changes, so let's do that ahead of time
                        try
                        {
                            osmIDQueryFilter.SubFields = osmPointFeatureClass.ShapeFieldName + "," + osmPointFeatureClass.Fields.get_Field(osmPointIDFieldIndex).Name + "," + osmPointFeatureClass.Fields.get_Field(osmWayRefCountFieldIndex).Name;
                        }
                        catch
                        { }

                        osmFileXmlReader.MoveToContent();
                        while (osmFileXmlReader.Read())
                        {
                            if (osmFileXmlReader.IsStartElement())
                            {
                                if (osmFileXmlReader.Name == "way")
                                {
                                    string currentwayString = osmFileXmlReader.ReadOuterXml();

                                    // assuming the way to be a polyline is sort of a safe assumption
                                    // and won't cause any topology problem due to orientation and closeness
                                    bool wayIsLine = true;
                                    bool wayIsComplete = true;

                                    way currentWay = null;

                                    try
                                    {
                                        using (StringReader wayReader = new System.IO.StringReader(currentwayString))
                                        {
                                            currentWay = waySerializer.Deserialize(wayReader) as way;
                                        }

                                        // if the deserialization fails then go ahead and read the next xml element
                                        if (currentWay == null)
                                        {
                                            continue;
                                        }

                                        // and we are expecting at least some nodes on the way itself
                                        if (currentWay.nd == null)
                                        {
                                            continue;
                                        }

                                        featureLineBuffer = osmLineFeatureClass.CreateFeatureBuffer();
                                        featurePolygonBuffer = osmPolygonFeatureClass.CreateFeatureBuffer();

                                        IPointCollection wayPointCollection = null;
                                        wayIsLine = IsThisWayALine(currentWay);

                                        if (wayIsLine)
                                        {

                                            // check if a feature with the same OSMID already exists, because the can only be one
                                            if (checkForExisting == true)
                                            {
                                                if (CheckIfExists(osmLineFeatureClass as ITable, currentWay.id))
                                                {
                                                    continue;
                                                }
                                            }

                                            IPolyline wayPolyline = new PolylineClass();
                                            comReleaser.ManageLifetime(wayPointCollection);

                                            wayPolyline.SpatialReference = downloadSpatialReference;

                                            IPointIDAware polylineIDAware = wayPolyline as IPointIDAware;
                                            polylineIDAware.PointIDAware = true;

                                            wayPointCollection = wayPolyline as IPointCollection;

                                            # region generate line geometry
                                            if (conserveMemory == false)
                                            {
                                                for (int ndIndex = 0; ndIndex < currentWay.nd.Length; ndIndex++)
                                                {
                                                    string ndID = currentWay.nd[ndIndex].@ref;
                                                    if (osmNodeDictionary.ContainsKey(ndID))
                                                    {
                                                        IPoint newPoint = new PointClass();
                                                        newPoint.X = osmNodeDictionary[ndID].Longitude;
                                                        newPoint.Y = osmNodeDictionary[ndID].Latitude;

                                                        newPoint.SpatialReference = wgs84;

                                                        if (shouldProject)
                                                        {
                                                            newPoint.Project(((IGeoDataset)osmLineFeatureClass).SpatialReference);
                                                        }

                                                        IPointIDAware idAware = newPoint as IPointIDAware;
                                                        idAware.PointIDAware = true;

                                                        newPoint.ID = osmNodeDictionary[ndID].pointObjectID;

                                                        wayPointCollection.AddPoint(newPoint, ref missingValue, ref missingValue);

                                                        osmNodeDictionary[ndID].RefCounter = osmNodeDictionary[ndID].RefCounter + 1;
                                                    }
                                                    else
                                                    {
                                                        message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_undeterminedline_node"), currentWay.id, ndID));
                                                        // set the flag that the way is complete due to a missing node
                                                        wayIsComplete = false;
                                                        break;
                                                    }
                                                }

                                            }
                                            else
                                            {
                                                for (int pointIndex = 0; pointIndex < currentWay.nd.Length; pointIndex++)
                                                {
                                                    wayPointCollection.AddPoint(new PointClass());
                                                }

                                                List<string> idRequests = SplitOSMIDRequests(currentWay, 2);

                                                // build a list of node ids we can use to determine the point index in the line geometry
                                                // as well as a dictionary to determine the position in the list in case of duplicates nodes
                                                Dictionary<string, int> nodePositionDictionary = new Dictionary<string, int>(currentWay.nd.Length);
                                                List<string> nodeIDs = new List<string>(currentWay.nd.Length);

                                                foreach (nd wayNode in currentWay.nd)
                                                {
                                                    nodeIDs.Add(wayNode.@ref);

                                                    if (nodePositionDictionary.ContainsKey(wayNode.@ref) == false)
                                                    {
                                                        nodePositionDictionary.Add(wayNode.@ref, 0);
                                                    }
                                                }

                                                try
                                                {
                                                    osmIDQueryFilter.SubFields = osmPointFeatureClass.ShapeFieldName + "," + osmPointFeatureClass.Fields.get_Field(osmPointIDFieldIndex).Name + "," + osmPointFeatureClass.Fields.get_Field(osmWayRefCountFieldIndex).Name;
                                                }
                                                catch
                                                { }

                                                foreach (string request in idRequests)
                                                {
                                                    string idCompareString = request;
                                                    osmIDQueryFilter.WhereClause = sqlPointOSMID + " IN " + request;
                                                    using (ComReleaser innerComReleaser = new ComReleaser())
                                                    {
                                                        updatePointCursor = osmPointFeatureClass.Update(osmIDQueryFilter, true);
                                                        innerComReleaser.ManageLifetime(updatePointCursor);

                                                        IFeature nodeFeature = updatePointCursor.NextFeature();

                                                        while (nodeFeature != null)
                                                        {
                                                            // determine the index of the point in with respect to the node position
                                                            string nodeOSMIDString = Convert.ToString(nodeFeature.get_Value(osmPointIDFieldIndex));

                                                            // remove the ID from the request string
                                                            idCompareString = idCompareString.Replace(nodeOSMIDString, String.Empty);

                                                            int nodePositionIndex = -1;

                                                            while ((nodePositionIndex = nodeIDs.IndexOf(nodeOSMIDString, nodePositionDictionary[nodeOSMIDString])) != -1)
                                                            {
                                                                //// update the new position start search index
                                                                nodePositionDictionary[nodeOSMIDString] = nodePositionIndex + 1;

                                                                wayPointCollection.UpdatePoint(nodePositionIndex, (IPoint)nodeFeature.Shape);

                                                                // increase the reference counter
                                                                if (osmWayRefCountFieldIndex != -1)
                                                                {
                                                                    nodeFeature.set_Value(osmWayRefCountFieldIndex, ((int)nodeFeature.get_Value(osmWayRefCountFieldIndex)) + 1);

                                                                    updatePointCursor.UpdateFeature(nodeFeature);
                                                                }
                                                            }

                                                            if (nodeFeature != null)
                                                                Marshal.ReleaseComObject(nodeFeature);

                                                            nodeFeature = updatePointCursor.NextFeature();
                                                        }

                                                        idCompareString = CleanReportedNodes(idCompareString);

                                                        // after removing the commas we should be left with only paranthesis left, meaning a string of length 2
                                                        // if we have more then we have found a missing node, resulting in an incomplete way geometry
                                                        if (idCompareString.Length > 2)
                                                        {
                                                            message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_undeterminedline_node"), currentWay.id, idCompareString));
                                                            wayIsComplete = false;
                                                        }
                                                    }
                                                }
                                            }
                                            #endregion

                                            if (wayIsComplete == false)
                                            {
                                                // if the way geometry is incomplete due to a missing node let's continue to the next way element
                                                missingWays.Add(currentWay.id);
                                                continue;
                                            }

                                            featureLineBuffer.Shape = wayPolyline;
                                            featureLineBuffer.set_Value(osmLineIDFieldIndex, currentWay.id);
                                        }
                                        else
                                        {
                                            // check if a feature with the same OSMID already exists, because the can only be one
                                            if (checkForExisting == true)
                                            {
                                                if (CheckIfExists(osmPolygonFeatureClass as ITable, currentWay.id))
                                                {
                                                    continue;
                                                }
                                            }

                                            IPolygon wayPolygon = new PolygonClass();
                                            comReleaser.ManageLifetime(wayPointCollection);

                                            wayPolygon.SpatialReference = downloadSpatialReference;

                                            IPointIDAware polygonIDAware = wayPolygon as IPointIDAware;
                                            polygonIDAware.PointIDAware = true;

                                            wayPointCollection = wayPolygon as IPointCollection;

                                            #region generate polygon geometry
                                            if (conserveMemory == false)
                                            {
                                                for (int ndIndex = 0; ndIndex < currentWay.nd.Length; ndIndex++)
                                                {
                                                    string ndID = currentWay.nd[ndIndex].@ref;
                                                    if (osmNodeDictionary.ContainsKey(ndID))
                                                    {
                                                        IPoint newPoint = new PointClass();
                                                        newPoint.X = osmNodeDictionary[ndID].Longitude;
                                                        newPoint.Y = osmNodeDictionary[ndID].Latitude;
                                                        newPoint.SpatialReference = wgs84;

                                                        if (shouldProject)
                                                        {
                                                            newPoint.Project(nativePolygonSpatialReference);
                                                        }

                                                        IPointIDAware idAware = newPoint as IPointIDAware;
                                                        idAware.PointIDAware = true;

                                                        newPoint.ID = osmNodeDictionary[ndID].pointObjectID;

                                                        wayPointCollection.AddPoint(newPoint, ref missingValue, ref missingValue);
                                                    }
                                                    else
                                                    {
                                                        message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_undeterminedpolygon_node"), currentWay.id, ndID));
                                                        wayIsComplete = false;
                                                        break;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                for (int pointIndex = 0; pointIndex < currentWay.nd.Length; pointIndex++)
                                                {
                                                    wayPointCollection.AddPoint(new PointClass());
                                                }

                                                List<string> idRequests = SplitOSMIDRequests(currentWay, 2);

                                                // build a list of node ids we can use to determine the point index in the line geometry
                                                // as well as a dictionary to determine the position in the list in case of duplicates nodes
                                                Dictionary<string, int> nodePositionDictionary = new Dictionary<string, int>(currentWay.nd.Length);
                                                List<string> nodeIDs = new List<string>(currentWay.nd.Length);

                                                foreach (nd wayNode in currentWay.nd)
                                                {
                                                    nodeIDs.Add(wayNode.@ref);

                                                    if (nodePositionDictionary.ContainsKey(wayNode.@ref) == false)
                                                    {
                                                        nodePositionDictionary.Add(wayNode.@ref, 0);
                                                    }
                                                }

                                                try
                                                {
                                                    osmIDQueryFilter.SubFields = osmPointFeatureClass.ShapeFieldName + "," + osmPointFeatureClass.Fields.get_Field(osmPointIDFieldIndex).Name + "," + osmPointFeatureClass.Fields.get_Field(osmWayRefCountFieldIndex).Name;
                                                }
                                                catch
                                                { }

                                                foreach (string osmIDRequest in idRequests)
                                                {
                                                    string idCompareString = osmIDRequest;

                                                    using (ComReleaser innercomReleaser = new ComReleaser())
                                                    {
                                                        osmIDQueryFilter.WhereClause = sqlPointOSMID + " IN " + osmIDRequest;
                                                        updatePointCursor = osmPointFeatureClass.Update(osmIDQueryFilter, false);
                                                        innercomReleaser.ManageLifetime(updatePointCursor);

                                                        IFeature nodeFeature = updatePointCursor.NextFeature();

                                                        while (nodeFeature != null)
                                                        {
                                                            // determine the index of the point in with respect to the node position
                                                            string nodeOSMIDString = Convert.ToString(nodeFeature.get_Value(osmPointIDFieldIndex));

                                                            idCompareString = idCompareString.Replace(nodeOSMIDString, String.Empty);

                                                            int nodePositionIndex = nodeIDs.IndexOf(nodeOSMIDString, nodePositionDictionary[nodeOSMIDString]);

                                                            // update the new position start search index
                                                            nodePositionDictionary[nodeOSMIDString] = nodePositionIndex + 1;

                                                            wayPointCollection.UpdatePoint(nodePositionIndex, (IPoint)nodeFeature.Shape);

                                                            // increase the reference counter
                                                            if (osmWayRefCountFieldIndex != -1)
                                                            {
                                                                nodeFeature.set_Value(osmWayRefCountFieldIndex, ((int)nodeFeature.get_Value(osmWayRefCountFieldIndex)) + 1);

                                                                updatePointCursor.UpdateFeature(nodeFeature);
                                                            }

                                                            if (nodeFeature != null)
                                                                Marshal.ReleaseComObject(nodeFeature);

                                                            nodeFeature = updatePointCursor.NextFeature();
                                                        }

                                                        idCompareString = CleanReportedNodes(idCompareString);

                                                        if (idCompareString.Length > 2)
                                                        {
                                                            message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_undeterminedpolygon_node"), currentWay.id, idCompareString));
                                                            wayIsComplete = false;
                                                        }
                                                    }
                                                }
                                            }
                                            #endregion

                                            if (wayIsComplete == false)
                                            {
                                                continue;
                                            }

                                            // remove the last point as OSM considers them to be coincident
                                            wayPointCollection.RemovePoints(wayPointCollection.PointCount - 1, 1);
                                            ((IPolygon)wayPointCollection).Close();

                                            featurePolygonBuffer.Shape = (IPolygon)wayPointCollection;
                                            featurePolygonBuffer.set_Value(osmPolygonIDFieldIndex, currentWay.id);
                                        }

                                        if (wayIsLine)
                                        {
                                            insertTags(osmLineDomainAttributeFieldIndices, osmLineDomainAttributeFieldLength, tagCollectionPolylineFieldIndex, featureLineBuffer, currentWay.tag);
                                        }
                                        else
                                        {
                                            insertTags(osmPolygonDomainAttributeFieldIndices, osmPolygonDomainAttributeFieldLength, tagCollectionPolygonFieldIndex, featurePolygonBuffer, currentWay.tag);
                                        }

                                        // store the administrative attributes
                                        // user, uid, version, changeset, timestamp, visible
                                        if (fastLoad == false)
                                        {
                                            if (!String.IsNullOrEmpty(currentWay.user))
                                            {
                                                if (wayIsLine)
                                                {
                                                    if (osmUserPolylineFieldIndex != -1)
                                                    {
                                                        featureLineBuffer.set_Value(osmUserPolylineFieldIndex, currentWay.user);
                                                    }
                                                }
                                                else
                                                {
                                                    if (osmUserPolygonFieldIndex != -1)
                                                    {
                                                        featurePolygonBuffer.set_Value(osmUserPolygonFieldIndex, currentWay.user);
                                                    }
                                                }
                                            }

                                            if (!String.IsNullOrEmpty(currentWay.uid))
                                            {
                                                if (wayIsLine)
                                                {
                                                    if (osmUIDPolylineFieldIndex != -1)
                                                    {
                                                        featureLineBuffer.set_Value(osmUIDPolylineFieldIndex, Convert.ToInt32(currentWay.uid));
                                                    }
                                                }
                                                else
                                                {
                                                    if (osmUIDPolygonFieldIndex != -1)
                                                    {
                                                        featurePolygonBuffer.set_Value(osmUIDPolygonFieldIndex, Convert.ToInt32(currentWay.uid));
                                                    }
                                                }
                                            }

                                            if (wayIsLine)
                                            {
                                                if (osmVisiblePolylineFieldIndex != -1)
                                                {
                                                    featureLineBuffer.set_Value(osmVisiblePolylineFieldIndex, currentWay.visible.ToString());
                                                }
                                            }
                                            else
                                            {
                                                if (osmVisiblePolygonFieldIndex != -1)
                                                {
                                                    featurePolygonBuffer.set_Value(osmVisiblePolygonFieldIndex, currentWay.visible.ToString());
                                                }
                                            }

                                            if (!String.IsNullOrEmpty(currentWay.version))
                                            {
                                                if (wayIsLine)
                                                {
                                                    if (osmVersionPolylineFieldIndex != -1)
                                                    {
                                                        featureLineBuffer.set_Value(osmVersionPolylineFieldIndex, Convert.ToInt32(currentWay.version));
                                                    }
                                                }
                                                else
                                                {
                                                    if (osmVersionPolygonFieldIndex != -1)
                                                    {
                                                        featurePolygonBuffer.set_Value(osmVersionPolygonFieldIndex, Convert.ToInt32(currentWay.version));
                                                    }
                                                }
                                            }

                                            if (!String.IsNullOrEmpty(currentWay.changeset))
                                            {
                                                if (wayIsLine)
                                                {
                                                    if (osmChangesetPolylineFieldIndex != -1)
                                                    {
                                                        featureLineBuffer.set_Value(osmChangesetPolylineFieldIndex, Convert.ToInt32(currentWay.changeset));
                                                    }
                                                }
                                                else
                                                {
                                                    if (osmChangesetPolygonFieldIndex != -1)
                                                    {
                                                        featurePolygonBuffer.set_Value(osmChangesetPolygonFieldIndex, Convert.ToInt32(currentWay.changeset));
                                                    }
                                                }
                                            }

                                            if (!String.IsNullOrEmpty(currentWay.timestamp))
                                            {
                                                try
                                                {
                                                    if (wayIsLine)
                                                    {
                                                        if (osmTimeStampPolylineFieldIndex != -1)
                                                        {
                                                            featureLineBuffer.set_Value(osmTimeStampPolylineFieldIndex, Convert.ToDateTime(currentWay.timestamp));
                                                        }
                                                    }
                                                    else
                                                    {
                                                        if (osmTimeStampPolygonFieldIndex != -1)
                                                        {
                                                            featurePolygonBuffer.set_Value(osmTimeStampPolygonFieldIndex, Convert.ToDateTime(currentWay.timestamp));
                                                        }
                                                    }
                                                }
                                                catch (Exception ex)
                                                {
                                                    message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_invalidTimeFormat"), ex.Message));
                                                }
                                            }

                                            if (wayIsLine)
                                            {
                                                if (osmSupportingElementPolylineFieldIndex > -1)
                                                {
                                                    if (currentWay.tag == null)
                                                    {
                                                        featureLineBuffer.set_Value(osmSupportingElementPolylineFieldIndex, "yes");
                                                    }
                                                    else
                                                    {
                                                        featureLineBuffer.set_Value(osmSupportingElementPolylineFieldIndex, "no");
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                if (osmSupportingElementPolygonFieldIndex > -1)
                                                {
                                                    if (currentWay.tag == null)
                                                    {
                                                        featurePolygonBuffer.set_Value(osmSupportingElementPolygonFieldIndex, "yes");
                                                    }
                                                    else
                                                    {
                                                        featurePolygonBuffer.set_Value(osmSupportingElementPolygonFieldIndex, "no");
                                                    }
                                                }
                                            }
                                        } // fast load

                                        try
                                        {
                                            if (wayIsLine)
                                            {
                                                insertLineCursor.InsertFeature(featureLineBuffer);
                                                lineIndexRebuildRequired = true;
                                            }
                                            else
                                            {
                                                insertPolygonCursor.InsertFeature(featurePolygonBuffer);
                                                polygonIndexRebuildRequired = true;
                                            }

                                            wayCount = wayCount + 1;

                                            if (stepProgressor != null)
                                            {
                                                stepProgressor.Position = wayCount;
                                            }

                                            if ((wayCount % 50000) == 0)
                                            {
                                                message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_waysloaded"), wayCount));
                                            }

                                        }
                                        catch (Exception ex)
                                        {
                                            message.AddWarning(ex.Message);
                                            message.AddWarning(currentwayString);
                                        }

                                    }
                                    catch (Exception ex)
                                    {
                                        System.Diagnostics.Debug.WriteLine(ex.Message);
                                        System.Diagnostics.Debug.WriteLine(ex.StackTrace);
                                    }
                                    finally
                                    {
                                        if (featureLineBuffer != null)
                                        {
                                            Marshal.ReleaseComObject(featureLineBuffer);

                                            if (featureLineBuffer != null)
                                                featureLineBuffer = null;
                                        }

                                        if (featurePolygonBuffer != null)
                                        {
                                            Marshal.ReleaseComObject(featurePolygonBuffer);

                                            if (featurePolygonBuffer != null)
                                                featurePolygonBuffer = null;
                                        }

                                        currentWay = null;
                                    }

                                    if (TrackCancel.Continue() == false)
                                    {
                                        insertPolygonCursor.Flush();
                                        if (polygonFeatureLoad != null)
                                        {
                                            polygonFeatureLoad.LoadOnlyMode = false;
                                        }

                                        insertLineCursor.Flush();
                                        if (lineFeatureLoad != null)
                                        {
                                            lineFeatureLoad.LoadOnlyMode = false;
                                        }

                                        return missingWays;
                                    }
                                }
                            }
                        }

                        osmFileXmlReader.Close();

                        if (stepProgressor != null)
                        {
                            stepProgressor.Hide();
                        }

                        message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_waysloaded"), wayCount));

                        insertPolygonCursor.Flush();
                        if (polygonFeatureLoad != null)
                        {
                            polygonFeatureLoad.LoadOnlyMode = false;
                        }

                        insertLineCursor.Flush();
                        if (lineFeatureLoad != null)
                        {
                            lineFeatureLoad.LoadOnlyMode = false;
                        }
                    }
                }

                IGeoProcessor2 geoProcessor = new GeoProcessorClass();
                IGPUtilities3 gpUtilities3 = new GPUtilitiesClass();
                bool storedOriginal = geoProcessor.AddOutputsToMap;
                IVariantArray parameterArrary = null;
                IGeoProcessorResult2 gpResults2 = null;

                try
                {
                    geoProcessor.AddOutputsToMap = false;

                    if (lineIndexRebuildRequired)
                    {
                        IIndexes featureClassIndexes = osmLineFeatureClass.Indexes;
                        int indexPosition = -1;
                        featureClassIndexes.FindIndex("osmID_IDX", out indexPosition);

                        string fcLocation = GetLocationString(targetGPValue, osmLineFeatureClass);

                        if (indexPosition == -1)
                        {
                            message.AddMessage(_resourceManager.GetString("GPTools_buildinglineidx"));

                            // Addd index for osmid column
                            parameterArrary = CreateAddIndexParameterArray(fcLocation, "OSMID", "osmID_IDX", "UNIQUE", "");
                            gpResults2 = geoProcessor.Execute("AddIndex_management", parameterArrary, TrackCancel) as IGeoProcessorResult2;
                        }

                        if (wayCount > 100)
                        {
                            // in this case we are dealing with a file geodatabase
                            if (lineFeatureLoad == null)
                            {
                                UpdateSpatialGridIndex(TrackCancel, message, geoProcessor, fcLocation);
                            }
                        }
                    }

                    if (polygonIndexRebuildRequired)
                    {
                        IIndexes featureClassIndexes = osmPolygonFeatureClass.Indexes;
                        int indexPosition = -1;
                        featureClassIndexes.FindIndex("osmID_IDX", out indexPosition);

                        string fcLocation = GetLocationString(targetGPValue, osmPolygonFeatureClass);

                        if (indexPosition == -1)
                        {
                            message.AddMessage(_resourceManager.GetString("GPTools_buildingpolygonidx"));

                            IGPValue polygonFeatureClassGPValue = gpUtilities3.MakeGPValueFromObject(osmPolygonFeatureClass);

                            if (polygonFeatureClassGPValue != null)
                            {
                                // Addd index for osmid column
                                parameterArrary = CreateAddIndexParameterArray(fcLocation, "OSMID", "osmID_IDX", "UNIQUE", "");
                                gpResults2 = geoProcessor.Execute("AddIndex_management", parameterArrary, TrackCancel) as IGeoProcessorResult2;
                            }
                        }

                        if (wayCount > 100)
                        {
                            if (polygonFeatureLoad == null)
                            {
                                UpdateSpatialGridIndex(TrackCancel, message, geoProcessor, fcLocation);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    message.AddWarning(ex.Message);
                }
                finally
                {
                    geoProcessor.AddOutputsToMap = storedOriginal;

                    Marshal.FinalReleaseComObject(gpUtilities3);
                    Marshal.FinalReleaseComObject(geoProcessor);
                }
            }
            catch (Exception ex)
            {
                message.AddWarning(ex.Message);
            }
            finally
            {
                if (waySerializer != null)
                    waySerializer = null;

                if (osmFileXmlReader != null)
                    osmFileXmlReader = null;

                System.GC.Collect();
                System.GC.WaitForPendingFinalizers();
            }

            return missingWays;
        }
        internal void loadOSMNodes(string osmFileLocation, ref ITrackCancel TrackCancel, ref IGPMessages message,IGPValue targetGPValue,  IFeatureClass osmPointFeatureClass, bool conserveMemory, bool fastLoad, int nodeCapacity, ref Dictionary<string, simplePointRef> osmNodeDictionary, IFeatureWorkspace featureWorkspace, ISpatialReference downloadSpatialReference, OSMDomains availableDomains, bool checkForExisting)
        {
            XmlReader osmFileXmlReader = null;
            XmlSerializer nodeSerializer = null;

            try
            {
                osmFileXmlReader = System.Xml.XmlReader.Create(osmFileLocation);
                nodeSerializer = new XmlSerializer(typeof(node));

                ISpatialReferenceFactory spatialRef = new SpatialReferenceEnvironmentClass();
                ISpatialReference wgs84 = spatialRef.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);

                bool shouldProject = !((IClone)wgs84).IsEqual((IClone)downloadSpatialReference);

                int osmPointIDFieldIndex = osmPointFeatureClass.FindField("OSMID");
                Dictionary<string, int> osmPointDomainAttributeFieldIndices = new Dictionary<string, int>();
                Dictionary<string, int> osmPointDomainAttributeFieldLength = new Dictionary<string, int>();

                foreach (var domains in availableDomains.domain)
                {
                    int currentFieldIndex = osmPointFeatureClass.FindField(domains.name);

                    if (currentFieldIndex != -1)
                    {
                        osmPointDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex);
                        osmPointDomainAttributeFieldLength.Add(domains.name, osmPointFeatureClass.Fields.get_Field(currentFieldIndex).Length);
                    }
                }

                int tagCollectionPointFieldIndex = osmPointFeatureClass.FindField("osmTags");
                int osmUserPointFieldIndex = osmPointFeatureClass.FindField("osmuser");
                int osmUIDPointFieldIndex = osmPointFeatureClass.FindField("osmuid");
                int osmVisiblePointFieldIndex = osmPointFeatureClass.FindField("osmvisible");
                int osmVersionPointFieldIndex = osmPointFeatureClass.FindField("osmversion");
                int osmChangesetPointFieldIndex = osmPointFeatureClass.FindField("osmchangeset");
                int osmTimeStampPointFieldIndex = osmPointFeatureClass.FindField("osmtimestamp");
                int osmMemberOfPointFieldIndex = osmPointFeatureClass.FindField("osmMemberOf");
                int osmSupportingElementPointFieldIndex = osmPointFeatureClass.FindField("osmSupportingElement");
                int osmWayRefCountFieldIndex = osmPointFeatureClass.FindField("wayRefCount");

                // set up the progress indicator
                IStepProgressor stepProgressor = TrackCancel as IStepProgressor;

                if (stepProgressor != null)
                {
                    stepProgressor.MinRange = 0;
                    stepProgressor.MaxRange = nodeCapacity;
                    stepProgressor.StepValue = (1);
                    stepProgressor.Message = _resourceManager.GetString("GPTools_OSMGPFileReader_loadingNodes");
                    stepProgressor.Position = 0;
                    stepProgressor.Show();
                }

                // flag to determine if a computation of indices is required
                bool indexBuildRequired = false;
                if (nodeCapacity > 0)
                    indexBuildRequired = true;

                int pointCount = 0;

                // let's insert all the points first
                if (osmPointFeatureClass != null)
                {
                    IFeatureBuffer pointFeature = null;
                    IFeatureClassLoad pointFeatureLoad = null;

                    using (ComReleaser comReleaser = new ComReleaser())
                    {
                        using (SchemaLockManager schemaLockManager = new SchemaLockManager(osmPointFeatureClass as ITable))
                        {

                            if (((IWorkspace)featureWorkspace).WorkspaceFactory.WorkspaceType == esriWorkspaceType.esriRemoteDatabaseWorkspace)
                            {
                                pointFeatureLoad = osmPointFeatureClass as IFeatureClassLoad;
                            }

                            IFeatureCursor pointInsertCursor = osmPointFeatureClass.Insert(true);
                            comReleaser.ManageLifetime(pointInsertCursor);

                            pointFeature = osmPointFeatureClass.CreateFeatureBuffer();
                            comReleaser.ManageLifetime(pointFeature);

                            if (pointFeatureLoad != null)
                            {
                                pointFeatureLoad.LoadOnlyMode = true;
                            }

                            osmFileXmlReader.MoveToContent();

                            while (osmFileXmlReader.Read())
                            {
                                if (osmFileXmlReader.IsStartElement())
                                {
                                    if (osmFileXmlReader.Name == "node")
                                    {
                                        string currentNodeString = osmFileXmlReader.ReadOuterXml();
                                        // turn the xml node representation into a node class representation
                                        ESRI.ArcGIS.OSM.OSMClassExtension.node currentNode = null;
                                        using (StringReader nodeReader = new System.IO.StringReader(currentNodeString))
                                        {
                                            currentNode = nodeSerializer.Deserialize(nodeReader) as ESRI.ArcGIS.OSM.OSMClassExtension.node;
                                        }

                                        // check if a feature with the same OSMID already exists, because the can only be one
                                        if (checkForExisting == true)
                                        {
                                            if (CheckIfExists(osmPointFeatureClass as ITable, currentNode.id))
                                            {
                                                continue;
                                            }
                                        }

                                        try
                                        {
                                            //if (pointFeature == null)
                                            //{
                                            pointFeature = osmPointFeatureClass.CreateFeatureBuffer();
                                            comReleaser.ManageLifetime(pointFeature);
                                            //}

                                            IPoint pointGeometry = new PointClass();
                                            comReleaser.ManageLifetime(pointGeometry);

                                            pointGeometry.X = Convert.ToDouble(currentNode.lon, new CultureInfo("en-US"));
                                            pointGeometry.Y = Convert.ToDouble(currentNode.lat, new CultureInfo("en-US"));
                                            pointGeometry.SpatialReference = wgs84;

                                            if (shouldProject)
                                            {
                                                pointGeometry.Project(downloadSpatialReference);
                                            }

                                            pointFeature.Shape = pointGeometry;

                                            pointFeature.set_Value(osmPointIDFieldIndex, currentNode.id);

                                            string isSupportingNode = "";
                                            if (_osmUtility.DoesHaveKeys(currentNode))
                                            {
                                                // if case it has tags I assume that the node presents an entity of it own,
                                                // hence it is not a supporting node in the context of supporting a way or relation
                                                isSupportingNode = "no";

                                                if (conserveMemory == false)
                                                {
                                                    osmNodeDictionary[currentNode.id] = new simplePointRef(Convert.ToSingle(currentNode.lon, new CultureInfo("en-US")), Convert.ToSingle(currentNode.lat, new CultureInfo("en-US")), 0, 0);
                                                }
                                            }
                                            else
                                            {
                                                // node has no tags -- at this point I assume that the absence of tags indicates that it is a supporting node
                                                // for a way or a relation
                                                isSupportingNode = "yes";

                                                if (conserveMemory == false)
                                                {
                                                    osmNodeDictionary[currentNode.id] = new simplePointRef(Convert.ToSingle(currentNode.lon, new CultureInfo("en-US")), Convert.ToSingle(currentNode.lat, new CultureInfo("en-US")), 0, 0);
                                                }
                                            }

                                            insertTags(osmPointDomainAttributeFieldIndices, osmPointDomainAttributeFieldLength, tagCollectionPointFieldIndex, pointFeature, currentNode.tag);

                                            if (fastLoad == false)
                                            {
                                                if (osmSupportingElementPointFieldIndex > -1)
                                                {
                                                    pointFeature.set_Value(osmSupportingElementPointFieldIndex, isSupportingNode);
                                                }

                                                if (osmWayRefCountFieldIndex > -1)
                                                {
                                                    pointFeature.set_Value(osmWayRefCountFieldIndex, 0);
                                                }

                                                // store the administrative attributes
                                                // user, uid, version, changeset, timestamp, visible
                                                if (osmUserPointFieldIndex > -1)
                                                {
                                                    if (!String.IsNullOrEmpty(currentNode.user))
                                                    {
                                                        pointFeature.set_Value(osmUserPointFieldIndex, currentNode.user);
                                                    }
                                                }

                                                if (osmUIDPointFieldIndex > -1)
                                                {
                                                    if (!String.IsNullOrEmpty(currentNode.uid))
                                                    {
                                                        pointFeature.set_Value(osmUIDPointFieldIndex, Convert.ToInt32(currentNode.uid));
                                                    }
                                                }

                                                if (osmVisiblePointFieldIndex > -1)
                                                {
                                                    pointFeature.set_Value(osmVisiblePointFieldIndex, currentNode.visible.ToString());
                                                }

                                                if (osmVersionPointFieldIndex > -1)
                                                {
                                                    if (!String.IsNullOrEmpty(currentNode.version))
                                                    {
                                                        pointFeature.set_Value(osmVersionPointFieldIndex, Convert.ToInt32(currentNode.version));
                                                    }
                                                }

                                                if (osmChangesetPointFieldIndex > -1)
                                                {
                                                    if (!String.IsNullOrEmpty(currentNode.changeset))
                                                    {
                                                        pointFeature.set_Value(osmChangesetPointFieldIndex, Convert.ToInt32(currentNode.changeset));
                                                    }
                                                }

                                                if (osmTimeStampPointFieldIndex > -1)
                                                {
                                                    if (!String.IsNullOrEmpty(currentNode.timestamp))
                                                    {
                                                        try
                                                        {
                                                            pointFeature.set_Value(osmTimeStampPointFieldIndex, Convert.ToDateTime(currentNode.timestamp));
                                                        }
                                                        catch (Exception ex)
                                                        {
                                                            message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_invalidTimeFormat"), ex.Message));
                                                        }
                                                    }
                                                }
                                            }
                                            try
                                            {
                                                pointInsertCursor.InsertFeature(pointFeature);
                                                pointCount = pointCount + 1;

                                                if (stepProgressor != null)
                                                {
                                                    stepProgressor.Position = pointCount;
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                System.Diagnostics.Debug.WriteLine(ex.Message);
                                                message.AddWarning(ex.Message);
                                            }

                                            if (TrackCancel.Continue() == false)
                                            {
                                                return;
                                            }

                                            if ((pointCount % 50000) == 0)
                                            {
                                                message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_pointsloaded"), pointCount));
                                                pointInsertCursor.Flush();
                                                System.GC.Collect();
                                            }

                                            if (pointGeometry != null)
                                                Marshal.ReleaseComObject(pointGeometry);
                                        }
                                        catch (Exception ex)
                                        {
                                            System.Diagnostics.Debug.WriteLine(ex.Message);
                                            message.AddWarning(ex.Message);
                                        }
                                        finally
                                        {
                                            if (pointFeature != null)
                                            {
                                                Marshal.ReleaseComObject(pointFeature);

                                                if (pointFeature != null)
                                                    pointFeature = null;

                                            }
                                        }

                                        currentNode = null;
                                    }
                                }
                            }

                            if (stepProgressor != null)
                            {
                                stepProgressor.Hide();
                            }

                            pointInsertCursor.Flush();
                            osmFileXmlReader.Close();

                            message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_pointsloaded"), pointCount));
                            message.AddMessage(_resourceManager.GetString("GPTools_buildingpointidx"));

                            if (pointFeatureLoad != null)
                            {
                                pointFeatureLoad.LoadOnlyMode = false;
                            }
                        }
                    }

                    if (TrackCancel.Continue() == false)
                    {
                        return;
                    }

                    using (ComReleaser comReleaser = new ComReleaser())
                    {
                        IFeatureCursor updatePoints = osmPointFeatureClass.Update(null, false);
                        comReleaser.ManageLifetime(updatePoints);

                        IFeature feature2Update = updatePoints.NextFeature();

                        while (feature2Update != null)
                        {
                            IPoint pointGeometry = feature2Update.Shape as IPoint;
                            pointGeometry.ID = feature2Update.OID;
                            feature2Update.Shape = pointGeometry;

                            if (conserveMemory == false)
                            {
                                string osmid = Convert.ToString(feature2Update.get_Value(osmPointIDFieldIndex));
                                if (osmNodeDictionary.ContainsKey(osmid))
                                    osmNodeDictionary[osmid].pointObjectID = feature2Update.OID;
                            }

                            updatePoints.UpdateFeature(feature2Update);

                            if (TrackCancel.Continue() == false)
                            {
                                return;
                            }

                            if (feature2Update != null)
                                Marshal.ReleaseComObject(feature2Update);

                            if (pointGeometry != null)
                                Marshal.ReleaseComObject(pointGeometry);

                            feature2Update = updatePoints.NextFeature();
                        }
                    }

                    if (indexBuildRequired)
                    {

                        IGeoProcessor2 geoProcessor = new GeoProcessorClass();
                        bool storedOriginal = geoProcessor.AddOutputsToMap;

                        try
                        {
                            IGPUtilities3 gpUtilities3 = new GPUtilitiesClass();

                            IGPValue pointFeatureClass = gpUtilities3.MakeGPValueFromObject(osmPointFeatureClass);

                            string fcLocation = GetLocationString(targetGPValue, osmPointFeatureClass);

                            IIndexes featureClassIndexes = osmPointFeatureClass.Indexes;
                            int indexPosition = -1;
                            featureClassIndexes.FindIndex("osmID_IDX", out indexPosition);

                            if (indexPosition == -1)
                            {
                                {
                                    geoProcessor.AddOutputsToMap = false;

                                    IVariantArray parameterArrary = CreateAddIndexParameterArray(fcLocation, "OSMID", "osmID_IDX", "UNIQUE", "");
                                    IGeoProcessorResult2 gpResults2 = geoProcessor.Execute("AddIndex_management", parameterArrary, TrackCancel) as IGeoProcessorResult2;
                                }
                            }
                            if (pointCount > 500)
                            {
                                if (pointFeatureLoad == null)
                                {
                                    UpdateSpatialGridIndex(TrackCancel, message, geoProcessor, fcLocation);
                                }
                            }
                        }
                        catch (COMException comEx)
                        {
                            message.AddWarning(comEx.Message);
                        }
                        catch (Exception ex)
                        {
                            message.AddWarning(ex.Message);
                        }
                        finally
                        {
                            geoProcessor.AddOutputsToMap = storedOriginal;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                message.AddError(120100, String.Format(_resourceManager.GetString("GPTools_Utility_NodeLoadError"), ex.Message));
            }
            finally
            {
                if (osmFileXmlReader != null)
                    osmFileXmlReader = null;

                if (nodeSerializer != null)
                    nodeSerializer = null;
            }
        }
 private void AddMessage(string messageString, IGPMessages messages, ITrackCancel trackcancel)
 {
     messages.AddMessage(messageString);
     IStepProgressor sp = trackcancel as IStepProgressor;
     if (sp != null)
         sp.Message = messageString;
 }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                IJTXConfiguration3 configMgr = WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXMapEdit        wmxMapDoc = configMgr.GetJTXMap(this.m_targetName) as IJTXMapEdit;

                // If we're not allowed to overwrite an existing map document, then do some error checking
                if (!this.m_overwriteExisting && wmxMapDoc != null)
                {
                    msgs.AddWarning("Did not overwrite Map Document: " + this.m_targetName);
                    return;
                }
                else if (wmxMapDoc != null)
                {
                    msgs.AddMessage("Replacing Map Document '" + this.m_targetName + "' in database...");
                }
                else // wmxMapDoc == null
                {
                    msgs.AddMessage("Adding Map Document '" + this.m_targetName + "' to database...");
                    wmxMapDoc = configMgr.CreateJTXMap() as IJTXMapEdit;
                }

                IMapDocument mapDoc = new MapDocumentClass() as IMapDocument;
                mapDoc.Open(this.m_mxdFilePath, string.Empty);
                wmxMapDoc.Name = this.m_targetName;
                if (!string.IsNullOrEmpty(this.m_targetCategory))
                {
                    wmxMapDoc.Category = this.m_targetCategory;
                }
                if (!string.IsNullOrEmpty(this.m_description))
                {
                    wmxMapDoc.Description = this.m_description;
                }
                wmxMapDoc.Directory   = string.Empty;
                wmxMapDoc.FileName    = string.Empty;
                wmxMapDoc.MapDocument = mapDoc;
                wmxMapDoc.Store();
                mapDoc.Close();

                // Update the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_TARGET_NAME);
                IGPString         outValue     = new GPStringClass();
                outValue.Value     = m_targetName;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_MXD_UPLOAD_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
        }
Exemple #21
0
        public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages message)
        {
            // Get Parameters
            IGPParameter3 inputParameter   = (IGPParameter3)paramvalues.get_Element(0);
            IGPParameter3 polygonParameter = (IGPParameter3)paramvalues.get_Element(1);
            IGPParameter3 outputParameter  = (IGPParameter3)paramvalues.get_Element(2);
            IGPParameter3 fieldParameter   = (IGPParameter3)paramvalues.get_Element(3);

            // UnPackGPValue. This ensures you get the value from either the dataelement or GpVariable (ModelBuilder)
            IGPValue inputParameterValue   = m_GPUtilities.UnpackGPValue(inputParameter);
            IGPValue polygonParameterValue = m_GPUtilities.UnpackGPValue(polygonParameter);
            IGPValue outputParameterValue  = m_GPUtilities.UnpackGPValue(outputParameter);
            IGPValue fieldParameterValue   = m_GPUtilities.UnpackGPValue(fieldParameter);

            // Decode Input Feature Layers
            IFeatureClass inputFeatureClass;
            IFeatureClass polygonFeatureClass;

            IQueryFilter inputFeatureClassQF;
            IQueryFilter polygonFeatureClassQF;

            m_GPUtilities.DecodeFeatureLayer(inputParameterValue, out inputFeatureClass, out inputFeatureClassQF);
            m_GPUtilities.DecodeFeatureLayer(polygonParameterValue, out polygonFeatureClass, out polygonFeatureClassQF);

            if (inputFeatureClass == null)
            {
                message.AddError(2, "Could not open input dataset.");
                return;
            }

            if (polygonFeatureClass == null)
            {
                message.AddError(2, "Could not open clipping polygon dataset.");
                return;
            }

            if (polygonFeatureClass.FeatureCount(null) > 1)
            {
                message.AddWarning("Clipping polygon feature class contains more than one feature.");
            }

            // Create the Geoprocessor
            Geoprocessor gp = new Geoprocessor();

            // Create Output Polygon Feature Class
            CreateFeatureclass cfc      = new CreateFeatureclass();
            IName               name    = m_GPUtilities.CreateFeatureClassName(outputParameterValue.GetAsText());
            IDatasetName        dsName  = name as IDatasetName;
            IFeatureClassName   fcName  = dsName as IFeatureClassName;
            IFeatureDatasetName fdsName = fcName.FeatureDatasetName as IFeatureDatasetName;

            // Check if output is in a FeatureDataset or not. Set the output path parameter for CreateFeatureClass tool.
            if (fdsName != null)
            {
                cfc.out_path = fdsName;
            }
            else
            {
                cfc.out_path = dsName.WorkspaceName.PathName;
            }

            // Set the output Coordinate System for CreateFeatureClass tool.
            // ISpatialReference3 sr = null;
            IGPEnvironment env = envMgr.FindEnvironment("outputCoordinateSystem");

            // Same as Input
            if (env.Value.IsEmpty())
            {
                IGeoDataset ds = inputFeatureClass as IGeoDataset;
                cfc.spatial_reference = ds.SpatialReference as ISpatialReference3;
            }
            // Use the environment setting
            else
            {
                IGPCoordinateSystem cs = env.Value as IGPCoordinateSystem;
                cfc.spatial_reference = cs.SpatialReference as ISpatialReference3;
            }

            // Remaining properties for Create Feature Class Tool
            cfc.out_name      = dsName.Name;
            cfc.geometry_type = "POLYGON";

            // Execute Geoprocessor
            gp.Execute(cfc, null);

            // Get Unique Field
            int    iField      = inputFeatureClass.FindField(fieldParameterValue.GetAsText());
            IField uniqueField = inputFeatureClass.Fields.get_Field(iField);

            // Extract Clipping Polygon Geometry
            IFeature polygonFeature  = polygonFeatureClass.GetFeature(0);
            IPolygon clippingPolygon = (IPolygon)polygonFeature.Shape;

            // Spatial Filter
            ISpatialFilter spatialFilter = new SpatialFilterClass();

            spatialFilter.Geometry   = polygonFeature.ShapeCopy;
            spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;

            // Debug Message
            message.AddMessage("Generating TIN...");

            // Create TIN
            ITinEdit tinEdit = new TinClass();

            // Advanced TIN Functions
            ITinAdvanced2 tinAdv = (ITinAdvanced2)tinEdit;

            try
            {
                // Initialize New TIN
                IGeoDataset gds = inputFeatureClass as IGeoDataset;
                tinEdit.InitNew(gds.Extent);

                // Add Mass Points to TIN
                tinEdit.StartEditing();
                tinEdit.AddFromFeatureClass(inputFeatureClass, spatialFilter, uniqueField, uniqueField, esriTinSurfaceType.esriTinMassPoint);
                tinEdit.Refresh();

                // Get TIN Nodes
                ITinNodeCollection tinNodeCollection = (ITinNodeCollection)tinEdit;

                // Report Node Count
                message.AddMessage("Input Node Count: " + inputFeatureClass.FeatureCount(null).ToString());
                message.AddMessage("TIN Node Count: " + tinNodeCollection.NodeCount.ToString());

                // Open Output Feature Class
                IFeatureClass outputFeatureClass = m_GPUtilities.OpenFeatureClassFromString(outputParameterValue.GetAsText());

                // Debug Message
                message.AddMessage("Generating Polygons...");

                // Create Voronoi Polygons
                tinNodeCollection.ConvertToVoronoiRegions(outputFeatureClass, null, clippingPolygon, "", "");

                // Release COM Objects
                tinEdit.StopEditing(false);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(tinNodeCollection);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(tinEdit);
            }
            catch (Exception ex)
            {
                message.AddError(2, ex.Message);
            }
        }
Exemple #22
0
        // Execute: Execute the function given the array of the parameters
        public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages message)
        {
            IFeatureClass outputFeatureClass = null;

            try
            {
                // get the input feature class
                IGPMultiValue inputFeatureClasses_Parameter = (IGPMultiValue)m_GPUtilities.UnpackGPValue(paramvalues.get_Element(0));
                layer[]       input_featureClasses          = new layer[inputFeatureClasses_Parameter.Count];
                for (int i = 0; i < inputFeatureClasses_Parameter.Count; i++)
                {
                    IGPValue inputFeatureClass_Parameter = inputFeatureClasses_Parameter.get_Value(i);

                    IFeatureClass inputFeatureClass;
                    IQueryFilter  inputQF;

                    m_GPUtilities.DecodeFeatureLayer(inputFeatureClass_Parameter, out inputFeatureClass, out inputQF);

                    input_featureClasses[i] = new layer()
                    {
                        featureclass = inputFeatureClass, qFilter = inputQF
                    };
                }


                if (input_featureClasses.Length == 0 || input_featureClasses.Any(w => w.featureclass == null))
                {
                    message.AddError(2, "Could not open one or more input dataset.");
                    return;
                }

                //IFields additionalFields = new FieldsClass();
                //additionalFields.AddField(FEATURE_SOURCE_FIELD_NAME, esriFieldType.esriFieldTypeString);
                //additionalFields.AddField(FEATURE_ID_FIELD_NAME, esriFieldType.esriFieldTypeInteger);
                //additionalFields.AddField(
                //    input_featureClasses[0].featureclass.Fields.get_Field(
                //    input_featureClasses[0].featureclass.Fields.FindField(
                //    input_featureClasses[0].featureclass.ShapeFieldName)));

                // create the output feature class
                IGPValue outputFeatureClass_Parameter = m_GPUtilities.UnpackGPValue(paramvalues.get_Element(1));
                outputFeatureClass = GPHelperFunctions.CreateFeatureClass(outputFeatureClass_Parameter, envMgr);

                if (outputFeatureClass == null)
                {
                    message.AddError(2, "Could not create output dataset.");
                    return;
                }



                IGPString curveTypeParameter = (IGPString)m_GPUtilities.UnpackGPValue(paramvalues.get_Element(2));
                ArcConstructionMethods method;
                if (!Enum.TryParse <ArcConstructionMethods>(curveTypeParameter.Value, true, out method))
                {
                    message.AddError(2, string.Format("The value {0} is not expected.  Expected values are: {1}.",
                                                      curveTypeParameter.Value,
                                                      string.Join(",", Enum.GetNames(typeof(ArcConstructionMethods)))));
                    return;
                }

                IStepProgressor stepPro = (IStepProgressor)trackcancel;
                GPHelperFunctions.dropSpatialIndex(outputFeatureClass);

                BoostVoronoi bv = new BoostVoronoi(100);

                double          minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
                List <site_key> point_sites   = new List <site_key>();
                List <site_key> segment_sites = new List <site_key>();

                for (short i = 0; i < input_featureClasses.Length; i++)
                {
                    layer l         = input_featureClasses[i];
                    int   featcount = l.featureclass.FeatureCount(l.qFilter);

                    stepPro.MinRange  = 0;
                    stepPro.MaxRange  = featcount;
                    stepPro.StepValue = (1);
                    stepPro.Message   = "Reading features";
                    stepPro.Position  = 0;
                    stepPro.Show();

                    IFeatureCursor cursor = null;
                    IFeature       row    = null;

                    try
                    {
                        cursor = l.featureclass.Search(l.qFilter, false);
                        while ((row = cursor.NextFeature()) != null)
                        {
                            stepPro.Step();
                            IPoint point = row.Shape as IPoint;
                            if (point != null)
                            {
                                double X = point.X;
                                double Y = point.Y;

                                minX = Math.Min(minX, X);
                                maxX = Math.Max(maxX, X);

                                minY = Math.Min(minY, Y);
                                maxY = Math.Max(maxY, Y);

                                bv.AddPoint(point.X, point.Y);
                                point_sites.Add(new site_key(i, row.OID));
                            }

                            IMultipoint multipoint = row.Shape as IMultipoint;
                            if (multipoint != null)
                            {
                                IPointCollection pointCollection = (IPointCollection)multipoint;
                                IEnumVertex      vertices        = pointCollection.EnumVertices;

                                IPoint vertex = null; int part, index;
                                vertices.Next(out vertex, out part, out index);

                                minX = Math.Min(minX, multipoint.Envelope.XMin);
                                maxX = Math.Max(maxX, multipoint.Envelope.XMax);

                                minY = Math.Min(minY, multipoint.Envelope.YMin);
                                maxY = Math.Max(maxY, multipoint.Envelope.YMax);

                                while (vertex != null)
                                {
                                    bv.AddPoint(vertex.X, vertex.Y);
                                    point_sites.Add(new site_key(i, row.OID));

                                    vertices.Next(out vertex, out part, out index);
                                }
                            }

                            IPolyline polyline = row.Shape as IPolyline;
                            if (polyline != null)
                            {
                                double fromX = polyline.FromPoint.X;
                                double fromY = polyline.FromPoint.Y;
                                double toX   = polyline.ToPoint.X;
                                double toY   = polyline.ToPoint.Y;

                                if (toX < fromX)
                                {
                                    minX = Math.Min(minX, toX);
                                    maxX = Math.Max(maxX, fromX);
                                }
                                else
                                {
                                    minX = Math.Min(minX, fromX);
                                    maxX = Math.Max(maxX, toX);
                                }

                                if (toY < fromY)
                                {
                                    minY = Math.Min(minY, toY);
                                    maxY = Math.Max(maxY, fromY);
                                }
                                else
                                {
                                    minY = Math.Min(minY, fromY);
                                    maxY = Math.Max(maxY, toY);
                                }

                                bv.AddSegment(
                                    polyline.FromPoint.X, polyline.FromPoint.Y,
                                    polyline.ToPoint.X, polyline.ToPoint.Y
                                    );


                                segment_sites.Add(new site_key(i, row.OID));
                            }

                            Marshal.ReleaseComObject(row);
                        }
                    }
                    finally
                    {
                        if (row != null)
                        {
                            Marshal.ReleaseComObject(row);
                        }
                        if (cursor != null)
                        {
                            Marshal.ReleaseComObject(cursor);
                        }

                        stepPro.Hide();
                    }
                }

                message.AddMessage(String.Format("{0}, {1} -> {2}, {3}", minX, minY, maxX, maxY));

                int width  = Math.Max((int)((maxX - minX) * 0.1), 1);
                int height = Math.Max((int)((maxY - minY) * 0.1), 1);

                maxX = maxX + width;
                minX = minX - width;
                maxY = maxY + height;
                minY = minY - height;

                message.AddMessage(String.Format("{0}, {1} -> {2}, {3}", minX, minY, maxX, maxY));
                bv.AddSegment(minX, minY, maxX, minY);
                segment_sites.Add(new site_key(-1, -1));
                bv.AddSegment(maxX, minY, maxX, maxY);
                segment_sites.Add(new site_key(-1, -1));
                bv.AddSegment(maxX, maxY, minX, maxY);
                segment_sites.Add(new site_key(-1, -1));
                bv.AddSegment(minX, maxY, minX, minY);
                segment_sites.Add(new site_key(-1, -1));

                stepPro.Message  = "Solve Voronoi";
                stepPro.MaxRange = 0;
                stepPro.MaxRange = 0;
                stepPro.Show();

                bv.Construct();

                stepPro.Hide();

                int featureSourceIndx = outputFeatureClass.Fields.FindField(FEATURE_SOURCE_FIELD_NAME);
                int featureIDIndx     = outputFeatureClass.Fields.FindField(FEATURE_ID_FIELD_NAME);

                IFeatureCursor inserts = null;
                IFeatureBuffer buffer  = null;
                try
                {
                    object            missing          = Type.Missing;
                    ISpatialReference spatialReference = ((IGeoDataset)outputFeatureClass).SpatialReference;
                    inserts = outputFeatureClass.Insert(false);
                    buffer  = outputFeatureClass.CreateFeatureBuffer();

                    List <Cell> cells = bv.Cells;
                    message.AddMessage(string.Format("{0} cells calculated", cells.Count));
                    List <Edge> edges = bv.Edges;
                    message.AddMessage(string.Format("{0} edges calculated", edges.Count));
                    List <Vertex> vertices = bv.Vertices;
                    message.AddMessage(string.Format("{0} vertexes calculated", vertices.Count));

                    stepPro.Message  = "Write cells";
                    stepPro.MaxRange = 0;
                    stepPro.MaxRange = cells.Count;
                    stepPro.Show();


                    for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++)
                    {
                        try
                        {
                            if (cellIndex % 5000 == 0)
                            {
                                message.AddMessage(String.Format("{0}. {1} cells processed.", DateTime.Now, cellIndex));
                            }

                            Cell cell        = cells[cellIndex];
                            int  currentSite = cell.Site;
                            IGeometryCollection geometryCollection = new GeometryBagClass()
                            {
                                SpatialReference = spatialReference
                            };

                            //ignores any sliver cells
                            if (cell.IsOpen || cell.EdgesIndex.Count < 3)
                            {
                                continue;
                            }

                            ISegmentCollection segmentCollection = createSegments(cell, bv, method, spatialReference);

                            if (((IArea)segmentCollection).Area <= 0)
                            {
                                message.AddMessage("A invalid geometry has been detected, try reversing the orientation.");
                                ISegmentCollection reversed_segmentCollection = new PolygonClass()
                                {
                                    SpatialReference = spatialReference
                                };
                                for (int i = segmentCollection.SegmentCount - 1; i >= 0; i--)
                                {
                                    ISegment segment = (ISegment)segmentCollection.get_Segment(i);
                                    segment.ReverseOrientation();
                                    reversed_segmentCollection.AddSegment(segment);
                                }
                                segmentCollection = reversed_segmentCollection;
                            }

                            ((IPolygon)segmentCollection).SpatialReference = spatialReference;
                            if (((IArea)segmentCollection).Area <= 0)
                            {
                                message.AddWarning("An empty shell has been created");

                                for (int i = 0; i < segmentCollection.SegmentCount; i++)
                                {
                                    ISegment segment = (ISegment)segmentCollection.get_Segment(i);
                                    message.AddMessage(String.Format("From {0}, {1} To {2},{3}",
                                                                     segment.FromPoint.X, segment.FromPoint.Y,
                                                                     segment.ToPoint.X, segment.ToPoint.Y));
                                }
                            }


                            //set attributes
                            site_key sk = (currentSite >= point_sites.Count) ? segment_sites[currentSite - point_sites.Count] : point_sites[currentSite];
                            if (!sk.isEmpty)
                            {
                                buffer.set_Value(featureSourceIndx, input_featureClasses[sk.featureClassIndex].featureclass.AliasName);
                                buffer.set_Value(featureIDIndx, sk.objectID);
                            }
                            else
                            {
                                buffer.set_Value(featureSourceIndx, DBNull.Value);
                                buffer.set_Value(featureIDIndx, DBNull.Value);
                            }


                            IPolygon voronoiPolygon = (IPolygon)segmentCollection;
                            buffer.Shape = (IPolygon)voronoiPolygon;
                            inserts.InsertFeature(buffer);
                        }
                        catch (Exception e)
                        {
                            message.AddWarning("Failed to create a cell");
                        }
                    }
                }
                finally
                {
                    if (buffer != null)
                    {
                        Marshal.ReleaseComObject(buffer);
                    }
                    if (inserts != null)
                    {
                        Marshal.ReleaseComObject(inserts);
                    }
                }

                GPHelperFunctions.createSpatialIndex(outputFeatureClass);
            }
            catch (Exception exx)
            {
                message.AddError(2, exx.Message);
                message.AddMessage(exx.ToString());
            }
            finally
            {
                if (outputFeatureClass != null)
                {
                    Marshal.ReleaseComObject(outputFeatureClass);
                }

                ((IProgressor)trackcancel).Hide();
            }
        }
Exemple #23
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                // Create the object needed to get at the data workspaces
                IJTXDatabaseConnectionManager dbConnectionManager = new JTXDatabaseConnectionManagerClass();
                IJTXDatabaseConnection        dbConnection        = dbConnectionManager.GetConnection(this.WmxDatabase.Alias);

                // Loop through the data workspaces until we find the one we're looking for, then
                // delete it
                bool removedWorkspace = false;
                for (int i = 0; i < dbConnection.DataWorkspaceCount; i++)
                {
                    IJTXWorkspaceConfiguration workspaceCfg = dbConnection.get_DataWorkspace(i);
                    if (workspaceCfg.Name.Equals(m_dataWorkspace))
                    {
                        dbConnection.RemoveDataWorkspace(i);
                        removedWorkspace = true;
                        break;
                    }
                }

                // Raise an error if we somehow couldn't find it (should never happen with
                // the domain on the input param)
                if (!removedWorkspace)
                {
                    throw new WmauException(WmauErrorCodes.C_WORKSPACE_NOT_FOUND_ERROR);
                }

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_DATA_WORKSPACE);
                IGPString         outParamStr  = new GPStringClass();
                outParamStr.Value  = m_dataWorkspace;
                outParamEdit.Value = outParamStr as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            finally
            {
                // Release any COM objects here!
            }
        }
        // Execute: Execute the function given the array of the parameters
        public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages message)
        {
            IFeatureClass outputFeatureClass = null;
            try
            {
                // get the input feature class
                IGPMultiValue inputFeatureClasses_Parameter = (IGPMultiValue)m_GPUtilities.UnpackGPValue(paramvalues.get_Element(0));
                layer[] input_featureClasses = new layer[inputFeatureClasses_Parameter.Count];
                for (int i = 0; i < inputFeatureClasses_Parameter.Count; i++)
                {
                    IGPValue inputFeatureClass_Parameter = inputFeatureClasses_Parameter.get_Value(i);

                    IFeatureClass inputFeatureClass;
                    IQueryFilter inputQF;

                    m_GPUtilities.DecodeFeatureLayer(inputFeatureClass_Parameter, out inputFeatureClass, out inputQF);

                    input_featureClasses[i] = new layer() { featureclass = inputFeatureClass, qFilter = inputQF};
                }

                if (input_featureClasses.Length == 0 || input_featureClasses.Any(w=> w.featureclass == null))
                {
                    message.AddError(2, "Could not open one or more input dataset.");
                    return;
                }

                //IFields additionalFields = new FieldsClass();
                //additionalFields.AddField(FEATURE_SOURCE_FIELD_NAME, esriFieldType.esriFieldTypeString);
                //additionalFields.AddField(FEATURE_ID_FIELD_NAME, esriFieldType.esriFieldTypeInteger);
                //additionalFields.AddField(
                //    input_featureClasses[0].featureclass.Fields.get_Field(
                //    input_featureClasses[0].featureclass.Fields.FindField(
                //    input_featureClasses[0].featureclass.ShapeFieldName)));

                // create the output feature class
                IGPValue outputFeatureClass_Parameter = m_GPUtilities.UnpackGPValue(paramvalues.get_Element(1));
                outputFeatureClass = GPHelperFunctions.CreateFeatureClass(outputFeatureClass_Parameter, envMgr);

                if (outputFeatureClass == null)
                {
                    message.AddError(2, "Could not create output dataset.");
                    return;
                }

                IGPString curveTypeParameter = (IGPString)m_GPUtilities.UnpackGPValue(paramvalues.get_Element(2));
                ArcConstructionMethods method;
                if (!Enum.TryParse<ArcConstructionMethods>(curveTypeParameter.Value, true, out method))
                {
                    message.AddError(2, string.Format("The value {0} is not expected.  Expected values are: {1}.",
                        curveTypeParameter.Value,
                        string.Join(",", Enum.GetNames(typeof(ArcConstructionMethods)))));
                    return;
                }

                IStepProgressor stepPro = (IStepProgressor)trackcancel;
                GPHelperFunctions.dropSpatialIndex(outputFeatureClass);

                BoostVoronoi bv = new BoostVoronoi(100);

                double minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
                List<site_key> point_sites = new List<site_key>();
                List<site_key> segment_sites = new List<site_key>();

                for (short i = 0; i < input_featureClasses.Length; i++)
                {
                    layer l = input_featureClasses[i];
                    int featcount = l.featureclass.FeatureCount(l.qFilter);

                    stepPro.MinRange = 0;
                    stepPro.MaxRange = featcount;
                    stepPro.StepValue = (1);
                    stepPro.Message = "Reading features";
                    stepPro.Position = 0;
                    stepPro.Show();

                    IFeatureCursor cursor = null;
                    IFeature row = null;

                    try
                    {
                        cursor = l.featureclass.Search(l.qFilter, false);
                        while ((row = cursor.NextFeature()) != null)
                        {
                            stepPro.Step();
                            IPoint point = row.Shape as IPoint;
                            if (point != null)
                            {
                                double X = point.X;
                                double Y = point.Y;

                                minX = Math.Min(minX, X);
                                maxX = Math.Max(maxX, X);

                                minY = Math.Min(minY, Y);
                                maxY = Math.Max(maxY, Y);

                                bv.AddPoint(point.X, point.Y);
                                point_sites.Add(new site_key(i, row.OID));
                            }

                            IMultipoint multipoint = row.Shape as IMultipoint;
                            if (multipoint != null)
                            {
                                IPointCollection pointCollection = (IPointCollection)multipoint;
                                IEnumVertex vertices = pointCollection.EnumVertices;

                                IPoint vertex = null; int part, index;
                                vertices.Next(out vertex, out part, out index);

                                minX = Math.Min(minX, multipoint.Envelope.XMin);
                                maxX = Math.Max(maxX, multipoint.Envelope.XMax);

                                minY = Math.Min(minY, multipoint.Envelope.YMin);
                                maxY = Math.Max(maxY, multipoint.Envelope.YMax);

                                while (vertex != null)
                                {
                                    bv.AddPoint(vertex.X, vertex.Y);
                                    point_sites.Add(new site_key(i, row.OID));

                                    vertices.Next(out vertex, out part, out index);
                                }
                            }

                            IPolyline polyline = row.Shape as IPolyline;
                            if (polyline != null)
                            {
                                double fromX = polyline.FromPoint.X;
                                double fromY = polyline.FromPoint.Y;
                                double toX = polyline.ToPoint.X;
                                double toY = polyline.ToPoint.Y;

                                if (toX < fromX)
                                {
                                    minX = Math.Min(minX, toX);
                                    maxX = Math.Max(maxX, fromX);
                                }
                                else
                                {
                                    minX = Math.Min(minX, fromX);
                                    maxX = Math.Max(maxX, toX);
                                }

                                if (toY < fromY)
                                {
                                    minY = Math.Min(minY, toY);
                                    maxY = Math.Max(maxY, fromY);
                                }
                                else
                                {
                                    minY = Math.Min(minY, fromY);
                                    maxY = Math.Max(maxY, toY);
                                }

                                bv.AddSegment(
                                    polyline.FromPoint.X, polyline.FromPoint.Y,
                                    polyline.ToPoint.X, polyline.ToPoint.Y
                                );

                                segment_sites.Add(new site_key(i, row.OID));
                            }

                            Marshal.ReleaseComObject(row);
                        }
                    }
                    finally
                    {
                        if (row != null) Marshal.ReleaseComObject(row);
                        if (cursor != null) Marshal.ReleaseComObject(cursor);

                        stepPro.Hide();
                    }
                }

                message.AddMessage(String.Format("{0}, {1} -> {2}, {3}", minX, minY, maxX, maxY));

                int width = Math.Max((int)((maxX - minX) * 0.1), 1);
                int height = Math.Max((int)((maxY - minY) * 0.1), 1);

                maxX = maxX + width;
                minX = minX - width;
                maxY = maxY + height;
                minY = minY - height;

                message.AddMessage(String.Format("{0}, {1} -> {2}, {3}", minX, minY, maxX, maxY));
                bv.AddSegment(minX, minY, maxX, minY);
                segment_sites.Add(new site_key(-1, -1));
                bv.AddSegment(maxX, minY, maxX, maxY);
                segment_sites.Add(new site_key(-1, -1));
                bv.AddSegment(maxX, maxY, minX, maxY);
                segment_sites.Add(new site_key(-1, -1));
                bv.AddSegment(minX, maxY, minX, minY);
                segment_sites.Add(new site_key(-1, -1));

                stepPro.Message = "Solve Voronoi";
                stepPro.MaxRange = 0;
                stepPro.MaxRange = 0;
                stepPro.Show();

                bv.Construct();

                stepPro.Hide();

                int featureSourceIndx = outputFeatureClass.Fields.FindField(FEATURE_SOURCE_FIELD_NAME);
                int featureIDIndx = outputFeatureClass.Fields.FindField(FEATURE_ID_FIELD_NAME);

                IFeatureCursor inserts = null;
                IFeatureBuffer buffer = null;
                try
                {
                    object missing = Type.Missing;
                    ISpatialReference spatialReference = ((IGeoDataset)outputFeatureClass).SpatialReference;
                    inserts = outputFeatureClass.Insert(false);
                    buffer = outputFeatureClass.CreateFeatureBuffer();

                    List<Cell> cells = bv.Cells;
                    message.AddMessage(string.Format("{0} cells calculated", cells.Count));
                    List<Edge> edges = bv.Edges;
                    message.AddMessage(string.Format("{0} edges calculated", edges.Count));
                    List<Vertex> vertices = bv.Vertices;
                    message.AddMessage(string.Format("{0} vertexes calculated", vertices.Count));

                    stepPro.Message = "Write cells";
                    stepPro.MaxRange = 0;
                    stepPro.MaxRange = cells.Count;
                    stepPro.Show();

                    for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++)
                    {
                        try
                        {
                            if(cellIndex % 5000 == 0) message.AddMessage(String.Format("{0}. {1} cells processed.", DateTime.Now, cellIndex));

                            Cell cell = cells[cellIndex];
                            int currentSite = cell.Site;
                            IGeometryCollection geometryCollection = new GeometryBagClass() { SpatialReference = spatialReference };

                            //ignores any sliver cells
                            if (cell.IsOpen || cell.EdgesIndex.Count < 3)
                                continue;

                            ISegmentCollection segmentCollection = createSegments(cell, bv, method, spatialReference);

                            if (((IArea)segmentCollection).Area <= 0)
                            {

                                message.AddMessage("A invalid geometry has been detected, try reversing the orientation.");
                                ISegmentCollection reversed_segmentCollection = new PolygonClass() { SpatialReference = spatialReference };
                                for (int i = segmentCollection.SegmentCount - 1; i >= 0; i--)
                                {
                                    ISegment segment = (ISegment)segmentCollection.get_Segment(i);
                                    segment.ReverseOrientation();
                                    reversed_segmentCollection.AddSegment(segment);
                                }
                                segmentCollection = reversed_segmentCollection;
                            }

                            ((IPolygon)segmentCollection).SpatialReference = spatialReference;
                            if (((IArea)segmentCollection).Area <= 0)
                            {
                                message.AddWarning("An empty shell has been created");

                                for (int i = 0; i < segmentCollection.SegmentCount; i++)
                                {
                                    ISegment segment = (ISegment)segmentCollection.get_Segment(i);
                                    message.AddMessage(String.Format("From {0}, {1} To {2},{3}",
                                    segment.FromPoint.X, segment.FromPoint.Y,
                                    segment.ToPoint.X, segment.ToPoint.Y));
                                }

                            }

                            //set attributes
                            site_key sk = (currentSite >= point_sites.Count) ? segment_sites[currentSite - point_sites.Count] : point_sites[currentSite];
                            if (!sk.isEmpty)
                            {
                                buffer.set_Value(featureSourceIndx, input_featureClasses[sk.featureClassIndex].featureclass.AliasName);
                                buffer.set_Value(featureIDIndx, sk.objectID);
                            }
                            else
                            {
                                buffer.set_Value(featureSourceIndx, DBNull.Value);
                                buffer.set_Value(featureIDIndx, DBNull.Value);
                            }

                            IPolygon voronoiPolygon = (IPolygon)segmentCollection;
                            buffer.Shape = (IPolygon)voronoiPolygon;
                            inserts.InsertFeature(buffer);
                        }
                        catch (Exception e)
                        {
                            message.AddWarning("Failed to create a cell");
                        }
                    }
                }
                finally
                {
                    if (buffer != null) Marshal.ReleaseComObject(buffer);
                    if (inserts != null) Marshal.ReleaseComObject(inserts);
                }

                GPHelperFunctions.createSpatialIndex(outputFeatureClass);

            }
            catch (Exception exx)
            {
                message.AddError(2, exx.Message);
                message.AddMessage(exx.ToString());
            }
            finally
            {
                if (outputFeatureClass != null) Marshal.ReleaseComObject(outputFeatureClass);

                ((IProgressor)trackcancel).Hide();
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                // Indicate if changes are not actually being made
                string actionStr = "  Deleting";
                if (m_previewChanges)
                {
                    msgs.AddMessage("PREVIEWING CHANGES ONLY; no changes will be made");
                    actionStr = "  Found";
                }

                IJTXConfiguration3     configMgr  = WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXConfigurationEdit2 configEdit = WmxDatabase.ConfigurationManager as IJTXConfigurationEdit2;

                // Find all of the orphans in the database
                msgs.AddMessage("Searching for orphaned items...");
                int orphanCount = UpdateAllOrphans();
                msgs.AddMessage("Found " + orphanCount.ToString() + " total orphaned items");

                // If requested, delete any workflows first
                if (m_cleanWorkflows)
                {
                    List <int> unusedWorkflowIds = m_unusedWorkflows.Keys.ToList();
                    unusedWorkflowIds.Sort();
                    foreach (int id in unusedWorkflowIds)
                    {
                        msgs.AddMessage(actionStr + " workflow " + id.ToString() + " (" + m_unusedWorkflows[id] + ")");
                        if (!this.m_previewChanges)
                        {
                            configMgr.DeleteWorkflow(id);
                        }
                    }
                }

                // If requested, delete any step types
                if (m_cleanStepTypes)
                {
                    List <int> unusedStepTypeIds = m_unusedStepTypes.Keys.ToList();
                    unusedStepTypeIds.Sort();
                    foreach (int stepTypeId in unusedStepTypeIds)
                    {
                        msgs.AddMessage(actionStr + " step type " + stepTypeId.ToString() + " (" + m_unusedStepTypes[stepTypeId] + ")");
                        if (!this.m_previewChanges)
                        {
                            configEdit.DeleteStepType(stepTypeId);
                        }
                    }
                }

                // If requested, delete any status types
                if (m_cleanStatusTypes)
                {
                    List <int> unusedStatusTypeIds = m_unusedStatusTypes.Keys.ToList();
                    unusedStatusTypeIds.Sort();
                    foreach (int statusTypeId in unusedStatusTypeIds)
                    {
                        msgs.AddMessage(actionStr + " status type " + statusTypeId.ToString() + " (" + m_unusedStatusTypes[statusTypeId] + ")");
                        if (!this.m_previewChanges)
                        {
                            configEdit.DeleteStatus(statusTypeId);
                        }
                    }
                }

                // If requested, delete any priority types
                if (m_cleanPriorities)
                {
                    List <int> unusedPriorityTypeIds = m_unusedPriorities.Keys.ToList();
                    unusedPriorityTypeIds.Sort();
                    foreach (int priority in unusedPriorityTypeIds)
                    {
                        msgs.AddMessage(actionStr + " priority " + priority.ToString() + " (" + m_unusedPriorities[priority] + ")");
                        if (!m_previewChanges)
                        {
                            configEdit.DeletePriority(priority);
                        }
                    }
                }

                // If requested, delete any unused Task Assistant workbooks
                if (m_cleanTaWorkbooks)
                {
                    List <string> unusedTaWorkbookNames = m_unusedTaWorkbooks.Keys.ToList();
                    unusedTaWorkbookNames.Sort();
                    foreach (string workbookName in unusedTaWorkbookNames)
                    {
                        msgs.AddMessage(actionStr + " workbook " + workbookName);
                        if (!m_previewChanges)
                        {
                            configMgr.RemoveTaskAssistantWorkflowRecord(workbookName);
                        }
                    }
                }

                // If requested, delete any unused users
                if (m_cleanUsers)
                {
                    List <string> unusedUserNames = m_unusedUsers.Keys.ToList();
                    unusedUserNames.Sort();
                    foreach (string user in unusedUserNames)
                    {
                        msgs.AddMessage(actionStr + " user " + user + " (" + m_unusedUsers[user] + ")");
                        if (!m_previewChanges)
                        {
                            configEdit.DeleteUser(user);
                        }
                    }
                }

                // If requested, delete any unused map documents
                if (m_cleanMapDocs)
                {
                    List <string> unusedMapDocs = m_unusedMapDocs.Keys.ToList();
                    unusedMapDocs.Sort();
                    foreach (string mapName in unusedMapDocs)
                    {
                        msgs.AddMessage(actionStr + " map document " + mapName + " (" + m_unusedMapDocs[mapName].ToString() + ")");
                        if (!m_previewChanges)
                        {
                            configMgr.DeleteJTXMap(m_unusedMapDocs[mapName]);
                        }
                    }
                }

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_NUM_ITEMS_DELETED);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = orphanCount;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            WorkspaceWorksheetReader reader = null;

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                reader = new WorkspaceWorksheetReader(this.m_excelFilePath, msgs);

                // Prepare to set/build the output parameter
                WmauParameterMap  paramMap      = new WmauParameterMap(paramValues);
                IGPParameter3     outParam      = paramMap.GetParam(C_PARAM_OUT_WORKSPACES_CREATED);
                IGPParameterEdit3 outParamEdit  = paramMap.GetParamEdit(C_PARAM_OUT_WORKSPACES_CREATED);
                IGPMultiValue     outMultiValue = new GPMultiValueClass();
                outMultiValue.MemberDataType = outParam.DataType;

                // Load the workspace info from the spreadsheet
                List <Common.WorkspaceInfo> dataWorkspaces = reader.GetWorkspacesFromSpreadsheet();

                // Loop through each of the workspaces
                IJTXDatabaseConnectionManager dbConnectionManager = new JTXDatabaseConnectionManagerClass();
                IJTXDatabaseConnection        dbConnection        = dbConnectionManager.GetConnection(WmxDatabase.Alias);
                foreach (Common.WorkspaceInfo wmauWorkspaceInfo in dataWorkspaces)
                {
                    string workspaceName = wmauWorkspaceInfo.Name;
                    if (Common.WmauHelperFunctions.LookupWorkspaceNameObj(this.WmxDatabase, workspaceName) != null)
                    {
                        msgs.AddWarning("Skipping existing workspace '" + workspaceName + "'");
                    }
                    else
                    {
                        IJTXWorkspaceConfiguration workspaceInfo = dbConnection.AddDataWorkspace();
                        this.CopyDataWorkspace(wmauWorkspaceInfo, ref workspaceInfo, msgs);
                        workspaceInfo.Store();
                        msgs.AddMessage("Added new workspace '" + workspaceName + "'");

                        IGPString outElement = new GPStringClass();
                        outElement.Value = workspaceName;
                        outMultiValue.AddValue(outElement as IGPValue);
                    }
                }

                // Set the value of the output parameter
                outParamEdit.Value = outMultiValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_WORKSPACE_LOAD_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens }
                }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }
        }
Exemple #27
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            ICursor cursor = null;

            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                IJTXSpatialNotificationManager snManager = this.WmxDatabase.SpatialNotificationManager;

                // Find the rule that we're modifying
                IJTXChangeRule2 changeRule = GetChangeRuleByName(m_spatialNotification) as IJTXChangeRule2;

                // Create and configure the area evaluator
                IJTXAOIConditionEvaluator areaEvaluator = CreateEvaluator(C_TYPE_AREA_EVALUATOR) as IJTXAOIConditionEvaluator;
                areaEvaluator.SpatialRel = m_geometricOperations[m_geometricOperation];
                areaEvaluator.UseInverse = m_useInverse;
                areaEvaluator.UseJobAOI  = m_useJobAoi;

                // Set the AOI of the job, if there is one
                // Ensure that there's nothing wrong with the AOI feature that is selected, if any
                if (!m_useJobAoi)
                {
                    if (m_alternateAoi != null)
                    {
                        IFeatureLayer     featLayer = m_alternateAoi as IFeatureLayer;
                        IFeatureSelection featSel   = m_alternateAoi as IFeatureSelection;
                        ISelectionSet     selSet    = featSel.SelectionSet as ISelectionSet;

                        if (featLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPolygon)
                        {
                            throw new WmauException(new WmauError(WmauErrorCodes.C_AOI_NOT_POLYGON_ERROR));
                        }
                        else if (selSet.Count != 1)
                        {
                            throw new WmauException(new WmauError(WmauErrorCodes.C_EXPECTED_ONE_SELECTED_FEATURE_ERROR));
                        }

                        // If we get this far, we know that there's exactly one selected feature, so we
                        // don't have to loop through the selection set
                        selSet.Search(null, true, out cursor);
                        IFeatureCursor featureCursor = cursor as IFeatureCursor;
                        IFeature       aoiCandidate  = featureCursor.NextFeature();

                        // We also know that the feature is a polygon, so just make the cast
                        areaEvaluator.AreaOfInterest = aoiCandidate.Shape as IPolygon;
                    }
                }

                // Associate the evaluator with the change rule and save the changes
                changeRule.Evaluators.Add(areaEvaluator as IJTXConditionEvaluator);
                changeRule.Store();

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_SPATIAL_NOTIFICATION);
                IGPString         outParamStr  = new GPStringClass();
                outParamStr.Value  = m_spatialNotification;
                outParamEdit.Value = outParamStr as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_ADD_AREA_EVAL_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            finally
            {
                // Release any COM objects here!
                if (cursor != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor);
                }
            }
        }
        public void Execute(IArray paramvalues,
                            ITrackCancel trackcancel,
                            IGPEnvironmentManager envMgr,
                            IGPMessages messages)
        {
            // Re-validate.
            IGPMessages ms = m_util.InternalValidate(ParameterInfo,
                                                     paramvalues,
                                                     false, false,
                                                     envMgr);


            messages.AddMessage("MWSW Boundary Generator, v. 0.0");

            if (((IGPMessage)(ms)).IsError())
            {
                messages.AddMessages(ms);
                return;
            }
            if (!AoGPParameter.ValidateAll(m_parms, paramvalues, messages))
            {
                return;
            }

            try {
                IGPValue  inlyr    = m_util.UnpackGPValue((paramvalues.get_Element(0) as IGPParameter).Value);
                IGPDouble ang_tol  = m_util.UnpackGPValue((paramvalues.get_Element(1) as IGPParameter).Value) as IGPDouble;
                IGPDouble dist_tol = m_util.UnpackGPValue((paramvalues.get_Element(2) as IGPParameter).Value) as IGPDouble;
                IGPValue  outlyr   = m_util.UnpackGPValue((paramvalues.get_Element(3) as IGPParameter).Value);

                //		DumpIt("In layer",inlyr,messages);
                //		DumpIt("Out layer",outlyr,typeof(IGPValue),messages);

                IFeatureClass inputfc;
                IQueryFilter  inputqf;
                m_util.DecodeFeatureLayer(inlyr, out inputfc, out inputqf);

                //			DumpIt("In Featureclass",inputfc,typeof(IFeatureClass),messages);
                //			DumpIt("In QF",inputqf,typeof(IQueryFilter),messages);

                messages.AddMessage("In angle tolerance: " + ang_tol.Value);
                messages.AddMessage("In distance tolerance: " + dist_tol.Value);
                messages.AddMessage("Input featureclass: " + inputfc.AliasName);
                messages.AddMessage("Output path: " + outlyr.GetAsText());

                trackcancel.Progressor.Show();
                trackcancel.Progressor.Message = "Processing...";

                string             outp_txt = outlyr.GetAsText();
                AoFeatureClassName fcname   = new AoFeatureClassName(outp_txt);
                ISpatialReference  spref    = AoTable.From(inputfc)[inputfc.ShapeFieldName].Field.GeometryDef.SpatialReference;

                string shapename = fcname.ShapeFieldName != "" ? fcname.ShapeFieldName : "Shape";
                m_outp_schema[shapename] = AoField.Shape(shapename,
                                                         esriGeometryType.esriGeometryPolyline,
                                                         spref);


                // TODO: shapefiles seem to get an FID automatically,
                //   while geodb needs an 'OBJECTID',
                //   who knows about other workspace types?
                // Is there a way to figure this out w/o looking at the type?

                IFeatureClass outputfc =
                    fcname.Workspace.CreateFeatureClass(fcname.Basename,
                                                        m_outp_schema.Fields,
                                                        null,
                                                        null,
                                                        esriFeatureType.esriFTSimple,
                                                        shapename,
                                                        "");

                IStepProgressor progressor = trackcancel.Progressor as IStepProgressor;
                progressor.MaxRange = 200;

                BGenImp implementation = new BGenImp(spref, ang_tol.Value, dist_tol.Value);
                implementation.Run(inputfc, outputfc, delegate(double howfar) {
                    progressor.Position = (int)(200.0 * howfar);
                });

                messages.AddMessage("Finished, worked through " + implementation.TotalSegments + " line segments total.");
                return;
            } catch (Exception e) {
                while (e != null)
                {
                    messages.AddError(1, "Exception: " + e.Message);
                    e = e.InnerException;
                }
            }
        }
Exemple #29
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            IJTXJob4 job = null;

            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            //////////////////////////////////////////////////////////////////////
            // TODO: Update the job-creation logic.
            //
            // In subsequent builds of Workflow Manager (post-10.0), there may be
            // a new API that creates jobs and handles much of the logic included
            // in this function (and this class at large).  If so, this GP tool
            // should be revised to make use of this simplified interface.
            //
            // Anyone using this tool as a reference, particularly with regards
            // to creating Workflow Manager jobs, should keep this in mind.
            //////////////////////////////////////////////////////////////////////

            // Try to create the job, as requested
            try
            {
                IJTXJobManager2   jobManager = this.WmxDatabase.JobManager as IJTXJobManager2;
                IJTXConfiguration configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration;
                IJTXJobType4      jobTypeObj = configMgr.GetJobType(m_jobTypeAsString) as IJTXJobType4;

                // Set up the description object to be used to create this job
                IJTXJobDescription jobDescription = new JTXJobDescriptionClass();
                jobDescription.JobTypeName = m_jobTypeAsString;
                jobDescription.AOI         = GetPolygonFromSpecifiedLayer(m_aoiLayer);

                // Set up the ownership & assignment of the job
                jobDescription.OwnedBy = m_jobOwner;
                if (m_assigneeType.Equals(C_OPT_ASSIGN_TO_GROUP))
                {
                    jobDescription.AssignedType = jtxAssignmentType.jtxAssignmentTypeGroup;
                    jobDescription.AssignedTo   = m_assignee;
                }
                else if (m_assigneeType.Equals(C_OPT_ASSIGN_TO_USER))
                {
                    jobDescription.AssignedType = jtxAssignmentType.jtxAssignmentTypeUser;
                    jobDescription.AssignedTo   = m_assignee;
                }
                else if (m_assigneeType.Equals(C_OPT_UNASSIGNED))
                {
                    jobDescription.AssignedType = jtxAssignmentType.jtxAssignmentTypeUnassigned;
                    jobDescription.AssignedTo   = string.Empty;
                }
                else
                {
                    // Do nothing; let the job type defaults take over
                    msgs.AddMessage("Using job type defaults for job assignment");
                    jobDescription.AssignedType = jobTypeObj.DefaultAssignedType;
                    jobDescription.AssignedTo   = jobTypeObj.DefaultAssignedTo;
                }

                // Start date
                if (m_startDate != null && m_startDate.Value != null)
                {
                    string tempStr = m_startDate.Value.ToString();

                    // Workflow Manager stores times as UTC times; input times must
                    // therefore be pre-converted
                    DateTime tempDate = DateTime.Parse(tempStr);
                    jobDescription.StartDate = TimeZone.CurrentTimeZone.ToUniversalTime(tempDate);
                }
                else
                {
                    msgs.AddMessage("Using job type defaults for start date");
                    jobDescription.StartDate = jobTypeObj.DefaultStartDate;
                }

                // Due date
                if (m_dueDate != null && m_dueDate.Value != null)
                {
                    string tempStr = m_dueDate.Value.ToString();

                    // Workflow Manager stores times as UTC times; input times must
                    // therefore be pre-converted
                    DateTime tempDate = DateTime.Parse(tempStr);
                    jobDescription.DueDate = TimeZone.CurrentTimeZone.ToUniversalTime(tempDate);
                }
                else
                {
                    msgs.AddMessage("Using job type defaults for due date");
                    jobDescription.DueDate = jobTypeObj.DefaultDueDate;
                }

                // Priority
                if (!m_priority.Equals(string.Empty))
                {
                    IJTXPriority priority = configMgr.GetPriority(m_priority);
                    jobDescription.Priority = priority;
                }
                else
                {
                    msgs.AddMessage("Using job type defaults for priority");
                    jobDescription.Priority = jobTypeObj.DefaultPriority;
                }

                // Parent job
                if (m_parentJobId > 0)
                {
                    jobDescription.ParentJobId = m_parentJobId;
                }

                // Data workspace
                if (m_dataWorkspaceId.Equals(C_OPT_VAL_NOT_SET))
                {
                    jobDescription.DataWorkspaceID = string.Empty;
                }
                else if (!m_dataWorkspaceId.Equals(string.Empty))
                {
                    jobDescription.DataWorkspaceID = m_dataWorkspaceId;
                }
                else
                {
                    msgs.AddMessage("Using job type defaults for data workspace");
                    if (jobTypeObj.DefaultDataWorkspace != null)
                    {
                        jobDescription.DataWorkspaceID = jobTypeObj.DefaultDataWorkspace.DatabaseID;
                    }
                }

                // Parent version
                if (m_parentVersion.Equals(C_OPT_VAL_NOT_SET))
                {
                    jobDescription.ParentVersionName = string.Empty;
                }
                else if (!m_parentVersion.Equals(string.Empty))
                {
                    jobDescription.ParentVersionName = m_parentVersion;
                }
                else
                {
                    msgs.AddMessage("Using job type defaults for parent version");
                    jobDescription.ParentVersionName = jobTypeObj.DefaultParentVersionName;
                }

                // Auto-execution
                jobDescription.AutoExecuteOnCreate = m_executeNewJob;

                // Create the new job
                int             expectedNumJobs = 1;
                bool            checkAoi        = true;
                IJTXJobSet      jobSet          = null;
                IJTXExecuteInfo execInfo;
                try
                {
                    jobSet = jobManager.CreateJobsFromDescription(jobDescription, expectedNumJobs, checkAoi, out execInfo);
                }
                catch (System.Runtime.InteropServices.COMException comEx)
                {
                    throw new WmauException(WmauErrorCodes.C_CREATE_JOB_ERROR, comEx);
                }

                if ((execInfo != null && execInfo.ThrewError) ||
                    jobSet == null ||
                    jobSet.Count != expectedNumJobs)
                {
                    if (execInfo != null && !string.IsNullOrEmpty(execInfo.ErrorDescription))
                    {
                        throw new WmauException(
                                  WmauErrorCodes.C_CREATE_JOB_ERROR,
                                  new Exception(execInfo.ErrorCode.ToString() + ": " + execInfo.ErrorDescription));
                    }
                    else
                    {
                        throw new WmauException(WmauErrorCodes.C_CREATE_JOB_ERROR);
                    }
                }

                // If it gets all the way down here without errors, set the output ID with the
                // ID of the job that was created.
                job = jobSet.Next() as IJTXJob4;
                WmauParameterMap paramMap   = new WmauParameterMap(paramValues);
                IGPValue         jobIdGpVal = new GPLongClass();
                jobIdGpVal.SetAsText(job.ID.ToString());
                IGPParameterEdit3 jobIdParam = paramMap.GetParamEdit(C_PARAM_NEWJOBID);
                jobIdParam.Value = jobIdGpVal;
                msgs.AddMessage("Created job: " + job.ID.ToString() + " (" + job.Name + ")");

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                    if (job != null)
                    {
                        this.WmxDatabase.JobManager.DeleteJob(job.ID, true);
                    }
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_CREATE_JOB_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                    if (job != null)
                    {
                        this.WmxDatabase.JobManager.DeleteJob(job.ID, true);
                    }
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
        }
        private void CreateAndPopulateTurnFeatureClass(string outputFileGdbPath, string fdsName,
                                                       string ProhibRdmsTableName, string tempStatsTableName,
                                                       IGPMessages messages, ITrackCancel trackcancel)
        {
            // Determine the number of AltID fields we need (one more than the MAX_SEQ_NUMBER value).

            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var wsf = Activator.CreateInstance(factoryType) as IWorkspaceFactory;
            var fws = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            ITable tempStatsTable = fws.OpenTable(tempStatsTableName);
            short numAltIDFields = 2;
            if (tempStatsTable.RowCount(null) == 1)
                numAltIDFields = (short)(1 + (double)(tempStatsTable.GetRow(1).get_Value(tempStatsTable.FindField("MAX_SEQ_NUMBER"))));

            // Open the Rdms table and find the fields we need

            ITable rdmsTable = fws.OpenTable(ProhibRdmsTableName);
            int seqNumberField = rdmsTable.FindField("SEQ_NUMBER");
            int linkIDFieldOnRdms = rdmsTable.FindField("LINK_ID");
            int manLinkIDField = rdmsTable.FindField("MAN_LINKID");
            int condIDFieldOnRdms = rdmsTable.FindField("COND_ID");
            int endOfLkFieldOnRdms = rdmsTable.FindField("END_OF_LK");

            // Create a temporary template feature class

            var fcd = new FeatureClassDescriptionClass() as IFeatureClassDescription;
            var ocd = fcd as IObjectClassDescription;
            var fieldsEdit = ocd.RequiredFields as IFieldsEdit;
            IField fieldOnRdmsTable = rdmsTable.Fields.get_Field(linkIDFieldOnRdms);  // use the LINK_ID field as a template for the AltID fields
            for (short i = 1; i <= numAltIDFields; i++)
            {
                IFieldEdit newField = new FieldClass();
                newField.Name_2 = "AltID" + i;
                newField.Precision_2 = fieldOnRdmsTable.Precision;
                newField.Scale_2 = fieldOnRdmsTable.Scale;
                newField.Type_2 = fieldOnRdmsTable.Type;
                fieldsEdit.AddField(newField as IField);
            }
            fieldOnRdmsTable = rdmsTable.Fields.get_Field(condIDFieldOnRdms);
            fieldsEdit.AddField(fieldOnRdmsTable);
            var fieldChk = new FieldCheckerClass() as IFieldChecker;
            IEnumFieldError enumFieldErr = null;
            IFields validatedFields = null;
            fieldChk.ValidateWorkspace = fws as IWorkspace;
            fieldChk.Validate(fieldsEdit as IFields, out enumFieldErr, out validatedFields);
            var tempFC = fws.CreateFeatureClass("TheTemplate", validatedFields, ocd.InstanceCLSID, ocd.ClassExtensionCLSID,
                                                esriFeatureType.esriFTSimple, fcd.ShapeFieldName, "") as IDataset;

            // Create the turn feature class from the template, then delete the template

            Geoprocessor gp = new Geoprocessor();
            CreateTurnFeatureClass createTurnFCTool = new CreateTurnFeatureClass();
            string pathToFds = outputFileGdbPath + "\\" + fdsName;
            createTurnFCTool.out_location = pathToFds;
            createTurnFCTool.out_feature_class_name = TurnFCName;
            createTurnFCTool.maximum_edges = numAltIDFields;
            createTurnFCTool.in_template_feature_class = outputFileGdbPath + "\\TheTemplate";
            gp.Execute(createTurnFCTool, trackcancel);
            tempFC.Delete();

            // Open the new turn feature class and find all the fields on it

            IFeatureClass turnFC = fws.OpenFeatureClass(TurnFCName);
            int[] altIDFields = new int[numAltIDFields];
            int[] edgeFCIDFields = new int[numAltIDFields];
            int[] edgeFIDFields = new int[numAltIDFields];
            int[] edgePosFields = new int[numAltIDFields];
            for (short i = 0; i < numAltIDFields; i++)
            {
                altIDFields[i] = turnFC.FindField("AltID" + (i + 1));
                edgeFCIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FCID");
                edgeFIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FID");
                edgePosFields[i] = turnFC.FindField("Edge" + (i + 1) + "Pos");
            }
            int edge1endField = turnFC.FindField("Edge1End");
            int condIDFieldOnTurnFC = turnFC.FindField("COND_ID");

            // Look up the FCID of the Streets feature class

            IFeatureClass streetsFC = fws.OpenFeatureClass(StreetsFCName);
            int streetsFCID = streetsFC.FeatureClassID;

            // Set up queries

            var ts = new TableSortClass() as ITableSort;
            ts.Fields = "COND_ID, SEQ_NUMBER";
            ts.set_Ascending("COND_ID", true);
            ts.set_Ascending("SEQ_NUMBER", true);
            ts.QueryFilter = new QueryFilterClass();
            ts.Table = rdmsTable;
            ts.Sort(null);
            ICursor rdmsCursor = ts.Rows;
            IFeatureCursor turnFCCursor = turnFC.Insert(true);
            IFeatureBuffer turnBuffer = turnFC.CreateFeatureBuffer();

            // Write the field values to the turn feature class accordingly

            int numFeatures = 0;
            IRow rdmsRow = rdmsCursor.NextRow();
            while (rdmsRow != null)
            {
                // Transfer the non-edge identifying field values to the buffer
                turnBuffer.set_Value(condIDFieldOnTurnFC, rdmsRow.get_Value(condIDFieldOnRdms));

                // Write the Edge1End field value to the buffer
                switch ((string)(rdmsRow.get_Value(endOfLkFieldOnRdms)))
                {
                    case "N":
                        turnBuffer.set_Value(edge1endField, "Y");
                        break;
                    case "R":
                        turnBuffer.set_Value(edge1endField, "N");
                        break;
                    default:
                        break;    // not expected
                }

                // Write the AltID values to the buffer
                turnBuffer.set_Value(altIDFields[0], rdmsRow.get_Value(linkIDFieldOnRdms));
                short seq = (short)(rdmsRow.get_Value(seqNumberField));
                short lastEntry;
                do
                {
                    lastEntry = seq;
                    turnBuffer.set_Value(altIDFields[lastEntry], rdmsRow.get_Value(manLinkIDField));
                    rdmsRow = rdmsCursor.NextRow();
                    if (rdmsRow == null) break;
                    seq = (short)(rdmsRow.get_Value(seqNumberField));
                } while (seq != 1);

                // Zero-out the unused fields
                for (int i = lastEntry + 1; i < numAltIDFields; i++)
                    turnBuffer.set_Value(altIDFields[i], 0);

                // Write the FCID and Pos field values to the buffer
                for (short i = 0; i < numAltIDFields; i++)
                {
                    int altID = (int)(turnBuffer.get_Value(altIDFields[i]));
                    if (altID != 0)
                    {
                        turnBuffer.set_Value(edgeFCIDFields[i], streetsFCID);
                        turnBuffer.set_Value(edgeFIDFields[i], 1);
                        turnBuffer.set_Value(edgePosFields[i], 0.5);
                    }
                    else
                    {
                        turnBuffer.set_Value(edgeFCIDFields[i], 0);
                        turnBuffer.set_Value(edgeFIDFields[i], 0);
                        turnBuffer.set_Value(edgePosFields[i], 0);
                    }
                }

                // Create the turn feature
                turnFCCursor.InsertFeature(turnBuffer);
                numFeatures++;

                if ((numFeatures % 100) == 0)
                {
                    // check for user cancel

                    if (trackcancel != null && !trackcancel.Continue())
                        throw (new COMException("Function cancelled."));
                }
            }

            // Flush any outstanding writes to the turn feature class
            turnFCCursor.Flush();

            messages.AddMessage("Updating the EdgeFID values...");

            // Create a temporary network dataset for updating the EdgeFID values

            IDENetworkDataset dends = new DENetworkDatasetClass();
            dends.SupportsTurns = true;
            dends.Buildable = true;
            (dends as IDataElement).Name = StreetsFCName;
            (dends as IDEGeoDataset).SpatialReference = (streetsFC as IGeoDataset).SpatialReference;
            IArray sourceArray = new ArrayClass();
            var efs = new EdgeFeatureSourceClass() as IEdgeFeatureSource;
            (efs as INetworkSource).Name = StreetsFCName;
            efs.UsesSubtypes = false;
            efs.ClassConnectivityGroup = 1;
            efs.ClassConnectivityPolicy = esriNetworkEdgeConnectivityPolicy.esriNECPEndVertex;
            sourceArray.Add(efs);
            var tfs = new TurnFeatureSourceClass() as INetworkSource;
            tfs.Name = TurnFCName;
            sourceArray.Add(tfs);
            dends.Sources = sourceArray;
            var fdxc = fws.OpenFeatureDataset(fdsName) as IFeatureDatasetExtensionContainer;
            var dsCont = fdxc.FindExtension(esriDatasetType.esriDTNetworkDataset) as IDatasetContainer2;
            var tempNDS = dsCont.CreateDataset(dends as IDEDataset) as IDataset;

            // Set the EdgeFID field values by running UpdateByAlternateIDFields

            UpdateByAlternateIDFields updateByAltIDTool = new UpdateByAlternateIDFields();
            updateByAltIDTool.in_network_dataset = pathToFds + "\\" + StreetsFCName;
            updateByAltIDTool.alternate_ID_field_name = "LINK_ID";
            gp.Execute(updateByAltIDTool, trackcancel);

            // Delete the temporary network dataset

            tempNDS.Delete();

            // Write the turn geometries

            TurnGeometryUtilities.WriteTurnGeometry(outputFileGdbPath, StreetsFCName, TurnFCName,
                                                    numAltIDFields, 0.3, messages, trackcancel);

            // Index the turn geometries

            messages.AddMessage("Creating spatial index on the turn feature class...");

            AddSpatialIndex addSpatialIndexTool = new AddSpatialIndex();
            addSpatialIndexTool.in_features = pathToFds + "\\" + TurnFCName;
            gp.Execute(addSpatialIndexTool, trackcancel);

            return;
        }
Exemple #31
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                // Retrieve the TA workbook
                IJTXConfiguration3 defaultDbReadonly      = WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXTaskAssistantWorkflowRecord tamRecord = defaultDbReadonly.GetTaskAssistantWorkflowRecord(this.m_targetName);
                string styleFileName = this.DetermineStyleFileName(this.m_xmlFilePath);

                // If we're not allowed to overwrite an existing TA record, then do some error checking
                if (!this.m_overwriteExisting && tamRecord != null)
                {
                    msgs.AddWarning("Did not overwrite Task Assistant workbook: " + this.m_targetName);
                    return;
                }
                else if (tamRecord != null)
                {
                    msgs.AddMessage("Replacing Task Assistant workbook '" + m_targetName + "' in database...");
                    defaultDbReadonly.ReplaceTaskAssistantWorkflowRecord(this.m_targetName, this.m_targetName, this.m_xmlFilePath, styleFileName);
                }
                else // tamRecord == null
                {
                    msgs.AddMessage("Adding Task Assistant workbook '" + m_targetName + "' to database...");
                    defaultDbReadonly.AddTaskAssistantWorkflowRecord(this.m_targetName, this.m_xmlFilePath, styleFileName);
                }

                // Update the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_TARGET_NAME);
                IGPString         outValue     = new GPStringClass();
                outValue.Value     = m_targetName;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_TAM_UPLOAD_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
        }
Exemple #32
0
        public static void WriteTurnGeometry(string outputFileGdbPath, string StreetsFCName, string TurnFCName,
                                             int numAltIDFields, double trimRatio, IGPMessages messages, ITrackCancel trackcancel)
        {
            messages.AddMessage("Writing turn geometries...");

            // Open the feature classes in the file geodatabase

            Type          factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var           wsf         = Activator.CreateInstance(factoryType) as IWorkspaceFactory;
            var           fws         = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            IFeatureClass streetsFC   = fws.OpenFeatureClass(StreetsFCName);
            IFeatureClass turnFC      = fws.OpenFeatureClass(TurnFCName);

            // Look up the Edge1End, EdgeFCID and EdgeFID fields on the turn feature class

            int edge1EndField = turnFC.FindField("Edge1End");

            int[] edgeFCIDFields = new int[numAltIDFields];
            int[] edgeFIDFields  = new int[numAltIDFields];
            for (int i = 0; i < numAltIDFields; i++)
            {
                edgeFCIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FCID");
                edgeFIDFields[i]  = turnFC.FindField("Edge" + (i + 1) + "FID");
            }

            // Look up the FCID of the Streets feature class and open a random access cursor on it

            int streetsFCID         = streetsFC.FeatureClassID;
            IRandomAccessCursor rac = (streetsFC as IRandomAccessTable).GetRandomRows("", true);

            // Create an update cursor on the turn feature class

            var            qf              = new QueryFilterClass() as IQueryFilter;
            IFeatureCursor featCursor      = turnFC.Update(qf, false);
            IFeature       turnFeat        = null;
            int            numFeatures     = 0;
            double         lastCurveLength = 0.0;

            while ((turnFeat = featCursor.NextFeature()) != null)
            {
                // Get the geometry of the first line in the turn, rotate and trim it
                var    lineFeat     = rac.GetRow((int)turnFeat.get_Value(edgeFIDFields[0])) as IFeature;
                var    featCurve    = lineFeat.ShapeCopy as ICurve;
                ICurve workingCurve = null;
                switch ((string)turnFeat.get_Value(edge1EndField))
                {
                case "Y":
                    featCurve.GetSubcurve(1.0 - trimRatio, 1.0, true, out workingCurve);
                    break;

                case "N":
                    featCurve.GetSubcurve(0.0, trimRatio, true, out workingCurve);
                    workingCurve.ReverseOrientation();
                    break;

                default:
                    messages.AddWarning("ERROR: Invalid Edge1End value!  Turn OID: " + turnFeat.OID);
                    break;
                }
                if (workingCurve == null)
                {
                    continue;
                }

                // Create a new polyline and add the trimmed first line to it
                var segColl = new PolylineClass() as ISegmentCollection;
                segColl.AddSegmentCollection(workingCurve as ISegmentCollection);

                // Remember the last point of the curve
                IPoint lastCurveEnd = workingCurve.ToPoint;

                bool earlyExit = false;
                for (int i = 1; i < numAltIDFields; i++)
                {
                    if ((int)turnFeat.get_Value(edgeFCIDFields[i]) != streetsFCID)
                    {
                        // This was the last part of the turn -- break out and finalize the geometry
                        break;
                    }

                    // Otherwise get the geometry of this line in the turn, rotate it if necessary,
                    // and add it to the segment collection
                    lineFeat = rac.GetRow((int)turnFeat.get_Value(edgeFIDFields[i])) as IFeature;
                    var  poly = lineFeat.ShapeCopy as IPolycurve;
                    bool splitHappened;
                    int  newPart, newSeg;
                    poly.SplitAtDistance(0.5, true, false, out splitHappened, out newPart, out newSeg);
                    featCurve = poly as ICurve;
                    IPoint myPoint = featCurve.FromPoint;
                    if (EqualPoints(myPoint, lastCurveEnd))
                    {
                        segColl.AddSegmentCollection(featCurve as ISegmentCollection);
                    }
                    else
                    {
                        myPoint = featCurve.ToPoint;
                        if (EqualPoints(myPoint, lastCurveEnd))
                        {
                            featCurve.ReverseOrientation();
                            segColl.AddSegmentCollection(featCurve as ISegmentCollection);
                        }
                        else
                        {
                            messages.AddWarning("ERROR: Edge " + (i + 1) + " is discontinuous with the previous curve!  Turn OID: " + turnFeat.OID);
                            earlyExit = true;
                            break;
                        }
                    }

                    // Remember the length of the last curve added, and the last point of the curve
                    lastCurveLength = featCurve.Length;
                    lastCurveEnd    = featCurve.ToPoint;
                }
                // If the edges of the turn were read in successfully...
                if (!earlyExit)
                {
                    // Trim the segment such that the last curve is the length of the trim ratio
                    workingCurve = segColl as ICurve;
                    workingCurve.GetSubcurve(0.0, workingCurve.Length - ((1.0 - trimRatio) * lastCurveLength), false, out featCurve);
                    turnFeat.Shape = featCurve as IGeometry;

                    // Write out the turn geometry and increment the count
                    featCursor.UpdateFeature(turnFeat);
                    numFeatures++;

                    if ((numFeatures % 100) == 0)
                    {
                        // check for user cancel

                        if (trackcancel != null && !trackcancel.Continue())
                        {
                            throw (new COMException("Function cancelled."));
                        }
                    }
                }
            }
        }
        public static void WriteTurnGeometry(string outputFileGdbPath, string StreetsFCName, string TurnFCName,
                                             int numAltIDFields, double trimRatio, IGPMessages messages, ITrackCancel trackcancel)
        {
            messages.AddMessage("Writing turn geometries...");

            // Open the feature classes in the file geodatabase

            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var wsf = Activator.CreateInstance(factoryType) as IWorkspaceFactory;
            var fws = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            IFeatureClass streetsFC = fws.OpenFeatureClass(StreetsFCName);
            IFeatureClass turnFC = fws.OpenFeatureClass(TurnFCName);

            // Look up the Edge1End, EdgeFCID and EdgeFID fields on the turn feature class

            int edge1EndField = turnFC.FindField("Edge1End");
            int[] edgeFCIDFields = new int[numAltIDFields];
            int[] edgeFIDFields = new int[numAltIDFields];
            for (int i = 0; i < numAltIDFields; i++)
            {
                edgeFCIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FCID");
                edgeFIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FID");
            }

            // Look up the FCID of the Streets feature class and open a random access cursor on it

            int streetsFCID = streetsFC.FeatureClassID;
            IRandomAccessCursor rac = (streetsFC as IRandomAccessTable).GetRandomRows("", true);

            // Create an update cursor on the turn feature class

            var qf = new QueryFilterClass() as IQueryFilter;
            IFeatureCursor featCursor = turnFC.Update(qf, false);
            IFeature turnFeat = null;
            int numFeatures = 0;
            double lastCurveLength = 0.0;
            while ((turnFeat = featCursor.NextFeature()) != null)
            {
                // Get the geometry of the first line in the turn, rotate and trim it
                var lineFeat = rac.GetRow((int)turnFeat.get_Value(edgeFIDFields[0])) as IFeature;
                var featCurve = lineFeat.ShapeCopy as ICurve;
                ICurve workingCurve = null;
                switch ((string)turnFeat.get_Value(edge1EndField))
                {
                    case "Y":
                        featCurve.GetSubcurve(1.0 - trimRatio, 1.0, true, out workingCurve);
                        break;
                    case "N":
                        featCurve.GetSubcurve(0.0, trimRatio, true, out workingCurve);
                        workingCurve.ReverseOrientation();
                        break;
                    default:
                        messages.AddWarning("ERROR: Invalid Edge1End value!  Turn OID: " + turnFeat.OID);
                        break;
                }
                if (workingCurve == null)
                {
                    continue;
                }

                // Create a new polyline and add the trimmed first line to it
                var segColl = new PolylineClass() as ISegmentCollection;
                segColl.AddSegmentCollection(workingCurve as ISegmentCollection);

                // Remember the last point of the curve
                IPoint lastCurveEnd = workingCurve.ToPoint;

                bool earlyExit = false;
                for (int i = 1; i < numAltIDFields; i++)
                {
                    if ((int)turnFeat.get_Value(edgeFCIDFields[i]) != streetsFCID)
                    {
                        // This was the last part of the turn -- break out and finalize the geometry
                        break;
                    }

                    // Otherwise get the geometry of this line in the turn, rotate it if necessary,
                    // and add it to the segment collection
                    lineFeat = rac.GetRow((int)turnFeat.get_Value(edgeFIDFields[i])) as IFeature;
                    var poly = lineFeat.ShapeCopy as IPolycurve;
                    bool splitHappened;
                    int newPart, newSeg;
                    poly.SplitAtDistance(0.5, true, false, out splitHappened, out newPart, out newSeg);
                    featCurve = poly as ICurve;
                    IPoint myPoint = featCurve.FromPoint;
                    if (EqualPoints(myPoint, lastCurveEnd))
                    {
                        segColl.AddSegmentCollection(featCurve as ISegmentCollection);
                    }
                    else
                    {
                        myPoint = featCurve.ToPoint;
                        if (EqualPoints(myPoint, lastCurveEnd))
                        {
                            featCurve.ReverseOrientation();
                            segColl.AddSegmentCollection(featCurve as ISegmentCollection);
                        }
                        else
                        {
                            messages.AddWarning("ERROR: Edge " + (i+1) + " is discontinuous with the previous curve!  Turn OID: " + turnFeat.OID);
                            earlyExit = true;
                            break;
                        }
                    }

                    // Remember the length of the last curve added, and the last point of the curve
                    lastCurveLength = featCurve.Length;
                    lastCurveEnd = featCurve.ToPoint;
                }
                // If the edges of the turn were read in successfully...
                if (!earlyExit)
                {
                    // Trim the segment such that the last curve is the length of the trim ratio
                    workingCurve = segColl as ICurve;
                    workingCurve.GetSubcurve(0.0, workingCurve.Length - ((1.0 - trimRatio) * lastCurveLength), false, out featCurve);
                    turnFeat.Shape = featCurve as IGeometry;

                    // Write out the turn geometry and increment the count
                    featCursor.UpdateFeature(turnFeat);
                    numFeatures++;

                    if ((numFeatures % 100) == 0)
                    {
                        // check for user cancel

                        if (trackcancel != null && !trackcancel.Continue())
                            throw (new COMException("Function cancelled."));
                    }
                }
            }
        }
        private void CreateSignposts(string inputSITablePath, string inputSPTablePath, string outputFileGdbPath, 
                                     IGPMessages messages, ITrackCancel trackcancel)
        {
            // Open the input SI and SP tables

            ITable inputSignInformationTable = m_gpUtils.OpenTableFromString(inputSITablePath);
            ITable inputSignPathTable = m_gpUtils.OpenTableFromString(inputSPTablePath);

            // Open the Streets feature class

            Type gdbFactoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var gdbWSF = Activator.CreateInstance(gdbFactoryType) as IWorkspaceFactory;
            var gdbFWS = gdbWSF.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            IFeatureClass inputLineFeatures = gdbFWS.OpenFeatureClass(StreetsFCName);

            // Create the signpost feature class and table

            IFeatureClass outputSignFeatures = SignpostUtilities.CreateSignsFeatureClass(inputLineFeatures, SignpostFCName);
            ITable outputSignDetailTable = SignpostUtilities.CreateSignsDetailTable(inputLineFeatures, SignpostJoinTableName);

            #region Find fields
            //(Validate checked that these exist)
            IFields inputSITableFields = inputSignInformationTable.Fields;
            int inSiIdFI = inputSITableFields.FindField("ID");
            int inSiInfoTypFI = inputSITableFields.FindField("INFOTYP");
            int inSiTxtContFI = inputSITableFields.FindField("TXTCONT");
            int inSiTxtContLCFI = inputSITableFields.FindField("TXTCONTLC");
            int inSiConTypFI = inputSITableFields.FindField("CONTYP");
            IFields inputSPTableFields = inputSignPathTable.Fields;
            int inSpIdFI = inputSPTableFields.FindField("ID");
            int inSpSeqNrFI = inputSPTableFields.FindField("SEQNR");
            int inSpTrpElIdFI = inputSPTableFields.FindField("TRPELID");
            int inSpTrpElTypFI = inputSPTableFields.FindField("TRPELTYP");

            // Find output fields (we just made these)

            IFields outputSignFeatureFields = outputSignFeatures.Fields;
            int outExitNameFI = outputSignFeatureFields.FindField("ExitName");

            int[] outBranchXFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outBranchXDirFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outBranchXLngFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outTowardXFI = new int[SignpostUtilities.MaxBranchCount];
            int[] outTowardXLngFI = new int[SignpostUtilities.MaxBranchCount];

            string indexString;

            for (int i = 0; i < SignpostUtilities.MaxBranchCount; i++)
            {
                indexString = Convert.ToString(i, System.Globalization.CultureInfo.InvariantCulture);

                outBranchXFI[i] = outputSignFeatureFields.FindField("Branch" + indexString);
                outBranchXDirFI[i] = outputSignFeatureFields.FindField("Branch" + indexString + "Dir");
                outBranchXLngFI[i] = outputSignFeatureFields.FindField("Branch" + indexString + "Lng");
                outTowardXFI[i] = outputSignFeatureFields.FindField("Toward" + indexString);
                outTowardXLngFI[i] = outputSignFeatureFields.FindField("Toward" + indexString + "Lng");
            }

            IFields outputTableFields = outputSignDetailTable.Fields;
            int outTblSignpostIDFI = outputTableFields.FindField("SignpostID");
            int outTblSequenceFI = outputTableFields.FindField("Sequence");
            int outTblEdgeFCIDFI = outputTableFields.FindField("EdgeFCID");
            int outTblEdgeFIDFI = outputTableFields.FindField("EdgeFID");
            int outTblEdgeFrmPosFI = outputTableFields.FindField("EdgeFrmPos");
            int outTblEdgeToPosFI = outputTableFields.FindField("EdgeToPos");

            // Find ID fields on referenced lines

            int inLinesOIDFI = inputLineFeatures.FindField(inputLineFeatures.OIDFieldName);
            int inLinesUserIDFI = inputLineFeatures.FindField("ID");
            int inLinesShapeFI = inputLineFeatures.FindField(inputLineFeatures.ShapeFieldName);

            #endregion

            // Get the language lookup hash

            System.Collections.Hashtable langLookup = CreateLanguageLookup();

            // Fetch all line features referenced by the input signs table.  We do the
            // "join" this hard way to support all data sources in the sample.
            // Also, for large numbers of sign records, this strategy of fetching all
            // related features and holding them in RAM could be a problem.  To fix
            // this, one could process the input sign records in batches.

            System.Collections.Hashtable lineFeaturesList = SignpostUtilities.FillFeatureCache(inputSignPathTable, inSpTrpElIdFI, -1, inputLineFeatures, "ID", trackcancel);

            // Create output feature/row buffers

            IFeatureBuffer featureBuffer = outputSignFeatures.CreateFeatureBuffer();
            IFeature feature = featureBuffer as IFeature;
            IRowBuffer featureRowBuffer = featureBuffer as IRowBuffer;

            IRowBuffer tableBuffer = outputSignDetailTable.CreateRowBuffer();
            IRow row = tableBuffer as IRow;
            IRowBuffer tableRowBuffer = tableBuffer as IRowBuffer;

            // Create insert cursors.

            IFeatureCursor featureInsertCursor = outputSignFeatures.Insert(true);
            ICursor tableInsertCursor = outputSignDetailTable.Insert(true);

            // Create input cursors for the sign tables we are importing

            ITableSort spTableSort = new TableSortClass();
            spTableSort.Fields = "ID, SEQNR";
            spTableSort.set_Ascending("ID", true);
            spTableSort.set_Ascending("SEQNR", true);
            spTableSort.QueryFilter = null;
            spTableSort.Table = inputSignPathTable;
            spTableSort.Sort(null);
            ICursor spInputCursor = spTableSort.Rows;

            ITableSort siTableSort = new TableSortClass();
            siTableSort.Fields = "ID, SEQNR, DESTSEQ, RNPART";
            siTableSort.set_Ascending("ID", true);
            siTableSort.set_Ascending("SEQNR", true);
            siTableSort.set_Ascending("DESTSEQ", true);
            siTableSort.set_Ascending("RNPART", true);
            siTableSort.QueryFilter = null;
            siTableSort.Table = inputSignInformationTable;
            siTableSort.Sort(null);
            ICursor siInputCursor = siTableSort.Rows;

            IRow inputSpTableRow;
            IRow inputSiTableRow;
            long currentID = -1, loopSpID, loopSiID;

            int numOutput = 0;
            int numInput = 0;
            bool fetchFeatureDataSucceeded;
            ArrayList idVals = new System.Collections.ArrayList(2);
            ArrayList edgesData = new System.Collections.ArrayList(2);
            ArrayList reverseEdge = new System.Collections.ArrayList(2);
            SignpostUtilities.FeatureData currentFeatureData = new SignpostUtilities.FeatureData(-1, null);
            ICurve earlierEdgeCurve, laterEdgeCurve;
            IPoint earlierEdgeStart, earlierEdgeEnd;
            IPoint laterEdgeStart, laterEdgeEnd;

            int nextBranchNum = -1, nextTowardNum = -1;
            string infoTypText, txtContText;
            string txtContTextLC, langVal;
            int conTypVal;

            int refLinesFCID = inputLineFeatures.ObjectClassID;
            IGeometry outputSignGeometry;
            object newOID;

            inputSpTableRow = spInputCursor.NextRow();
            inputSiTableRow = siInputCursor.NextRow();
            while (inputSpTableRow != null && inputSiTableRow != null)
            {
                currentID = Convert.ToInt64(inputSpTableRow.get_Value(inSpIdFI));

                // fetch the edge ID values from the SP table for the current sign ID

                idVals.Clear();
                while (true)
                {
                    idVals.Add(Convert.ToInt64(inputSpTableRow.get_Value(inSpTrpElIdFI)));

                    inputSpTableRow = spInputCursor.NextRow();
                    if (inputSpTableRow == null)
                        break;    // we've reached the end of the SP table

                    loopSpID = Convert.ToInt64(inputSpTableRow.get_Value(inSpIdFI));
                    if (loopSpID != currentID)
                        break;    // we're now on a new ID value
                }

                numInput++;

                // fetch the FeatureData for each of these edges

                edgesData.Clear();
                fetchFeatureDataSucceeded = true;
                foreach (long currentIDVal in idVals)
                {
                    try
                    {
                        currentFeatureData = (SignpostUtilities.FeatureData)lineFeaturesList[currentIDVal];
                        edgesData.Add(currentFeatureData);
                    }
                    catch
                    {
                        fetchFeatureDataSucceeded = false;
                        if (numInput - numOutput < 100)
                        {
                            messages.AddWarning("Line feature not found for signpost with ID: " +
                                Convert.ToString(currentIDVal, System.Globalization.CultureInfo.InvariantCulture));
                        }
                        break;
                    }
                }
                if (!fetchFeatureDataSucceeded)
                    continue;

                if (edgesData.Count == 1)
                {
                    messages.AddWarning("Signpost with ID " + Convert.ToString(currentID, System.Globalization.CultureInfo.InvariantCulture)
                        + " only has one transportation element.");
                    continue;
                }

                // determine the orientation for each of these edges

                reverseEdge.Clear();
                for (int i = 1; i < edgesData.Count; i++)
                {
                    // get the endpoints of the earlier curve
                    currentFeatureData = (SignpostUtilities.FeatureData)edgesData[i - 1];
                    earlierEdgeCurve = currentFeatureData.feature as ICurve;
                    earlierEdgeStart = earlierEdgeCurve.FromPoint;
                    earlierEdgeEnd = earlierEdgeCurve.ToPoint;

                    // get the endpoints of the later curve
                    currentFeatureData = (SignpostUtilities.FeatureData)edgesData[i];
                    laterEdgeCurve = currentFeatureData.feature as ICurve;
                    laterEdgeStart = laterEdgeCurve.FromPoint;
                    laterEdgeEnd = laterEdgeCurve.ToPoint;

                    // determine the orientation of the first edge
                    // (first edge is reversed if its Start point is coincident with either point of the second edge)
                    if (i == 1)
                        reverseEdge.Add(TurnGeometryUtilities.EqualPoints(earlierEdgeStart, laterEdgeStart) || TurnGeometryUtilities.EqualPoints(earlierEdgeStart, laterEdgeEnd));

                    // determine the orientation of the i'th edge
                    // (i'th edge is reversed if its End point is coincident with either point of the previous edge)
                    reverseEdge.Add(TurnGeometryUtilities.EqualPoints(laterEdgeEnd, earlierEdgeStart) || TurnGeometryUtilities.EqualPoints(laterEdgeEnd, earlierEdgeEnd));
                }

                // write out the sign geometry to the featureBuffer

                outputSignGeometry = MakeSignGeometry(edgesData, reverseEdge);
                featureBuffer.Shape = outputSignGeometry;

                // fetch the signpost information from the SI table for the current sign ID

                nextBranchNum = 0;
                nextTowardNum = 0;
                featureBuffer.set_Value(outExitNameFI, "");

                while (inputSiTableRow != null)
                {
                    loopSiID = Convert.ToInt64(inputSiTableRow.get_Value(inSiIdFI));
                    if (loopSiID < currentID)
                    {
                        inputSiTableRow = siInputCursor.NextRow();
                        continue;
                    }
                    else if (loopSiID > currentID)
                    {
                        break;    // we're now on a new ID value
                    }

                    infoTypText = inputSiTableRow.get_Value(inSiInfoTypFI) as string;
                    txtContText = inputSiTableRow.get_Value(inSiTxtContFI) as string;
                    txtContTextLC = inputSiTableRow.get_Value(inSiTxtContLCFI) as string;
                    langVal = SignpostUtilities.GetLanguageValue(txtContTextLC, langLookup);
                    conTypVal = Convert.ToInt32(inputSiTableRow.get_Value(inSiConTypFI));

                    switch (infoTypText)
                    {
                        case "4E":    // exit number

                            featureBuffer.set_Value(outExitNameFI, txtContText);

                            break;
                        case "9D":    // place name
                        case "4I":    // other destination

                            // check for schema overflow
                            if (nextTowardNum > SignpostUtilities.MaxBranchCount - 1)
                            {
                                inputSiTableRow = siInputCursor.NextRow();
                                continue;
                            }

                            // set values
                            featureBuffer.set_Value(outTowardXFI[nextTowardNum], txtContText);
                            featureBuffer.set_Value(outTowardXLngFI[nextTowardNum], langVal);

                            // get ready for next toward
                            nextTowardNum++;

                            break;
                        case "6T":    // street name
                        case "RN":    // route number

                            if (conTypVal == 2)    // toward
                            {
                                // check for schema overflow
                                if (nextTowardNum > SignpostUtilities.MaxBranchCount - 1)
                                {
                                    inputSiTableRow = siInputCursor.NextRow();
                                    continue;
                                }

                                // set values
                                featureBuffer.set_Value(outTowardXFI[nextTowardNum], txtContText);
                                featureBuffer.set_Value(outTowardXLngFI[nextTowardNum], langVal);

                                // get ready for next toward
                                nextTowardNum++;
                            }
                            else    // branch
                            {
                                // check for schema overflow
                                if (nextBranchNum > SignpostUtilities.MaxBranchCount - 1)
                                {
                                    inputSiTableRow = siInputCursor.NextRow();
                                    continue;
                                }

                                // set values
                                featureBuffer.set_Value(outBranchXFI[nextBranchNum], txtContText);
                                featureBuffer.set_Value(outBranchXDirFI[nextBranchNum], "");
                                featureBuffer.set_Value(outBranchXLngFI[nextBranchNum], "en");

                                // get ready for next branch
                                nextBranchNum++;
                            }

                            break;
                    }  // switch

                    inputSiTableRow = siInputCursor.NextRow();

                }  // each SI table record

                // clean up unused parts of the row and pack toward/branch items

                SignpostUtilities.CleanUpSignpostFeatureValues(featureBuffer, nextBranchNum - 1, nextTowardNum - 1,
                                                               outBranchXFI, outBranchXDirFI, outBranchXLngFI,
                                                               outTowardXFI, outTowardXLngFI);

                // insert sign feature record

                newOID = featureInsertCursor.InsertFeature(featureBuffer);

                // set streets table values

                tableRowBuffer.set_Value(outTblSignpostIDFI, newOID);
                tableRowBuffer.set_Value(outTblEdgeFCIDFI, refLinesFCID);
                for (int i = 0; i < edgesData.Count; i++)
                {
                    currentFeatureData = (SignpostUtilities.FeatureData)edgesData[i];
                    tableRowBuffer.set_Value(outTblSequenceFI, i + 1);
                    tableRowBuffer.set_Value(outTblEdgeFIDFI, currentFeatureData.OID);
                    if ((bool)reverseEdge[i])
                    {
                        tableRowBuffer.set_Value(outTblEdgeFrmPosFI, 1.0);
                        tableRowBuffer.set_Value(outTblEdgeToPosFI, 0.0);
                    }
                    else
                    {
                        tableRowBuffer.set_Value(outTblEdgeFrmPosFI, 0.0);
                        tableRowBuffer.set_Value(outTblEdgeToPosFI, 1.0);
                    }

                    // insert detail record

                    tableInsertCursor.InsertRow(tableRowBuffer);
                }

                numOutput++;
                if ((numOutput % 100) == 0)
                {
                    // check for user cancel

                    if (trackcancel != null && !trackcancel.Continue())
                        throw (new COMException("Function cancelled."));
                }

            }  // outer while

            // Flush any outstanding writes to the feature class and table
            featureInsertCursor.Flush();
            tableInsertCursor.Flush();

            // add a summary message

            messages.AddMessage(Convert.ToString(numOutput) + " of " + Convert.ToString(numInput) + " signposts added.");

            return;
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Assign the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXJob3           job        = jobManager.GetJob(m_jobId) as IJTXJob3;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;

                // As of Jan. 2011, the core Workflow Manager libraries do not
                // seem to check if the user has the privilege to add an attachment
                // if a job as a hold on it.  So run the check here.
                IJTXJobHolds jobHolds = job as IJTXJobHolds;
                if (jobHolds.Holds != null &&
                    jobHolds.Holds.Count > 0 &&
                    !CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_CAN_ADD_ATTACHES_FOR_HELD_JOBS))
                {
                    throw new WmauException(WmauErrorCodes.C_NO_ADD_ATTACHMENTS_HELD_JOBS_ERROR);
                }

                // If we get this far, then figure out how to associate the attachment
                // with the job, and add the attachment.
                jtxFileStorageType attachmentType;
                if (m_attachmentType.Equals(C_OPT_EMBEDDED))
                {
                    attachmentType = jtxFileStorageType.jtxStoreInDB;
                }
                else
                {
                    attachmentType = jtxFileStorageType.jtxStoreAsLink;
                }

                msgs.AddMessage("Adding attachment '" + m_attachmentPath + "' to job " + m_jobId + " (" + job.Name + ")");
                job.AddAttachment(m_attachmentPath, attachmentType, m_attachmentType);
                job.Store();

                // Do the other things that still need to be handled manually, such as logging
                // the job's reassignment and sending any necessary notifications.
                IPropertySet propSet = new PropertySetClass();
                propSet.SetProperty(C_PROP_VAL_ATTACHMENT, "'" + m_attachmentPath + "'");
                job.LogJobAction(
                    configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_ADD_ATTACHMENT),
                    propSet,
                    string.Empty);
                Common.WmauHelperFunctions.SendNotification(
                    ESRI.ArcGIS.JTX.Utilities.Constants.NOTIF_ATTACHMENT_ADDED,
                    this.WmxDatabase,
                    job);

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                // Stash away the executing user's information, if appropriate
                string             username      = ESRI.ArcGIS.JTXUI.ConfigurationCache.GetCurrentSystemUser(ESRI.ArcGIS.JTXUI.ConfigurationCache.UseUserDomain);
                IJTXConfiguration3 configMgr     = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXUser3          executingUser = configMgr.GetUser(username) as IJTXUser3;

                // Import the AD information
                string domain         = System.Environment.UserDomainName;
                string domainUsername = string.Empty;
                string domainPassword = string.Empty;
                int    numUsers       = 0;
                int    numGroups      = 0;
                ActiveDirectoryHelper.SyncronizeJTXDatabaseWithActiveDirectory(this.WmxDatabase, domain, domainUsername, domainPassword, m_userGroup, m_groupGroup, out numGroups, out numUsers);

                // If the tool was set to preserve the current user's account and the user
                // was removed from the DB, then re-add their account
                if (configMgr.GetUser(username) == null)
                {
                    if (m_preserveCurrentUser)
                    {
                        IJTXConfigurationEdit2 configEdit = this.WmxDatabase.ConfigurationManager as IJTXConfigurationEdit2;
                        IJTXUserConfig         newUser    = configEdit.CreateUser() as IJTXUserConfig;
                        newUser.FirstName_2 = executingUser.FirstName;
                        newUser.FullName_2  = executingUser.FullName;
                        newUser.LastName_2  = executingUser.LastName;
                        newUser.UserName_2  = executingUser.UserName;
                        (newUser as IJTXUser3).IsAdministrator = executingUser.IsAdministrator;
                        newUser.Store();

                        msgs.AddMessage("User '" + username + "' not found in Active Directory group '" + m_userGroup + "'; re-added placeholder to Workflow Manager database");
                    }
                    else
                    {
                        msgs.AddWarning("User '" + username + "' removed from Workflow Manager database");
                    }
                }

                // Update the output parameters
                WmauParameterMap  paramMap = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParam = paramMap.GetParamEdit(C_PARAM_OUT_NUM_USERS);
                IGPLong           value    = new GPLongClass();
                value.Value    = numUsers;
                outParam.Value = value as IGPValue;

                outParam       = paramMap.GetParamEdit(C_PARAM_OUT_NUM_GROUPS);
                value          = new GPLongClass();
                value.Value    = numGroups;
                outParam.Value = value as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            finally
            {
                // Release any COM objects here!
            }
        }
        internal List<string> loadOSMRelations(string osmFileLocation, ref ITrackCancel TrackCancel, ref IGPMessages message, IGPValue targetGPValue, IFeatureClass osmPointFeatureClass, IFeatureClass osmLineFeatureClass, IFeatureClass osmPolygonFeatureClass, int relationCapacity, ITable relationTable, OSMDomains availableDomains, bool fastLoad, bool checkForExisting)
        {
            List<string> missingRelations = null;
            XmlReader osmFileXmlReader = null;
            XmlSerializer relationSerializer = null;

            try
            {

                missingRelations = new List<string>();

                if (osmLineFeatureClass == null)
                {
                    throw new ArgumentNullException("osmLineFeatureClass");
                }

                if (osmPolygonFeatureClass == null)
                {
                    throw new ArgumentNullException("osmPolygonFeatureClass");
                }

                if (relationTable == null)
                {
                    throw new ArgumentNullException("relationTable");
                }

                int osmPointIDFieldIndex = osmPointFeatureClass.FindField("OSMID");
                Dictionary<string, int> osmPointDomainAttributeFieldIndices = new Dictionary<string, int>();
                foreach (var domains in availableDomains.domain)
                {
                    int currentFieldIndex = osmPointFeatureClass.FindField(domains.name);

                    if (currentFieldIndex != -1)
                    {
                        osmPointDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex);
                    }
                }
                int tagCollectionPointFieldIndex = osmPointFeatureClass.FindField("osmTags");
                int osmUserPointFieldIndex = osmPointFeatureClass.FindField("osmuser");
                int osmUIDPointFieldIndex = osmPointFeatureClass.FindField("osmuid");
                int osmVisiblePointFieldIndex = osmPointFeatureClass.FindField("osmvisible");
                int osmVersionPointFieldIndex = osmPointFeatureClass.FindField("osmversion");
                int osmChangesetPointFieldIndex = osmPointFeatureClass.FindField("osmchangeset");
                int osmTimeStampPointFieldIndex = osmPointFeatureClass.FindField("osmtimestamp");
                int osmMemberOfPointFieldIndex = osmPointFeatureClass.FindField("osmMemberOf");
                int osmSupportingElementPointFieldIndex = osmPointFeatureClass.FindField("osmSupportingElement");
                int osmWayRefCountFieldIndex = osmPointFeatureClass.FindField("wayRefCount");

                int osmLineIDFieldIndex = osmLineFeatureClass.FindField("OSMID");
                Dictionary<string, int> osmLineDomainAttributeFieldIndices = new Dictionary<string, int>();
                Dictionary<string, int> osmLineDomainAttributeFieldLength = new Dictionary<string, int>();
                foreach (var domains in availableDomains.domain)
                {
                    int currentFieldIndex = osmLineFeatureClass.FindField(domains.name);

                    if (currentFieldIndex != -1)
                    {
                        osmLineDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex);
                        osmLineDomainAttributeFieldLength.Add(domains.name, osmLineFeatureClass.Fields.get_Field(currentFieldIndex).Length);
                    }
                }
                int tagCollectionPolylineFieldIndex = osmLineFeatureClass.FindField("osmTags");
                int osmUserPolylineFieldIndex = osmLineFeatureClass.FindField("osmuser");
                int osmUIDPolylineFieldIndex = osmLineFeatureClass.FindField("osmuid");
                int osmVisiblePolylineFieldIndex = osmLineFeatureClass.FindField("osmvisible");
                int osmVersionPolylineFieldIndex = osmLineFeatureClass.FindField("osmversion");
                int osmChangesetPolylineFieldIndex = osmLineFeatureClass.FindField("osmchangeset");
                int osmTimeStampPolylineFieldIndex = osmLineFeatureClass.FindField("osmtimestamp");
                int osmMemberOfPolylineFieldIndex = osmLineFeatureClass.FindField("osmMemberOf");
                int osmMembersPolylineFieldIndex = osmLineFeatureClass.FindField("osmMembers");
                int osmSupportingElementPolylineFieldIndex = osmLineFeatureClass.FindField("osmSupportingElement");

                int osmPolygonIDFieldIndex = osmPolygonFeatureClass.FindField("OSMID");
                Dictionary<string, int> osmPolygonDomainAttributeFieldIndices = new Dictionary<string, int>();
                Dictionary<string, int> osmPolygonDomainAttributeFieldLength = new Dictionary<string, int>();
                foreach (var domains in availableDomains.domain)
                {
                    int currentFieldIndex = osmPolygonFeatureClass.FindField(domains.name);

                    if (currentFieldIndex != -1)
                    {
                        osmPolygonDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex);
                        osmPolygonDomainAttributeFieldLength.Add(domains.name, osmPolygonFeatureClass.Fields.get_Field(currentFieldIndex).Length);
                    }
                }
                int tagCollectionPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmTags");
                int osmUserPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmuser");
                int osmUIDPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmuid");
                int osmVisiblePolygonFieldIndex = osmPolygonFeatureClass.FindField("osmvisible");
                int osmVersionPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmversion");
                int osmChangesetPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmchangeset");
                int osmTimeStampPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmtimestamp");
                int osmMemberOfPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmMemberOf");
                int osmMembersPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmMembers");
                int osmSupportingElementPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmSupportingElement");

                int osmRelationIDFieldIndex = relationTable.FindField("OSMID");
                int tagCollectionRelationFieldIndex = relationTable.FindField("osmTags");
                int osmUserRelationFieldIndex = relationTable.FindField("osmuser");
                int osmUIDRelationFieldIndex = relationTable.FindField("osmuid");
                int osmVisibleRelationFieldIndex = relationTable.FindField("osmvisible");
                int osmVersionRelationFieldIndex = relationTable.FindField("osmversion");
                int osmChangesetRelationFieldIndex = relationTable.FindField("osmchangeset");
                int osmTimeStampRelationFieldIndex = relationTable.FindField("osmtimestamp");
                int osmMemberOfRelationFieldIndex = relationTable.FindField("osmMemberOf");
                int osmMembersRelationFieldIndex = relationTable.FindField("osmMembers");
                int osmSupportingElementRelationFieldIndex = relationTable.FindField("osmSupportingElement");

                // list for reference count and relation list for lines/polygons/relations
                // set up the progress indicator
                IStepProgressor stepProgressor = TrackCancel as IStepProgressor;

                if (stepProgressor != null)
                {
                    stepProgressor.MinRange = 0;
                    stepProgressor.MaxRange = relationCapacity;
                    stepProgressor.Position = 0;
                    stepProgressor.Message = _resourceManager.GetString("GPTools_OSMGPFileReader_loadingRelations");
                    stepProgressor.StepValue = 1;
                    stepProgressor.Show();
                }

                bool relationIndexRebuildRequired = false;

                if (relationTable != null)
                {
                    osmFileXmlReader = System.Xml.XmlReader.Create(osmFileLocation);
                    relationSerializer = new XmlSerializer(typeof(relation));

                    using (ComReleaser comReleaser = new ComReleaser())
                    {
                        using (SchemaLockManager linelock = new SchemaLockManager(osmLineFeatureClass as ITable), polygonLock = new SchemaLockManager(osmPolygonFeatureClass as ITable), relationLock = new SchemaLockManager(relationTable))
                        {
                            ICursor rowCursor = relationTable.Insert(true);
                            comReleaser.ManageLifetime(rowCursor);

                            IRowBuffer rowBuffer = relationTable.CreateRowBuffer();
                            comReleaser.ManageLifetime(rowBuffer);

                            IFeatureCursor lineFeatureInsertCursor = osmLineFeatureClass.Insert(true);
                            comReleaser.ManageLifetime(lineFeatureInsertCursor);

                            IFeatureBuffer lineFeatureBuffer = osmLineFeatureClass.CreateFeatureBuffer();
                            comReleaser.ManageLifetime(lineFeatureBuffer);

                            IFeatureCursor polygonFeatureInsertCursor = osmPolygonFeatureClass.Insert(true);
                            comReleaser.ManageLifetime(polygonFeatureInsertCursor);

                            IFeatureBuffer polygonFeatureBuffer = osmPolygonFeatureClass.CreateFeatureBuffer();
                            comReleaser.ManageLifetime(polygonFeatureBuffer);

                            int relationCount = 1;
                            int relationDebugCount = 1;

                            string lineSQLIdentifier = osmLineFeatureClass.SqlIdentifier("OSMID");
                            string polygonSQLIdentifier = osmPolygonFeatureClass.SqlIdentifier("OSMID");

                            message.AddMessage(_resourceManager.GetString("GPTools_OSMGPFileReader_resolvegeometries"));

                            osmFileXmlReader.MoveToContent();
                            while (osmFileXmlReader.Read())
                            {
                                if (osmFileXmlReader.IsStartElement())
                                {
                                    if (osmFileXmlReader.Name == "relation")
                                    {
                                        relation currentRelation = null;
                                        try
                                        {
                                            // read the full relation node
                                            string currentrelationString = osmFileXmlReader.ReadOuterXml();

                                            using (StringReader relationReader = new System.IO.StringReader(currentrelationString))
                                            {
                                                // de-serialize the xml into to the class instance
                                                currentRelation = relationSerializer.Deserialize(relationReader) as relation;
                                            }

                                            if (currentRelation == null)
                                                continue;

                                            relationDebugCount = relationDebugCount + 1;
                                            esriGeometryType detectedGeometryType = determineRelationGeometryType(osmLineFeatureClass, osmPolygonFeatureClass, relationTable, currentRelation);

                                            if (checkForExisting)
                                            {
                                                switch (detectedGeometryType)
                                                {
                                                    case esriGeometryType.esriGeometryAny:
                                                        if (CheckIfExists(relationTable, currentRelation.id))
                                                            continue;
                                                        break;
                                                    case esriGeometryType.esriGeometryBag:
                                                        if (CheckIfExists(relationTable, currentRelation.id))
                                                            continue;
                                                        break;
                                                    case esriGeometryType.esriGeometryBezier3Curve:
                                                        break;
                                                    case esriGeometryType.esriGeometryCircularArc:
                                                        break;
                                                    case esriGeometryType.esriGeometryEllipticArc:
                                                        break;
                                                    case esriGeometryType.esriGeometryEnvelope:
                                                        break;
                                                    case esriGeometryType.esriGeometryLine:
                                                        if (CheckIfExists(osmLineFeatureClass as ITable, currentRelation.id))
                                                            continue;
                                                        break;
                                                    case esriGeometryType.esriGeometryMultiPatch:
                                                        break;
                                                    case esriGeometryType.esriGeometryMultipoint:
                                                        break;
                                                    case esriGeometryType.esriGeometryNull:
                                                        if (CheckIfExists(relationTable, currentRelation.id))
                                                            continue;
                                                        break;
                                                    case esriGeometryType.esriGeometryPath:
                                                        break;
                                                    case esriGeometryType.esriGeometryPoint:
                                                        break;
                                                    case esriGeometryType.esriGeometryPolygon:
                                                        if (CheckIfExists(osmPolygonFeatureClass as ITable, currentRelation.id))
                                                            continue;
                                                        break;
                                                    case esriGeometryType.esriGeometryPolyline:
                                                        if (CheckIfExists(osmLineFeatureClass as ITable, currentRelation.id))
                                                            continue;
                                                        break;
                                                    case esriGeometryType.esriGeometryRay:
                                                        break;
                                                    case esriGeometryType.esriGeometryRing:
                                                        break;
                                                    case esriGeometryType.esriGeometrySphere:
                                                        break;
                                                    case esriGeometryType.esriGeometryTriangleFan:
                                                        break;
                                                    case esriGeometryType.esriGeometryTriangleStrip:
                                                        break;
                                                    case esriGeometryType.esriGeometryTriangles:
                                                        break;
                                                    default:
                                                        break;
                                                }
                                            }

                                            List<tag> relationTagList = new List<tag>();
                                            List<member> relationMemberList = new List<member>();
                                            Dictionary<string, string> wayList = new Dictionary<string, string>();

                                            // sanity check that the overall relation notation contains at least something
                                            if (currentRelation.Items == null)
                                                continue;

                                            List<OSMNodeFeature> osmPointList = null;
                                            List<OSMLineFeature> osmLineList = null;
                                            List<OSMPolygonFeature> osmPolygonList = null;
                                            List<OSMRelation> osmRelationList = null;

                                            rowBuffer = relationTable.CreateRowBuffer();
                                            comReleaser.ManageLifetime(rowBuffer);

                                            lineFeatureBuffer = osmLineFeatureClass.CreateFeatureBuffer();
                                            comReleaser.ManageLifetime(lineFeatureBuffer);

                                            polygonFeatureBuffer = osmPolygonFeatureClass.CreateFeatureBuffer();
                                            comReleaser.ManageLifetime(polygonFeatureBuffer);

                                            foreach (var item in currentRelation.Items)
                                            {
                                                if (item is member)
                                                {
                                                    member memberItem = item as member;
                                                    relationMemberList.Add(memberItem);

                                                    switch (memberItem.type)
                                                    {
                                                        case memberType.way:

                                                            if (!wayList.ContainsKey(memberItem.@ref))
                                                                wayList.Add(memberItem.@ref, memberItem.role);

                                                            if (IsThisWayALine(memberItem.@ref, osmLineFeatureClass, lineSQLIdentifier, osmPolygonFeatureClass, polygonSQLIdentifier))
                                                            {
                                                                if (osmLineList == null)
                                                                {
                                                                    osmLineList = new List<OSMLineFeature>();
                                                                }

                                                                OSMLineFeature lineFeature = new OSMLineFeature();
                                                                lineFeature.relationList = new List<string>();
                                                                lineFeature.lineID = memberItem.@ref;

                                                                if (detectedGeometryType == esriGeometryType.esriGeometryPolygon)
                                                                {
                                                                    lineFeature.relationList.Add(currentRelation.id + "_ply");
                                                                }
                                                                else if (detectedGeometryType == esriGeometryType.esriGeometryPolyline)
                                                                {
                                                                    lineFeature.relationList.Add(currentRelation.id + "_ln");
                                                                }
                                                                else
                                                                {
                                                                    lineFeature.relationList.Add(currentRelation.id + "_rel");
                                                                }

                                                                osmLineList.Add(lineFeature);
                                                            }
                                                            else
                                                            {
                                                                if (osmPolygonList == null)
                                                                {
                                                                    osmPolygonList = new List<OSMPolygonFeature>();
                                                                }

                                                                OSMPolygonFeature polygonFeature = new OSMPolygonFeature();
                                                                polygonFeature.relationList = new List<string>();
                                                                polygonFeature.polygonID = memberItem.@ref;

                                                                if (detectedGeometryType == esriGeometryType.esriGeometryPolygon)
                                                                {
                                                                    polygonFeature.relationList.Add(currentRelation.id + "_ply");
                                                                }
                                                                else if (detectedGeometryType == esriGeometryType.esriGeometryPolyline)
                                                                {
                                                                    polygonFeature.relationList.Add(currentRelation.id + "_ln");
                                                                }
                                                                else
                                                                {
                                                                    polygonFeature.relationList.Add(currentRelation.id + "_rel");
                                                                }

                                                                osmPolygonList.Add(polygonFeature);
                                                            }

                                                            break;
                                                        case memberType.node:

                                                            if (osmPointList == null)
                                                            {
                                                                osmPointList = new List<OSMNodeFeature>();
                                                            }

                                                            OSMNodeFeature nodeFeature = new OSMNodeFeature();
                                                            nodeFeature.relationList = new List<string>();
                                                            nodeFeature.nodeID = memberItem.@ref;

                                                            nodeFeature.relationList.Add(currentRelation.id + "_rel");

                                                            osmPointList.Add(nodeFeature);

                                                            break;
                                                        case memberType.relation:

                                                            if (osmRelationList == null)
                                                            {
                                                                osmRelationList = new List<OSMRelation>();
                                                            }

                                                            OSMRelation relation = new OSMRelation();
                                                            relation.relationList = new List<string>();
                                                            relation.relationID = memberItem.@ref;
                                                            relation.relationList.Add(currentRelation.id + "_rel");

                                                            break;
                                                        default:
                                                            break;
                                                    }

                                                }
                                                else if (item is tag)
                                                {
                                                    relationTagList.Add((tag)item);
                                                }
                                            }

                                            // if there is a defined geometry type use it to generate a multipart geometry
                                            if (detectedGeometryType == esriGeometryType.esriGeometryPolygon)
                                            {
                                                #region create multipart polygon geometry
                                                //IFeature mpFeature = osmPolygonFeatureClass.CreateFeature();

                                                IPolygon relationMPPolygon = new PolygonClass();
                                                relationMPPolygon.SpatialReference = ((IGeoDataset)osmPolygonFeatureClass).SpatialReference;

                                                ISegmentCollection relationPolygonGeometryCollection = relationMPPolygon as ISegmentCollection;

                                                IQueryFilter osmIDQueryFilter = new QueryFilterClass();
                                                string sqlPolyOSMID = osmPolygonFeatureClass.SqlIdentifier("OSMID");
                                                object missing = Type.Missing;
                                                bool relationComplete = true;

                                                // loop through the list of referenced ways that are listed in a relation
                                                // for each of the items we need to make a decision if they have merit to qualify as stand-alone features
                                                // due to the presence of meaningful attributes (tags)
                                                foreach (KeyValuePair<string, string> wayKey in wayList)
                                                {
                                                    if (relationComplete == false)
                                                        break;

                                                    if (TrackCancel.Continue() == false)
                                                    {
                                                        return missingRelations;
                                                    }

                                                    osmIDQueryFilter.WhereClause = sqlPolyOSMID + " = '" + wayKey.Key + "'";

                                                    System.Diagnostics.Debug.WriteLine("Relation (Polygon) #: " + relationDebugCount + " :___: " + currentRelation.id + " :___: " + wayKey.Key);

                                                    using (ComReleaser relationComReleaser = new ComReleaser())
                                                    {
                                                        IFeatureCursor featureCursor = osmPolygonFeatureClass.Search(osmIDQueryFilter, false);
                                                        relationComReleaser.ManageLifetime(featureCursor);

                                                        IFeature partFeature = featureCursor.NextFeature();

                                                        // set the appropriate field attribute to become invisible as a standalone features
                                                        if (partFeature != null)
                                                        {
                                                            IGeometryCollection ringCollection = partFeature.Shape as IGeometryCollection;

                                                            // test for available content in the geometry collection
                                                            if (ringCollection.GeometryCount > 0)
                                                            {
                                                                // test if we dealing with a valid geometry
                                                                if (ringCollection.get_Geometry(0).IsEmpty == false)
                                                                {
                                                                    // add it to the new geometry and mark the added geometry as a supporting element
                                                                    relationPolygonGeometryCollection.AddSegmentCollection((ISegmentCollection)ringCollection.get_Geometry(0));

                                                                    if (osmSupportingElementPolygonFieldIndex > -1)
                                                                    {
                                                                        // if the member of a relation has the role of "inner" and it has tags, then let's keep it
                                                                        // as a standalone feature as well
                                                                        // the geometry is then a hole in the relation but due to the tags it also has merits to be
                                                                        // considered a stand-alone feature
                                                                        if (wayKey.Value.ToLower().Equals("inner"))
                                                                        {
                                                                            if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolygonFieldIndex, null))
                                                                            {
                                                                                partFeature.set_Value(osmSupportingElementPolygonFieldIndex, "yes");
                                                                            }
                                                                        }
                                                                        else
                                                                        {
                                                                            // relation member without an explicit role or the role of "outer" are turned into
                                                                            // supporting features if they don't have relevant attribute
                                                                            if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null))
                                                                            {
                                                                                partFeature.set_Value(osmSupportingElementPolygonFieldIndex, "yes");
                                                                            }
                                                                        }
                                                                    }

                                                                    partFeature.Store();
                                                                }
                                                            }
                                                        }
                                                        else
                                                        {
                                                            // it still can be a line geometry that will be pieced together into a polygon
                                                            IFeatureCursor lineFeatureCursor = osmLineFeatureClass.Search(osmIDQueryFilter, false);
                                                            relationComReleaser.ManageLifetime(lineFeatureCursor);

                                                            partFeature = lineFeatureCursor.NextFeature();

                                                            if (partFeature != null)
                                                            {
                                                                IGeometryCollection ringCollection = partFeature.Shape as IGeometryCollection;

                                                                // test for available content in the geometry collection
                                                                if (ringCollection.GeometryCount > 0)
                                                                {
                                                                    // test if we dealing with a valid geometry
                                                                    if (ringCollection.get_Geometry(0).IsEmpty == false)
                                                                    {
                                                                        // add it to the new geometry and mark the added geometry as a supporting element
                                                                        relationPolygonGeometryCollection.AddSegmentCollection((ISegmentCollection)ringCollection.get_Geometry(0));

                                                                        if (osmSupportingElementPolylineFieldIndex > -1)
                                                                        {
                                                                            // if the member of a relation has the role of "inner" and it has tags, then let's keep it
                                                                            // as a standalone feature as well
                                                                            // the geometry is then a hole in the relation but due to the tags it also has merits to be
                                                                            // considered a stand-alone feature
                                                                            if (wayKey.Value.ToLower().Equals("inner"))
                                                                            {
                                                                                if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null))
                                                                                {
                                                                                    partFeature.set_Value(osmSupportingElementPolylineFieldIndex, "yes");
                                                                                }
                                                                            }
                                                                            else
                                                                            {
                                                                                // relation member without an explicit role or the role of "outer" are turned into
                                                                                // supporting features if they don't have relevant attribute
                                                                                if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null))
                                                                                {
                                                                                    partFeature.set_Value(osmSupportingElementPolylineFieldIndex, "yes");
                                                                                }
                                                                            }
                                                                        }

                                                                        partFeature.Store();
                                                                    }
                                                                }
                                                            }
                                                            else
                                                            {
                                                                relationComplete = false;
                                                                continue;
                                                            }
                                                        }
                                                    }
                                                }

                                                // mark the relation as incomplete
                                                if (relationComplete == false)
                                                {
                                                    missingRelations.Add(currentRelation.id);
                                                    continue;
                                                }

                                                // transform the added collections for geometries into a topological correct geometry representation
                                                ((IPolygon4)relationMPPolygon).SimplifyEx(true, false, true);

                                                polygonFeatureBuffer.Shape = relationMPPolygon;

                                                if (_osmUtility.DoesHaveKeys(currentRelation))
                                                {
                                                }
                                                else
                                                {
                                                    relationTagList = MergeTagsFromOuterPolygonToRelation(currentRelation, osmPolygonFeatureClass);
                                                }

                                                insertTags(osmPolygonDomainAttributeFieldIndices, osmPolygonDomainAttributeFieldLength, tagCollectionPolygonFieldIndex, polygonFeatureBuffer, relationTagList.ToArray());

                                                if (fastLoad == false)
                                                {
                                                    if (osmMembersPolygonFieldIndex > -1)
                                                    {
                                                        _osmUtility.insertMembers(osmMembersPolygonFieldIndex, (IFeature)polygonFeatureBuffer, relationMemberList.ToArray());
                                                    }

                                                    // store the administrative attributes
                                                    // user, uid, version, changeset, timestamp, visible
                                                    if (osmUserPolygonFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.user))
                                                        {
                                                            polygonFeatureBuffer.set_Value(osmUserPolygonFieldIndex, currentRelation.user);
                                                        }
                                                    }

                                                    if (osmUIDPolygonFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.uid))
                                                        {
                                                            polygonFeatureBuffer.set_Value(osmUIDPolygonFieldIndex, Convert.ToInt32(currentRelation.uid));
                                                        }
                                                    }

                                                    if (osmVisiblePolygonFieldIndex != -1)
                                                    {
                                                        if (String.IsNullOrEmpty(currentRelation.visible) == false)
                                                        {
                                                            polygonFeatureBuffer.set_Value(osmVisiblePolygonFieldIndex, currentRelation.visible.ToString());
                                                        }
                                                        else
                                                        {
                                                            polygonFeatureBuffer.set_Value(osmVisiblePolygonFieldIndex, "unknown");
                                                        }
                                                    }

                                                    if (osmVersionPolygonFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.version))
                                                        {
                                                            polygonFeatureBuffer.set_Value(osmVersionPolygonFieldIndex, Convert.ToInt32(currentRelation.version));
                                                        }
                                                    }

                                                    if (osmChangesetPolygonFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.changeset))
                                                        {
                                                            polygonFeatureBuffer.set_Value(osmChangesetPolygonFieldIndex, Convert.ToInt32(currentRelation.changeset));
                                                        }
                                                    }

                                                    if (osmTimeStampPolygonFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.timestamp))
                                                        {
                                                            polygonFeatureBuffer.set_Value(osmTimeStampPolygonFieldIndex, Convert.ToDateTime(currentRelation.timestamp));
                                                        }
                                                    }

                                                    if (osmPolygonIDFieldIndex != -1)
                                                    {
                                                        polygonFeatureBuffer.set_Value(osmPolygonIDFieldIndex, currentRelation.id);
                                                    }

                                                    if (osmSupportingElementPolygonFieldIndex > -1)
                                                    {
                                                        polygonFeatureBuffer.set_Value(osmSupportingElementPolygonFieldIndex, "no");
                                                    }
                                                }

                                                try
                                                {
                                                    //mpFeature.Store();
                                                    polygonFeatureInsertCursor.InsertFeature(polygonFeatureBuffer);
                                                }
                                                catch (Exception ex)
                                                {
                                                    message.AddWarning(ex.Message);
                                                }
                                                #endregion
                                            }
                                            else if (detectedGeometryType == esriGeometryType.esriGeometryPolyline)
                                            {
                                                #region create multipart polyline geometry
                                                //IFeature mpFeature = osmLineFeatureClass.CreateFeature();

                                                IPolyline relationMPPolyline = new PolylineClass();
                                                relationMPPolyline.SpatialReference = ((IGeoDataset)osmLineFeatureClass).SpatialReference;

                                                IGeometryCollection relationPolylineGeometryCollection = relationMPPolyline as IGeometryCollection;

                                                IQueryFilter osmIDQueryFilter = new QueryFilterClass();
                                                object missing = Type.Missing;

                                                // loop through the
                                                foreach (KeyValuePair<string, string> wayKey in wayList)
                                                {
                                                    if (TrackCancel.Continue() == false)
                                                    {
                                                        return missingRelations;
                                                    }

                                                    osmIDQueryFilter.WhereClause = osmLineFeatureClass.WhereClauseByExtensionVersion(wayKey.Key, "OSMID", 2);

                                                    System.Diagnostics.Debug.WriteLine("Relation (Polyline) #: " + relationDebugCount + " :___: " + currentRelation.id + " :___: " + wayKey);

                                                    using (ComReleaser relationComReleaser = new ComReleaser())
                                                    {
                                                        IFeatureCursor featureCursor = osmLineFeatureClass.Search(osmIDQueryFilter, false);
                                                        relationComReleaser.ManageLifetime(featureCursor);

                                                        IFeature partFeature = featureCursor.NextFeature();

                                                        // set the appropriate field attribute to become invisible as a standalone features
                                                        if (partFeature != null)
                                                        {
                                                            if (partFeature.Shape.IsEmpty == false)
                                                            {
                                                                IGeometryCollection pathCollection = partFeature.Shape as IGeometryCollection;
                                                                relationPolylineGeometryCollection.AddGeometry(pathCollection.get_Geometry(0), ref missing, ref missing);

                                                                if (osmSupportingElementPolylineFieldIndex > -1)
                                                                {
                                                                    if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null))
                                                                    {
                                                                        partFeature.set_Value(osmSupportingElementPolylineFieldIndex, "yes");
                                                                    }
                                                                }

                                                                partFeature.Store();
                                                            }
                                                        }
                                                    }
                                                }

                                                lineFeatureBuffer.Shape = relationMPPolyline;

                                                insertTags(osmLineDomainAttributeFieldIndices, osmLineDomainAttributeFieldLength, tagCollectionPolylineFieldIndex, lineFeatureBuffer, relationTagList.ToArray());

                                                if (fastLoad == false)
                                                {
                                                    if (osmMembersPolylineFieldIndex > -1)
                                                    {
                                                        _osmUtility.insertMembers(osmMembersPolylineFieldIndex, (IFeature)lineFeatureBuffer, relationMemberList.ToArray());
                                                    }

                                                    // store the administrative attributes
                                                    // user, uid, version, changeset, timestamp, visible
                                                    if (osmUserPolylineFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.user))
                                                        {
                                                            lineFeatureBuffer.set_Value(osmUserPolylineFieldIndex, currentRelation.user);
                                                        }
                                                    }

                                                    if (osmUIDPolylineFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.uid))
                                                        {
                                                            lineFeatureBuffer.set_Value(osmUIDPolylineFieldIndex, Convert.ToInt32(currentRelation.uid));
                                                        }
                                                    }

                                                    if (osmVisiblePolylineFieldIndex != -1)
                                                    {
                                                        if (String.IsNullOrEmpty(currentRelation.visible) == false)
                                                        {
                                                            lineFeatureBuffer.set_Value(osmVisiblePolylineFieldIndex, currentRelation.visible.ToString());
                                                        }
                                                        else
                                                        {
                                                            lineFeatureBuffer.set_Value(osmVisiblePolylineFieldIndex, "unknown");
                                                        }
                                                    }

                                                    if (osmVersionPolylineFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.version))
                                                        {
                                                            lineFeatureBuffer.set_Value(osmVersionPolylineFieldIndex, Convert.ToInt32(currentRelation.version));
                                                        }
                                                    }

                                                    if (osmChangesetPolylineFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.changeset))
                                                        {
                                                            lineFeatureBuffer.set_Value(osmChangesetPolylineFieldIndex, Convert.ToInt32(currentRelation.changeset));
                                                        }
                                                    }

                                                    if (osmTimeStampPolylineFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.timestamp))
                                                        {
                                                            lineFeatureBuffer.set_Value(osmTimeStampPolylineFieldIndex, Convert.ToDateTime(currentRelation.timestamp));
                                                        }
                                                    }

                                                    if (osmLineIDFieldIndex != -1)
                                                    {
                                                        lineFeatureBuffer.set_Value(osmLineIDFieldIndex, currentRelation.id);
                                                    }

                                                    if (osmSupportingElementPolylineFieldIndex > -1)
                                                    {
                                                        lineFeatureBuffer.set_Value(osmSupportingElementPolylineFieldIndex, "no");
                                                    }
                                                }

                                                try
                                                {
                                                    lineFeatureInsertCursor.InsertFeature(lineFeatureBuffer);
                                                }
                                                catch (Exception ex)
                                                {
                                                    message.AddWarning(ex.Message);
                                                }
                                                #endregion

                                            }
                                            else if (detectedGeometryType == esriGeometryType.esriGeometryPoint)
                                            {
                                                System.Diagnostics.Debug.WriteLine("Relation #: " + relationDebugCount + " :____: POINT!!!");

                                                if (TrackCancel.Continue() == false)
                                                {
                                                    return missingRelations;
                                                }
                                            }
                                            else
                                            // otherwise it is relation that needs to be dealt with separately
                                            {
                                                if (TrackCancel.Continue() == false)
                                                {
                                                    return missingRelations;
                                                }

                                                System.Diagnostics.Debug.WriteLine("Relation #: " + relationDebugCount + " :____: Kept as relation");

                                                if (tagCollectionRelationFieldIndex != -1)
                                                {
                                                    _osmUtility.insertOSMTags(tagCollectionRelationFieldIndex, rowBuffer, relationTagList.ToArray());
                                                }

                                                if (fastLoad == false)
                                                {
                                                    if (osmMembersRelationFieldIndex != -1)
                                                    {
                                                        _osmUtility.insertMembers(osmMembersRelationFieldIndex, rowBuffer, relationMemberList.ToArray());
                                                    }

                                                    // store the administrative attributes
                                                    // user, uid, version, changeset, timestamp, visible
                                                    if (osmUserRelationFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.user))
                                                        {
                                                            rowBuffer.set_Value(osmUserRelationFieldIndex, currentRelation.user);
                                                        }
                                                    }

                                                    if (osmUIDRelationFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.uid))
                                                        {
                                                            rowBuffer.set_Value(osmUIDRelationFieldIndex, Convert.ToInt64(currentRelation.uid));
                                                        }
                                                    }

                                                    if (osmVisibleRelationFieldIndex != -1)
                                                    {
                                                        if (currentRelation.visible != null)
                                                        {
                                                            rowBuffer.set_Value(osmVisibleRelationFieldIndex, currentRelation.visible.ToString());
                                                        }
                                                    }

                                                    if (osmVersionRelationFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.version))
                                                        {
                                                            rowBuffer.set_Value(osmVersionRelationFieldIndex, Convert.ToInt32(currentRelation.version));
                                                        }
                                                    }

                                                    if (osmChangesetRelationFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.changeset))
                                                        {
                                                            rowBuffer.set_Value(osmChangesetRelationFieldIndex, Convert.ToInt32(currentRelation.changeset));
                                                        }
                                                    }

                                                    if (osmTimeStampRelationFieldIndex != -1)
                                                    {
                                                        if (!String.IsNullOrEmpty(currentRelation.timestamp))
                                                        {
                                                            try
                                                            {
                                                                rowBuffer.set_Value(osmTimeStampRelationFieldIndex, Convert.ToDateTime(currentRelation.timestamp));
                                                            }
                                                            catch (Exception ex)
                                                            {
                                                                message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_invalidTimeFormat"), ex.Message));
                                                            }
                                                        }
                                                    }

                                                    if (osmRelationIDFieldIndex != -1)
                                                    {
                                                        rowBuffer.set_Value(osmRelationIDFieldIndex, currentRelation.id);
                                                    }
                                                }

                                                try
                                                {
                                                    rowCursor.InsertRow(rowBuffer);
                                                    relationCount = relationCount + 1;

                                                    relationIndexRebuildRequired = true;
                                                }
                                                catch (Exception ex)
                                                {
                                                    System.Diagnostics.Debug.WriteLine(ex.Message);
                                                }

                                                // check for user interruption
                                                if (TrackCancel.Continue() == false)
                                                {
                                                    return missingRelations;
                                                }
                                            }

                                            // update the isMemberOf fields of the attached features
                                            if (osmPointList != null)
                                            {
                                                foreach (OSMNodeFeature nodeFeature in osmPointList)
                                                {
                                                    updateIsMemberOf(osmLineFeatureClass, osmMemberOfPolylineFieldIndex, nodeFeature.nodeID, nodeFeature.relationList);
                                                }
                                            }

                                            if (osmLineList != null)
                                            {
                                                foreach (OSMLineFeature lineFeature in osmLineList)
                                                {
                                                    updateIsMemberOf(osmLineFeatureClass, osmMemberOfPolylineFieldIndex, lineFeature.lineID, lineFeature.relationList);
                                                }
                                            }

                                            if (osmPolygonList != null)
                                            {
                                                foreach (OSMPolygonFeature polygonFeature in osmPolygonList)
                                                {
                                                    updateIsMemberOf(osmLineFeatureClass, osmMemberOfPolylineFieldIndex, polygonFeature.polygonID, polygonFeature.relationList);
                                                }
                                            }

                                            if (stepProgressor != null)
                                            {
                                                stepProgressor.Position = relationCount;
                                            }

                                            if ((relationCount % 50000) == 0)
                                            {
                                                message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_relationsloaded"), relationCount));
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            message.AddWarning(ex.Message);
                                        }
                                        finally
                                        {
                                            if (rowBuffer != null)
                                            {
                                                Marshal.ReleaseComObject(rowBuffer);

                                                if (rowBuffer != null)
                                                    rowBuffer = null;
                                            }
                                            if (lineFeatureBuffer != null)
                                            {
                                                Marshal.ReleaseComObject(lineFeatureBuffer);

                                                if (lineFeatureBuffer != null)
                                                    lineFeatureBuffer = null;
                                            }

                                            if (polygonFeatureBuffer != null)
                                            {
                                                Marshal.ReleaseComObject(polygonFeatureBuffer);

                                                if (polygonFeatureBuffer != null)
                                                    polygonFeatureBuffer = null;
                                            }

                                            currentRelation = null;
                                        }
                                    }
                                }
                            }

                            // close the OSM file
                            osmFileXmlReader.Close();

                            // flush any remaining entities from the cursor
                            rowCursor.Flush();
                            polygonFeatureInsertCursor.Flush();
                            lineFeatureInsertCursor.Flush();

                            // force a garbage collection
                            System.GC.Collect();

                            // let the user know that we are done dealing with the relations
                            message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_relationsloaded"), relationCount));
                        }
                    }

                    if (stepProgressor != null)
                    {
                        stepProgressor.Hide();
                    }

                    // Addd index for osmid column as well
                    IGeoProcessor2 geoProcessor = new GeoProcessorClass();
                    bool storedOriginalLocal = geoProcessor.AddOutputsToMap;
                    IGPUtilities3 gpUtilities3 = new GPUtilitiesClass();

                    try
                    {
                        geoProcessor.AddOutputsToMap = false;

                        if (relationIndexRebuildRequired)
                        {
                            IIndexes tableIndexes = relationTable.Indexes;
                            int indexPosition = -1;
                            tableIndexes.FindIndex("osmID_IDX", out indexPosition);

                            if (indexPosition == -1)
                            {
                                IGPValue relationTableGPValue = gpUtilities3.MakeGPValueFromObject(relationTable);
                                string sddd = targetGPValue.GetAsText();
                                string tableLocation = GetLocationString(targetGPValue, relationTable);
                                IVariantArray parameterArrary = CreateAddIndexParameterArray(tableLocation, "OSMID", "osmID_IDX", "UNIQUE", "");
                                IGeoProcessorResult2 gpResults2 = geoProcessor.Execute("AddIndex_management", parameterArrary, TrackCancel) as IGeoProcessorResult2;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        message.AddWarning(ex.Message);
                    }
                    finally
                    {
                        geoProcessor.AddOutputsToMap = storedOriginalLocal;

                        Marshal.FinalReleaseComObject(gpUtilities3);
                        Marshal.FinalReleaseComObject(geoProcessor);
                    }
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (relationSerializer != null)
                    relationSerializer = null;

                if (osmFileXmlReader != null)
                    osmFileXmlReader = null;

                System.GC.Collect();
                System.GC.WaitForPendingFinalizers();
            }

            return missingRelations;
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Set the default properties for the specified job type
            try
            {
                IJTXConfiguration3     configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXConfigurationEdit2 configEdit = this.WmxDatabase.ConfigurationManager as IJTXConfigurationEdit2;
                IJTXJobTypeEdit3       jobType    = configEdit.GetJobType(m_jobTypeName) as IJTXJobTypeEdit3;

                // Set the default data workspace for the selected job type
                if (m_dataWorkspaceName.Equals(C_OPT_NONE))
                {
                    jobType.DefaultDataWorkspace = null;
                    msgs.AddMessage("Clearing default data workspace for job type '" + m_jobTypeName + "'");
                }
                else
                {
                    // Translate the workspace name to a DB name object
                    IJTXDataWorkspaceName dwName =
                        Common.WmauHelperFunctions.LookupWorkspaceNameObj(this.WmxDatabase, m_dataWorkspaceName);

                    msgs.AddMessage("Default data workspace for job type '" + m_jobTypeName + "' is now '" + dwName.Name + "'");
                    jobType.DefaultDataWorkspace = dwName;
                }

                // Set the default parent version for the selected job type
                if (m_parentVersion.Equals(C_OPT_NONE))
                {
                    msgs.AddMessage("Clearing default parent version for job type '" + m_jobTypeName + "'");
                    jobType.DefaultParentVersionName_2 = string.Empty;
                }
                else
                {
                    msgs.AddMessage("Default parent version for job type '" + m_jobTypeName + "' is now '" + m_parentVersion + "'");
                    jobType.DefaultParentVersionName_2 = m_parentVersion;
                }

                // Save the changes to the job type
                jobType.Store();

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_DATA_WORKSPACE);
                IGPString         outValue     = new GPStringClass();
                outValue.Value     = m_jobTypeName;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
Exemple #39
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            try
            {
                // Ensure that the current user has admin access to the current Workflow Manager DB
                if (!CurrentUserIsWmxAdministrator())
                {
                    throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR);
                }

                IJTXSpatialNotificationManager snManager          = this.WmxDatabase.SpatialNotificationManager;
                IJTXSpatialNotifierNameSet     allSnNames         = snManager.SpatialNotifiers;
                IJTXNotificationConfiguration  notificationConfig = this.WmxDatabase.ConfigurationManager as IJTXNotificationConfiguration;

                // Create a new spatial notification
                IJTXChangeRule2 changeRule = snManager.AddChangeRule() as IJTXChangeRule2;

                // Set the name
                changeRule.Name = m_snName;

                // Set the notifier
                IJTXNotificationType srcNotifType = notificationConfig.GetNotificationType(m_emailNotifier);

                // Set the properties of the spatial notification's e-mail notification to match that
                // of the source e-mail notification (phew!)
                IJTXEmailSpatialNotifier emailNotifier = this.CreateSpatialNotifierByName(C_TYPE_EMAIL_NOTIFIER) as IJTXEmailSpatialNotifier;
                emailNotifier.Subject           = srcNotifType.SubjectTemplate;
                emailNotifier.Body              = srcNotifType.MessageTemplate;
                emailNotifier.SenderEmail       = srcNotifType.SenderTemplate;
                emailNotifier.SenderDisplayName = srcNotifType.SenderDisplayNameTemplate;

                string[]     subscribers    = srcNotifType.get_Subscribers();
                IStringArray subscribersObj = new StrArrayClass();
                foreach (string subscriber in subscribers)
                {
                    subscribersObj.Add(subscriber);
                }
                emailNotifier.Subscribers = subscribersObj;

                changeRule.Notifier = emailNotifier as IJTXSpatialNotifier;

                // Set the description, if applicable
                if (!string.IsNullOrEmpty(m_snDescription))
                {
                    changeRule.Description = m_snDescription;
                }

                // Set the summarization behavior
                changeRule.SummarizeNotifications = m_summarize;

                // Store the resulting change rule
                changeRule.Store();

                // Update the output parameter
                WmauParameterMap  paramMap = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParam = paramMap.GetParamEdit(C_PARAM_OUT_NAME);
                IGPString         strValue = new GPStringClass();
                strValue.Value = m_snName;
                outParam.Value = strValue as IGPValue;

                msgs.AddWarning("To avoid database corruption, at least one dataset or area evaluator must be added to notification '" + m_snName + "' immediately!");
                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                try
                {
                    WmauError error = new WmauError(WmauErrorCodes.C_SN_CREATION_ERROR);
                    msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            finally
            {
                // Release any COM objects here!
            }
        }
        private void parseOSMDocument(string osmFileLocation, ref IGPMessages message, ref List<string> nodeList, ref List<string> wayList, ref List<string> relationList, ref List<string> downloadedDocuments, string baseURL, api apiCapabilities)
        {
            try
            {
                XmlSerializer nodeSerializer = new XmlSerializer(typeof(node));
                XmlSerializer waySerializer = new XmlSerializer(typeof(way));
                XmlSerializer relationSerializer = new XmlSerializer(typeof(relation));

                string requestURL = String.Empty;

                using (System.Xml.XmlReader osmFileXmlReader = System.Xml.XmlReader.Create(osmFileLocation))
                {
                    osmFileXmlReader.MoveToContent();

                    while (osmFileXmlReader.Read())
                    {
                        if (osmFileXmlReader.IsStartElement())
                        {
                            if (osmFileXmlReader.Name == "node")
                            {
                                string currentNodeString = osmFileXmlReader.ReadOuterXml();
                                // turn the xml node representation into a node class representation
                                node currentNode = nodeSerializer.Deserialize(new System.IO.StringReader(currentNodeString)) as node;
                                if (!nodeList.Contains(currentNode.id))
                                {
                                    nodeList.Add(currentNode.id);
                                }
                            }
                            else if (osmFileXmlReader.Name == "way")
                            {
                                string currentWayString = osmFileXmlReader.ReadOuterXml();
                                // turn the xml way representation into a way class representation
                                way currentWay = waySerializer.Deserialize(new System.IO.StringReader(currentWayString)) as way;
                                if (!wayList.Contains(currentWay.id))
                                {
                                    wayList.Add(currentWay.id);
                                }

                                //if (currentWay.nd != null)
                                //{
                                //    foreach (nd wayNd in currentWay.nd)
                                //    {
                                //        if (!nodeList.Contains(wayNd.@ref))
                                //        {
                                //            string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_node"), wayNd.@ref);
                                //            message.AddMessage(resolveMessage);
                                //            requestURL = baseURL + "/api/0.6/node/" + wayNd.@ref + "/full";
                                //            string nodeDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities);
                                //            parseOSMDocument(nodeDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities);
                                //            downloadedDocuments.Insert(1, nodeDownloadDocument);
                                //        }
                                //    }
                                //}
                            }
                            else if (osmFileXmlReader.Name == "relation")
                            {
                                string currentRelationString = osmFileXmlReader.ReadOuterXml();
                                // turn the xml way representation into a way class representation
                                relation currentRelation = relationSerializer.Deserialize(new System.IO.StringReader(currentRelationString)) as relation;
                                if (!relationList.Contains(currentRelation.id))
                                {
                                    relationList.Add(currentRelation.id);
                                }

                                foreach (object relationItem in currentRelation.Items)
                                {
                                    if (relationItem is member)
                                    {
                                        //if (((member)relationItem).type == memberType.node)
                                        //{
                                        //    string memberNodeID = ((member)relationItem).@ref;
                                        //    if (!nodeList.Contains(memberNodeID))
                                        //    {
                                        //        string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_node"), memberNodeID);
                                        //        message.AddMessage(resolveMessage);
                                        //        requestURL = baseURL + "/api/0.6/node/" + memberNodeID + "/full";
                                        //        string nodeDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities);
                                        //        parseOSMDocument(nodeDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities);
                                        //        downloadedDocuments.Insert(1, nodeDownloadDocument);
                                        //    }
                                        //}
                                        if (((member)relationItem).type == memberType.way)
                                        {
                                            string memberWayID = ((member)relationItem).@ref;
                                            if (!wayList.Contains(memberWayID))
                                            {
                                                string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_way"), memberWayID);
                                                message.AddMessage(resolveMessage);
                                                requestURL = baseURL + "/api/0.6/way/" + memberWayID + "/full";
                                                string wayDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities);
                                                if (!String.IsNullOrEmpty(wayDownloadDocument))
                                                {
                                                    parseOSMDocument(wayDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities);
                                                    downloadedDocuments.Insert(1, wayDownloadDocument);
                                                }
                                            }
                                        }
                                        else if (((member)relationItem).type == memberType.relation)
                                        {
                                            string memberRelationID = ((member)relationItem).@ref;
                                            if (!wayList.Contains(memberRelationID))
                                            {
                                                string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_relation"), memberRelationID);
                                                message.AddMessage(resolveMessage);
                                                requestURL = baseURL + "/api/0.6/relation/" + memberRelationID + "/full";
                                                string relationDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities);
                                                if (!String.IsNullOrEmpty(relationDownloadDocument))
                                                {
                                                    parseOSMDocument(relationDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities);
                                                    downloadedDocuments.Insert(1, relationDownloadDocument);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    osmFileXmlReader.Close();
                }
            }
            catch (Exception ex)
            {
                message.AddError(120051, ex.Message);
            }
        }
Exemple #41
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Assign the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXJob3           job        = jobManager.GetJob(m_jobId) as IJTXJob3;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;

                jtxAssignmentType assigneeType;
                string            descriptionStr;
                string            assigneeStr;
                if (m_assigneeType.Equals(C_OPT_ASSIGN_TO_GROUP))
                {
                    assigneeType   = jtxAssignmentType.jtxAssignmentTypeGroup;
                    assigneeStr    = m_assignee;
                    descriptionStr = "group '" + assigneeStr + "'";
                }
                else if (m_assigneeType.Equals(C_OPT_ASSIGN_TO_USER))
                {
                    assigneeType   = jtxAssignmentType.jtxAssignmentTypeUser;
                    assigneeStr    = m_assignee;
                    descriptionStr = "user '" + assigneeStr + "'";
                }
                else
                {
                    assigneeType   = jtxAssignmentType.jtxAssignmentTypeUnassigned;
                    assigneeStr    = string.Empty;
                    descriptionStr = "no one (unassigned)";
                }

                msgs.AddMessage("Assigning job " + m_jobId + " (" + job.Name + ") to " + descriptionStr);
                job.AssignedType = assigneeType;
                job.AssignedTo   = assigneeStr;
                job.Store();

                // Do the other things that still need to be handled manually, such as logging
                // the job's reassignment and sending any necessary notifications.
                job.LogJobAction(
                    configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_ASSIGN_JOB),
                    null,
                    string.Empty);
                Common.WmauHelperFunctions.SendNotification(
                    ESRI.ArcGIS.JTX.Utilities.Constants.NOTIF_JOB_ASSIGNED,
                    this.WmxDatabase,
                    job);

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }