/// <summary> /// Copies the essential attributes from one JTX workspace configuration object to another /// </summary> /// <param name="source">The source object</param> /// <param name="target">The target object</param> private void CopyDataWorkspace( Common.WorkspaceInfo source, ref IJTXWorkspaceConfiguration target, IGPMessages msgs) { target.Name = source.Name; target.Server = source.Server; target.Instance = source.Instance; target.Database = source.Database; target.Version = source.Version; target.OSAuthentication = source.UseOsAuthentication; target.IndividualLogins = source.UseIndividualLogins; foreach (Common.WorkspaceInfo.LoginInfo srcLogin in source.Logins) { string srcPassword = srcLogin.DatabasePassword; bool isPasswordEncrypted = srcLogin.IsPasswordEncrypted; // TODO: Remove this once the "blank password" bug is fixed (WMX TFS #4449) if (string.IsNullOrEmpty(srcPassword)) { srcPassword = "******"; isPasswordEncrypted = false; } // END TODO // NOTE: This seems to be where an actual database connection is finally // made, and so is the source for many of the exceptions that can be // encountered when using this tool. With this in mind, try to handle // exceptions appropriately starting here. try { target.AddLogin(srcLogin.WmxUsername, srcLogin.DatabaseUsername, srcPassword, isPasswordEncrypted); } catch (System.Runtime.InteropServices.COMException comEx) { if (m_errorBehavior.Equals(C_OPT_FAIL_ON_ERROR)) { throw comEx; } else if (m_errorBehavior.Equals(C_OPT_IGNORE_LOGIN_ERRORS)) { if (comEx.ErrorCode == (int)fdoError.FDO_E_SE_INVALID_USER) { msgs.AddWarning("Invalid user login detected for workspace '" + target.Name + "'; proceeding anyway"); } else { throw comEx; } } else { msgs.AddWarning(target.Name + ": " + comEx.Message + "; proceeding anyway"); } } } }
/// <summary> /// Verifies that the <paramref name="workspace" /> is at a valid ArcFM version. /// </summary> /// <param name="workspace">The workspace.</param> /// <param name="messages">The messagesfor the geoproccessing tool.</param> /// <returns> /// Returns a <see cref="bool" /> representing <c>true</c> when the workspace is the correct version. /// </returns> protected bool VerifyVersion(IWorkspace workspace, IGPMessages messages) { IMMArcFMDatabaseUpgradeInfo upgradeInfo = new DatabaseUpgradeInfo(workspace); upgradeInfo.Workspace = workspace; if (upgradeInfo.UpgradeRequired) { messages.AddWarning(string.Format("Please run the Upgrade ArcFM Solution Database tool before modifying the database. An upgrade from {0} to {1} is required.", upgradeInfo.CurrentBuildNumber, upgradeInfo.UpgradeBuildNumber)); return(false); } return(true); }
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); } }
/// <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); WorkspaceWorksheetWriter writer = 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); } // Load the workspace information from the database IJTXDatabaseConnectionManager dbConnectionManager = new JTXDatabaseConnectionManagerClass(); IJTXDatabaseConnection dbConnection = dbConnectionManager.GetConnection(WmxDatabase.Alias); int numWorkspaces = dbConnection.DataWorkspaceCount; // Copy the info into an intermediate list List <Common.WorkspaceInfo> workspaceInfo = new List <Common.WorkspaceInfo>(); Dictionary <string, string> namedWorkspaces = new Dictionary <string, string>(); for (int i = 0; i < numWorkspaces; i++) { IJTXWorkspaceConfiguration workspace = dbConnection.get_DataWorkspace(i); Common.WorkspaceInfo tempInfo = new Common.WorkspaceInfo(); tempInfo.Name = workspace.Name; tempInfo.Server = workspace.Server; tempInfo.Instance = workspace.Instance; tempInfo.Database = workspace.Database; tempInfo.Version = workspace.Version; tempInfo.UseOsAuthentication = workspace.OSAuthentication; tempInfo.UseIndividualLogins = workspace.IndividualLogins; int numLogins = workspace.LoginCount; for (int j = 0; j < numLogins; j++) { IJTXWorkspaceLogin tempLogin = workspace.get_Login(j); tempInfo.AddLogin(tempLogin.JTXUserName, tempLogin.UserName, tempLogin.Password, true); } if (namedWorkspaces.Keys.Contains(tempInfo.Name)) { msgs.AddWarning("Multiple workspaces detected with name '" + tempInfo.Name + "'; only the first workspace found will be exported."); } else { workspaceInfo.Add(tempInfo); namedWorkspaces.Add(tempInfo.Name, null); } } // Save the list to an Excel worksheet writer = new WorkspaceWorksheetWriter(this.m_excelFilePath, msgs); writer.SaveWorkspacesToSpreadsheet(workspaceInfo); 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 (writer != null) { writer.Close(); } } }
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 void Execute(IArray paramvalues, ITrackCancel TrackCancel, IGPEnvironmentManager envMgr, IGPMessages message) { IAoInitialize aoInitialize = new AoInitializeClass(); esriLicenseStatus naStatus = esriLicenseStatus.esriLicenseUnavailable; IGPUtilities2 gpUtil = null; IDataset osmDataset = null; try { if (!aoInitialize.IsExtensionCheckedOut(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork)) naStatus = aoInitialize.CheckOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork); gpUtil = new GPUtilitiesClass(); // OSM Dataset Param IGPParameter osmDatasetParam = paramvalues.get_Element(in_osmFeatureDataset) as IGPParameter; IDEDataset2 osmDEDataset = gpUtil.UnpackGPValue(osmDatasetParam) as IDEDataset2; if (osmDEDataset == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), osmDatasetParam.Name)); return; } osmDataset = gpUtil.OpenDatasetFromLocation(((IDataElement)osmDEDataset).CatalogPath) as IDataset; // Network Config File Param IGPParameter osmNetConfigParam = paramvalues.get_Element(in_NetworkConfigurationFile) as IGPParameter; IGPValue osmNetConfigFile = gpUtil.UnpackGPValue(osmNetConfigParam) as IGPValue; if ((osmNetConfigFile == null) || (string.IsNullOrEmpty(osmNetConfigFile.GetAsText()))) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), osmNetConfigParam.Name)); return; } // Target Network Dataset Param IGPParameter ndsParam = paramvalues.get_Element(out_NetworkDataset) as IGPParameter; IDataElement deNDS = gpUtil.UnpackGPValue(ndsParam) as IDataElement; if (deNDS == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), ndsParam.Name)); return; } // Create Network Dataset using (NetworkDataset nd = new NetworkDataset(osmNetConfigFile.GetAsText(), osmDataset, deNDS.Name, message, TrackCancel)) { if (nd.CanCreateNetworkDataset()) nd.CreateNetworkDataset(); } } catch (UserCancelException ex) { message.AddWarning(ex.Message); } catch (Exception ex) { message.AddError(120008, ex.Message); #if DEBUG message.AddError(120008, ex.StackTrace); #endif } finally { if (osmDataset != null) ComReleaser.ReleaseCOMObject(osmDataset); if (naStatus == esriLicenseStatus.esriLicenseCheckedOut) aoInitialize.CheckInExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork); if (gpUtil != null) ComReleaser.ReleaseCOMObject(gpUtil); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } }
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 void Execute(IArray paramvalues, ITrackCancel TrackCancel, IGPEnvironmentManager envMgr, IGPMessages message) { IAoInitialize aoInitialize = new AoInitializeClass(); esriLicenseStatus naStatus = esriLicenseStatus.esriLicenseUnavailable; IGPUtilities2 gpUtil = null; IDataset osmDataset = null; try { if (!aoInitialize.IsExtensionCheckedOut(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork)) { naStatus = aoInitialize.CheckOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork); } gpUtil = new GPUtilitiesClass(); // OSM Dataset Param IGPParameter osmDatasetParam = paramvalues.get_Element(in_osmFeatureDataset) as IGPParameter; IDEDataset2 osmDEDataset = gpUtil.UnpackGPValue(osmDatasetParam) as IDEDataset2; if (osmDEDataset == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), osmDatasetParam.Name)); return; } osmDataset = gpUtil.OpenDatasetFromLocation(((IDataElement)osmDEDataset).CatalogPath) as IDataset; // Network Config File Param IGPParameter osmNetConfigParam = paramvalues.get_Element(in_NetworkConfigurationFile) as IGPParameter; IGPValue osmNetConfigFile = gpUtil.UnpackGPValue(osmNetConfigParam) as IGPValue; if ((osmNetConfigFile == null) || (string.IsNullOrEmpty(osmNetConfigFile.GetAsText()))) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), osmNetConfigParam.Name)); return; } // Target Network Dataset Param IGPParameter ndsParam = paramvalues.get_Element(out_NetworkDataset) as IGPParameter; IDataElement deNDS = gpUtil.UnpackGPValue(ndsParam) as IDataElement; if (deNDS == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), ndsParam.Name)); return; } // Create Network Dataset using (NetworkDataset nd = new NetworkDataset(osmNetConfigFile.GetAsText(), osmDataset, deNDS.Name, message, TrackCancel)) { if (nd.CanCreateNetworkDataset()) { nd.CreateNetworkDataset(); } } } catch (UserCancelException ex) { message.AddWarning(ex.Message); } catch (Exception ex) { message.AddError(120008, ex.Message); #if DEBUG message.AddError(120008, ex.StackTrace); #endif } finally { if (osmDataset != null) { ComReleaser.ReleaseCOMObject(osmDataset); } if (naStatus == esriLicenseStatus.esriLicenseCheckedOut) { aoInitialize.CheckInExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork); } if (gpUtil != null) { ComReleaser.ReleaseCOMObject(gpUtil); } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } }
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; }
private void CreateRoadSplitsTable(string inputRdmsTable, string outputFileGdbPath, IGPMessages messages, ITrackCancel trackcancel) { // Open the Rdms table and find all the fields we need Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory"); var wsf = Activator.CreateInstance(factoryType) as IWorkspaceFactory; var fws = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace; ITable rdmsTable = fws.OpenTable(inputRdmsTable); 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"); // Open the Streets feature class and get its feature class ID IFeatureClass inputLineFeatures = fws.OpenFeatureClass(StreetsFCName); int streetsFCID = inputLineFeatures.FeatureClassID; // Define the fields for the RoadSplits table var ocd = new ObjectClassDescriptionClass() as IObjectClassDescription; var fieldsEdit = ocd.RequiredFields as IFieldsEdit; IFieldEdit field; // Add the anchor edge fields to the table field = new FieldClass(); field.Name_2 = "EdgeFCID"; field.Type_2 = esriFieldType.esriFieldTypeInteger; fieldsEdit.AddField(field); field = new FieldClass(); field.Name_2 = "EdgeFID"; field.Type_2 = esriFieldType.esriFieldTypeInteger; fieldsEdit.AddField(field); field = new FieldClass(); field.Name_2 = "EdgeFrmPos"; field.Type_2 = esriFieldType.esriFieldTypeDouble; fieldsEdit.AddField(field); field = new FieldClass(); field.Name_2 = "EdgeToPos"; field.Type_2 = esriFieldType.esriFieldTypeDouble; fieldsEdit.AddField(field); // Add the branch edge fields to the table for (int i = 0; i < 3; i++) { field = new FieldClass(); field.Name_2 = "Branch" + i + "FCID"; field.Type_2 = esriFieldType.esriFieldTypeInteger; fieldsEdit.AddField(field); field = new FieldClass(); field.Name_2 = "Branch" + i + "FID"; field.Type_2 = esriFieldType.esriFieldTypeInteger; fieldsEdit.AddField(field); field = new FieldClass(); field.Name_2 = "Branch" + i + "FrmPos"; field.Type_2 = esriFieldType.esriFieldTypeDouble; fieldsEdit.AddField(field); field = new FieldClass(); field.Name_2 = "Branch" + i + "ToPos"; field.Type_2 = esriFieldType.esriFieldTypeDouble; fieldsEdit.AddField(field); } // Check the fields and create the RoadSplits table 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 roadSplitsTable = fws.CreateTable(RoadSplitsTableName, validatedFields, ocd.InstanceCLSID, ocd.ClassExtensionCLSID, "") as ITable; // Find all the fields int EdgeFCIDFI = roadSplitsTable.FindField("EdgeFCID"); int EdgeFIDFI = roadSplitsTable.FindField("EdgeFID"); int EdgeFrmPosFI = roadSplitsTable.FindField("EdgeFrmPos"); int EdgeToPosFI = roadSplitsTable.FindField("EdgeToPos"); int Branch0FCIDFI = roadSplitsTable.FindField("Branch0FCID"); int Branch0FIDFI = roadSplitsTable.FindField("Branch0FID"); int Branch0FrmPosFI = roadSplitsTable.FindField("Branch0FrmPos"); int Branch0ToPosFI = roadSplitsTable.FindField("Branch0ToPos"); int Branch1FCIDFI = roadSplitsTable.FindField("Branch1FCID"); int Branch1FIDFI = roadSplitsTable.FindField("Branch1FID"); int Branch1FrmPosFI = roadSplitsTable.FindField("Branch1FrmPos"); int Branch1ToPosFI = roadSplitsTable.FindField("Branch1ToPos"); int Branch2FCIDFI = roadSplitsTable.FindField("Branch2FCID"); int Branch2FIDFI = roadSplitsTable.FindField("Branch2FID"); int Branch2FrmPosFI = roadSplitsTable.FindField("Branch2FrmPos"); int Branch2ToPosFI = roadSplitsTable.FindField("Branch2ToPos"); // Fetch all line features referenced by the input Rdms table. We do the // "join" this hard way to support all data sources in the sample. // Also, for large numbers of special explications, this strategy of fetching all // related features and holding them in RAM could be a problem. To fix // this, one could process the input records from the Rdms table in batches. System.Collections.Hashtable lineFeaturesList = SignpostUtilities.FillFeatureCache(rdmsTable, linkIDFieldOnRdms, manLinkIDField, inputLineFeatures, "LINK_ID", trackcancel); // Create insert cursor and row buffer for output ICursor tableInsertCursor = roadSplitsTable.Insert(true); IRowBuffer tableBuffer = roadSplitsTable.CreateRowBuffer(); IRow row = tableBuffer as IRow; // Create input cursor for the Rdms table we are importing ITableSort tableSort = new TableSortClass(); tableSort.Fields = "LINK_ID, COND_ID, SEQ_NUMBER"; tableSort.set_Ascending("LINK_ID", true); tableSort.set_Ascending("COND_ID", true); tableSort.set_Ascending("SEQ_NUMBER", true); tableSort.QueryFilter = null; tableSort.Table = rdmsTable; tableSort.Sort(null); ICursor inputCursor = tableSort.Rows; IRow inputTableRow = inputCursor.NextRow(); if (inputTableRow == null) return; // if Rdms table is empty, there's nothing to do // these are initialized to prevent uninitialized variable compiler error SignpostUtilities.FeatureData linkFeatureData = new SignpostUtilities.FeatureData(-1, null); SignpostUtilities.FeatureData manLinkFeatureData = new SignpostUtilities.FeatureData(-1, null); ICurve fromEdgeCurve, toEdgeCurve; IPoint fromEdgeStart, fromEdgeEnd, toEdgeStart, toEdgeEnd; double fromEdgeFromPos = 0.0; double fromEdgeToPos = 1.0; double toEdgeFromPos = 0.0; double toEdgeToPos = 1.0; long currentLinkID = Convert.ToInt64(inputTableRow.get_Value(linkIDFieldOnRdms)); long manLinkID = Convert.ToInt64(inputTableRow.get_Value(manLinkIDField)); try { linkFeatureData = (SignpostUtilities.FeatureData)lineFeaturesList[currentLinkID]; manLinkFeatureData = (SignpostUtilities.FeatureData)lineFeaturesList[manLinkID]; // To set from and to position in the output table, we need see where and // if the two edge features connect to figure out their digitized direction. fromEdgeCurve = linkFeatureData.feature as ICurve; toEdgeCurve = manLinkFeatureData.feature as ICurve; fromEdgeStart = fromEdgeCurve.FromPoint; fromEdgeEnd = fromEdgeCurve.ToPoint; toEdgeStart = toEdgeCurve.FromPoint; toEdgeEnd = toEdgeCurve.ToPoint; // 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 the field values in the buffer tableBuffer.set_Value(EdgeFCIDFI, streetsFCID); tableBuffer.set_Value(EdgeFIDFI, linkFeatureData.OID); tableBuffer.set_Value(EdgeFrmPosFI, fromEdgeFromPos); tableBuffer.set_Value(EdgeToPosFI, fromEdgeToPos); tableBuffer.set_Value(Branch0FCIDFI, streetsFCID); tableBuffer.set_Value(Branch0FIDFI, manLinkFeatureData.OID); tableBuffer.set_Value(Branch0FrmPosFI, toEdgeFromPos); tableBuffer.set_Value(Branch0ToPosFI, toEdgeToPos); tableBuffer.set_Value(Branch1FCIDFI, null); tableBuffer.set_Value(Branch1FIDFI, null); tableBuffer.set_Value(Branch1FrmPosFI, null); tableBuffer.set_Value(Branch1ToPosFI, null); tableBuffer.set_Value(Branch2FCIDFI, null); tableBuffer.set_Value(Branch2FIDFI, null); tableBuffer.set_Value(Branch2FrmPosFI, null); tableBuffer.set_Value(Branch2ToPosFI, null); } catch { messages.AddWarning("Line feature not found for explication with from ID: " + Convert.ToString(currentLinkID, System.Globalization.CultureInfo.InvariantCulture) + ", To ID: " + Convert.ToString(manLinkID, System.Globalization.CultureInfo.InvariantCulture)); } long previousLinkID = currentLinkID; int nextBranch = 1; while ((inputTableRow = inputCursor.NextRow()) != null) { currentLinkID = Convert.ToInt64(inputTableRow.get_Value(linkIDFieldOnRdms)); manLinkID = Convert.ToInt64(inputTableRow.get_Value(manLinkIDField)); try { linkFeatureData = (SignpostUtilities.FeatureData)lineFeaturesList[currentLinkID]; manLinkFeatureData = (SignpostUtilities.FeatureData)lineFeaturesList[manLinkID]; } catch { messages.AddWarning("Line feature not found for explication with from ID: " + Convert.ToString(currentLinkID, System.Globalization.CultureInfo.InvariantCulture) + ", To ID: " + Convert.ToString(manLinkID, System.Globalization.CultureInfo.InvariantCulture)); continue; } // To set from and to position in the output table, we need see where and // if the two edge features connect to figure out their digitized direction. fromEdgeCurve = linkFeatureData.feature as ICurve; toEdgeCurve = manLinkFeatureData.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 the field values in the buffer if (previousLinkID == currentLinkID) { switch (nextBranch) { case 1: tableBuffer.set_Value(Branch1FCIDFI, streetsFCID); tableBuffer.set_Value(Branch1FIDFI, manLinkFeatureData.OID); tableBuffer.set_Value(Branch1FrmPosFI, toEdgeFromPos); tableBuffer.set_Value(Branch1ToPosFI, toEdgeToPos); nextBranch = 2; break; case 2: tableBuffer.set_Value(Branch2FCIDFI, streetsFCID); tableBuffer.set_Value(Branch2FIDFI, manLinkFeatureData.OID); tableBuffer.set_Value(Branch2FrmPosFI, toEdgeFromPos); tableBuffer.set_Value(Branch2ToPosFI, toEdgeToPos); nextBranch = 3; break; case 3: messages.AddWarning("There are more than three road splits for From ID: " + Convert.ToString(currentLinkID, System.Globalization.CultureInfo.InvariantCulture)); nextBranch = 4; break; case 4: // do nothing here, as there's no need to repeat the warning message. break; } } else { // write out the previous buffered row... tableInsertCursor.InsertRow(tableBuffer); // ...and then set field values in the fresh buffer tableBuffer.set_Value(EdgeFCIDFI, streetsFCID); tableBuffer.set_Value(EdgeFIDFI, linkFeatureData.OID); tableBuffer.set_Value(EdgeFrmPosFI, fromEdgeFromPos); tableBuffer.set_Value(EdgeToPosFI, fromEdgeToPos); tableBuffer.set_Value(Branch0FCIDFI, streetsFCID); tableBuffer.set_Value(Branch0FIDFI, manLinkFeatureData.OID); tableBuffer.set_Value(Branch0FrmPosFI, toEdgeFromPos); tableBuffer.set_Value(Branch0ToPosFI, toEdgeToPos); tableBuffer.set_Value(Branch1FCIDFI, null); tableBuffer.set_Value(Branch1FIDFI, null); tableBuffer.set_Value(Branch1FrmPosFI, null); tableBuffer.set_Value(Branch1ToPosFI, null); tableBuffer.set_Value(Branch2FCIDFI, null); tableBuffer.set_Value(Branch2FIDFI, null); tableBuffer.set_Value(Branch2FrmPosFI, null); tableBuffer.set_Value(Branch2ToPosFI, null); nextBranch = 1; } previousLinkID = currentLinkID; } // Write out the final row and flush tableInsertCursor.InsertRow(tableBuffer); tableInsertCursor.Flush(); }
/// <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 properties of the spatial notification's e-mail notification IJTXEmailSpatialNotifier emailNotifier = CreateSpatialNotifierByName(C_TYPE_EMAIL_NOTIFIER) as IJTXEmailSpatialNotifier; emailNotifier.Subject = m_subject; emailNotifier.Body = m_message; // Default the sender's name and e-mail, if none is specified if (string.IsNullOrEmpty(m_senderEmail)) { IJTXConfigurationProperties configProps = this.WmxDatabase.ConfigurationManager as IJTXConfigurationProperties; emailNotifier.SenderEmail = configProps.GetProperty(Constants.JTX_PROPERTY_DEFAULT_SENDER_EMAIL); } else { emailNotifier.SenderEmail = m_senderEmail; } if (string.IsNullOrEmpty(m_senderName)) { IJTXConfigurationProperties configProps = this.WmxDatabase.ConfigurationManager as IJTXConfigurationProperties; emailNotifier.SenderDisplayName = configProps.GetProperty(Constants.JTX_PROPERTY_DEFAULT_SENDER_NAME); } else { emailNotifier.SenderDisplayName = m_senderName; } // Split the subscribers into a list (assume semicolon-deliminted) string[] subscribers = m_subscribers.Split(new char[] { C_DELIM_SUBSCRIBERS }); IStringArray subscribersObj = new StrArrayClass(); foreach (string subscriber in subscribers) { string tempStr = subscriber.Trim(); if (!tempStr.Equals(string.Empty)) { subscribersObj.Add(subscriber.Trim()); } } 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! } }
/// <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); } IJTXConfigurationEdit2 configEdit = this.WmxDatabase.ConfigurationManager as IJTXConfigurationEdit2; // Look up the appropriate user(s) IJTXUserSet users = null; if (m_userName.Equals(C_OPT_ALL_USERS)) { users = configEdit.Users; } else { users = new JTXUserSetClass(); (users as IJTXUserSetEdit).Add(configEdit.GetUser(m_userName)); } // Grant/revoke admin access to the specified users for (int i = 0; i < users.Count; i++) { IJTXUser3 user = users.get_Item(i) as IJTXUser3; user.IsAdministrator = m_privilegeAction.Equals(C_OPT_GRANT) ? true : false; (user as IJTXUserConfig).Store(); } // If the tool was set to preserve the current user's access and the tool removed it, // re-grant their access string username = ESRI.ArcGIS.JTXUI.ConfigurationCache.GetCurrentSystemUser(ESRI.ArcGIS.JTXUI.ConfigurationCache.UseUserDomain); IJTXUser3 userObj = configEdit.GetUser(username) as IJTXUser3; if (!userObj.IsAdministrator) { if (m_preserveCurrentUser) { userObj.IsAdministrator = true; (userObj as IJTXUserConfig).Store(); msgs.AddMessage("Re-granting admin access for user '" + username + "'"); } else { msgs.AddWarning("User '" + username + "' is no longer an administrator on this Workflow Manager database"); } } // Update the output parameter WmauParameterMap paramMap = new WmauParameterMap(paramValues); IGPParameterEdit3 outParam = paramMap.GetParamEdit(C_PARAM_OUT_USER_NAME); IGPString strValue = new GPStringClass(); strValue.Value = m_userName; outParam.Value = strValue 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! } }
/// <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); ////////////////////////////////////////////////////////////////////// // TODO: Update the job-deletion logic. // // In subsequent builds of Workflow Manager (post-10.0), there may be // a new API that deletes jobs and handles some of the logic included // in this class (ex: checking permissions, deleting versions, etc.). // 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 deleting Workflow Manager jobs, should keep this in mind. ////////////////////////////////////////////////////////////////////// // Delete the requested job try { IJTXJobManager jobManager = this.WmxDatabase.JobManager; IJTXJob3 job = jobManager.GetJob(m_jobToDelete) as IJTXJob3; msgs.AddMessage("Deleting job " + m_jobToDelete + " (" + job.Name + ")"); job.DeleteMXD(); if (job.VersionExists()) { if (CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_DELETE_VERSION)) { try { job.DeleteVersion(null); } catch (System.Runtime.InteropServices.COMException comEx) { if (comEx.ErrorCode == (int)fdoError.FDO_E_SE_VERSION_NOEXIST) { // The "VersionExists" method above can apparently be fooled; if it is, an exception with this // error code is thrown. In this case, add a warning and continue on. msgs.AddWarning("Version '" + job.VersionName + "' is assigned to job " + job.ID.ToString() + " but could not be found"); } else { // If there's a different error, then re-throw it for someone else to deal with throw comEx; } } } else { string username = ESRI.ArcGIS.JTXUI.ConfigurationCache.GetCurrentSystemUser(ESRI.ArcGIS.JTXUI.ConfigurationCache.UseUserDomain); msgs.AddWarning("User '" + username + "' does not have permissions to " + "delete job versions; version '" + job.VersionName + "' will not be deleted"); } } jobManager.DeleteJob(m_jobToDelete, true); // Set the output parameter WmauParameterMap paramMap = new WmauParameterMap(paramValues); IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_JOB_DELETED); IGPLong outValue = new GPLongClass(); outValue.Value = m_jobToDelete; outParamEdit.Value = outValue as IGPValue; msgs.AddMessage(Properties.Resources.MSG_DONE); } catch (Exception ex) { WmauError error = new WmauError(WmauErrorCodes.C_DELETE_JOB_VERSION_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message); } }
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); 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 } } }
/// <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! } }
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; } }
// 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(); } }
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); 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 } } }
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; }
/// <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! } }
/// <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(); } } }
private void BuildSpatialIndex(IGPValue gpFeatureClass, Geoprocessor.Geoprocessor geoProcessor, IGPUtilities gpUtil, ITrackCancel trackCancel, IGPMessages message) { if ((gpFeatureClass == null) || (geoProcessor == null) || (gpUtil == null)) return; // Check if the feature class supports spatial index grids IFeatureClass fc = gpUtil.OpenDataset(gpFeatureClass) as IFeatureClass; if (fc == null) return; int idxShapeField = fc.FindField(fc.ShapeFieldName); if (idxShapeField >= 0) { IField shapeField = fc.Fields.get_Field(idxShapeField); if (shapeField.GeometryDef.GridCount > 0) { if (shapeField.GeometryDef.get_GridSize(0) == -2.0) return; } } // Create the new spatial index grid bool storedOriginal = geoProcessor.AddOutputsToMap; try { geoProcessor.AddOutputsToMap = false; DataManagementTools.CalculateDefaultGridIndex calculateDefaultGridIndex = new DataManagementTools.CalculateDefaultGridIndex(gpFeatureClass); IGeoProcessorResult2 gpResults2 = geoProcessor.Execute(calculateDefaultGridIndex, trackCancel) as IGeoProcessorResult2; message.AddMessages(gpResults2.GetResultMessages()); if (gpResults2 != null) { DataManagementTools.RemoveSpatialIndex removeSpatialIndex = new DataManagementTools.RemoveSpatialIndex(gpFeatureClass.GetAsText()); removeSpatialIndex.out_feature_class = gpFeatureClass.GetAsText(); gpResults2 = geoProcessor.Execute(removeSpatialIndex, trackCancel) as IGeoProcessorResult2; message.AddMessages(gpResults2.GetResultMessages()); DataManagementTools.AddSpatialIndex addSpatialIndex = new DataManagementTools.AddSpatialIndex(gpFeatureClass.GetAsText()); addSpatialIndex.out_feature_class = gpFeatureClass.GetAsText(); addSpatialIndex.spatial_grid_1 = calculateDefaultGridIndex.grid_index1; addSpatialIndex.spatial_grid_2 = calculateDefaultGridIndex.grid_index2; addSpatialIndex.spatial_grid_3 = calculateDefaultGridIndex.grid_index3; gpResults2 = geoProcessor.Execute(addSpatialIndex, trackCancel) as IGeoProcessorResult2; message.AddMessages(gpResults2.GetResultMessages()); } } catch (Exception ex) { message.AddWarning(ex.Message); } finally { geoProcessor.AddOutputsToMap = storedOriginal; } }
// 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(); } }