public NetworkDataset(string configXML, IDataset osmDataset, string ndsName, IGPMessages messages, ITrackCancel trackCancel) { _xml = new NetworkDatasetXML(configXML, RESMGR); _osmDataset = osmDataset; _ndsName = ndsName; _messages = messages; _trackCancel = trackCancel; IDataElement deOSM = GPUtil.MakeDataElementFromNameObject(_osmDataset.FullName); _dsPath = deOSM.CatalogPath; _osmLineName = _osmDataset.Name + "_osm_ln"; _osmLinePath = _dsPath + "\\" + _osmLineName; _osmPointName = _osmDataset.Name + "_osm_pt"; _osmPointPath = _dsPath + "\\" + _osmPointName; // Get the extent from the point feature class // NOTE: the feature dataset is not used for this because exceptions occur (SDE only) // if a feature class was recently deleted from the feature dataset. IFeatureClass fcPoint = ((IFeatureWorkspace)_osmDataset.Workspace).OpenFeatureClass(_osmPointName); IGeoDataset gds = (IGeoDataset)fcPoint; _extent = gds.Extent; _spatialReference = gds.SpatialReference; }
public static void WriteBuildErrorsToTurnFC(string outputFileGdbPath, string fdsName, string turnFCName, IGPMessages messages, ITrackCancel trackcancel) { messages.AddMessage("Writing build errors to the turn feature class..."); // Create a new field on the turn feature class for the build errors Geoprocessor gp = new Geoprocessor(); gp.AddOutputsToMap = false; AddField addFieldTool = new AddField(); addFieldTool.in_table = outputFileGdbPath + "\\" + fdsName + "\\" + turnFCName; addFieldTool.field_name = "BuildError"; addFieldTool.field_type = "SHORT"; gp.Execute(addFieldTool, trackcancel); // Open the turn feature class in the file geodatabase and find the BuildError field on it Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory"); var wsf = Activator.CreateInstance(factoryType) as IWorkspaceFactory; var fws = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace; IFeatureClass turnFC = fws.OpenFeatureClass(turnFCName); int buildErrorField = turnFC.FindField("BuildError"); // Open the BuildErrors.txt file generated from building the network dataset string s, leftTrimmedString, oidString; int leftTrimAmt = 24 + turnFCName.Length; IFeature feat = null; string[] buildErrorsFiles = System.IO.Directory.GetFiles(Environment.GetEnvironmentVariable("TEMP"), "BuildErrors.txt", System.IO.SearchOption.AllDirectories); string buildErrorsFile = buildErrorsFiles[0]; System.IO.StreamReader f = new System.IO.StreamReader(buildErrorsFile); // Loop through the BuildErrors.txt file and write the value 1 for each entry found. while ((s = f.ReadLine()) != null) { // ignore blank lines if (s.Length == 0) continue; // ignore build errors not dealing with the turn source if (s.Remove(leftTrimAmt) != ("SourceName: " + turnFCName + ", ObjectID: ")) continue; leftTrimmedString = s.Substring(leftTrimAmt); oidString = leftTrimmedString.Remove(leftTrimmedString.IndexOf(", ")); feat = turnFC.GetFeature(Convert.ToInt32(oidString, System.Globalization.CultureInfo.InvariantCulture)); feat.set_Value(buildErrorField, 1); feat.Store(); } f.Close(); }
public RunTaskManager(ITrackCancel trackCancel, IGPMessages messages) { if (trackCancel == null) throw new ArgumentNullException("TrackCancel"); if (messages == null) throw new ArgumentNullException("Messages"); _trackCancel = trackCancel; _messages = messages; _taskMessages = new List<string>(); StepProgressor = _trackCancel as IStepProgressor; }
private void AddMessage(string messageString, IGPMessages messages, ITrackCancel trackcancel) { messages.AddMessage(messageString); IStepProgressor sp = trackcancel as IStepProgressor; if (sp != null) sp.Message = messageString; }
/// <summary> /// Called immediately after a tool is executed by the GeoProcessor. /// </summary> /// <param name="Tool"></param> /// <param name="Values"></param> /// <param name="result"></param> /// <param name="Messages"></param> void IGeoProcessorEvents.PostToolExecute(IGPTool Tool, IArray Values, int result, IGPMessages Messages) { GPMessageEventArgs[] messages = new GPMessageEventArgs[Messages.Count]; IGPMessage gpMessage = null; for (int i = 0; i < Messages.Count; i++) { gpMessage = Messages.GetMessage(i); GPMessageEventArgs message = new GPMessageEventArgs(gpMessage.Description, gpMessage.Type, gpMessage.ErrorCode); messages[i] = message; } //create a new instance of GPPostToolExecuteEventArgs GPPostToolExecuteEventArgs e = new GPPostToolExecuteEventArgs(); e.DisplayName = Tool.DisplayName; e.Name = Tool.Name; e.PathName = Tool.PathName; e.Toolbox = Tool.Toolbox.Alias; e.ToolCategory = Tool.ToolCategory; e.ToolType = Tool.ToolType; e.Description = Tool.Description; e.Result = result; //fire the Post tool event if (null != GPPostToolExecute) GPPostToolExecute(this, e); }
// Execute: Execute the function given the array of the parameters public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages message) { // Get the first Input Parameter IGPParameter parameter = (IGPParameter)paramvalues.get_Element(0); // UnPackGPValue. This ensures you get the value either form the dataelement or GpVariable (ModelBuilder) IGPValue parameterValue = m_GPUtilities.UnpackGPValue(parameter); // Open Input Dataset IFeatureClass inputFeatureClass; IQueryFilter qf; m_GPUtilities.DecodeFeatureLayer(parameterValue, out inputFeatureClass, out qf); if (inputFeatureClass == null) { message.AddError(2, "Could not open input dataset."); return; } // Add the field if it does not exist. int indexA; parameter = (IGPParameter)paramvalues.get_Element(1); string field = parameter.Value.GetAsText(); indexA = inputFeatureClass.FindField(field); if (indexA < 0) { IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble; fieldEdit.Name_2 = field; inputFeatureClass.AddField(fieldEdit); } int featcount = inputFeatureClass.FeatureCount(null); //Set the properties of the Step Progressor IStepProgressor pStepPro = (IStepProgressor)trackcancel; pStepPro.MinRange = 0; pStepPro.MaxRange = featcount; pStepPro.StepValue = (1); pStepPro.Message = "Calculating Area"; pStepPro.Position = 0; pStepPro.Show(); // Create an Update Cursor indexA = inputFeatureClass.FindField(field); IFeatureCursor updateCursor = inputFeatureClass.Update(qf, false); IFeature updateFeature = updateCursor.NextFeature(); IGeometry geometry; IArea area; double dArea; while (updateFeature != null) { geometry = updateFeature.Shape; area = (IArea)geometry; dArea = area.Area; updateFeature.set_Value(indexA, dArea); updateCursor.UpdateFeature(updateFeature); updateFeature.Store(); updateFeature = updateCursor.NextFeature(); pStepPro.Step(); } pStepPro.Hide(); // Release the update cursor to remove the lock on the input data. System.Runtime.InteropServices.Marshal.ReleaseComObject(updateCursor); }
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> /// Takes an IGPMessages object and converts it to a nicely-formatted string. /// </summary> /// <param name="messages">An IGPMessages object containing one or more messages.</param> /// <param name="bFailureMessages">Set to true if any failure messages (aborts or errors) were detected; false otherwise</param> /// <returns>A string formatted in the GP-style message.</returns> private string ConvertGPMessagesToString(IGPMessages messages, out bool bFailureMessages) { string msgsAsString = String.Empty; StringBuilder sb = new StringBuilder(); bFailureMessages = false; if (messages != null) { // Iterate through each of the messages for (int i = 0; i < messages.Count; i++) { IGPMessage message = messages.GetMessage(i); if ((message != null) && !string.IsNullOrEmpty(message.Description)) { string strType = ""; switch (message.Type) { case esriGPMessageType.esriGPMessageTypeAbort: strType = "Abort:"; bFailureMessages = true; break; case esriGPMessageType.esriGPMessageTypeEmpty: strType = "Empty:"; break; case esriGPMessageType.esriGPMessageTypeError: strType = "Error:"; bFailureMessages = true; break; case esriGPMessageType.esriGPMessageTypeInformative: strType = "Info:"; break; case esriGPMessageType.esriGPMessageTypeProcessDefinition: strType = "ProcessDef:"; break; case esriGPMessageType.esriGPMessageTypeProcessStart: strType = "ProcessStart:"; break; case esriGPMessageType.esriGPMessageTypeProcessStop: strType = "ProcessStop:"; break; case esriGPMessageType.esriGPMessageTypeWarning: strType = "Warning:"; break; } sb.AppendLine(strType + " " + message.Description); } } } return sb.ToString(); }
//********************************************************************************* // Gather the error/warning/informative messages from GPMessages //********************************************************************************* public string GetGPMessagesAsString(IGPMessages gpMessages) { // Gather Error/Warning/Informative Messages var messages = new StringBuilder(); if (gpMessages != null) { for (int i = 0; i < gpMessages.Count; i++) { IGPMessage gpMessage = gpMessages.GetMessage(i); string message = gpMessage.Description; switch (gpMessages.GetMessage(i).Type) { case esriGPMessageType.esriGPMessageTypeError: messages.AppendLine("Error " + gpMessage.ErrorCode + ": " + message); break; case esriGPMessageType.esriGPMessageTypeWarning: messages.AppendLine("Warning: " + message); break; default: messages.AppendLine("Information: " + message); break; } } } return messages.ToString(); }
/// <summary> /// Executes the geoprocessing function using the given array of parameter values. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="trackCancel">The track cancel.</param> /// <param name="environmentManager">Provides access to all the current environments and settings of the current client.</param> /// <param name="messages">The messages.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// parameters;A function tool must always have an output. At the minimum, /// your function should output a Boolean value containing success or failure. /// </exception> public virtual void Execute(IArray parameters, ITrackCancel trackCancel, IGPEnvironmentManager environmentManager, IGPMessages messages) { try { if (parameters.AsEnumerable <IGPParameter>().All(o => o.Direction != esriGPParameterDirection.esriGPParameterDirectionOutput)) { throw new ArgumentOutOfRangeException(nameof(parameters), @"A function tool must always have an output. At the minimum, your function should output a Boolean value containing success or failure."); } var list = this.Unpack(parameters); this.Execute(list, trackCancel, environmentManager, messages, this.Utilities); } catch (Exception ex) { messages.AddError(-1, ex.StackTrace); } }
/// <summary> /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed. /// </summary> /// <param name="paramValues"></param> /// <param name="trackCancel"></param> /// <param name="envMgr"></param> /// <param name="msgs"></param> public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs) { // Do some common error-checking base.Execute(paramValues, trackCancel, envMgr, msgs); // Close the requested job try { IJTXJobManager jobManager = this.WmxDatabase.JobManager; IJTXJob3 job = jobManager.GetJob(m_jobToClose) as IJTXJob3; IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; if (job.Stage != jtxJobStage.jtxJobStageClosed && !job.CanClose()) { throw new WmauException(WmauErrorCodes.C_CANNOT_CLOSE_JOB_ERROR); } msgs.AddMessage("Closing job " + m_jobToClose + " (" + job.Name + ")"); job.Close(); // Once the job is closed, do the other things that still need to be handled // separately (status updates, notifications, ...) Common.WmauHelperFunctions.UpdateJobStatus(this.WmxDatabase, job); job.Store(); job.LogJobAction( configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_CLOSE_JOB), null, string.Empty); Common.WmauHelperFunctions.SendNotification( ESRI.ArcGIS.JTX.Utilities.Constants.NOTIF_JOB_CLOSED, this.WmxDatabase, job); // Set the output parameter WmauParameterMap paramMap = new WmauParameterMap(paramValues); IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_JOB_CLOSED); IGPLong outValue = new GPLongClass(); outValue.Value = m_jobToClose; outParamEdit.Value = outValue as IGPValue; msgs.AddMessage(Properties.Resources.MSG_DONE); } catch (WmauException wmEx) { try { msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message); } catch { // Catch anything else that possibly happens } } catch (Exception ex) { WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message); } }
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; } }
/// <summary> /// Executes the geoprocessing function using the given array of parameter values. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="trackCancel">The track cancel.</param> /// <param name="environmentManager">Provides access to all the current environments and settings of the current client.</param> /// <param name="messages">The messages that are reported to the user.</param> /// <param name="utilities"> /// The utilities object that provides access to the properties and methods of a geoprocessing /// objects. /// </param> protected override void Execute(Dictionary <string, IGPValue> parameters, ITrackCancel trackCancel, IGPEnvironmentManager environmentManager, IGPMessages messages, IGPUtilities2 utilities) { IGPValue value = parameters["in_table"]; IObjectClass table = utilities.OpenTable(value); if (table != null) { IGPMultiValue onCreate = (IGPMultiValue)parameters["in_create"]; IGPMultiValue onUpdate = (IGPMultiValue)parameters["in_update"]; IGPMultiValue onDelete = (IGPMultiValue)parameters["in_delete"]; IGPMultiValue onBeforeSplit = (IGPMultiValue)parameters["in_before"]; IGPMultiValue onSplit = (IGPMultiValue)parameters["in_split"]; IGPMultiValue onAfterSplit = (IGPMultiValue)parameters["in_after"]; // Load "Special" AUs. var uids = new Dictionary <mmEditEvent, IEnumerable <IUID> >(); uids.Add(mmEditEvent.mmEventFeatureCreate, onCreate.AsEnumerable().Cast <IGPAutoValue>().Select(o => o.UID)); uids.Add(mmEditEvent.mmEventFeatureUpdate, onUpdate.AsEnumerable().Cast <IGPAutoValue>().Select(o => o.UID)); uids.Add(mmEditEvent.mmEventFeatureDelete, onDelete.AsEnumerable().Cast <IGPAutoValue>().Select(o => o.UID)); uids.Add(mmEditEvent.mmEventBeforeFeatureSplit, onBeforeSplit.AsEnumerable().Cast <IGPAutoValue>().Select(o => o.UID)); uids.Add(mmEditEvent.mmEventFeatureSplit, onSplit.AsEnumerable().Cast <IGPAutoValue>().Select(o => o.UID)); uids.Add(mmEditEvent.mmEventAfterFeatureSplit, onAfterSplit.AsEnumerable().Cast <IGPAutoValue>().Select(o => o.UID)); IMMConfigTopLevel configTopLevel = ConfigTopLevel.Instance; configTopLevel.Workspace = utilities.GetWorkspace(value); // Load all of the subtypes when the user specified "All" or "-1". int subtype = parameters["in_subtype"].Cast(-1); var subtypeCodes = new List <int>(new[] { subtype }); if (subtype == -1) { ISubtypes subtypes = (ISubtypes)table; subtypeCodes.AddRange(subtypes.Subtypes.AsEnumerable().Select(o => o.Key)); } // Enumerate through all of the subtypes making changes. foreach (var subtypeCode in subtypeCodes) { // Load the configurations for the table and subtype. ID8List list = (ID8List)configTopLevel.GetSubtypeByID(table, subtypeCode, false); // Update the list to have these UIDs removed. this.Add(uids, list, messages); } // Commit the changes to the database. configTopLevel.SaveFeatureClassToDB(table); // Success. parameters["out_results"].SetAsText("true"); } else { // Failure. parameters["out_results"].SetAsText("false"); } }
/// <summary> /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed. /// </summary> /// <param name="paramValues"></param> /// <param name="trackCancel"></param> /// <param name="envMgr"></param> /// <param name="msgs"></param> public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs) { // Do some common error-checking base.Execute(paramValues, trackCancel, envMgr, msgs); try { // Retrieve the parameter in which the list of workbook names will be stored WmauParameterMap paramMap = new WmauParameterMap(paramValues); IGPParameter3 param = paramMap.GetParam(C_PARAM_TAM_WORKBOOK_LIST); IGPParameterEdit3 paramEdit = paramMap.GetParamEdit(C_PARAM_TAM_WORKBOOK_LIST); // Set up the multi-value objects IGPMultiValue mvValue = new GPMultiValueClass(); mvValue.MemberDataType = param.DataType; // Get the list of TA workbook names and add them all to the multivalue SortedList <string, string> tamWorkbooks = this.ListTamWorkbooksInDatabase(); foreach (string workbookAlias in tamWorkbooks.Keys) { IGPString strVal = new GPStringClass(); strVal.Value = workbookAlias; mvValue.AddValue(strVal as IGPValue); msgs.AddMessage("Workbook: " + workbookAlias); } paramEdit.Value = (IGPValue)mvValue; msgs.AddMessage(Properties.Resources.MSG_DONE); } catch (WmauException wmEx) { try { msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message); } catch { // Catch anything else that possibly happens } } catch (Exception ex) { try { WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message); } catch { // Catch anything else that possibly happens } } }
/// <summary> /// Post validates the given set of values. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="environmentManager">Provides access to all the current environments and settings of the current client.</param> /// <param name="messages">The messages that are reported to the user.</param> /// <param name="utilities"> /// The utilities object that provides access to the properties and methods of a geoprocessing /// objects. /// </param> protected virtual void UpdateMessages(Dictionary <string, IGPParameter> parameters, IGPEnvironmentManager environmentManager, IGPMessages messages, IGPUtilities2 utilities) { }
/// <summary> /// Executes the geoprocessing function using the given array of parameter values. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="trackCancel">The track cancel.</param> /// <param name="environmentManager">Provides access to all the current environments and settings of the current client.</param> /// <param name="messages">The messages that are reported to the user.</param> /// <param name="utilities"> /// The utilities object that provides access to the properties and methods of a geoprocessing /// objects. /// </param> protected abstract void Execute(Dictionary <string, IGPValue> parameters, ITrackCancel trackCancel, IGPEnvironmentManager environmentManager, IGPMessages messages, IGPUtilities2 utilities);
/// <summary> /// Post validates the given set of values. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="environmentManager">Provides access to all the current environments and settings of the current client.</param> /// <param name="messages">The messages that are reported to the user.</param> /// <remarks> /// This method is called after returning from the internal validation routine performed by the geoprocessing /// framework. This method is where you can examine the messages created from internal validation and change them if /// desired. /// You should only change existing messages here and should not add any new messages. /// </remarks> public void UpdateMessages(IArray parameters, IGPEnvironmentManager environmentManager, IGPMessages messages) { try { var list = parameters.AsEnumerable <IGPParameter>().ToDictionary(o => o.Name, o => o); this.UpdateMessages(list, environmentManager, messages, this.Utilities); } catch (Exception ex) { messages.AddError(-1, ex.StackTrace); } }
/// <summary> /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed. /// </summary> /// <param name="paramValues"></param> /// <param name="trackCancel"></param> /// <param name="envMgr"></param> /// <param name="msgs"></param> public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs) { // Do some common error-checking base.Execute(paramValues, trackCancel, envMgr, msgs); try { // Ensure that the current user has admin access to the current Workflow Manager DB if (!CurrentUserIsWmxAdministrator()) { throw new WmauException(WmauErrorCodes.C_USER_NOT_ADMIN_ERROR); } // Retrieve the MXD IJTXConfiguration3 defaultDbReadonly = WmxDatabase.ConfigurationManager as IJTXConfiguration3; IJTXMap map = defaultDbReadonly.GetJTXMap(this.m_sourceName); // Delete any existing file that we're going to replace this.DeleteFile(this.m_mxdFilePath); // Save the map to disk map.CopyToLocation(this.m_mxdFilePath); msgs.AddMessage(Properties.Resources.MSG_DONE); } catch (System.IO.IOException ioEx) { try { WmauError error = new WmauError(WmauErrorCodes.C_FILE_ACCESS_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ioEx.Message); } catch { // Catch anything else that possibly happens } } catch (WmauException wmEx) { try { msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message); } catch { // Catch anything else that possibly happens } } catch (Exception ex) { try { WmauError error = new WmauError(WmauErrorCodes.C_MXD_DOWNLOAD_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message); } catch { // Catch anything else that possibly happens } } }
private void WriteAverageSpeedsToStreets(string outputFileGdbPath, string streetsFeatureClassPath, bool usesNTPFullCoverage, Geoprocessor gp, IGPMessages messages, ITrackCancel trackcancel) { string joinFieldName = (usesNTPFullCoverage ? "LINK_PVID" : "LINK_ID"); string refTablePath = outputFileGdbPath + "\\" + HistTrafficJoinTableName; // Separate out the FT and TF speeds into separate tables and index the ID fields string FTSpeedsTablePath = outputFileGdbPath + "\\FT_Speeds"; string TFSpeedsTablePath = outputFileGdbPath + "\\TF_Speeds"; AddMessage("Extracting FT average speeds...", messages, trackcancel); TableSelect tableSelectTool = new TableSelect(); tableSelectTool.in_table = refTablePath; tableSelectTool.out_table = FTSpeedsTablePath; tableSelectTool.where_clause = (usesNTPFullCoverage ? "\"TRAVEL_DIRECTION\" = 'F'" : "\"TRAFFIC_CD\" LIKE '+%'"); gp.Execute(tableSelectTool, trackcancel); AddMessage("Extracting TF average speeds...", messages, trackcancel); tableSelectTool.out_table = TFSpeedsTablePath; tableSelectTool.where_clause = (usesNTPFullCoverage ? "\"TRAVEL_DIRECTION\" = 'T'" : "\"TRAFFIC_CD\" LIKE '-%'"); gp.Execute(tableSelectTool, trackcancel); AddIndex addIndexTool = new AddIndex(); addIndexTool.in_table = FTSpeedsTablePath; addIndexTool.fields = joinFieldName; addIndexTool.index_name = joinFieldName; gp.Execute(addIndexTool, trackcancel); addIndexTool.in_table = TFSpeedsTablePath; gp.Execute(addIndexTool, trackcancel); // Calculate the average speed fields on the Streets feature class string FTCodeBlock = "x = [" + StreetsFCName + ".FT_AverageSpeed]\na = [FT_Speeds.AverageSpeed]\nIf Not IsNull(a) Then x = a"; string TFCodeBlock = "x = [" + StreetsFCName + ".TF_AverageSpeed]\na = [TF_Speeds.AverageSpeed]\nIf Not IsNull(a) Then x = a"; string FTExpression = "x"; string TFExpression = "x"; MakeFeatureLayer makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = streetsFeatureClassPath; makeFeatureLayerTool.out_layer = "Streets_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); AddJoin addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = FTSpeedsTablePath; addJoinTool.join_field = joinFieldName; gp.Execute(addJoinTool, trackcancel); AddMessage("Copying over the FT average speeds...", messages, trackcancel); CalculateField calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".FT_AverageSpeed"; calcFieldTool.code_block = FTCodeBlock; calcFieldTool.expression = FTExpression; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); RemoveJoin removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "FT_Speeds"; gp.Execute(removeJoinTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = TFSpeedsTablePath; addJoinTool.join_field = joinFieldName; gp.Execute(addJoinTool, trackcancel); AddMessage("Copying over the TF average speeds...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".TF_AverageSpeed"; calcFieldTool.code_block = TFCodeBlock; calcFieldTool.expression = TFExpression; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "TF_Speeds"; gp.Execute(removeJoinTool, trackcancel); Delete deleteTool = new Delete(); deleteTool.in_data = "Streets_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = FTSpeedsTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = TFSpeedsTablePath; gp.Execute(deleteTool, trackcancel); return; }
public void UpdateMessages(IArray paramvalues, IGPEnvironmentManager pEnvMgr, IGPMessages Messages) { }
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; } }
/// <summary> /// Executes the geoprocessing function using the given array of parameter values. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="trackCancel">The track cancel.</param> /// <param name="environmentManager">Provides access to all the current environments and settings of the current client.</param> /// <param name="messages">The messages that are reported to the user.</param> /// <param name="utilities"> /// The utilities object that provides access to the properties and methods of a geoprocessing /// objects. /// </param> protected override void Execute(Dictionary<string, IGPValue> parameters, ITrackCancel trackCancel, IGPEnvironmentManager environmentManager, IGPMessages messages, IGPUtilities2 utilities) { IGPMultiValue fieldNames = (IGPMultiValue) parameters["in_fields"]; IGPMultiValue modelNames = (IGPMultiValue) parameters["in_field_model_names"]; IObjectClass oclass = utilities.OpenTable(parameters["in_table"]); if (fieldNames.Count > 0 && modelNames.Count > 0) { foreach (var field in fieldNames.AsEnumerable()) { var fieldName = field.GetAsText(); int index = oclass.FindField(fieldName); foreach (var modelName in modelNames.AsEnumerable().Select(o => o.GetAsText())) { messages.Add(esriGPMessageType.esriGPMessageTypeInformative, "Adding the {0} field model name to the {1} field.", modelName, fieldName); ModelNameManager.Instance.AddFieldModelName(oclass, oclass.Fields.Field[index], modelName); } } // Success. parameters["out_results"].SetAsText("true"); } else { // Failure. parameters["out_results"].SetAsText("false"); } }
/// <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(); } } }
/// <summary> /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed. /// </summary> /// <param name="paramValues"></param> /// <param name="trackCancel"></param> /// <param name="envMgr"></param> /// <param name="msgs"></param> public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs) { // Do some common error-checking base.Execute(paramValues, trackCancel, envMgr, msgs); // Assign the requested job try { IJTXJobManager jobManager = this.WmxDatabase.JobManager; IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; IJTXJob3 job = jobManager.GetJob(m_jobId) as IJTXJob3; // As of Jan. 2011, the core Workflow Manager libraries do not // seem to check if the user has the privilege to add a comment // if a job as a hold on it. So run the check here. IJTXJobHolds jobHolds = job as IJTXJobHolds; if (jobHolds.Holds != null && jobHolds.Holds.Count > 0 && !CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_CAN_ADD_COMMENTS_FOR_HELD_JOBS)) { throw new WmauException(WmauErrorCodes.C_NO_ADD_COMMENTS_HELD_JOBS_ERROR); } // If we get this far, then add the comment to the job. IJTXActivityType commentType = configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_COMMENT); job.LogJobAction(commentType, null, m_comment); job.Store(); // Set the output parameter WmauParameterMap paramMap = new WmauParameterMap(paramValues); IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID); IGPLong outValue = new GPLongClass(); outValue.Value = m_jobId; outParamEdit.Value = outValue as IGPValue; msgs.AddMessage(Properties.Resources.MSG_DONE); } catch (WmauException wmEx) { try { msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message); } catch { // Catch anything else that possibly happens } } catch (Exception ex) { WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message); } }
/// <summary> /// Helper function that runs all of those checks that operate on each job; intended /// to make the checks slightly more efficient by running through them all at once /// rather than looping through all of the elements multiple times /// </summary> /// <param name="msgs">Add any GP messages to this object</param> /// <param name="errorCount">Counter used to track the number of problems found</param> /// <param name="logFileWriter">Object used to write error descriptions to a text file</param> private void ExecuteJobChecks(IGPMessages msgs, ref int errorCount, StreamWriter logFileWriter) { // Only continue executing this function if needed if (!m_flagInvalidJobAssign && !m_flagIsSelfParent && !m_flagJobsWithoutTypes) { return; } IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; IJTXConfigurationEdit2 configEdit = configMgr as IJTXConfigurationEdit2; IJTXJobManager jobMgr = this.WmxDatabase.JobManager; // Use a database query as an alternate way of finding certain specific // problems with jobs. Declare some of these ComReleaser objects to help // ensure that cursors, etc., are immediately released after they go out // of scope. // Check for jobs without any job types set (should be a DB error) if (m_flagJobsWithoutTypes) { using (ComReleaser cr1 = new ComReleaser(), cr2 = new ComReleaser()) { IFeatureWorkspace featureWorkspace = this.WmxDatabase.JTXWorkspace as IFeatureWorkspace; // Get the name of the correct table from the jobs workspace, so // that the table doesn't have to be owned by the connecting user. string tableName = Common.WmauHelperFunctions.GetQualifiedTableName(Constants.JTX_TABLE_JTX_JOBS_TABLE, this.WmxDatabase.JTXWorkspace); ITable jobsTable = featureWorkspace.OpenTable(tableName); cr1.ManageLifetime(jobsTable); IQueryFilter query = new QueryFilterClass(); query.WhereClause = Constants.FIELD_JOBTYPEID + " IS NULL"; ICursor searchCursor = jobsTable.Search(query, true); cr2.ManageLifetime(searchCursor); // Store the ID and name of each job matching this query int idIndex = jobsTable.FindField(Constants.FIELD_JOBID); int nameIndex = jobsTable.FindField(Constants.FIELD_JOBNAME); IRow row = null; while ((row = searchCursor.NextRow()) != null) { string idStr = row.get_Value(idIndex).ToString(); string nameStr = row.get_Value(nameIndex).ToString(); string msg = "Job " + idStr + " (" + nameStr + ") has no associated job type"; RecordMessage(msg, msgs, logFileWriter); errorCount++; } } } // Check for jobs that are their own parent job if (m_flagIsSelfParent) { using (ComReleaser cr1 = new ComReleaser(), cr2 = new ComReleaser()) { IFeatureWorkspace featureWorkspace = this.WmxDatabase.JTXWorkspace as IFeatureWorkspace; // Get the name of the correct table from the jobs workspace, so // that the table doesn't have to be owned by the connecting user. string tableName = Common.WmauHelperFunctions.GetQualifiedTableName(Constants.JTX_TABLE_JTX_JOBS_TABLE, this.WmxDatabase.JTXWorkspace); ITable jobsTable = featureWorkspace.OpenTable(tableName); cr1.ManageLifetime(jobsTable); const string C_FIELD_PARENT_JOB = "PARENT_JOB"; IQueryFilter query = new QueryFilterClass(); query.WhereClause = Constants.FIELD_JOBID + " = " + C_FIELD_PARENT_JOB; ICursor searchCursor = jobsTable.Search(query, true); cr2.ManageLifetime(searchCursor); // Store the ID and name of each job matching this query int idIndex = jobsTable.FindField(Constants.FIELD_JOBID); int nameIndex = jobsTable.FindField(Constants.FIELD_JOBNAME); IRow row = null; while ((row = searchCursor.NextRow()) != null) { string idStr = row.get_Value(idIndex).ToString(); string nameStr = row.get_Value(nameIndex).ToString(); string msg = "Job " + idStr + " (" + nameStr + ") is its own parent"; RecordMessage(msg, msgs, logFileWriter); errorCount++; } } } // See if there are any checks selected for which we should iterate through // all of the jobs using the WMX interfaces if (m_flagInvalidJobAssign) { // Put the items into a sorted list in order to make the output easier to // read/follow IJTXJobSet allJobs = jobMgr.GetAllJobs(); SortedList <int, IJTXJob3> allJobsSorted = new SortedList <int, IJTXJob3>(); for (int i = 0; i < allJobs.Count; i++) { allJobsSorted[allJobs.get_Item(i).ID] = allJobs.get_Item(i) as IJTXJob3; } // Iterate over all of the jobs foreach (IJTXJob3 job in allJobsSorted.Values) { string assignedTo = job.AssignedTo; // Check for any existing jobs with an invalid job assignment. NOTE: only // want to flag jobs that are not closed if (m_flagInvalidJobAssign && job.Stage != jtxJobStage.jtxJobStageClosed) { if (job.AssignedType == jtxAssignmentType.jtxAssignmentTypeUser && configMgr.GetUser(assignedTo) == null) { string message = "Job '" + job.ID.ToString() + "' assigned to unknown user '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } else if (job.AssignedType == jtxAssignmentType.jtxAssignmentTypeGroup && configMgr.GetUserGroup(assignedTo) == null) { string message = "Job '" + job.ID.ToString() + "' assigned to unknown group '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } } } }
public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages messages) { // Remember the original GP environment settings and temporarily override these settings var gpSettings = envMgr as IGeoProcessorSettings; bool origAddOutputsToMapSetting = gpSettings.AddOutputsToMap; bool origLogHistorySetting = gpSettings.LogHistory; gpSettings.AddOutputsToMap = false; gpSettings.LogHistory = false; // Create the Geoprocessor Geoprocessor gp = new Geoprocessor(); try { // Validate our values IGPMessages validateMessages = ((IGPFunction2)this).Validate(paramvalues, false, envMgr); if ((validateMessages as IGPMessage).IsError()) { messages.AddError(1, "Validate failed"); return; } // Unpack values IGPParameter gpParam = paramvalues.get_Element(InputStreetsFeatureClass) as IGPParameter; IGPValue inputStreetsFeatureClassValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputAltStreetsFeatureClass) as IGPParameter; IGPValue inputAltStreetsFeatureClassValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputZLevelsFeatureClass) as IGPParameter; IGPValue inputZLevelsFeatureClassValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputCdmsTable) as IGPParameter; IGPValue inputCdmsTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputRdmsTable) as IGPParameter; IGPValue inputRdmsTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputSignsTable) as IGPParameter; IGPValue inputSignsTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(OutputFileGDB) as IGPParameter; IGPValue outputFileGDBValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(OutputFileGDBVersion) as IGPParameter; IGPValue outputFileGDBVersionValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputFeatureDatasetName) as IGPParameter; IGPValue inputFeatureDatasetNameValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputNetworkDatasetName) as IGPParameter; IGPValue inputNetworkDatasetNameValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputCreateNetworkAttributesInMetric) as IGPParameter; IGPValue inputCreateNetworkAttributeInMetricValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputCreateArcGISOnlineNetworkAttributes) as IGPParameter; IGPValue inputCreateArcGISOnlineNetworkAttributesValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputTimeZoneIDBaseFieldName) as IGPParameter; IGPValue inputTimeZoneIDBaseFieldNameValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputTimeZoneTable) as IGPParameter; IGPValue inputTimeZoneTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputCommonTimeZoneForTheEntireDataset) as IGPParameter; IGPValue inputCommonTimeZoneForTheEntireDatasetValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputTrafficTable) as IGPParameter; IGPValue inputTrafficTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputLinkReferenceFileFC14) as IGPParameter; IGPValue inputLinkReferenceFileFC14Value = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputLinkReferenceFileFC5) as IGPParameter; IGPValue inputLinkReferenceFileFC5Value = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputTMCReferenceFile) as IGPParameter; IGPValue inputTMCReferenceFileValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputSPDFile) as IGPParameter; IGPValue inputSPDFileValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputLiveTrafficFeedFolder) as IGPParameter; IGPValue inputLiveTrafficFeedFolderValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputLiveTrafficFeedArcGISServerConnection) as IGPParameter; IGPValue inputLiveTrafficFeedArcGISServerConnectionValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputLiveTrafficFeedGeoprocessingServiceName) as IGPParameter; IGPValue inputLiveTrafficFeedGeoprocessingServiceNameValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputLiveTrafficFeedGeoprocessingTaskName) as IGPParameter; IGPValue inputLiveTrafficFeedGeoprocessingTaskNameValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputUSCndModTable) as IGPParameter; IGPValue inputUSCndModTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputNonUSCndModTable) as IGPParameter; IGPValue inputNonUSCndModTableValue = m_gpUtils.UnpackGPValue(gpParam); double fgdbVersion = 0.0; if (!(outputFileGDBVersionValue.IsEmpty())) fgdbVersion = Convert.ToDouble(outputFileGDBVersionValue.GetAsText(), System.Globalization.CultureInfo.InvariantCulture); bool createNetworkAttributesInMetric = false; if (!(inputCreateNetworkAttributeInMetricValue.IsEmpty())) createNetworkAttributesInMetric = ((inputCreateNetworkAttributeInMetricValue.GetAsText()).ToUpper() == "TRUE"); bool createArcGISOnlineNetworkAttributes = false; if (!(inputCreateArcGISOnlineNetworkAttributesValue.IsEmpty())) createArcGISOnlineNetworkAttributes = ((inputCreateArcGISOnlineNetworkAttributesValue.GetAsText()).ToUpper() == "TRUE"); if (inputTimeZoneIDBaseFieldNameValue.IsEmpty() ^ inputTimeZoneTableValue.IsEmpty()) { messages.AddError(1, "The Time Zone ID Base Field Name and the Time Zone Table must be specified together."); return; } string timeZoneIDBaseFieldName = ""; bool directedTimeZoneIDFields = false; if (!(inputTimeZoneIDBaseFieldNameValue.IsEmpty())) { timeZoneIDBaseFieldName = inputTimeZoneIDBaseFieldNameValue.GetAsText(); IDETable inputTable = m_gpUtils.DecodeDETable(inputStreetsFeatureClassValue); if (inputTable.Fields.FindField(timeZoneIDBaseFieldName) == -1) { directedTimeZoneIDFields = true; if (((inputTable.Fields.FindField("FT_" + timeZoneIDBaseFieldName) == -1) || (inputTable.Fields.FindField("TF_" + timeZoneIDBaseFieldName) == -1))) { messages.AddError(1, "Field named " + timeZoneIDBaseFieldName + " does not exist, nor the pair of fields with FT_ and TF_ prefixing " + timeZoneIDBaseFieldName + " does not exist."); return; } } } string commonTimeZone = ""; if (!(inputCommonTimeZoneForTheEntireDatasetValue.IsEmpty())) commonTimeZone = inputCommonTimeZoneForTheEntireDatasetValue.GetAsText(); if (inputLinkReferenceFileFC14Value.IsEmpty() ^ inputLinkReferenceFileFC5Value.IsEmpty()) { messages.AddError(1, "Both Traffic Patterns Link Reference .csv files must be specified together."); return; } bool usesHistoricalTraffic = !(inputSPDFileValue.IsEmpty()); bool usesNTPFullCoverage = !(inputLinkReferenceFileFC5Value.IsEmpty()); if ((inputTMCReferenceFileValue.IsEmpty() & !usesNTPFullCoverage) ^ inputSPDFileValue.IsEmpty()) { messages.AddError(1, "The Traffic Patterns SPD .csv file must be specified with the Traffic Patterns Link/TMC Reference .csv file(s)."); return; } if (inputTrafficTableValue.IsEmpty() & !inputTMCReferenceFileValue.IsEmpty()) { messages.AddError(1, "If the TMC Reference .csv file is specified, then the Traffic table must also be specified."); return; } bool agsConnectionIsEmpty = inputLiveTrafficFeedArcGISServerConnectionValue.IsEmpty(); bool gpServiceNameIsEmpty = inputLiveTrafficFeedGeoprocessingServiceNameValue.IsEmpty(); bool gpTaskNameIsEmpty = inputLiveTrafficFeedGeoprocessingTaskNameValue.IsEmpty(); if ((agsConnectionIsEmpty | gpServiceNameIsEmpty | gpTaskNameIsEmpty) ^ (agsConnectionIsEmpty & gpServiceNameIsEmpty & gpTaskNameIsEmpty)) { messages.AddError(1, "The ArcGIS Server Connection, Geoprocessing Service Name, and Geoprocessing Task Name must all be specified together."); return; } bool feedFolderIsEmpty = inputLiveTrafficFeedFolderValue.IsEmpty(); if (!(feedFolderIsEmpty | agsConnectionIsEmpty)) { messages.AddError(1, "The live traffic feed folder and live traffic feed connection cannot be specified together."); return; } if (inputTrafficTableValue.IsEmpty() & !(feedFolderIsEmpty & agsConnectionIsEmpty)) { messages.AddError(1, "The Traffic table must be specified to use Live Traffic."); return; } bool usesTransport = true; if (inputUSCndModTableValue.IsEmpty() && inputNonUSCndModTableValue.IsEmpty()) usesTransport = false; ITrafficFeedLocation trafficFeedLocation = null; if (!agsConnectionIsEmpty) { // We're using an ArcGIS Server Connection and Geoprocessing Service/Task ITrafficFeedGPService tfgps = new TrafficFeedGPServiceClass(); IName trafficFeedGPServiceName = m_gpUtils.GetNameObject(inputLiveTrafficFeedArcGISServerConnectionValue as IDataElement); tfgps.ConnectionProperties = ((IAGSServerConnectionName)trafficFeedGPServiceName).ConnectionProperties; tfgps.ServiceName = inputLiveTrafficFeedGeoprocessingServiceNameValue.GetAsText(); tfgps.TaskName = inputLiveTrafficFeedGeoprocessingTaskNameValue.GetAsText(); trafficFeedLocation = tfgps as ITrafficFeedLocation; } else if (!feedFolderIsEmpty) { // We're using a Traffic Feed Folder ITrafficFeedDirectory tfd = new TrafficFeedDirectoryClass(); tfd.TrafficDirectory = inputLiveTrafficFeedFolderValue.GetAsText(); trafficFeedLocation = tfd as ITrafficFeedLocation; } // Get the path to the output file GDB, and feature dataset and network dataset names string outputFileGdbPath = outputFileGDBValue.GetAsText(); string fdsName = inputFeatureDatasetNameValue.GetAsText(); string ndsName = inputNetworkDatasetNameValue.GetAsText(); // Create the new file geodatabase and feature dataset AddMessage("Creating the file geodatabase and feature dataset...", messages, trackcancel); int lastBackslash = outputFileGdbPath.LastIndexOf("\\"); CreateFileGDB createFGDBTool = new CreateFileGDB(); createFGDBTool.out_folder_path = outputFileGdbPath.Remove(lastBackslash); createFGDBTool.out_name = outputFileGdbPath.Substring(lastBackslash + 1); createFGDBTool.out_version = "9.3"; gp.Execute(createFGDBTool, trackcancel); CreateFeatureDataset createFDSTool = new CreateFeatureDataset(); createFDSTool.out_dataset_path = outputFileGdbPath; createFDSTool.out_name = fdsName; createFDSTool.spatial_reference = inputStreetsFeatureClassValue.GetAsText(); gp.Execute(createFDSTool, trackcancel); // Import the Streets feature class to the file geodatabase // If we're using ArcInfo, also sort the feature class string pathToFds = outputFileGdbPath + "\\" + fdsName; string streetsFeatureClassPath = pathToFds + "\\" + StreetsFCName; IAoInitialize aoi = new AoInitializeClass(); if (aoi.InitializedProduct() == esriLicenseProductCode.esriLicenseProductCodeAdvanced) { AddMessage("Importing and spatially sorting the Streets feature class...", messages, trackcancel); Sort sortTool = new Sort(); sortTool.in_dataset = inputStreetsFeatureClassValue.GetAsText(); sortTool.out_dataset = streetsFeatureClassPath; sortTool.sort_field = "Shape"; sortTool.spatial_sort_method = "PEANO"; gp.Execute(sortTool, trackcancel); } else { AddMessage("Importing the Streets feature class...", messages, trackcancel); FeatureClassToFeatureClass importFCTool = new FeatureClassToFeatureClass(); importFCTool.in_features = inputStreetsFeatureClassValue.GetAsText(); importFCTool.out_path = pathToFds; importFCTool.out_name = StreetsFCName; gp.Execute(importFCTool, trackcancel); } // Add an index to the Streets feature class's LINK_ID field AddMessage("Indexing the LINK_ID field...", messages, trackcancel); AddIndex addIndexTool = new AddIndex(); addIndexTool.in_table = streetsFeatureClassPath; addIndexTool.fields = "LINK_ID"; addIndexTool.index_name = "LINK_ID"; gp.Execute(addIndexTool, trackcancel); // Add the alternate street name fields to the Streets feature class AddMessage("Creating fields on the Streets feature class for the alternate street names...", messages, trackcancel); AddField addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 240; addFieldTool.field_name = "ST_NAME_Alt"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_length = 3; addFieldTool.field_name = "ST_LANGCD_Alt"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_length = 6; addFieldTool.field_name = "ST_NM_PREF_Alt"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_length = 90; addFieldTool.field_name = "ST_TYP_BEF_Alt"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_length = 105; addFieldTool.field_name = "ST_NM_BASE_Alt"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_length = 6; addFieldTool.field_name = "ST_NM_SUFF_Alt"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_length = 90; addFieldTool.field_name = "ST_TYP_AFT_Alt"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_length = 1; addFieldTool.field_name = "DIRONSIGN_Alt"; gp.Execute(addFieldTool, trackcancel); // Extract the explicatable street names string ExplicatblTablePath = outputFileGdbPath + "\\Explicatbl"; AddMessage("Extracting the explicatable street names...", messages, trackcancel); TableSelect tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputAltStreetsFeatureClassValue.GetAsText(); tableSelectTool.out_table = ExplicatblTablePath; tableSelectTool.where_clause = "EXPLICATBL = 'Y'"; gp.Execute(tableSelectTool, trackcancel); // Determine which explicatable names are alternate names and extract them MakeTableView makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = ExplicatblTablePath; makeTableViewTool.out_view = "Explicatbl_View"; gp.Execute(makeTableViewTool, trackcancel); AddJoin addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Explicatbl_View"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = streetsFeatureClassPath; addJoinTool.join_field = "LINK_ID"; gp.Execute(addJoinTool, trackcancel); AddMessage("Extracting the alternate street names...", messages, trackcancel); TableToTable importTableTool = new TableToTable(); importTableTool.in_rows = "Explicatbl_View"; importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = "AltNames"; importTableTool.where_clause = "Explicatbl.ST_TYP_BEF <> " + StreetsFCName + ".ST_TYP_BEF OR " + "Explicatbl.ST_NM_BASE <> " + StreetsFCName + ".ST_NM_BASE OR " + "Explicatbl.ST_TYP_AFT <> " + StreetsFCName + ".ST_TYP_AFT"; importTableTool.field_mapping = "LINK_ID \"LINK_ID\" true true false 4 Long 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.LINK_ID,-1,-1;" + "ST_NAME \"ST_NAME\" true true false 240 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.ST_NAME,-1,-1;" + "ST_LANGCD \"ST_LANGCD\" true true false 3 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.ST_LANGCD,-1,-1;" + "ST_NM_PREF \"ST_NM_PREF\" true true false 6 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.ST_NM_PREF,-1,-1;" + "ST_TYP_BEF \"ST_TYP_BEF\" true true false 90 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.ST_TYP_BEF,-1,-1;" + "ST_NM_BASE \"ST_NM_BASE\" true true false 105 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.ST_NM_BASE,-1,-1;" + "ST_NM_SUFF \"ST_NM_SUFF\" true true false 6 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.ST_NM_SUFF,-1,-1;" + "ST_TYP_AFT \"ST_TYP_AFT\" true true false 90 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.ST_TYP_AFT,-1,-1;" + "DIRONSIGN \"DIRONSIGN\" true true false 1 Text 0 0 ,First,#," + ExplicatblTablePath + ",Explicatbl.DIRONSIGN,-1,-1"; gp.Execute(importTableTool, trackcancel); RemoveJoin removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Explicatbl_View"; removeJoinTool.join_name = StreetsFCName; gp.Execute(removeJoinTool, trackcancel); Delete deleteTool = new Delete(); deleteTool.in_data = "Explicatbl_View"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = ExplicatblTablePath; gp.Execute(deleteTool, trackcancel); string AltNamesTablePath = outputFileGdbPath + "\\AltNames"; addIndexTool = new AddIndex(); addIndexTool.in_table = AltNamesTablePath; addIndexTool.fields = "LINK_ID"; addIndexTool.index_name = "LINK_ID"; gp.Execute(addIndexTool, trackcancel); // Calculate the alternate street name fields MakeFeatureLayer makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = streetsFeatureClassPath; makeFeatureLayerTool.out_layer = "Streets_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = AltNamesTablePath; addJoinTool.join_field = "LINK_ID"; gp.Execute(addJoinTool, trackcancel); AddMessage("Copying over the alternate ST_NAME values...", messages, trackcancel); CalculateField calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.expression_type = "VB"; calcFieldTool.field = StreetsFCName + ".ST_NAME_Alt"; calcFieldTool.expression = "[AltNames.ST_NAME]"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Copying over the alternate ST_LANGCD values...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".ST_LANGCD_Alt"; calcFieldTool.expression = "[AltNames.ST_LANGCD]"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Copying over the alternate ST_NM_PREF values...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".ST_NM_PREF_Alt"; calcFieldTool.expression = "[AltNames.ST_NM_PREF]"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Copying over the alternate ST_TYP_BEF values...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".ST_TYP_BEF_Alt"; calcFieldTool.expression = "[AltNames.ST_TYP_BEF]"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Copying over the alternate ST_NM_BASE values...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".ST_NM_BASE_Alt"; calcFieldTool.expression = "[AltNames.ST_NM_BASE]"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Copying over the alternate ST_NM_SUFF values...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".ST_NM_SUFF_Alt"; calcFieldTool.expression = "[AltNames.ST_NM_SUFF]"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Copying over the alternate ST_TYP_AFT values...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".ST_TYP_AFT_Alt"; calcFieldTool.expression = "[AltNames.ST_TYP_AFT]"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Copying over the alternate DIRONSIGN values...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".DIRONSIGN_Alt"; calcFieldTool.expression = "[AltNames.DIRONSIGN]"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "AltNames"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = AltNamesTablePath; gp.Execute(deleteTool, trackcancel); // Add fields for the Z-Level values to the Streets feature class AddMessage("Creating fields on the Streets feature class for the Z-Level values...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_type = "SHORT"; addFieldTool.field_name = "F_ZLEV"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "T_ZLEV"; gp.Execute(addFieldTool, trackcancel); // Separate out the From and To Z-Level values into separate tables and index the LINK_ID fields string FromZsTablePath = outputFileGdbPath + "\\FromZs"; string ToZsTablePath = outputFileGdbPath + "\\ToZs"; AddMessage("Extracting the From Z-Level information...", messages, trackcancel); tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputZLevelsFeatureClassValue.GetAsText(); tableSelectTool.out_table = FromZsTablePath; tableSelectTool.where_clause = "INTRSECT = 'Y' AND POINT_NUM = 1"; gp.Execute(tableSelectTool, trackcancel); AddMessage("Extracting the To Z-Level information...", messages, trackcancel); tableSelectTool.out_table = ToZsTablePath; tableSelectTool.where_clause = "INTRSECT = 'Y' AND POINT_NUM > 1"; gp.Execute(tableSelectTool, trackcancel); AddMessage("Analyzing the Z-Level information...", messages, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = FromZsTablePath; addIndexTool.fields = "LINK_ID"; addIndexTool.index_name = "LINK_ID"; gp.Execute(addIndexTool, trackcancel); addIndexTool.in_table = ToZsTablePath; gp.Execute(addIndexTool, trackcancel); // Calculate the Z-Level fields makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = streetsFeatureClassPath; makeFeatureLayerTool.out_layer = "Streets_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = FromZsTablePath; addJoinTool.join_field = "LINK_ID"; gp.Execute(addJoinTool, trackcancel); AddMessage("Copying over the F_ZLEV values...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".F_ZLEV"; calcFieldTool.expression = "[FromZs.Z_LEVEL]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "FromZs"; gp.Execute(removeJoinTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = ToZsTablePath; addJoinTool.join_field = "LINK_ID"; gp.Execute(addJoinTool, trackcancel); AddMessage("Copying over the T_ZLEV values...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".T_ZLEV"; calcFieldTool.expression = "[ToZs.Z_LEVEL]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "ToZs"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = FromZsTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = ToZsTablePath; gp.Execute(deleteTool, trackcancel); // Add fields for the distance (Meters), language, and speed (KPH) values to the Streets feature class AddMessage("Creating fields on the Streets feature class for distance, speed, and language...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_type = "DOUBLE"; addFieldTool.field_name = "Meters"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_type = "FLOAT"; addFieldTool.field_name = "KPH"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_type = "TEXT"; addFieldTool.field_name = "Language"; addFieldTool.field_length = 2; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_type = "TEXT"; addFieldTool.field_name = "Language_Alt"; addFieldTool.field_length = 2; gp.Execute(addFieldTool, trackcancel); // Calculate the distance (Meters), language, and speed (KPH) fields AddMessage("Calculating the distance, speed, and language fields...", messages, trackcancel); CalculateMetersKPHAndLanguageFields(outputFileGdbPath); if (createArcGISOnlineNetworkAttributes) { CreateAndPopulateDirectionalVehicleAccessFields("AR_AUTO", streetsFeatureClassPath, gp, messages, trackcancel); CreateAndPopulateDirectionalVehicleAccessFields("AR_BUS", streetsFeatureClassPath, gp, messages, trackcancel); CreateAndPopulateDirectionalVehicleAccessFields("AR_TAXIS", streetsFeatureClassPath, gp, messages, trackcancel); CreateAndPopulateDirectionalVehicleAccessFields("AR_TRUCKS", streetsFeatureClassPath, gp, messages, trackcancel); CreateAndPopulateDirectionalVehicleAccessFields("AR_DELIV", streetsFeatureClassPath, gp, messages, trackcancel); CreateAndPopulateDirectionalVehicleAccessFields("AR_EMERVEH", streetsFeatureClassPath, gp, messages, trackcancel); CreateAndPopulateDirectionalVehicleAccessFields("AR_MOTOR", streetsFeatureClassPath, gp, messages, trackcancel); } // Add a field to the Streets feature class indicating roads closed for construction AddMessage("Creating the ClosedForConstruction field on the Streets feature class...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_type = "TEXT"; addFieldTool.field_name = "ClosedForConstruction"; addFieldTool.field_length = 1; gp.Execute(addFieldTool, trackcancel); // Create a table for looking up roads closed for construction AddMessage("Creating and indexing the table containing roads closed for construction...", messages, trackcancel); string closedForConstructionTablePath = outputFileGdbPath + "\\ClosedForConstruction"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputCdmsTableValue.GetAsText(); tableSelectTool.out_table = closedForConstructionTablePath; tableSelectTool.where_clause = "COND_TYPE = 3"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = closedForConstructionTablePath; addIndexTool.fields = "LINK_ID"; addIndexTool.index_name = "LINK_ID"; gp.Execute(addIndexTool, trackcancel); makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = streetsFeatureClassPath; makeFeatureLayerTool.out_layer = "Streets_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = closedForConstructionTablePath; addJoinTool.join_field = "LINK_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the ClosedForConstruction field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = "Streets.ClosedForConstruction"; calcFieldTool.expression = "\"Y\""; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "ClosedForConstruction"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = closedForConstructionTablePath; gp.Execute(deleteTool, trackcancel); // Add fields to the Streets feature class indicating roads with usage fees string[] arFieldSuffixes = new string[] { "AUTO", "BUS", "TAXIS", "CARPOOL", "PEDSTRN", "TRUCKS", "THRUTR", "DELIVER", "EMERVEH", "MOTOR" }; AddMessage("Creating the UFR fields on the Streets feature class...", messages, trackcancel); foreach (string arFieldSuffix in arFieldSuffixes) { addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_name = "UFR_" + arFieldSuffix; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 1; gp.Execute(addFieldTool, trackcancel); } // Create a table for looking up roads with usage fees AddMessage("Creating and indexing the table containing roads with usage fees...", messages, trackcancel); string usageFeeRequiredTablePath = outputFileGdbPath + "\\UsageFeeRequired"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputCdmsTableValue.GetAsText(); tableSelectTool.out_table = usageFeeRequiredTablePath; tableSelectTool.where_clause = "COND_TYPE = 12"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = usageFeeRequiredTablePath; addIndexTool.fields = "LINK_ID"; addIndexTool.index_name = "LINK_ID"; gp.Execute(addIndexTool, trackcancel); makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = streetsFeatureClassPath; makeFeatureLayerTool.out_layer = "Streets_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = usageFeeRequiredTablePath; addJoinTool.join_field = "LINK_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the ClosedForConstruction field...", messages, trackcancel); foreach (string arFieldSuffix in arFieldSuffixes) { AddMessage("Calculating the UFR_" + arFieldSuffix + " field on the Streets feature class...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = "Streets.UFR_" + arFieldSuffix; calcFieldTool.expression = "[UsageFeeRequired.AR_" + arFieldSuffix + "]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); } removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "UsageFeeRequired"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = usageFeeRequiredTablePath; gp.Execute(deleteTool, trackcancel); // Copy the time zones table to the file geodatabase if (timeZoneIDBaseFieldName != "") { AddMessage("Copying the TimeZones table...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = inputTimeZoneTableValue.GetAsText(); importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = "TimeZones"; gp.Execute(importTableTool, trackcancel); } #region Process Historical Traffic Tables if (usesHistoricalTraffic) { // Create the Patterns table and index its PatternID field AddMessage("Creating the Patterns table...", messages, trackcancel); string listOfConstantPatterns = CreatePatternsTable(inputSPDFileValue.GetAsText(), outputFileGdbPath, fgdbVersion); string patternsTablePath = outputFileGdbPath + "\\" + ProfilesTableName; addIndexTool = new AddIndex(); addIndexTool.in_table = patternsTablePath; addIndexTool.fields = "PatternID"; addIndexTool.index_name = "PatternID"; gp.Execute(addIndexTool, trackcancel); string histTrafficJoinTablePath = outputFileGdbPath + "\\" + HistTrafficJoinTableName; // Add fields for the average speeds to the Streets feature class AddMessage("Creating fields for the average speeds and travel times...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_type = "FLOAT"; addFieldTool.field_name = "FT_AverageSpeed"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "TF_AverageSpeed"; gp.Execute(addFieldTool, trackcancel); if (usesNTPFullCoverage) { // Convert the Link Reference files to a FileGDB table AddMessage("Converting the Link Reference files to a table...", messages, trackcancel); ConvertLinkReferenceFilesToFGDBTable(inputLinkReferenceFileFC14Value.GetAsText(), inputLinkReferenceFileFC5Value.GetAsText(), outputFileGdbPath); string referenceTablePath = outputFileGdbPath + "\\TempRefTable"; // Extract out the rows we want in our historical traffic table AddMessage("Creating the historical traffic join table...", messages, trackcancel); if (listOfConstantPatterns == "") { Rename renameTool = new Rename(); renameTool.in_data = referenceTablePath; renameTool.out_data = histTrafficJoinTablePath; gp.Execute(renameTool, trackcancel); } else { tableSelectTool = new TableSelect(); tableSelectTool.in_table = referenceTablePath; tableSelectTool.out_table = histTrafficJoinTablePath; tableSelectTool.where_clause = "NOT ( IS_FC5 = 'Y' AND U IN (" + listOfConstantPatterns + ") AND U = M AND M = T AND T = W AND W = R AND R = F AND F = S )"; gp.Execute(tableSelectTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = referenceTablePath; gp.Execute(deleteTool, trackcancel); } } else { // Convert the TMC Reference file to a FileGDB table and index its TMC field AddMessage("Converting the TMC Reference file to a table...", messages, trackcancel); ConvertTMCReferenceFileToFGDBTable(inputTMCReferenceFileValue.GetAsText(), outputFileGdbPath); string referenceTablePath = outputFileGdbPath + "\\TempRefTable"; addIndexTool = new AddIndex(); addIndexTool.in_table = referenceTablePath; addIndexTool.fields = "TMC"; addIndexTool.index_name = "TMC"; gp.Execute(addIndexTool, trackcancel); // Copy over the Traffic table to the file geodatabase AddMessage("Copying Traffic table to the file geodatabase...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = inputTrafficTableValue.GetAsText(); importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = "Street"; gp.Execute(importTableTool, trackcancel); string trafficTablePath = outputFileGdbPath + "\\Street"; // Add the TMC field and calculate it AddMessage("Calculating TMC values for historical traffic...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = trafficTablePath; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 9; addFieldTool.field_name = "TMC"; gp.Execute(addFieldTool, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = trafficTablePath; calcFieldTool.field = "TMC"; calcFieldTool.expression = "Replace(Replace(Right([TRAFFIC_CD], 9), \"+\", \"P\"), \"-\", \"N\")"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Creating the historical traffic join table...", messages, trackcancel); // Join the Traffic table to the Reference table... makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = trafficTablePath; makeTableViewTool.out_view = "Traffic_View"; gp.Execute(makeTableViewTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Traffic_View"; addJoinTool.in_field = "TMC"; addJoinTool.join_table = referenceTablePath; addJoinTool.join_field = "TMC"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); // ...then create the Streets_Patterns table by copying out the joined rows importTableTool = new TableToTable(); importTableTool.in_rows = "Traffic_View"; importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = HistTrafficJoinTableName; importTableTool.field_mapping = "LINK_ID \"LINK_ID\" true true false 4 Long 0 0 ,First,#," + trafficTablePath + ",Street.LINK_ID,-1,-1;" + "TRAFFIC_CD \"TRAFFIC_CD\" true true false 10 Text 0 0 ,First,#," + trafficTablePath + ",Street.TRAFFIC_CD,-1,-1;" + "TMC \"TMC\" true true false 9 Text 0 0 ,First,#," + trafficTablePath + ",Street.TMC,-1,-1;" + "U \"U\" true true false 2 Short 0 0 ,First,#," + trafficTablePath + ",TempRefTable.U,-1,-1;" + "M \"M\" true true false 2 Short 0 0 ,First,#," + trafficTablePath + ",TempRefTable.M,-1,-1;" + "T \"T\" true true false 2 Short 0 0 ,First,#," + trafficTablePath + ",TempRefTable.T,-1,-1;" + "W \"W\" true true false 2 Short 0 0 ,First,#," + trafficTablePath + ",TempRefTable.W,-1,-1;" + "R \"R\" true true false 2 Short 0 0 ,First,#," + trafficTablePath + ",TempRefTable.R,-1,-1;" + "F \"F\" true true false 2 Short 0 0 ,First,#," + trafficTablePath + ",TempRefTable.F,-1,-1;" + "S \"S\" true true false 2 Short 0 0 ,First,#," + trafficTablePath + ",TempRefTable.S,-1,-1"; gp.Execute(importTableTool, trackcancel); // Delete the join, view, and temporary tables removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Traffic_View"; removeJoinTool.join_name = "TempRefTable"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Traffic_View"; gp.Execute(deleteTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = referenceTablePath; gp.Execute(deleteTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = trafficTablePath; gp.Execute(deleteTool, trackcancel); } AddMessage("Creating fields on the historical traffic join table...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = histTrafficJoinTablePath; // Add FCID, FID, position, AverageSpeed[_X], and BaseSpeed[_X] fields to the Streets_Patterns table addFieldTool.field_type = "LONG"; addFieldTool.field_name = "EdgeFCID"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "EdgeFID"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_type = "DOUBLE"; addFieldTool.field_name = "EdgeFrmPos"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "EdgeToPos"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_type = "FLOAT"; addFieldTool.field_name = "AverageSpeed"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "AverageSpeed_U"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "AverageSpeed_M"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "AverageSpeed_T"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "AverageSpeed_W"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "AverageSpeed_R"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "AverageSpeed_F"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "AverageSpeed_S"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_type = "FLOAT"; addFieldTool.field_name = "BaseSpeed"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "BaseSpeed_U"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "BaseSpeed_M"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "BaseSpeed_T"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "BaseSpeed_W"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "BaseSpeed_R"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "BaseSpeed_F"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "BaseSpeed_S"; gp.Execute(addFieldTool, trackcancel); // If we're creating 10.0, then we also need to create the BaseMinutes field if (fgdbVersion == 10.0) { addFieldTool.field_type = "DOUBLE"; addFieldTool.field_name = "BaseMinutes"; gp.Execute(addFieldTool, trackcancel); } // Populate the AverageSpeed_X and BaseSpeed_X fields makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = histTrafficJoinTablePath; makeTableViewTool.out_view = "Streets_Patterns_View"; gp.Execute(makeTableViewTool, trackcancel); PopulateAverageSpeedAndBaseSpeedFields(patternsTablePath, "U", gp, messages, trackcancel); PopulateAverageSpeedAndBaseSpeedFields(patternsTablePath, "M", gp, messages, trackcancel); PopulateAverageSpeedAndBaseSpeedFields(patternsTablePath, "T", gp, messages, trackcancel); PopulateAverageSpeedAndBaseSpeedFields(patternsTablePath, "W", gp, messages, trackcancel); PopulateAverageSpeedAndBaseSpeedFields(patternsTablePath, "R", gp, messages, trackcancel); PopulateAverageSpeedAndBaseSpeedFields(patternsTablePath, "F", gp, messages, trackcancel); PopulateAverageSpeedAndBaseSpeedFields(patternsTablePath, "S", gp, messages, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Patterns_View"; gp.Execute(deleteTool, trackcancel); // Calculate the AverageSpeed and BaseSpeed fields AddMessage("Calculating the AverageSpeed field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = histTrafficJoinTablePath; calcFieldTool.field = "AverageSpeed"; calcFieldTool.expression = "( (1/[AverageSpeed_U]) + (1/[AverageSpeed_M]) + (1/[AverageSpeed_T]) + (1/[AverageSpeed_W]) + (1/[AverageSpeed_R]) + (1/[AverageSpeed_F]) + (1/[AverageSpeed_S]) ) / " + "( (1/[AverageSpeed_U]/[AverageSpeed_U]) + (1/[AverageSpeed_M]/[AverageSpeed_M]) + (1/[AverageSpeed_T]/[AverageSpeed_T]) + (1/[AverageSpeed_W]/[AverageSpeed_W]) + (1/[AverageSpeed_R]/[AverageSpeed_R]) + (1/[AverageSpeed_F]/[AverageSpeed_F]) + (1/[AverageSpeed_S]/[AverageSpeed_S]) )"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the BaseSpeed field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = histTrafficJoinTablePath; calcFieldTool.field = "BaseSpeed"; calcFieldTool.expression = "( (1/[BaseSpeed_U]) + (1/[BaseSpeed_M]) + (1/[BaseSpeed_T]) + (1/[BaseSpeed_W]) + (1/[BaseSpeed_R]) + (1/[BaseSpeed_F]) + (1/[BaseSpeed_S]) ) / " + "( (1/[BaseSpeed_U]/[BaseSpeed_U]) + (1/[BaseSpeed_M]/[BaseSpeed_M]) + (1/[BaseSpeed_T]/[BaseSpeed_T]) + (1/[BaseSpeed_W]/[BaseSpeed_W]) + (1/[BaseSpeed_R]/[BaseSpeed_R]) + (1/[BaseSpeed_F]/[BaseSpeed_F]) + (1/[BaseSpeed_S]/[BaseSpeed_S]) )"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); DeleteField deleteFieldTool = new DeleteField(); deleteFieldTool.in_table = histTrafficJoinTablePath; deleteFieldTool.drop_field = "AverageSpeed_U;AverageSpeed_M;AverageSpeed_T;AverageSpeed_W;AverageSpeed_R;AverageSpeed_F;AverageSpeed_S;BaseSpeed_U;BaseSpeed_M;BaseSpeed_T;BaseSpeed_W;BaseSpeed_R;BaseSpeed_F;BaseSpeed_S"; gp.Execute(deleteFieldTool, trackcancel); makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = histTrafficJoinTablePath; makeTableViewTool.out_view = "Streets_Patterns_View"; gp.Execute(makeTableViewTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Patterns_View"; addJoinTool.in_field = (usesNTPFullCoverage ? "LINK_PVID" : "LINK_ID"); addJoinTool.join_table = streetsFeatureClassPath; addJoinTool.join_field = "LINK_ID"; gp.Execute(addJoinTool, trackcancel); // Calculate the BaseMinutes field (if 10.0) if (fgdbVersion == 10.0) { AddMessage("Calculating the BaseMinutes field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Patterns_View"; calcFieldTool.field = HistTrafficJoinTableName + ".BaseMinutes"; calcFieldTool.expression = "[" + StreetsFCName + ".Meters] * 0.06 / [" + HistTrafficJoinTableName + ".BaseSpeed]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); } // Calculate the FCID, FID, and position fields AddMessage("Calculating the EdgeFID field for historical traffic...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Patterns_View"; calcFieldTool.field = HistTrafficJoinTableName + ".EdgeFID"; calcFieldTool.expression = "[" + StreetsFCName + ".OBJECTID]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Patterns_View"; removeJoinTool.join_name = StreetsFCName; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Patterns_View"; gp.Execute(deleteTool, trackcancel); AddMessage("Calculating the EdgeFCID field for historical traffic...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = histTrafficJoinTablePath; calcFieldTool.field = "EdgeFCID"; calcFieldTool.expression = "1"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the EdgeFrmPos field for historical traffic...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = histTrafficJoinTablePath; calcFieldTool.field = "EdgeFrmPos"; calcFieldTool.expression = "x"; calcFieldTool.code_block = (usesNTPFullCoverage ? "Select Case [TRAVEL_DIRECTION]\n Case \"F\": x = 0\n Case \"T\": x = 1\nEnd Select" : "Select Case Left([TRAFFIC_CD], 1)\n Case \"+\": x = 0\n Case \"-\": x = 1\nEnd Select"); calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the EdgeToPos field for historical traffic...", messages, trackcancel); calcFieldTool.field = "EdgeToPos"; calcFieldTool.expression = "x"; calcFieldTool.code_block = (usesNTPFullCoverage ? "Select Case [TRAVEL_DIRECTION]\n Case \"T\": x = 0\n Case \"F\": x = 1\nEnd Select" : "Select Case Left([TRAFFIC_CD], 1)\n Case \"-\": x = 0\n Case \"+\": x = 1\nEnd Select"); calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); // Write the average speeds to the streets feature class WriteAverageSpeedsToStreets(outputFileGdbPath, streetsFeatureClassPath, usesNTPFullCoverage, gp, messages, trackcancel); // Add fields for the average travel times to the Streets feature class AddMessage("Creating fields for the average travel times...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_type = "FLOAT"; addFieldTool.field_name = "FT_Minutes"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "TF_Minutes"; gp.Execute(addFieldTool, trackcancel); // Calculate the average travel time fields AddMessage("Calculating the FT travel times...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = streetsFeatureClassPath; calcFieldTool.field = "FT_Minutes"; calcFieldTool.expression = "[Meters] * 0.06 / s"; calcFieldTool.code_block = "s = [FT_AverageSpeed]\nIf IsNull(s) Then s = [KPH]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the TF travel times...", messages, trackcancel); calcFieldTool.field = "TF_Minutes"; calcFieldTool.expression = "[Meters] * 0.06 / s"; calcFieldTool.code_block = "s = [TF_AverageSpeed]\nIf IsNull(s) Then s = [KPH]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); // Offset the daily pattern fields (U,M,T,W,R,F,S) on the historical traffic join table OffsetDailyPatternFields(histTrafficJoinTablePath, patternsTablePath); // Add an index to the Streets feature class's FUNC_CLASS field AddMessage("Indexing the FUNC_CLASS field...", messages, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = streetsFeatureClassPath; addIndexTool.fields = "FUNC_CLASS"; addIndexTool.index_name = "FUNC_CLASS"; gp.Execute(addIndexTool, trackcancel); } else { // Create and calculate the generic Minutes field from speed categories addFieldTool = new AddField(); addFieldTool.in_table = streetsFeatureClassPath; addFieldTool.field_type = "FLOAT"; addFieldTool.field_name = "Minutes"; gp.Execute(addFieldTool, trackcancel); AddMessage("Calculating the Minutes field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = streetsFeatureClassPath; calcFieldTool.field = "Minutes"; calcFieldTool.expression = "[Meters] * 0.06 / [KPH]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); } #endregion #region Process Live Traffic Table // Create the live traffic table (for 10.1 or later) if (fgdbVersion >= 10.1 && !inputTrafficTableValue.IsEmpty()) { // Copy over the Traffic table to the file geodatabase AddMessage("Copying Traffic table to the file geodatabase...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = inputTrafficTableValue.GetAsText(); importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = TMCJoinTableName; gp.Execute(importTableTool, trackcancel); string TMCJoinTablePath = outputFileGdbPath + "\\" + TMCJoinTableName; // Add the TMC field and calculate it AddMessage("Calculating TMC values for live traffic...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = TMCJoinTablePath; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 9; addFieldTool.field_name = "TMC"; gp.Execute(addFieldTool, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = TMCJoinTablePath; calcFieldTool.field = "TMC"; calcFieldTool.expression = "Right([TRAFFIC_CD], 9)"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Creating the live traffic join table...", messages, trackcancel); // Add FCID, FID, and position fields to the Streets_TMC table AddMessage("Creating fields on the live traffic join table...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = TMCJoinTablePath; addFieldTool.field_type = "LONG"; addFieldTool.field_name = "EdgeFCID"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "EdgeFID"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_type = "DOUBLE"; addFieldTool.field_name = "EdgeFrmPos"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "EdgeToPos"; gp.Execute(addFieldTool, trackcancel); // Calculate the fields AddMessage("Calculating the EdgeFrmPos field for live traffic...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = TMCJoinTablePath; calcFieldTool.field = "EdgeFrmPos"; calcFieldTool.expression = "x"; calcFieldTool.code_block = "Select Case Left([TRAFFIC_CD], 1)\n Case \"+\": x = 0\n Case \"-\": x = 1\nEnd Select"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the EdgeToPos field for live traffic...", messages, trackcancel); calcFieldTool.field = "EdgeToPos"; calcFieldTool.expression = "x"; calcFieldTool.code_block = "Select Case Left([TRAFFIC_CD], 1)\n Case \"-\": x = 0\n Case \"+\": x = 1\nEnd Select"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the EdgeFCID field for live traffic...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = TMCJoinTablePath; calcFieldTool.field = "EdgeFCID"; calcFieldTool.expression = "1"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the EdgeFID field for live traffic...", messages, trackcancel); makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = TMCJoinTablePath; makeTableViewTool.out_view = "Streets_TMC_View"; gp.Execute(makeTableViewTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_TMC_View"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = streetsFeatureClassPath; addJoinTool.join_field = "LINK_ID"; gp.Execute(addJoinTool, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_TMC_View"; calcFieldTool.field = TMCJoinTableName + ".EdgeFID"; calcFieldTool.expression = "[" + StreetsFCName + ".OBJECTID]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_TMC_View"; removeJoinTool.join_name = StreetsFCName; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_TMC_View"; gp.Execute(deleteTool, trackcancel); // If Historical Traffic is not being used, then we need to create placeholder historical traffic tables if (!usesHistoricalTraffic) { // Create the Streets_Patterns table by starting with a copy of the Streets_TMC table AddMessage("Creating the historical traffic join table...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = TMCJoinTablePath; importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = HistTrafficJoinTableName; gp.Execute(importTableTool, trackcancel); string histTrafficJoinTablePath = outputFileGdbPath + "\\" + HistTrafficJoinTableName; AddMessage("Creating and calculating the KPH field on the historical traffic join table...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = histTrafficJoinTablePath; addFieldTool.field_type = "FLOAT"; addFieldTool.field_name = "KPH"; gp.Execute(addFieldTool, trackcancel); makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = histTrafficJoinTablePath; makeTableViewTool.out_view = "Streets_Patterns_View"; gp.Execute(makeTableViewTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Patterns_View"; addJoinTool.in_field = "EdgeFID"; addJoinTool.join_table = streetsFeatureClassPath; addJoinTool.join_field = "OBJECTID"; gp.Execute(addJoinTool, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Patterns_View"; calcFieldTool.field = HistTrafficJoinTableName + ".KPH"; calcFieldTool.expression = "[" + StreetsFCName + ".KPH]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Patterns_View"; removeJoinTool.join_name = StreetsFCName; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Patterns_View"; gp.Execute(deleteTool, trackcancel); AddMessage("Creating and calculating the daily patterns fields on the historical traffic join table...", messages, trackcancel); string[] fieldNames = new string[] { "S", "M", "T", "W", "R", "F", "S" }; foreach (string f in fieldNames) { addFieldTool = new AddField(); addFieldTool.in_table = histTrafficJoinTablePath; addFieldTool.field_type = "SHORT"; addFieldTool.field_name = f; gp.Execute(addFieldTool, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = histTrafficJoinTablePath; calcFieldTool.field = f; calcFieldTool.expression = "1"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); } // Create the Patterns table CreateNonHistoricalPatternsTable(outputFileGdbPath); } } #endregion // Copy the Cdms table to the file geodatabase AddMessage("Copying the Condition/Driving Manoeuvres (CDMS) table and indexing...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = inputCdmsTableValue.GetAsText(); importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = "Cdms"; gp.Execute(importTableTool, trackcancel); string cdmsTablePath = outputFileGdbPath + "\\Cdms"; addIndexTool = new AddIndex(); addIndexTool.in_table = cdmsTablePath; addIndexTool.fields = "COND_ID"; addIndexTool.index_name = "COND_ID"; gp.Execute(addIndexTool, trackcancel); // Copy the Rdms table to the file geodatabase AddMessage("Copying the Restricted Driving Manoeuvres (RDMS) table...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = inputRdmsTableValue.GetAsText(); importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = "Rdms"; gp.Execute(importTableTool, trackcancel); string rdmsTablePath = outputFileGdbPath + "\\Rdms"; // Add and calculate the end of link and condition type fields to the Rdms table AddMessage("Creating and calculating fields for the manoeuvre types and ends of link...", messages, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = rdmsTablePath; addFieldTool.field_name = "COND_TYPE"; addFieldTool.field_type = "LONG"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "END_OF_LK"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 1; gp.Execute(addFieldTool, trackcancel); makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = rdmsTablePath; makeTableViewTool.out_view = "Rdms_View"; gp.Execute(makeTableViewTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Rdms_View"; addJoinTool.in_field = "COND_ID"; addJoinTool.join_table = cdmsTablePath; addJoinTool.join_field = "COND_ID"; gp.Execute(addJoinTool, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Rdms_View"; calcFieldTool.field = "Rdms.COND_TYPE"; calcFieldTool.expression = "[Cdms.COND_TYPE]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); calcFieldTool.field = "Rdms.END_OF_LK"; calcFieldTool.expression = "[Cdms.END_OF_LK]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Rdms_View"; removeJoinTool.join_name = "Cdms"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Rdms_View"; gp.Execute(deleteTool, trackcancel); // Extract only the gates (condition type 4) and prohibitied manoeuvres (condition type 7) // If using Transport, also extract the Transport manoeuvres (condition type 26) AddMessage("Extracting restricted driving manoeuvres...", messages, trackcancel); string prohibRdmsWEndOfLkTablePath = outputFileGdbPath + "\\ProhibRdmsWEndOfLk"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = rdmsTablePath; tableSelectTool.out_table = prohibRdmsWEndOfLkTablePath; if (usesTransport) tableSelectTool.where_clause = "COND_TYPE IN (4, 7, 26)"; else tableSelectTool.where_clause = "COND_TYPE IN (4, 7)"; gp.Execute(tableSelectTool, trackcancel); AddMessage("Creating turn feature class...", messages, trackcancel); // Create the turn feature class string tempStatsTablePath = outputFileGdbPath + "\\tempStatsTable"; Statistics statsTool = new Statistics(); statsTool.in_table = prohibRdmsWEndOfLkTablePath; statsTool.out_table = tempStatsTablePath; statsTool.statistics_fields = "SEQ_NUMBER MAX"; gp.Execute(statsTool, null); CreateAndPopulateTurnFeatureClass(outputFileGdbPath, fdsName, "ProhibRdmsWEndOfLk", "tempStatsTable", messages, trackcancel); deleteTool = new Delete(); deleteTool.in_data = tempStatsTablePath; gp.Execute(deleteTool, trackcancel); string pathToTurnFC = pathToFds + "\\" + TurnFCName; // Create and calculate condition type and access restriction fields on the turn feature class addFieldTool = new AddField(); addFieldTool.in_table = pathToTurnFC; addFieldTool.field_name = "COND_TYPE"; addFieldTool.field_type = "LONG"; gp.Execute(addFieldTool, trackcancel); AddMessage("Creating access restriction fields on the turn feature class...", messages, trackcancel); foreach (string arFieldSuffix in arFieldSuffixes) { addFieldTool = new AddField(); addFieldTool.in_table = pathToTurnFC; addFieldTool.field_name = "AR_" + arFieldSuffix; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 1; gp.Execute(addFieldTool, trackcancel); } makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = pathToTurnFC; makeFeatureLayerTool.out_layer = "Turn_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Turn_Layer"; addJoinTool.in_field = "COND_ID"; addJoinTool.join_table = cdmsTablePath; addJoinTool.join_field = "COND_ID"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the COND_TYPE field on the turn feature class...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Turn_Layer"; calcFieldTool.field = TurnFCName + ".COND_TYPE"; calcFieldTool.expression = "[Cdms.COND_TYPE]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); foreach (string arFieldSuffix in arFieldSuffixes) { AddMessage("Calculating the AR_" + arFieldSuffix + " field on the turn feature class...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Turn_Layer"; calcFieldTool.field = TurnFCName + ".AR_" + arFieldSuffix; calcFieldTool.expression = "[Cdms.AR_" + arFieldSuffix + "]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); } removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Turn_Layer"; removeJoinTool.join_name = "Cdms"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Turn_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = cdmsTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = prohibRdmsWEndOfLkTablePath; gp.Execute(deleteTool, trackcancel); GC.Collect(); #region Process Transport Tables if (usesTransport) { string nonDimensionalCndModTablePath = outputFileGdbPath + "\\nonDimensionalCndMod"; string dimensionalCndModTablePath = outputFileGdbPath + "\\dimensionalCndMod"; if (!(inputUSCndModTableValue.IsEmpty())) { // Extract the Transport information for the US AddMessage("Extracting the US non-dimensional conditions...", messages, trackcancel); tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputUSCndModTableValue.GetAsText(); tableSelectTool.out_table = nonDimensionalCndModTablePath; tableSelectTool.where_clause = "MOD_TYPE IN (38, 39, 46, 49, 60, 75)"; gp.Execute(tableSelectTool, trackcancel); AddMessage("Extracting the US dimensional conditions...", messages, trackcancel); tableSelectTool.out_table = dimensionalCndModTablePath; tableSelectTool.where_clause = "MOD_TYPE IN (41, 42, 43, 44, 45, 48, 81)"; gp.Execute(tableSelectTool, trackcancel); // Create a new field to hold the dimension in a common unit (m or kg or KPH) addFieldTool = new AddField(); addFieldTool.in_table = dimensionalCndModTablePath; addFieldTool.field_name = "MetersOrKilogramsOrKPH"; addFieldTool.field_type = "DOUBLE"; gp.Execute(addFieldTool, trackcancel); AddMessage("Calculating common units of measure...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = dimensionalCndModTablePath; calcFieldTool.field = "MetersOrKilogramsOrKPH"; calcFieldTool.code_block = "x = CLng([MOD_VAL])\nSelect Case [MOD_TYPE]\n" + " Case 41, 44, 45, 81: x = x * 0.0254\n" + " Case 42, 43: x = x * 0.45359237\n" + " Case 48: x = x * 1.609344\nEnd Select"; calcFieldTool.expression = "x"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); if (!(inputNonUSCndModTableValue.IsEmpty())) { string tempNonDimensionalCndModTablePath = outputFileGdbPath + "\\tempNonDimensionalCndMod"; string tempDimensionalCndModTablePath = outputFileGdbPath + "\\tempDimensionalCndMod"; // Extract the Transport information for outside the US to temporary tables AddMessage("Extracting the non-US non-dimensional conditions...", messages, trackcancel); tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputNonUSCndModTableValue.GetAsText(); tableSelectTool.out_table = tempNonDimensionalCndModTablePath; tableSelectTool.where_clause = "MOD_TYPE IN (38, 39, 46, 49, 60, 75)"; gp.Execute(tableSelectTool, trackcancel); AddMessage("Extracting the non-US dimensional conditions...", messages, trackcancel); tableSelectTool.out_table = tempDimensionalCndModTablePath; tableSelectTool.where_clause = "MOD_TYPE IN (41, 42, 43, 44, 45, 48, 81)"; gp.Execute(tableSelectTool, trackcancel); // Create a new field to hold the dimension in a common unit (m or kg) addFieldTool = new AddField(); addFieldTool.in_table = tempDimensionalCndModTablePath; addFieldTool.field_name = "MetersOrKilogramsOrKPH"; addFieldTool.field_type = "DOUBLE"; gp.Execute(addFieldTool, trackcancel); AddMessage("Calculating common units of measure...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = dimensionalCndModTablePath; calcFieldTool.field = "MetersOrKilogramsOrKPH"; calcFieldTool.code_block = "x = CLng([MOD_VAL])\nSelect Case [MOD_TYPE]\n" + " Case 41, 44, 45, 81: x = x * 0.01\nEnd Select"; calcFieldTool.expression = "x"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); // Append the temporary tables to the main table containing US attributes Append appendTool = new Append(); appendTool.inputs = tempNonDimensionalCndModTablePath; appendTool.target = nonDimensionalCndModTablePath; gp.Execute(appendTool, trackcancel); appendTool.inputs = tempDimensionalCndModTablePath; appendTool.target = dimensionalCndModTablePath; gp.Execute(appendTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = tempNonDimensionalCndModTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = tempDimensionalCndModTablePath; gp.Execute(deleteTool, trackcancel); } } else { // Extract the Transport information for outside the US AddMessage("Extracting the non-US non-dimensional conditions...", messages, trackcancel); tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputNonUSCndModTableValue.GetAsText(); tableSelectTool.out_table = nonDimensionalCndModTablePath; tableSelectTool.where_clause = "MOD_TYPE IN (38, 39, 46, 49, 60, 75)"; gp.Execute(tableSelectTool, trackcancel); AddMessage("Extracting the non-US dimensional conditions...", messages, trackcancel); tableSelectTool.out_table = dimensionalCndModTablePath; tableSelectTool.where_clause = "MOD_TYPE IN (41, 42, 43, 44, 45, 48, 81)"; gp.Execute(tableSelectTool, trackcancel); // Create a new field to hold the dimension in a common unit (m or kg) addFieldTool = new AddField(); addFieldTool.in_table = dimensionalCndModTablePath; addFieldTool.field_name = "MetersOrKilogramsOrKPH"; addFieldTool.field_type = "DOUBLE"; gp.Execute(addFieldTool, trackcancel); AddMessage("Calculating common units of measure...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = dimensionalCndModTablePath; calcFieldTool.field = "MetersOrKilogramsOrKPH"; calcFieldTool.code_block = "x = CLng([MOD_VAL])\nSelect Case [MOD_TYPE]\n" + " Case 41, 44, 45, 81: x = x * 0.01\nEnd Select"; calcFieldTool.expression = "x"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); } // Create a table for looking up LINK_IDs from COND_IDs AddMessage("Creating and indexing LINK_ID/COND_ID look-up table for preferred roads...", messages, trackcancel); string preferredLinkIDLookupTablePath = outputFileGdbPath + "\\preferredLinkIDLookupTable"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputCdmsTableValue.GetAsText(); tableSelectTool.out_table = preferredLinkIDLookupTablePath; tableSelectTool.where_clause = "COND_TYPE = 27"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = preferredLinkIDLookupTablePath; addIndexTool.fields = "COND_ID"; addIndexTool.index_name = "COND_ID"; gp.Execute(addIndexTool, trackcancel); // Create a table for looking up the condition's direction AddMessage("Creating and indexing direction look-up table for preferred roads...", messages, trackcancel); string preferredDirectionLookupTablePath = outputFileGdbPath + "\\preferredDirectionLookupTable"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = nonDimensionalCndModTablePath; tableSelectTool.out_table = preferredDirectionLookupTablePath; tableSelectTool.where_clause = "MOD_TYPE = 60"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = preferredDirectionLookupTablePath; addIndexTool.fields = "COND_ID"; addIndexTool.index_name = "COND_ID"; gp.Execute(addIndexTool, trackcancel); // Create a table for looking up LINK_IDs from COND_IDs AddMessage("Creating and indexing LINK_ID/COND_ID look-up table for restrictions...", messages, trackcancel); string restrictionLinkIDLookupTablePath = outputFileGdbPath + "\\restrictionLinkIDLookupTable"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = inputCdmsTableValue.GetAsText(); tableSelectTool.out_table = restrictionLinkIDLookupTablePath; tableSelectTool.where_clause = "COND_TYPE = 23"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = restrictionLinkIDLookupTablePath; addIndexTool.fields = "COND_ID"; addIndexTool.index_name = "COND_ID"; gp.Execute(addIndexTool, trackcancel); // Create a table for looking up the condition's direction AddMessage("Creating and indexing direction look-up table for restrictions...", messages, trackcancel); string restrictionDirectionLookupTablePath = outputFileGdbPath + "\\restrictionDirectionLookupTable"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = nonDimensionalCndModTablePath; tableSelectTool.out_table = restrictionDirectionLookupTablePath; tableSelectTool.where_clause = "MOD_TYPE = 38"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = restrictionDirectionLookupTablePath; addIndexTool.fields = "COND_ID"; addIndexTool.index_name = "COND_ID"; gp.Execute(addIndexTool, trackcancel); makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = streetsFeatureClassPath; makeFeatureLayerTool.out_layer = "Streets_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); CreateAndPopulateTruckFCOverrideField(outputFileGdbPath, gp, messages, trackcancel); if (fgdbVersion >= 10.1) { // Create and calculate the preferred fields for Streets CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "STAAPreferred", "MOD_TYPE = 49 AND MOD_VAL = '1'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "TruckDesignatedPreferred", "MOD_TYPE = 49 AND MOD_VAL = '2'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "NRHMPreferred", "MOD_TYPE = 49 AND MOD_VAL = '3'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "ExplosivesPreferred", "MOD_TYPE = 49 AND MOD_VAL = '4'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "PIHPreferred", "MOD_TYPE = 49 AND MOD_VAL = '5'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "MedicalWastePreferred", "MOD_TYPE = 49 AND MOD_VAL = '6'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "RadioactivePreferred", "MOD_TYPE = 49 AND MOD_VAL = '7'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "HazmatPreferred", "MOD_TYPE = 49 AND MOD_VAL = '8'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, true, "LocallyPreferred", "MOD_TYPE = 49 AND MOD_VAL = '9'", gp, messages, trackcancel); if (createArcGISOnlineNetworkAttributes) { CreateAndPopulateAGOLTextTransportFieldsOnStreets(outputFileGdbPath, "PreferredTruckRoute", new string[] { "STAAPreferred", "TruckDesignatedPreferred", "LocallyPreferred" }, gp, messages, trackcancel); CreateAndPopulateAGOLTextTransportFieldsOnStreets(outputFileGdbPath, "PreferredHazmatRoute", new string[] { "NRHMPreferred", "ExplosivesPreferred", "PIHPreferred", "MedicalWastePreferred", "RadioactivePreferred", "HazmatPreferred" }, gp, messages, trackcancel); } } // Create and calculate the HazMat restriction fields for Streets CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "ExplosivesProhibited", "MOD_TYPE = 39 AND MOD_VAL = '1'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "GasProhibited", "MOD_TYPE = 39 AND MOD_VAL = '2'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "FlammableProhibited", "MOD_TYPE = 39 AND MOD_VAL = '3'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "CombustibleProhibited", "MOD_TYPE = 39 AND MOD_VAL = '4'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "OrganicProhibited", "MOD_TYPE = 39 AND MOD_VAL = '5'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "PoisonProhibited", "MOD_TYPE = 39 AND MOD_VAL = '6'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "RadioactiveProhibited", "MOD_TYPE = 39 AND MOD_VAL = '7'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "CorrosiveProhibited", "MOD_TYPE = 39 AND MOD_VAL = '8'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "OtherHazmatProhibited", "MOD_TYPE = 39 AND MOD_VAL = '9'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "AnyHazmatProhibited", "MOD_TYPE = 39 AND MOD_VAL = '20'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "PIHProhibited", "MOD_TYPE = 39 AND MOD_VAL = '21'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "HarmfulToWaterProhibited", "MOD_TYPE = 39 AND MOD_VAL = '22'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "ExplosiveAndFlammableProhibited", "MOD_TYPE = 39 AND MOD_VAL = '23'", gp, messages, trackcancel); if (createArcGISOnlineNetworkAttributes) { CreateAndPopulateAGOLTextTransportFieldsOnStreets(outputFileGdbPath, "AGOL_AnyHazmatProhibited", new string[] { "ExplosivesProhibited", "GasProhibited", "FlammableProhibited", "CombustibleProhibited", "OrganicProhibited", "PoisonProhibited", "RadioactiveProhibited", "CorrosiveProhibited", "OtherHazmatProhibited", "AnyHazmatProhibited", "PIHProhibited", "HarmfulToWaterProhibited", "ExplosiveAndFlammableProhibited" }, gp, messages, trackcancel); } // Create and calculate the other restriction fields for Streets CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, true, false, false, "HeightLimit_Meters", "MOD_TYPE = 41", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, true, false, false, "WeightLimit_Kilograms", "MOD_TYPE = 42", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, true, false, false, "WeightLimitPerAxle_Kilograms", "MOD_TYPE = 43", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, true, false, false, "LengthLimit_Meters", "MOD_TYPE = 44", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, true, false, false, "WidthLimit_Meters", "MOD_TYPE = 45", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, true, false, "MaxTrailersAllowedOnTruck", "MOD_TYPE = 46 AND MOD_VAL IN ('1', '2', '3')", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "SemiOrTractorWOneOrMoreTrailersProhibited", "MOD_TYPE = 46 AND MOD_VAL = '4'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, true, false, "MaxAxlesAllowed", "MOD_TYPE = 75 AND MOD_VAL IN ('1', '2', '3', '4', '5')", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "SingleAxleProhibited", "MOD_TYPE = 75 AND MOD_VAL = '6'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, false, false, false, "TandemAxleProhibited", "MOD_TYPE = 75 AND MOD_VAL = '7'", gp, messages, trackcancel); CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, true, false, false, "KingpinToRearAxleLengthLimit_Meters", "MOD_TYPE = 81", gp, messages, trackcancel); // Create and calculate the truck speed fields for Streets CreateAndPopulateTransportFieldsOnStreets(outputFileGdbPath, true, false, true, "TruckKPH", "MOD_TYPE = 48", gp, messages, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = preferredLinkIDLookupTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = preferredDirectionLookupTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = restrictionLinkIDLookupTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = restrictionDirectionLookupTablePath; gp.Execute(deleteTool, trackcancel); makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = pathToTurnFC; makeFeatureLayerTool.out_layer = "RestrictedTurns_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); // Create and calculate the HazMat restriction fields for RestrictedTurns CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "ExplosivesProhibited", "MOD_TYPE = 39 AND MOD_VAL = '1'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "GasProhibited", "MOD_TYPE = 39 AND MOD_VAL = '2'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "FlammableProhibited", "MOD_TYPE = 39 AND MOD_VAL = '3'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "CombustibleProhibited", "MOD_TYPE = 39 AND MOD_VAL = '4'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "OrganicProhibited", "MOD_TYPE = 39 AND MOD_VAL = '5'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "PoisonProhibited", "MOD_TYPE = 39 AND MOD_VAL = '6'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "RadioactiveProhibited", "MOD_TYPE = 39 AND MOD_VAL = '7'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "CorrosiveProhibited", "MOD_TYPE = 39 AND MOD_VAL = '8'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "OtherHazmatProhibited", "MOD_TYPE = 39 AND MOD_VAL = '9'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "AnyHazmatProhibited", "MOD_TYPE = 39 AND MOD_VAL = '20'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "PIHProhibited", "MOD_TYPE = 39 AND MOD_VAL = '21'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "HarmfulToWaterProhibited", "MOD_TYPE = 39 AND MOD_VAL = '22'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "ExplosiveAndFlammableProhibited", "MOD_TYPE = 39 AND MOD_VAL = '23'", gp, messages, trackcancel); if (createArcGISOnlineNetworkAttributes) { CreateAndPopulateAGOLTextTransportFieldOnTurns(outputFileGdbPath, "AGOL_AnyHazmatProhibited", new string[] { "ExplosivesProhibited", "GasProhibited", "FlammableProhibited", "CombustibleProhibited", "OrganicProhibited", "PoisonProhibited", "RadioactiveProhibited", "CorrosiveProhibited", "OtherHazmatProhibited", "AnyHazmatProhibited", "PIHProhibited", "HarmfulToWaterProhibited", "ExplosiveAndFlammableProhibited" }, gp, messages, trackcancel); } // Create and calculate the other restriction fields for RestrictedTurns CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, true, false, "HeightLimit_Meters", "MOD_TYPE = 41", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, true, false, "WeightLimit_Kilograms", "MOD_TYPE = 42", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, true, false, "WeightLimitPerAxle_Kilograms", "MOD_TYPE = 43", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, true, false, "LengthLimit_Meters", "MOD_TYPE = 44", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, true, false, "WidthLimit_Meters", "MOD_TYPE = 45", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, true, "MaxTrailersAllowedOnTruck", "MOD_TYPE = 46 AND MOD_VAL IN ('1', '2', '3')", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "SemiOrTractorWOneOrMoreTrailersProhibited", "MOD_TYPE = 46 AND MOD_VAL = '4'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, true, "MaxAxlesAllowed", "MOD_TYPE = 75 AND MOD_VAL IN ('1', '2', '3', '4', '5')", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "SingleAxleProhibited", "MOD_TYPE = 75 AND MOD_VAL = '6'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, false, false, "TandemAxleProhibited", "MOD_TYPE = 75 AND MOD_VAL = '7'", gp, messages, trackcancel); CreateAndPopulateTransportFieldOnTurns(outputFileGdbPath, true, false, "KingpinToRearAxleLengthLimit_Meters", "MOD_TYPE = 81", gp, messages, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "RestrictedTurns_Layer"; gp.Execute(deleteTool, trackcancel); // Create and calculate the AllTransportProhibited field addFieldTool = new AddField(); addFieldTool.in_table = pathToTurnFC; addFieldTool.field_name = "AllTransportProhibited"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 1; gp.Execute(addFieldTool, trackcancel); makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = pathToTurnFC; makeFeatureLayerTool.out_layer = "RestrictedTurns_Layer"; makeFeatureLayerTool.where_clause = "COND_TYPE = 26 AND ExplosivesProhibited IS NULL AND GasProhibited IS NULL AND " + "FlammableProhibited IS NULL AND CombustibleProhibited IS NULL AND OrganicProhibited IS NULL AND " + "PoisonProhibited IS NULL AND RadioactiveProhibited IS NULL AND CorrosiveProhibited IS NULL AND " + "OtherHazmatProhibited IS NULL AND AnyHazmatProhibited IS NULL AND PIHProhibited IS NULL AND " + "HarmfulToWaterProhibited IS NULL AND ExplosiveAndFlammableProhibited IS NULL AND " + "HeightLimit_Meters IS NULL AND WeightLimit_Kilograms IS NULL AND WeightLimitPerAxle_Kilograms IS NULL AND " + "LengthLimit_Meters IS NULL AND WidthLimit_Meters IS NULL AND MaxTrailersAllowedOnTruck IS NULL AND " + "SemiOrTractorWOneOrMoreTrailersProhibited IS NULL AND MaxAxlesAllowed IS NULL AND " + "SingleAxleProhibited IS NULL AND TandemAxleProhibited IS NULL AND KingpinToRearAxleLengthLimit_Meters IS NULL"; gp.Execute(makeFeatureLayerTool, trackcancel); AddMessage("Calculating the AllTransportProhibited field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "RestrictedTurns_Layer"; calcFieldTool.field = "AllTransportProhibited"; calcFieldTool.expression = "\"Y\""; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "RestrictedTurns_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = nonDimensionalCndModTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = dimensionalCndModTablePath; gp.Execute(deleteTool, trackcancel); GC.Collect(); } #endregion // Extract the special explications (condition type 9) from the Rdms Table and create RoadSplits table AddMessage("Creating RoadSplits table...", messages, trackcancel); string specialExplicationRdmsWEndOfLkTablePath = outputFileGdbPath + "\\SpecialExplicationRdmsWEndOfLk"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = rdmsTablePath; tableSelectTool.out_table = specialExplicationRdmsWEndOfLkTablePath; tableSelectTool.where_clause = "COND_TYPE = 9"; gp.Execute(tableSelectTool, trackcancel); deleteTool.in_data = rdmsTablePath; gp.Execute(deleteTool, trackcancel); CreateRoadSplitsTable("SpecialExplicationRdmsWEndOfLk", outputFileGdbPath, messages, trackcancel); deleteTool.in_data = specialExplicationRdmsWEndOfLkTablePath; gp.Execute(deleteTool, trackcancel); // Create Signpost feature class and table AddMessage("Creating signpost feature class and table...", messages, trackcancel); CreateSignposts(inputSignsTableValue.GetAsText(), outputFileGdbPath, messages, trackcancel); AddSpatialIndex addSpatialIndexTool = new AddSpatialIndex(); addSpatialIndexTool.in_features = pathToFds + "\\" + SignpostFCName; gp.Execute(addSpatialIndexTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = outputFileGdbPath + "\\" + SignpostJoinTableName; addIndexTool.fields = "SignpostID"; addIndexTool.index_name = "SignpostID"; gp.Execute(addIndexTool, trackcancel); addIndexTool.fields = "Sequence"; addIndexTool.index_name = "Sequence"; gp.Execute(addIndexTool, trackcancel); addIndexTool.fields = "EdgeFCID"; addIndexTool.index_name = "EdgeFCID"; gp.Execute(addIndexTool, trackcancel); addIndexTool.fields = "EdgeFID"; addIndexTool.index_name = "EdgeFID"; gp.Execute(addIndexTool, trackcancel); GC.Collect(); // Upgrade the geodatabase (if not 9.3) if (fgdbVersion > 9.3) { UpgradeGDB upgradeGdbTool = new UpgradeGDB(); upgradeGdbTool.input_workspace = outputFileGdbPath; gp.Execute(upgradeGdbTool, trackcancel); } // Create and build the network dataset, then pack it in a GPValue AddMessage("Creating and building the network dataset...", messages, trackcancel); CreateAndBuildNetworkDataset(outputFileGdbPath, fgdbVersion, fdsName, ndsName, createNetworkAttributesInMetric, createArcGISOnlineNetworkAttributes, timeZoneIDBaseFieldName, directedTimeZoneIDFields, commonTimeZone, usesHistoricalTraffic, trafficFeedLocation, usesTransport); // Write the build errors to the turn feature class TurnGeometryUtilities.WriteBuildErrorsToTurnFC(outputFileGdbPath, fdsName, TurnFCName, messages, trackcancel); // Compact the output file geodatabase AddMessage("Compacting the output file geodatabase...", messages, trackcancel); Compact compactTool = new Compact(); compactTool.in_workspace = outputFileGdbPath; gp.Execute(compactTool, trackcancel); } catch (Exception e) { if (gp.MaxSeverity == 2) { object missing = System.Type.Missing; messages.AddError(1, gp.GetMessages(ref missing)); } messages.AddError(1, e.Message); messages.AddError(1, e.StackTrace); } finally { // Restore the original GP environment settings gpSettings.AddOutputsToMap = origAddOutputsToMapSetting; gpSettings.LogHistory = origLogHistorySetting; } GC.Collect(); return; }
/// <summary> /// Helper function that runs all of those checks that operate on each job type; /// intended to make the checks slightly more efficient by running through them all /// at once rather than looping through all of the elements multiple times /// </summary> /// <param name="msgs">Add any GP messages to this object</param> /// <param name="errorCount">Counter used to track the number of problems found</param> /// <param name="logFileWriter">Object used to write error descriptions to a text file</param> private void ExecuteJobTypeChecks(IGPMessages msgs, ref int errorCount, StreamWriter logFileWriter) { if (!m_flagInvalidJobTypeAssign && !m_flagJobTypesWithoutWorkflows && !m_flagMissingAoiMxds && !m_flagMissingBaseMxds && !m_flagNonActiveJobTypes) { return; } IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; IJTXConfigurationEdit2 configEdit = configMgr as IJTXConfigurationEdit2; // Put the items into a sorted list in order to make the output easier to // read/follow IJTXJobTypeSet allJobTypes = configMgr.JobTypes; SortedList <string, IJTXJobType3> allJobTypesSorted = new SortedList <string, IJTXJobType3>(); for (int i = 0; i < allJobTypes.Count; i++) { allJobTypesSorted[allJobTypes.get_Item(i).Name] = allJobTypes.get_Item(i) as IJTXJobType3; } // Iterate through each item foreach (IJTXJobType3 jobType in allJobTypesSorted.Values) { if (m_flagInvalidJobTypeAssign) { string assignedTo = jobType.DefaultAssignedTo; if (jobType.DefaultAssignedType == jtxAssignmentType.jtxAssignmentTypeUser && configMgr.GetUser(assignedTo) == null) { string message = "Job Type '" + jobType.Name + "' assigned to unknown user '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } else if (jobType.DefaultAssignedType == jtxAssignmentType.jtxAssignmentTypeGroup && configMgr.GetUserGroup(assignedTo) == null) { string message = "Job Type '" + jobType.Name + "' assigned to unknown group '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } if (m_flagJobTypesWithoutWorkflows) { if (jobType.Workflow == null) { string message = "Job Type '" + jobType.Name + "' has no workflow defined"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } if (m_flagMissingAoiMxds) { if (jobType.AOIMap == null) { string message = "Job Type '" + jobType.Name + "' has no AOI map defined"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } if (m_flagMissingBaseMxds) { if (jobType.JobMap == null) { string message = "Job Type '" + jobType.Name + "' has no job map (a.k.a. basemap) defined"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } if (m_flagNonActiveJobTypes) { if (jobType.State != jtxJobTypeState.jtxJobTypeStateActive) { string message = "Job Type '" + jobType.Name + "' is not active"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } } }
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> /// Helper function that runs all of those checks that operate on each step in /// every workflow; intended to make the checks slightly more efficient by running /// through them all at once rather than looping through all of the elements /// multiple times /// </summary> /// <param name="msgs">Add any GP messages to this object</param> /// <param name="errorCount">Counter used to track the number of problems found</param> /// <param name="logFileWriter">Object used to write error descriptions to a text file</param> private void ExecuteWorkflowStepChecks(IGPMessages msgs, ref int errorCount, StreamWriter logFileWriter) { // Only continue executing this function if needed if (!m_flagInvalidStepAssign && !m_flagUnassignedSteps && !m_flagZeroPctSteps && !m_flagDifferingStepNames) { return; } IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; IJTXConfigurationEdit2 configEdit = configMgr as IJTXConfigurationEdit2; // Put the items into a sorted list in order to make the output easier to // read/follow IJTXWorkflowSet allWorkflows = configMgr.Workflows; SortedList <string, IJTXWorkflow> allWorkflowsSorted = new SortedList <string, IJTXWorkflow>(); for (int i = 0; i < allWorkflows.Count; i++) { allWorkflowsSorted[allWorkflows.get_Item(i).Name] = allWorkflows.get_Item(i); } // Iterate through each item foreach (IJTXWorkflow workflow in allWorkflowsSorted.Values) { IJTXWorkflowConfiguration workflowCfg = workflow as IJTXWorkflowConfiguration; int[] allStepIds = workflowCfg.GetAllSteps(); foreach (int j in allStepIds) { IJTXStep3 step = workflowCfg.GetStep(j) as IJTXStep3; string assignedTo = step.AssignedTo; // Check for any default step types with an invalid step assignment if (m_flagInvalidStepAssign) { if (step.AssignedType == jtxAssignmentType.jtxAssignmentTypeUser && configMgr.GetUser(assignedTo) == null) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' assigned to unknown user '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } else if (step.AssignedType == jtxAssignmentType.jtxAssignmentTypeGroup && configMgr.GetUserGroup(assignedTo) == null) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' assigned to unknown group '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } // Check for any steps that have not been assigned to a group or user if (m_flagUnassignedSteps) { if (step.AssignedType == jtxAssignmentType.jtxAssignmentTypeUnassigned) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' is unassigned"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } // Check for any steps whose "post-complete" percentage is 0 if (m_flagZeroPctSteps) { if (step.DefaultPercComplete < double.Epsilon) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' sets percent complete to 0"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } // Check for any steps whose descriptions in a workflow does not match // the underlying step type name if (m_flagDifferingStepNames) { IJTXStepType2 stepType = configMgr.GetStepTypeByID(step.StepTypeID) as IJTXStepType2; if (!step.StepName.Equals(stepType.Name)) { string message = "Workflow '" + workflow.Name + "', step name '" + step.StepName + "' does not match step type name '" + stepType.Name + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } } // end for each step } // end for each workflow }
/// <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); StreamWriter logFileWriter = null; try { int errorCount = 0; if (!string.IsNullOrEmpty(m_logFilePath)) { logFileWriter = new StreamWriter(m_logFilePath); } IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; IJTXConfigurationEdit2 configEdit = configMgr as IJTXConfigurationEdit2; IJTXJobManager jobMgr = this.WmxDatabase.JobManager; // Workflow Manager intentionally caches the data workspaces in the system. To ensure // that we have the most current list of data workspaces, invalidate this cache // before attempting to retrieve the list from the system. this.WmxDatabase.InvalidateDataWorkspaceNames(); // Run checks against users ExecuteUserChecks(msgs, ref errorCount, logFileWriter); // Run checks against groups ExecuteGroupChecks(msgs, ref errorCount, logFileWriter); // Run checks against any existing jobs ExecuteJobChecks(msgs, ref errorCount, logFileWriter); // Check for any template job types with an invalid default assignment ExecuteJobTypeChecks(msgs, ref errorCount, logFileWriter); // Check the workflow steps for problems ExecuteWorkflowStepChecks(msgs, ref errorCount, logFileWriter); // Set the output parameter WmauParameterMap paramMap = new WmauParameterMap(paramValues); IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_ISSUES_FOUND); IGPLong outValue = new GPLongClass(); outValue.Value = errorCount; outParamEdit.Value = outValue as IGPValue; msgs.AddMessage(Properties.Resources.MSG_DONE); } catch (WmauException wmEx) { try { msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message); } catch { // Catch anything else that possibly happens } } catch (Exception ex) { try { WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message); } catch { // Catch anything else that possibly happens } } finally { // Release any COM objects here! if (logFileWriter != null) { logFileWriter.Close(); } } }
/// <summary> /// Post validates the given set of values. /// This is where you flag parameters with warnings and error messages, among other things. /// </summary> /// <param name="paramValues"></param> /// <param name="pEnvMgr"></param> /// <param name="msgs"></param> public override void UpdateMessages(IArray paramValues, IGPEnvironmentManager pEnvMgr, IGPMessages msgs) { try { UpdateMessagesCommon(paramValues, pEnvMgr, msgs); } catch (WmxDefaultDbNotSetException) { // If the default DB wasn't set, stop executing return; } // Build a hash of which parameter is at which index for ease of access WmauParameterMap paramMap = new WmauParameterMap(paramValues); // Ensure that the current user has permissions to be creating jobs if (!CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_DELETE_JOBS)) { WmauError error = new WmauError(WmauErrorCodes.C_NO_DELETE_JOB_PRIV_ERROR); msgs.ReplaceError(paramMap.GetIndex(C_PARAM_JOB_TO_DELETE), error.ErrorCodeAsInt, error.Message); } }
public void PostToolExecute(IGPTool Tool, IArray Values, int result, IGPMessages Messages) { }
/// <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); } }
// Called after returning from the update parameters routine. // You can examine the messages created from internal validation and change them if desired. public void UpdateMessages(IArray paramvalues, IGPEnvironmentManager pEnvMgr, IGPMessages Messages) { // Check for error messages IGPMessage msg = (IGPMessage)Messages; if (msg.IsError()) return; // Get the first Input Parameter IGPParameter parameter = (IGPParameter)paramvalues.get_Element(0); // UnPackGPValue. This ensures you get the value either form the dataelement or GpVariable (ModelBuilder) IGPValue parameterValue = m_GPUtilities.UnpackGPValue(parameter); // Open the Input Dataset - Use DecodeFeatureLayer as the input might be a layer file or a feature layer from ArcMap. IFeatureClass inputFeatureClass; IQueryFilter qf; m_GPUtilities.DecodeFeatureLayer(parameterValue, out inputFeatureClass, out qf); IGPParameter3 fieldParameter = (IGPParameter3)paramvalues.get_Element(1); string fieldName = fieldParameter.Value.GetAsText(); // Check if the field already exists and provide a warning. int indexA = inputFeatureClass.FindField(fieldName); if (indexA > 0) { Messages.ReplaceWarning(1, "Field already exists. It will be overwritten."); } return; }
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 UpdateMessages(IArray paramvalues, IGPEnvironmentManager pEnvMgr, IGPMessages messages) { // Check for error message IGPMessage msg = (IGPMessage)messages; if (msg.IsError()) return; // Verify chosen output file geodatabase has a ".gdb" extension var gpParam = paramvalues.get_Element(OutputFileGDB) as IGPParameter; IGPValue outputFileGDBValue = m_gpUtils.UnpackGPValue(gpParam); if (!outputFileGDBValue.IsEmpty()) { string outputFileGDBValueAsText = outputFileGDBValue.GetAsText(); if (!(outputFileGDBValueAsText.EndsWith(".gdb"))) { IGPMessage gpMessage = messages.GetMessage(OutputFileGDB); gpMessage.Type = esriGPMessageType.esriGPMessageTypeError; gpMessage.Description = "Input value is not a valid file geodatabase path."; } } // Verify chosen input MtdDST table has the expected fields gpParam = paramvalues.get_Element(InputMtdDSTTable) as IGPParameter; IGPValue tableValue = m_gpUtils.UnpackGPValue(gpParam); if (!tableValue.IsEmpty()) { IDETable inputTable = m_gpUtils.DecodeDETable(tableValue); CheckForTableFields(inputTable, MtdDSTFieldNames, MtdDSTFieldTypes, messages.GetMessage(InputMtdDSTTable)); } // Verify chosen input MtdCntryRef table has the expected fields gpParam = paramvalues.get_Element(InputMtdCntryRefTable) as IGPParameter; tableValue = m_gpUtils.UnpackGPValue(gpParam); if (!tableValue.IsEmpty()) { IDETable inputTable = m_gpUtils.DecodeDETable(tableValue); CheckForTableFields(inputTable, MtdCntryRefFieldNames, MtdCntryRefFieldTypes, messages.GetMessage(InputMtdCntryRefTable)); } // Verify chosen input MtdArea table has the expected fields gpParam = paramvalues.get_Element(InputMtdAreaTable) as IGPParameter; tableValue = m_gpUtils.UnpackGPValue(gpParam); if (!tableValue.IsEmpty()) { IDETable inputTable = m_gpUtils.DecodeDETable(tableValue); CheckForTableFields(inputTable, MtdAreaFieldNames, MtdAreaFieldTypes, messages.GetMessage(InputMtdAreaTable)); } // Verify chosen input AdminBndy feature classes have the expected fields gpParam = paramvalues.get_Element(InputAdminBndyFeatureClasses) as IGPParameter; IGPMultiValue multiValue = m_gpUtils.UnpackGPValue(gpParam) as IGPMultiValue; for (int i = 0; i < multiValue.Count; i++) { tableValue = multiValue.get_Value(i); if (!tableValue.IsEmpty()) { IDETable inputTable = m_gpUtils.DecodeDETable(tableValue); CheckForTableFields(inputTable, AdminBndyFieldNames, AdminBndyFieldTypes, messages.GetMessage(InputAdminBndyFeatureClasses)); } } // Check the input Streets feature class and Time Zone ID Field Name parameters together gpParam = paramvalues.get_Element(InputStreetsFeatureClass) as IGPParameter; tableValue = m_gpUtils.UnpackGPValue(gpParam); IGPParameter fieldNameParam = paramvalues.get_Element(InputTimeZoneIDBaseFieldName) as IGPParameter; IGPValue fieldNameValue = m_gpUtils.UnpackGPValue(fieldNameParam); if (!tableValue.IsEmpty()) { // Verify chosen input Streets feature class has the expected fields IDETable inputTable = m_gpUtils.DecodeDETable(tableValue); CheckForTableFields(inputTable, StreetsFieldNames, StreetsFieldTypes, messages.GetMessage(InputStreetsFeatureClass)); // Check to make sure that the Time Zone ID Base Field Name parameter is specified together with the Streets feature class if (fieldNameValue.IsEmpty()) { messages.GetMessage(InputTimeZoneIDBaseFieldName).Type = esriGPMessageType.esriGPMessageTypeError; messages.GetMessage(InputTimeZoneIDBaseFieldName).Description = "This parameter must be specified together with the NW feature class."; } else { // Verify chosen input time zone ID fields does not exist on the input Streets feature class string fieldName = fieldNameValue.GetAsText(); if (inputTable.Fields.FindField("FT_" + fieldName) != -1) { messages.GetMessage(InputTimeZoneIDBaseFieldName).Type = esriGPMessageType.esriGPMessageTypeError; messages.GetMessage(InputTimeZoneIDBaseFieldName).Description = "Field named FT_" + fieldName + " already exists."; } if (inputTable.Fields.FindField("TF_" + fieldName) != -1) { messages.GetMessage(InputTimeZoneIDBaseFieldName).Type = esriGPMessageType.esriGPMessageTypeError; messages.GetMessage(InputTimeZoneIDBaseFieldName).Description = "Field named TF_" + fieldName + " already exists."; } } } return; }
private void CreateAndPopulateTransportFieldsOnStreets(string outputFileGdbPath, bool isDimensional, bool isQuantitative, bool isPreferred, string newFieldNameBase, string queryExpression, Geoprocessor gp, IGPMessages messages, ITrackCancel trackcancel) { string cndModTableName = isDimensional ? "dimensionalCndMod" : "nonDimensionalCndMod"; string linkIDLookupTableName = isPreferred ? "preferredLinkIDLookupTable" : "restrictionLinkIDLookupTable"; string directionLookupTableName = isPreferred ? "preferredDirectionLookupTable" : "restrictionDirectionLookupTable"; // Add new fields to the Streets feature class AddField addFieldTool = new AddField(); addFieldTool.in_table = outputFileGdbPath + "\\" + StreetsFCName; if (isDimensional) { addFieldTool.field_type = "DOUBLE"; } else if (isQuantitative) { addFieldTool.field_type = "SHORT"; } else { addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 1; } addFieldTool.field_name = "FT_" + newFieldNameBase; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "TF_" + newFieldNameBase; gp.Execute(addFieldTool, trackcancel); // Extract the information needed for this field from the CndMod table string extractTablePath = outputFileGdbPath + "\\cndModExtract"; AddMessage("Extracting information for the " + newFieldNameBase + " fields...", messages, trackcancel); string cndModTablePath = outputFileGdbPath + "\\" + cndModTableName; TableSelect tableSelectTool = new TableSelect(); tableSelectTool.in_table = cndModTablePath; tableSelectTool.out_table = extractTablePath; tableSelectTool.where_clause = queryExpression; gp.Execute(tableSelectTool, trackcancel); // Create LINK_ID and Direction fields on the extract table addFieldTool = new AddField(); addFieldTool.in_table = extractTablePath; addFieldTool.field_name = "LINK_ID"; addFieldTool.field_type = "LONG"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "Direction"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 2; gp.Execute(addFieldTool, trackcancel); // Copy over the LINK_ID values to the extract table MakeTableView makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = extractTablePath; makeTableViewTool.out_view = "cndModExtract_View"; gp.Execute(makeTableViewTool, trackcancel); AddJoin addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "cndModExtract_View"; addJoinTool.in_field = "COND_ID"; addJoinTool.join_table = outputFileGdbPath + "\\" + linkIDLookupTableName; addJoinTool.join_field = "COND_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Looking up LINK_ID values for the " + newFieldNameBase + " fields...", messages, trackcancel); CalculateField calcFieldTool = new CalculateField(); calcFieldTool.in_table = "cndModExtract_View"; calcFieldTool.field = "cndModExtract.LINK_ID"; calcFieldTool.expression = "[" + linkIDLookupTableName + ".LINK_ID]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); RemoveJoin removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "cndModExtract_View"; removeJoinTool.join_name = linkIDLookupTableName; gp.Execute(removeJoinTool, trackcancel); // Calculate the Direction values in the extract table addJoinTool.in_layer_or_view = "cndModExtract_View"; addJoinTool.in_field = "COND_ID"; addJoinTool.join_table = outputFileGdbPath + "\\" + directionLookupTableName; addJoinTool.join_field = "COND_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Looking up direction values for the " + newFieldNameBase + " fields...", messages, trackcancel); calcFieldTool.in_table = "cndModExtract_View"; calcFieldTool.field = "cndModExtract.Direction"; if (isPreferred) calcFieldTool.code_block = "dir = \"\"\nSelect Case [" + directionLookupTableName + ".MOD_VAL]\n" + " Case \"1\": dir = \"FT\"\n Case \"2\": dir = \"TF\"\n Case \"3\": dir = \"B\"\nEnd Select"; else calcFieldTool.code_block = "dir = \"\"\nSelect Case [" + directionLookupTableName + ".MOD_VAL]\n" + " Case \"1\": dir = \"B\"\n Case \"2\": dir = \"FT\"\n Case \"3\": dir = \"TF\"\nEnd Select"; calcFieldTool.expression = "dir"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool.in_layer_or_view = "cndModExtract_View"; removeJoinTool.join_name = directionLookupTableName; gp.Execute(removeJoinTool, trackcancel); Delete deleteTool = new Delete(); deleteTool.in_data = "cndModExtract_View"; gp.Execute(deleteTool, trackcancel); AddMessage("Indexing the LINK_ID lookup values...", messages, trackcancel); AddIndex addIndexTool = new AddIndex(); addIndexTool.fields = "LINK_ID"; addIndexTool.index_name = "LINK_ID"; addIndexTool.in_table = extractTablePath; gp.Execute(addIndexTool, trackcancel); // Calculate the preferred route/restriction fields addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = extractTablePath; addJoinTool.join_field = "LINK_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.expression_type = "VB"; string fieldVal = isDimensional ? "[cndModExtract.MetersOrKilogramsOrKPH]" : (isQuantitative ? "CInt( [cndModExtract.MOD_VAL] )" : "\"Y\""); AddMessage("Calculating the FT_" + newFieldNameBase + " field...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".FT_" + newFieldNameBase; calcFieldTool.code_block = "Select Case [cndModExtract.Direction]\n" + " Case \"FT\", \"B\": val = " + fieldVal + "\n Case Else: val = Null\nEnd Select"; calcFieldTool.expression = "val"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the TF_" + newFieldNameBase + " field...", messages, trackcancel); calcFieldTool.field = StreetsFCName + ".TF_" + newFieldNameBase; calcFieldTool.code_block = "Select Case [cndModExtract.Direction]\n" + " Case \"TF\", \"B\": val = " + fieldVal + "\n Case Else: val = Null\nEnd Select"; calcFieldTool.expression = "val"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "cndModExtract"; gp.Execute(removeJoinTool, trackcancel); deleteTool.in_data = extractTablePath; gp.Execute(deleteTool, trackcancel); }
public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages messages) { // Remember the original GP environment settings and temporarily override these settings var gpSettings = envMgr as IGeoProcessorSettings; bool origAddOutputsToMapSetting = gpSettings.AddOutputsToMap; bool origLogHistorySetting = gpSettings.LogHistory; gpSettings.AddOutputsToMap = false; gpSettings.LogHistory = false; // Create the Geoprocessor Geoprocessor gp = new Geoprocessor(); try { // Validate our values IGPMessages validateMessages = ((IGPFunction2)this).Validate(paramvalues, false, envMgr); if ((validateMessages as IGPMessage).IsError()) { messages.AddError(1, "Validate failed"); return; } // Unpack values IGPParameter gpParam = paramvalues.get_Element(InputMtdDSTTable) as IGPParameter; IGPValue inputMtdDSTTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputMtdCntryRefTable) as IGPParameter; IGPValue inputMtdCntryRefTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputMtdAreaTable) as IGPParameter; IGPValue inputMtdAreaTableValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputAdminBndyFeatureClasses) as IGPParameter; var inputAdminBndyFeatureClassesMultiValue = m_gpUtils.UnpackGPValue(gpParam) as IGPMultiValue; gpParam = paramvalues.get_Element(OutputFileGDB) as IGPParameter; IGPValue outputFileGDBValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputStreetsFeatureClass) as IGPParameter; IGPValue inputStreetsFeatureClassValue = m_gpUtils.UnpackGPValue(gpParam); gpParam = paramvalues.get_Element(InputTimeZoneIDBaseFieldName) as IGPParameter; IGPValue inputTimeZoneIDBaseFieldNameValue = m_gpUtils.UnpackGPValue(gpParam); bool processStreetsFC = (!(inputStreetsFeatureClassValue.IsEmpty())); string timeZoneIDBaseFieldName = ""; if (!(inputTimeZoneIDBaseFieldNameValue.IsEmpty())) timeZoneIDBaseFieldName = inputTimeZoneIDBaseFieldNameValue.GetAsText(); // Get the path to the output file GDB string outputFileGdbPath = outputFileGDBValue.GetAsText(); // Create the new file geodatabase AddMessage("Creating the file geodatabase...", messages, trackcancel); int lastBackslash = outputFileGdbPath.LastIndexOf("\\"); CreateFileGDB createFGDBTool = new CreateFileGDB(); createFGDBTool.out_folder_path = outputFileGdbPath.Remove(lastBackslash); createFGDBTool.out_name = outputFileGdbPath.Substring(lastBackslash + 1); gp.Execute(createFGDBTool, trackcancel); // Copy the MtdDST table to the file geodatabase and add the ADMIN_LVL and AREACODE fields to it AddMessage("Copying the MtdDST table to the file geodatabase...", messages, trackcancel); TableToTable importTableTool = new TableToTable(); string inputMtdDSTTablePath = inputMtdDSTTableValue.GetAsText(); importTableTool.in_rows = inputMtdDSTTablePath; importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = "MtdDST"; importTableTool.field_mapping = "AREA_ID \"AREA_ID\" true true false 4 Long 0 0 ,First,#," + inputMtdDSTTablePath + ",AREA_ID,-1,-1;" + "TIME_ZONE \"TIME_ZONE\" true true false 4 Text 0 0 ,First,#," + inputMtdDSTTablePath + ",TIME_ZONE,-1,-1;" + "DST_EXIST \"DST_EXIST\" true true false 1 Text 0 0 ,First,#," + inputMtdDSTTablePath + ",DST_EXIST,-1,-1"; gp.Execute(importTableTool, trackcancel); string mtdDSTTablePath = outputFileGdbPath + "\\MtdDST"; AddField addFieldTool = new AddField(); addFieldTool.in_table = mtdDSTTablePath; addFieldTool.field_name = "ADMIN_LVL"; addFieldTool.field_type = "SHORT"; gp.Execute(addFieldTool, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = mtdDSTTablePath; addFieldTool.field_name = "AREACODE"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 76; gp.Execute(addFieldTool, trackcancel); // Copy the MtdArea table to the file geodatabase and index the AREA_ID field AddMessage("Copying the MtdArea table to the file geodatabase...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = inputMtdAreaTableValue.GetAsText(); importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = "MtdArea"; gp.Execute(importTableTool, trackcancel); string mtdAreaTablePath = outputFileGdbPath + "\\MtdArea"; AddIndex addIndexTool = new AddIndex(); addIndexTool.in_table = mtdAreaTablePath; addIndexTool.fields = "AREA_ID"; addIndexTool.index_name = "AREA_ID"; gp.Execute(addIndexTool, trackcancel); // Calculate the ADMIN_LVL and AREACODE fields on the MtdDST table MakeTableView makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = mtdDSTTablePath; makeTableViewTool.out_view = "MtdDST_Layer"; gp.Execute(makeTableViewTool, trackcancel); AddJoin addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "MtdDST_Layer"; addJoinTool.in_field = "AREA_ID"; addJoinTool.join_table = mtdAreaTablePath; addJoinTool.join_field = "AREA_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the ADMIN_LVL field...", messages, trackcancel); CalculateField calcFieldTool = new CalculateField(); calcFieldTool.in_table = "MtdDST_Layer"; calcFieldTool.field = "MtdDST.ADMIN_LVL"; calcFieldTool.expression = "[MtdArea.ADMIN_LVL]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the AREACODE field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "MtdDST_Layer"; calcFieldTool.field = "MtdDST.AREACODE"; calcFieldTool.code_block = "lvl = [MtdArea.ADMIN_LVL]\n" + "s = CStr([MtdArea.AREACODE_1])\n" + "If lvl >= 2 Then s = s & \".\" & CStr([MtdArea.AREACODE_2])\n" + "If lvl >= 3 Then s = s & \".\" & CStr([MtdArea.AREACODE_3])\n" + "If lvl >= 4 Then s = s & \".\" & CStr([MtdArea.AREACODE_4])\n" + "If lvl >= 5 Then s = s & \".\" & CStr([MtdArea.AREACODE_5])\n" + "If lvl >= 6 Then s = s & \".\" & CStr([MtdArea.AREACODE_6])\n" + "If lvl >= 7 Then s = s & \".\" & CStr([MtdArea.AREACODE_7])"; calcFieldTool.expression = "s"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); RemoveJoin removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "MtdDST_Layer"; removeJoinTool.join_name = "MtdArea"; gp.Execute(removeJoinTool, trackcancel); Delete deleteTool = new Delete(); deleteTool.in_data = "MtdDST_Layer"; gp.Execute(deleteTool, trackcancel); // Create the MtdDST# tables by admin levels and index the AREACODE field TableSelect tableSelectTool = null; for (int i = 1; i <= 7; i++) { string iAsString = Convert.ToString(i, System.Globalization.CultureInfo.InvariantCulture); AddMessage("Extracting level " + iAsString + " MtdDST rows...", messages, trackcancel); tableSelectTool = new TableSelect(); tableSelectTool.in_table = mtdDSTTablePath; tableSelectTool.out_table = mtdDSTTablePath + iAsString; tableSelectTool.where_clause = "ADMIN_LVL = " + iAsString; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = mtdDSTTablePath + iAsString; addIndexTool.fields = "AREACODE"; addIndexTool.index_name = "AREACODE"; gp.Execute(addIndexTool, trackcancel); } deleteTool = new Delete(); deleteTool.in_data = mtdDSTTablePath; gp.Execute(deleteTool, trackcancel); // Copy the MtdCntryRef table to the file geodatabase (use Statistics tool to remove duplicate rows) AddMessage("Copying the MtdCntryRef table to the file geodatabase...", messages, trackcancel); string inputMtdCntryRefTablePath = inputMtdCntryRefTableValue.GetAsText(); string mtdCntryRefTablePath = outputFileGdbPath + "\\MtdCntryRef"; Statistics statsTool = new Statistics(); statsTool.in_table = inputMtdCntryRefTablePath; statsTool.out_table = mtdCntryRefTablePath; statsTool.statistics_fields = "ISO_CODE COUNT"; statsTool.case_field = "GOVT_CODE;ISO_CODE;DRIVING_SD;ADMINLEVEL"; gp.Execute(statsTool, trackcancel); DeleteField deleteFieldTool = new DeleteField(); deleteFieldTool.in_table = mtdCntryRefTablePath; deleteFieldTool.drop_field = "FREQUENCY;COUNT_ISO_CODE"; gp.Execute(deleteFieldTool, trackcancel); // Index the GOVT_CODE field addIndexTool = new AddIndex(); addIndexTool.in_table = mtdCntryRefTablePath; addIndexTool.fields = "GOVT_CODE"; addIndexTool.index_name = "GOVT_CODE"; gp.Execute(addIndexTool, trackcancel); // Extract the top level (country) records from the MtdArea table and index the AREACODE_1 field AddMessage("Extracting the top-level rows from the MtdArea table...", messages, trackcancel); string mtdTopAreaTablePath = outputFileGdbPath + "\\TopArea"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = mtdAreaTablePath; tableSelectTool.out_table = mtdTopAreaTablePath; tableSelectTool.where_clause = "AREACODE_2 = 0 AND AREA_TYPE = 'B'"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = mtdTopAreaTablePath; addIndexTool.fields = "AREACODE_1"; addIndexTool.index_name = "AREACODE_1"; gp.Execute(addIndexTool, trackcancel); // Create and calculate the TOP_GOVT_CODE field on the MtdArea table addFieldTool = new AddField(); addFieldTool.in_table = mtdAreaTablePath; addFieldTool.field_name = "TOP_GOVT_CODE"; addFieldTool.field_type = "LONG"; gp.Execute(addFieldTool, trackcancel); makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = mtdAreaTablePath; makeTableViewTool.out_view = "MtdArea_Layer"; gp.Execute(makeTableViewTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "MtdArea_Layer"; addJoinTool.in_field = "AREACODE_1"; addJoinTool.join_table = mtdTopAreaTablePath; addJoinTool.join_field = "AREACODE_1"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the TOP_GOVT_CODE field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "MtdArea_Layer"; calcFieldTool.field = "MtdArea.TOP_GOVT_CODE"; calcFieldTool.expression = "[TopArea.GOVT_CODE]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "MtdArea_Layer"; removeJoinTool.join_name = "TopArea"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = mtdTopAreaTablePath; gp.Execute(deleteTool, trackcancel); // Create and calculate the ISO_CODE and DRIVING_SD string fields addFieldTool = new AddField(); addFieldTool.in_table = mtdAreaTablePath; addFieldTool.field_name = "ISO_CODE"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 3; gp.Execute(addFieldTool, trackcancel); addFieldTool = new AddField(); addFieldTool.in_table = mtdAreaTablePath; addFieldTool.field_name = "DRIVING_SD"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 1; gp.Execute(addFieldTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "MtdArea_Layer"; addJoinTool.in_field = "TOP_GOVT_CODE"; addJoinTool.join_table = mtdCntryRefTablePath; addJoinTool.join_field = "GOVT_CODE"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the ISO_CODE field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "MtdArea_Layer"; calcFieldTool.field = "MtdArea.ISO_CODE"; calcFieldTool.expression = "[MtdCntryRef.ISO_CODE]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the DRIVING_SD field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "MtdArea_Layer"; calcFieldTool.field = "MtdArea.DRIVING_SD"; calcFieldTool.expression = "[MtdCntryRef.DRIVING_SD]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "MtdArea_Layer"; removeJoinTool.join_name = "MtdCntryRef"; gp.Execute(removeJoinTool, trackcancel); // Create and calculate the FullAREACODE# string fields and the UTCOffset and DST fields addFieldTool = new AddField(); addFieldTool.in_table = mtdAreaTablePath; addFieldTool.field_type = "SHORT"; addFieldTool.field_name = "UTCOffset"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "DST"; gp.Execute(addFieldTool, trackcancel); string codeBlock = "lvl = [ADMIN_LVL]\ns = CStr([AREACODE_1])"; for (int i = 1; i <= 7; i++) { string iAsString = Convert.ToString(i, System.Globalization.CultureInfo.InvariantCulture); string iPlusOne = Convert.ToString(i+1, System.Globalization.CultureInfo.InvariantCulture); string fullAreaCodeFieldName = "FullAREACODE" + iAsString; addFieldTool = new AddField(); addFieldTool.in_table = mtdAreaTablePath; addFieldTool.field_name = fullAreaCodeFieldName; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 76; gp.Execute(addFieldTool, trackcancel); AddMessage("Calculating the FullAREACODE" + iAsString + " field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = mtdAreaTablePath; calcFieldTool.field = fullAreaCodeFieldName; calcFieldTool.code_block = codeBlock; calcFieldTool.expression = "s"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); codeBlock = codeBlock + "\nIf lvl >= " + iPlusOne + " Then s = s & \".\" & CStr([AREACODE_" + iPlusOne + "])"; string dstJoinTableName = "MtdDST" + iAsString; string dstJoinTablePath = outputFileGdbPath + "\\" + dstJoinTableName; addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "MtdArea_Layer"; addJoinTool.in_field = fullAreaCodeFieldName; addJoinTool.join_table = dstJoinTablePath; addJoinTool.join_field = "AREACODE"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the UTCOffset field (" + iAsString + " of 7)...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "MtdArea_Layer"; calcFieldTool.field = "MtdArea.UTCOffset"; calcFieldTool.code_block = "s = [MtdArea.UTCOffset]\n" + "joinValue = [" + dstJoinTableName + ".TIME_ZONE]\n" + "If Not IsNull(joinValue) Then\n" + " If Trim(joinValue) <> \"\" Then s = CInt(joinValue) * 6\n" + "End If"; calcFieldTool.expression = "s"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the DST field (" + iAsString + " of 7)...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "MtdArea_Layer"; calcFieldTool.field = "MtdArea.DST"; calcFieldTool.code_block = "s = [MtdArea.DST]\n" + "joinValue = [" + dstJoinTableName + ".DST_EXIST]\n" + "If Not IsNull(joinValue) Then\n" + " Select Case Trim(joinValue)\n" + " Case \"Y\": s = 1\n Case \"N\": s = 0\n" + " End Select\n" + "End If"; calcFieldTool.expression = "s"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "MtdArea_Layer"; removeJoinTool.join_name = dstJoinTableName; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = dstJoinTablePath; gp.Execute(deleteTool, trackcancel); } deleteTool = new Delete(); deleteTool.in_data = "MtdArea_Layer"; gp.Execute(deleteTool, trackcancel); // Create and calculate the sortable MSTIMEZONE field on the MtdArea table addFieldTool = new AddField(); addFieldTool.in_table = mtdAreaTablePath; addFieldTool.field_name = "SortableMSTIMEZONE"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 60; gp.Execute(addFieldTool, trackcancel); AddMessage("Calculating the time zones...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = mtdAreaTablePath; calcFieldTool.field = "SortableMSTIMEZONE"; calcFieldTool.code_block = TimeZoneUtilities.MakeSortableMSTIMEZONECode("ISO_CODE"); calcFieldTool.expression = "z"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); // Extract the MtdArea rows to be used for generating the time zone polygons and index the AREA_ID field string mtdAreaForTZPolysTablePath = outputFileGdbPath + "\\MtdAreaForTZPolys"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = mtdAreaTablePath; tableSelectTool.out_table = mtdAreaForTZPolysTablePath; tableSelectTool.where_clause = CreateWhereClauseForAdminLvlByCountry(outputFileGdbPath, "MtdCntryRef"); gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = mtdAreaForTZPolysTablePath; addIndexTool.fields = "AREA_ID"; addIndexTool.index_name = "AREA_ID"; gp.Execute(addIndexTool, trackcancel); // We no longer need the MtdCntryRef table anymore deleteTool = new Delete(); deleteTool.in_data = mtdCntryRefTablePath; gp.Execute(deleteTool, trackcancel); // Merge the AdminBndy feature classes together into one feature class int numAdminBndyFCs = inputAdminBndyFeatureClassesMultiValue.Count; string mergeToolInputs = ""; for (int i = 0; i < numAdminBndyFCs; i++) { mergeToolInputs = mergeToolInputs + inputAdminBndyFeatureClassesMultiValue.get_Value(i).GetAsText() + ";"; } mergeToolInputs = mergeToolInputs.Remove(mergeToolInputs.Length - 1); string adminBndyFCPath = outputFileGdbPath + "\\AdminBndy"; AddMessage("Merging the Administrative Boundary feature classes...", messages, trackcancel); Merge mergeTool = new Merge(); mergeTool.inputs = mergeToolInputs; mergeTool.output = adminBndyFCPath; gp.Execute(mergeTool, trackcancel); // Join the AdminBndy polygons to the MtdArea rows to be used for generating the time zone polygons MakeFeatureLayer makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = adminBndyFCPath; makeFeatureLayerTool.out_layer = "AdminBndy_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "AdminBndy_Layer"; addJoinTool.in_field = "AREA_ID"; addJoinTool.join_table = mtdAreaForTZPolysTablePath; addJoinTool.join_field = "AREA_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); FeatureClassToFeatureClass importFCTool = new FeatureClassToFeatureClass(); importFCTool.in_features = "AdminBndy_Layer"; importFCTool.out_path = outputFileGdbPath; importFCTool.out_name = "UndissolvedTZPolys"; importFCTool.field_mapping = "SortableMSTIMEZONE \"SortableMSTIMEZONE\" true true false 60 Text 0 0 ,First,#," + mtdAreaForTZPolysTablePath + ",MtdAreaForTZPolys.SortableMSTIMEZONE,-1,-1"; gp.Execute(importFCTool, trackcancel); string undissolvedTZPolysFCPath = outputFileGdbPath + "\\UndissolvedTZPolys"; removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "AdminBndy_Layer"; removeJoinTool.join_name = "MtdAreaForTZPolys"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "AdminBndy_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = adminBndyFCPath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = mtdAreaForTZPolysTablePath; gp.Execute(deleteTool, trackcancel); // Dissolve the time zone polygons together AddMessage("Dissolving the time zones...", messages, trackcancel); string timeZoneFCPath = outputFileGdbPath + "\\" + TimeZoneFCName; Dissolve dissolveTool = new Dissolve(); dissolveTool.in_features = undissolvedTZPolysFCPath; dissolveTool.out_feature_class = timeZoneFCPath; dissolveTool.dissolve_field = "SortableMSTIMEZONE"; dissolveTool.multi_part = "MULTI_PART"; gp.Execute(dissolveTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = undissolvedTZPolysFCPath; gp.Execute(deleteTool, trackcancel); // Create and calculate the MSTIMEZONE field addFieldTool = new AddField(); addFieldTool.in_table = timeZoneFCPath; addFieldTool.field_name = "MSTIMEZONE"; addFieldTool.field_type = "TEXT"; addFieldTool.field_length = 50; gp.Execute(addFieldTool, trackcancel); AddMessage("Calculating the time zones...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = timeZoneFCPath; calcFieldTool.field = "MSTIMEZONE"; calcFieldTool.expression = "Mid([SortableMSTIMEZONE], 7)"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); // Delete the old sortable MSTIMEZONE field deleteFieldTool = new DeleteField(); deleteFieldTool.in_table = timeZoneFCPath; deleteFieldTool.drop_field = "SortableMSTIMEZONE"; gp.Execute(deleteFieldTool, trackcancel); if (processStreetsFC) { // Create the network dataset time zone table AddMessage("Creating the time zones table...", messages, trackcancel); importTableTool = new TableToTable(); importTableTool.in_rows = timeZoneFCPath; importTableTool.out_path = outputFileGdbPath; importTableTool.out_name = TimeZonesTableName; importTableTool.field_mapping = "MSTIMEZONE \"MSTIMEZONE\" true true false 50 Text 0 0 ,First,#," + timeZoneFCPath + ",MSTIMEZONE,-1,-1"; gp.Execute(importTableTool, trackcancel); // Separate the MtdArea table by driving side and index the AREA_ID field on each AddMessage("Extracting rows for the left-side driving areas...", messages, trackcancel); string drivingLTablePath = mtdAreaTablePath + "DrivingL"; string drivingRTablePath = mtdAreaTablePath + "DrivingR"; tableSelectTool = new TableSelect(); tableSelectTool.in_table = mtdAreaTablePath; tableSelectTool.out_table = drivingLTablePath; tableSelectTool.where_clause = "DRIVING_SD = 'L'"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = drivingLTablePath; addIndexTool.fields = "AREA_ID"; addIndexTool.index_name = "AREA_ID"; gp.Execute(addIndexTool, trackcancel); AddMessage("Extracting rows for the right-side driving areas...", messages, trackcancel); tableSelectTool = new TableSelect(); tableSelectTool.in_table = mtdAreaTablePath; tableSelectTool.out_table = drivingRTablePath; tableSelectTool.where_clause = "DRIVING_SD = 'R'"; gp.Execute(tableSelectTool, trackcancel); addIndexTool = new AddIndex(); addIndexTool.in_table = drivingRTablePath; addIndexTool.fields = "AREA_ID"; addIndexTool.index_name = "AREA_ID"; gp.Execute(addIndexTool, trackcancel); // Import the Streets feature class to the file geodatabase and // add the FT_TimeZoneID and TF_TimeZoneID fields AddMessage("Copying the Streets feature class to the geodatabase...", messages, trackcancel); importFCTool = new FeatureClassToFeatureClass(); importFCTool.in_features = inputStreetsFeatureClassValue.GetAsText(); importFCTool.out_path = outputFileGdbPath; importFCTool.out_name = StreetsFCName; gp.Execute(importFCTool, trackcancel); string pathToStreetsFC = outputFileGdbPath + "\\" + StreetsFCName; addFieldTool = new AddField(); addFieldTool.in_table = pathToStreetsFC; addFieldTool.field_name = "FT_" + timeZoneIDBaseFieldName; addFieldTool.field_type = "SHORT"; gp.Execute(addFieldTool, trackcancel); addFieldTool.field_name = "TF_" + timeZoneIDBaseFieldName; addFieldTool.field_type = "SHORT"; gp.Execute(addFieldTool, trackcancel); // Calculate the TimeZoneID fields makeFeatureLayerTool = new MakeFeatureLayer(); makeFeatureLayerTool.in_features = pathToStreetsFC; makeFeatureLayerTool.out_layer = "Streets_Layer"; gp.Execute(makeFeatureLayerTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "R_AREA_ID"; addJoinTool.join_table = drivingLTablePath; addJoinTool.join_field = "AREA_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the FT_" + timeZoneIDBaseFieldName + " field for left driving side roads...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".FT_" + timeZoneIDBaseFieldName; calcFieldTool.code_block = TimeZoneUtilities.MakeTimeZoneIDCode(outputFileGdbPath, TimeZonesTableName, "MtdAreaDrivingL.SortableMSTIMEZONE"); calcFieldTool.expression = "tzID"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "MtdAreaDrivingL"; gp.Execute(removeJoinTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "L_AREA_ID"; addJoinTool.join_table = drivingRTablePath; addJoinTool.join_field = "AREA_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the FT_" + timeZoneIDBaseFieldName + " field for right driving side roads...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".FT_" + timeZoneIDBaseFieldName; calcFieldTool.code_block = TimeZoneUtilities.MakeTimeZoneIDCode(outputFileGdbPath, TimeZonesTableName, "MtdAreaDrivingR.SortableMSTIMEZONE"); calcFieldTool.expression = "tzID"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "MtdAreaDrivingR"; gp.Execute(removeJoinTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "L_AREA_ID"; addJoinTool.join_table = drivingLTablePath; addJoinTool.join_field = "AREA_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the TF_" + timeZoneIDBaseFieldName + " field for left driving side roads...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".TF_" + timeZoneIDBaseFieldName; calcFieldTool.code_block = TimeZoneUtilities.MakeTimeZoneIDCode(outputFileGdbPath, TimeZonesTableName, "MtdAreaDrivingL.SortableMSTIMEZONE"); calcFieldTool.expression = "tzID"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "MtdAreaDrivingL"; gp.Execute(removeJoinTool, trackcancel); addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "R_AREA_ID"; addJoinTool.join_table = drivingRTablePath; addJoinTool.join_field = "AREA_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the TF_" + timeZoneIDBaseFieldName + " field for right driving side roads...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".TF_" + timeZoneIDBaseFieldName; calcFieldTool.code_block = TimeZoneUtilities.MakeTimeZoneIDCode(outputFileGdbPath, TimeZonesTableName, "MtdAreaDrivingR.SortableMSTIMEZONE"); calcFieldTool.expression = "tzID"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "MtdAreaDrivingR"; gp.Execute(removeJoinTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = "Streets_Layer"; gp.Execute(deleteTool, trackcancel); deleteTool = new Delete(); deleteTool.in_data = drivingLTablePath; gp.Execute(deleteTool, trackcancel); deleteTool.in_data = drivingRTablePath; gp.Execute(deleteTool, trackcancel); } else { // Create a dummy TimeZones table and a dummy Streets feature class CreateTable createTableTool = new CreateTable(); createTableTool.out_path = outputFileGdbPath; createTableTool.out_name = TimeZonesTableName; gp.Execute(createTableTool, trackcancel); CreateFeatureclass createFCTool = new CreateFeatureclass(); createFCTool.out_path = outputFileGdbPath; createFCTool.out_name = StreetsFCName; createFCTool.geometry_type = "POLYLINE"; gp.Execute(createFCTool, trackcancel); } deleteTool = new Delete(); deleteTool.in_data = mtdAreaTablePath; gp.Execute(deleteTool, trackcancel); // Compact the output file geodatabase AddMessage("Compacting the output file geodatabase...", messages, trackcancel); Compact compactTool = new Compact(); compactTool.in_workspace = outputFileGdbPath; gp.Execute(compactTool, trackcancel); } catch (Exception e) { if (gp.MaxSeverity == 2) { object missing = System.Type.Missing; messages.AddError(1, gp.GetMessages(ref missing)); } messages.AddError(1, e.Message); messages.AddError(1, e.StackTrace); } finally { // Restore the original GP environment settings gpSettings.AddOutputsToMap = origAddOutputsToMapSetting; gpSettings.LogHistory = origLogHistorySetting; } GC.Collect(); return; }
private void CreateAndPopulateTruckFCOverrideField(string outputFileGdbPath, Geoprocessor gp, IGPMessages messages, ITrackCancel trackcancel) { // Add the TruckFCOverride field to the Streets feature class AddField addFieldTool = new AddField(); addFieldTool.in_table = outputFileGdbPath + "\\" + StreetsFCName; addFieldTool.field_name = "TruckFCOverride"; addFieldTool.field_type = "SHORT"; gp.Execute(addFieldTool, trackcancel); string extractTablePath = outputFileGdbPath + "\\cndModExtract"; string cndModTablePath = outputFileGdbPath + "\\nonDimensionalCndMod"; for (short fc = 2; fc >= 1; fc--) { string fcAsString = Convert.ToString(fc, System.Globalization.CultureInfo.InvariantCulture); // Extract the FC Override information from the CndMod table AddMessage("Extracting the FC " + fcAsString + " Override information...", messages, trackcancel); TableSelect tableSelectTool = new TableSelect(); tableSelectTool.in_table = cndModTablePath; tableSelectTool.out_table = extractTablePath; tableSelectTool.where_clause = "MOD_TYPE = 49 AND MOD_VAL = '" + Convert.ToString(fc + 14, System.Globalization.CultureInfo.InvariantCulture) + "'"; gp.Execute(tableSelectTool, trackcancel); // Create the LINK_ID field on the extract table addFieldTool = new AddField(); addFieldTool.in_table = extractTablePath; addFieldTool.field_name = "LINK_ID"; addFieldTool.field_type = "LONG"; gp.Execute(addFieldTool, trackcancel); // Copy over the LINK_ID values to the extract table MakeTableView makeTableViewTool = new MakeTableView(); makeTableViewTool.in_table = extractTablePath; makeTableViewTool.out_view = "cndModExtract_View"; gp.Execute(makeTableViewTool, trackcancel); AddJoin addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "cndModExtract_View"; addJoinTool.in_field = "COND_ID"; addJoinTool.join_table = outputFileGdbPath + "\\preferredLinkIDLookupTable"; addJoinTool.join_field = "COND_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Looking up LINK_ID values for the FC " + fcAsString + " Override values...", messages, trackcancel); CalculateField calcFieldTool = new CalculateField(); calcFieldTool.in_table = "cndModExtract_View"; calcFieldTool.field = "cndModExtract.LINK_ID"; calcFieldTool.expression = "[preferredLinkIDLookupTable.LINK_ID]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); RemoveJoin removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "cndModExtract_View"; removeJoinTool.join_name = "preferredLinkIDLookupTable"; gp.Execute(removeJoinTool, trackcancel); Delete deleteTool = new Delete(); deleteTool.in_data = "cndModExtract_View"; gp.Execute(deleteTool, trackcancel); AddMessage("Indexing the LINK_ID lookup values...", messages, trackcancel); AddIndex addIndexTool = new AddIndex(); addIndexTool.fields = "LINK_ID"; addIndexTool.index_name = "LINK_ID"; addIndexTool.in_table = extractTablePath; gp.Execute(addIndexTool, trackcancel); // Populate the TruckFCOverride field with the FC Override values addJoinTool.in_layer_or_view = "Streets_Layer"; addJoinTool.in_field = "LINK_ID"; addJoinTool.join_table = extractTablePath; addJoinTool.join_field = "LINK_ID"; addJoinTool.join_type = "KEEP_COMMON"; gp.Execute(addJoinTool, trackcancel); AddMessage("Populating the TruckFCOverride field with FC " + fcAsString + " Override values...", messages, trackcancel); calcFieldTool.in_table = "Streets_Layer"; calcFieldTool.field = StreetsFCName + ".TruckFCOverride"; calcFieldTool.expression = fcAsString; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); removeJoinTool.in_layer_or_view = "Streets_Layer"; removeJoinTool.join_name = "cndModExtract"; gp.Execute(removeJoinTool, trackcancel); deleteTool.in_data = extractTablePath; gp.Execute(deleteTool, trackcancel); } }
/// <summary>IDisposable - dispose of open assets</summary> public void Dispose() { _xml = null; _osmDataset = null; _messages = null; _trackCancel = null; if (_edgeSources != null) { foreach (var efs in _edgeSources) ComReleaser.ReleaseCOMObject(efs); _edgeSources.Clear(); _edgeSources = null; } if (_junctionSources != null) { foreach (var jfs in _junctionSources) ComReleaser.ReleaseCOMObject(jfs); _junctionSources.Clear(); _junctionSources = null; } ComReleaser.ReleaseCOMObject(_turnSource); _turnSource = null; if (_networkAttrs != null) { foreach (var na in _networkAttrs) ComReleaser.ReleaseCOMObject(na); _networkAttrs.Clear(); _networkAttrs = null; } ComReleaser.ReleaseCOMObject(_networkDataset); _networkDataset = null; }
private void CreateAndPopulateTurnFeatureClass(string outputFileGdbPath, string fdsName, string ProhibRdmsTableName, string tempStatsTableName, IGPMessages messages, ITrackCancel trackcancel) { // Determine the number of AltID fields we need (one more than the MAX_SEQ_NUMBER value). Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory"); var wsf = Activator.CreateInstance(factoryType) as IWorkspaceFactory; var fws = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace; ITable tempStatsTable = fws.OpenTable(tempStatsTableName); short numAltIDFields = 2; if (tempStatsTable.RowCount(null) == 1) numAltIDFields = (short)(1 + (double)(tempStatsTable.GetRow(1).get_Value(tempStatsTable.FindField("MAX_SEQ_NUMBER")))); // Open the Rdms table and find the fields we need ITable rdmsTable = fws.OpenTable(ProhibRdmsTableName); int seqNumberField = rdmsTable.FindField("SEQ_NUMBER"); int linkIDFieldOnRdms = rdmsTable.FindField("LINK_ID"); int manLinkIDField = rdmsTable.FindField("MAN_LINKID"); int condIDFieldOnRdms = rdmsTable.FindField("COND_ID"); int endOfLkFieldOnRdms = rdmsTable.FindField("END_OF_LK"); // Create a temporary template feature class var fcd = new FeatureClassDescriptionClass() as IFeatureClassDescription; var ocd = fcd as IObjectClassDescription; var fieldsEdit = ocd.RequiredFields as IFieldsEdit; IField fieldOnRdmsTable = rdmsTable.Fields.get_Field(linkIDFieldOnRdms); // use the LINK_ID field as a template for the AltID fields for (short i = 1; i <= numAltIDFields; i++) { IFieldEdit newField = new FieldClass(); newField.Name_2 = "AltID" + i; newField.Precision_2 = fieldOnRdmsTable.Precision; newField.Scale_2 = fieldOnRdmsTable.Scale; newField.Type_2 = fieldOnRdmsTable.Type; fieldsEdit.AddField(newField as IField); } fieldOnRdmsTable = rdmsTable.Fields.get_Field(condIDFieldOnRdms); fieldsEdit.AddField(fieldOnRdmsTable); var fieldChk = new FieldCheckerClass() as IFieldChecker; IEnumFieldError enumFieldErr = null; IFields validatedFields = null; fieldChk.ValidateWorkspace = fws as IWorkspace; fieldChk.Validate(fieldsEdit as IFields, out enumFieldErr, out validatedFields); var tempFC = fws.CreateFeatureClass("TheTemplate", validatedFields, ocd.InstanceCLSID, ocd.ClassExtensionCLSID, esriFeatureType.esriFTSimple, fcd.ShapeFieldName, "") as IDataset; // Create the turn feature class from the template, then delete the template Geoprocessor gp = new Geoprocessor(); CreateTurnFeatureClass createTurnFCTool = new CreateTurnFeatureClass(); string pathToFds = outputFileGdbPath + "\\" + fdsName; createTurnFCTool.out_location = pathToFds; createTurnFCTool.out_feature_class_name = TurnFCName; createTurnFCTool.maximum_edges = numAltIDFields; createTurnFCTool.in_template_feature_class = outputFileGdbPath + "\\TheTemplate"; gp.Execute(createTurnFCTool, trackcancel); tempFC.Delete(); // Open the new turn feature class and find all the fields on it IFeatureClass turnFC = fws.OpenFeatureClass(TurnFCName); int[] altIDFields = new int[numAltIDFields]; int[] edgeFCIDFields = new int[numAltIDFields]; int[] edgeFIDFields = new int[numAltIDFields]; int[] edgePosFields = new int[numAltIDFields]; for (short i = 0; i < numAltIDFields; i++) { altIDFields[i] = turnFC.FindField("AltID" + (i + 1)); edgeFCIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FCID"); edgeFIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FID"); edgePosFields[i] = turnFC.FindField("Edge" + (i + 1) + "Pos"); } int edge1endField = turnFC.FindField("Edge1End"); int condIDFieldOnTurnFC = turnFC.FindField("COND_ID"); // Look up the FCID of the Streets feature class IFeatureClass streetsFC = fws.OpenFeatureClass(StreetsFCName); int streetsFCID = streetsFC.FeatureClassID; // Set up queries var ts = new TableSortClass() as ITableSort; ts.Fields = "COND_ID, SEQ_NUMBER"; ts.set_Ascending("COND_ID", true); ts.set_Ascending("SEQ_NUMBER", true); ts.QueryFilter = new QueryFilterClass(); ts.Table = rdmsTable; ts.Sort(null); ICursor rdmsCursor = ts.Rows; IFeatureCursor turnFCCursor = turnFC.Insert(true); IFeatureBuffer turnBuffer = turnFC.CreateFeatureBuffer(); // Write the field values to the turn feature class accordingly int numFeatures = 0; IRow rdmsRow = rdmsCursor.NextRow(); while (rdmsRow != null) { // Transfer the non-edge identifying field values to the buffer turnBuffer.set_Value(condIDFieldOnTurnFC, rdmsRow.get_Value(condIDFieldOnRdms)); // Write the Edge1End field value to the buffer switch ((string)(rdmsRow.get_Value(endOfLkFieldOnRdms))) { case "N": turnBuffer.set_Value(edge1endField, "Y"); break; case "R": turnBuffer.set_Value(edge1endField, "N"); break; default: break; // not expected } // Write the AltID values to the buffer turnBuffer.set_Value(altIDFields[0], rdmsRow.get_Value(linkIDFieldOnRdms)); short seq = (short)(rdmsRow.get_Value(seqNumberField)); short lastEntry; do { lastEntry = seq; turnBuffer.set_Value(altIDFields[lastEntry], rdmsRow.get_Value(manLinkIDField)); rdmsRow = rdmsCursor.NextRow(); if (rdmsRow == null) break; seq = (short)(rdmsRow.get_Value(seqNumberField)); } while (seq != 1); // Zero-out the unused fields for (int i = lastEntry + 1; i < numAltIDFields; i++) turnBuffer.set_Value(altIDFields[i], 0); // Write the FCID and Pos field values to the buffer for (short i = 0; i < numAltIDFields; i++) { int altID = (int)(turnBuffer.get_Value(altIDFields[i])); if (altID != 0) { turnBuffer.set_Value(edgeFCIDFields[i], streetsFCID); turnBuffer.set_Value(edgeFIDFields[i], 1); turnBuffer.set_Value(edgePosFields[i], 0.5); } else { turnBuffer.set_Value(edgeFCIDFields[i], 0); turnBuffer.set_Value(edgeFIDFields[i], 0); turnBuffer.set_Value(edgePosFields[i], 0); } } // Create the turn feature turnFCCursor.InsertFeature(turnBuffer); numFeatures++; if ((numFeatures % 100) == 0) { // check for user cancel if (trackcancel != null && !trackcancel.Continue()) throw (new COMException("Function cancelled.")); } } // Flush any outstanding writes to the turn feature class turnFCCursor.Flush(); messages.AddMessage("Updating the EdgeFID values..."); // Create a temporary network dataset for updating the EdgeFID values IDENetworkDataset dends = new DENetworkDatasetClass(); dends.SupportsTurns = true; dends.Buildable = true; (dends as IDataElement).Name = StreetsFCName; (dends as IDEGeoDataset).SpatialReference = (streetsFC as IGeoDataset).SpatialReference; IArray sourceArray = new ArrayClass(); var efs = new EdgeFeatureSourceClass() as IEdgeFeatureSource; (efs as INetworkSource).Name = StreetsFCName; efs.UsesSubtypes = false; efs.ClassConnectivityGroup = 1; efs.ClassConnectivityPolicy = esriNetworkEdgeConnectivityPolicy.esriNECPEndVertex; sourceArray.Add(efs); var tfs = new TurnFeatureSourceClass() as INetworkSource; tfs.Name = TurnFCName; sourceArray.Add(tfs); dends.Sources = sourceArray; var fdxc = fws.OpenFeatureDataset(fdsName) as IFeatureDatasetExtensionContainer; var dsCont = fdxc.FindExtension(esriDatasetType.esriDTNetworkDataset) as IDatasetContainer2; var tempNDS = dsCont.CreateDataset(dends as IDEDataset) as IDataset; // Set the EdgeFID field values by running UpdateByAlternateIDFields UpdateByAlternateIDFields updateByAltIDTool = new UpdateByAlternateIDFields(); updateByAltIDTool.in_network_dataset = pathToFds + "\\" + StreetsFCName; updateByAltIDTool.alternate_ID_field_name = "LINK_ID"; gp.Execute(updateByAltIDTool, trackcancel); // Delete the temporary network dataset tempNDS.Delete(); // Write the turn geometries TurnGeometryUtilities.WriteTurnGeometry(outputFileGdbPath, StreetsFCName, TurnFCName, numAltIDFields, 0.3, messages, trackcancel); // Index the turn geometries messages.AddMessage("Creating spatial index on the turn feature class..."); AddSpatialIndex addSpatialIndexTool = new AddSpatialIndex(); addSpatialIndexTool.in_features = pathToFds + "\\" + TurnFCName; gp.Execute(addSpatialIndexTool, trackcancel); return; }
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 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(); }
public static void WriteTurnGeometry(string outputFileGdbPath, string StreetsFCName, string TurnFCName, int numAltIDFields, double trimRatio, IGPMessages messages, ITrackCancel trackcancel) { messages.AddMessage("Writing turn geometries..."); // Open the feature classes in the file geodatabase Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory"); var wsf = Activator.CreateInstance(factoryType) as IWorkspaceFactory; var fws = wsf.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace; IFeatureClass streetsFC = fws.OpenFeatureClass(StreetsFCName); IFeatureClass turnFC = fws.OpenFeatureClass(TurnFCName); // Look up the Edge1End, EdgeFCID and EdgeFID fields on the turn feature class int edge1EndField = turnFC.FindField("Edge1End"); int[] edgeFCIDFields = new int[numAltIDFields]; int[] edgeFIDFields = new int[numAltIDFields]; for (int i = 0; i < numAltIDFields; i++) { edgeFCIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FCID"); edgeFIDFields[i] = turnFC.FindField("Edge" + (i + 1) + "FID"); } // Look up the FCID of the Streets feature class and open a random access cursor on it int streetsFCID = streetsFC.FeatureClassID; IRandomAccessCursor rac = (streetsFC as IRandomAccessTable).GetRandomRows("", true); // Create an update cursor on the turn feature class var qf = new QueryFilterClass() as IQueryFilter; IFeatureCursor featCursor = turnFC.Update(qf, false); IFeature turnFeat = null; int numFeatures = 0; double lastCurveLength = 0.0; while ((turnFeat = featCursor.NextFeature()) != null) { // Get the geometry of the first line in the turn, rotate and trim it var lineFeat = rac.GetRow((int)turnFeat.get_Value(edgeFIDFields[0])) as IFeature; var featCurve = lineFeat.ShapeCopy as ICurve; ICurve workingCurve = null; switch ((string)turnFeat.get_Value(edge1EndField)) { case "Y": featCurve.GetSubcurve(1.0 - trimRatio, 1.0, true, out workingCurve); break; case "N": featCurve.GetSubcurve(0.0, trimRatio, true, out workingCurve); workingCurve.ReverseOrientation(); break; default: messages.AddWarning("ERROR: Invalid Edge1End value! Turn OID: " + turnFeat.OID); break; } if (workingCurve == null) { continue; } // Create a new polyline and add the trimmed first line to it var segColl = new PolylineClass() as ISegmentCollection; segColl.AddSegmentCollection(workingCurve as ISegmentCollection); // Remember the last point of the curve IPoint lastCurveEnd = workingCurve.ToPoint; bool earlyExit = false; for (int i = 1; i < numAltIDFields; i++) { if ((int)turnFeat.get_Value(edgeFCIDFields[i]) != streetsFCID) { // This was the last part of the turn -- break out and finalize the geometry break; } // Otherwise get the geometry of this line in the turn, rotate it if necessary, // and add it to the segment collection lineFeat = rac.GetRow((int)turnFeat.get_Value(edgeFIDFields[i])) as IFeature; var poly = lineFeat.ShapeCopy as IPolycurve; bool splitHappened; int newPart, newSeg; poly.SplitAtDistance(0.5, true, false, out splitHappened, out newPart, out newSeg); featCurve = poly as ICurve; IPoint myPoint = featCurve.FromPoint; if (EqualPoints(myPoint, lastCurveEnd)) { segColl.AddSegmentCollection(featCurve as ISegmentCollection); } else { myPoint = featCurve.ToPoint; if (EqualPoints(myPoint, lastCurveEnd)) { featCurve.ReverseOrientation(); segColl.AddSegmentCollection(featCurve as ISegmentCollection); } else { messages.AddWarning("ERROR: Edge " + (i+1) + " is discontinuous with the previous curve! Turn OID: " + turnFeat.OID); earlyExit = true; break; } } // Remember the length of the last curve added, and the last point of the curve lastCurveLength = featCurve.Length; lastCurveEnd = featCurve.ToPoint; } // If the edges of the turn were read in successfully... if (!earlyExit) { // Trim the segment such that the last curve is the length of the trim ratio workingCurve = segColl as ICurve; workingCurve.GetSubcurve(0.0, workingCurve.Length - ((1.0 - trimRatio) * lastCurveLength), false, out featCurve); turnFeat.Shape = featCurve as IGeometry; // Write out the turn geometry and increment the count featCursor.UpdateFeature(turnFeat); numFeatures++; if ((numFeatures % 100) == 0) { // check for user cancel if (trackcancel != null && !trackcancel.Continue()) throw (new COMException("Function cancelled.")); } } } }
private void CreateSignposts(string 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 parseOSMDocument(string osmFileLocation, ref IGPMessages message, ref List<string> nodeList, ref List<string> wayList, ref List<string> relationList, ref List<string> downloadedDocuments, string baseURL, api apiCapabilities) { try { XmlSerializer nodeSerializer = new XmlSerializer(typeof(node)); XmlSerializer waySerializer = new XmlSerializer(typeof(way)); XmlSerializer relationSerializer = new XmlSerializer(typeof(relation)); string requestURL = String.Empty; using (System.Xml.XmlReader osmFileXmlReader = System.Xml.XmlReader.Create(osmFileLocation)) { osmFileXmlReader.MoveToContent(); while (osmFileXmlReader.Read()) { if (osmFileXmlReader.IsStartElement()) { if (osmFileXmlReader.Name == "node") { string currentNodeString = osmFileXmlReader.ReadOuterXml(); // turn the xml node representation into a node class representation node currentNode = nodeSerializer.Deserialize(new System.IO.StringReader(currentNodeString)) as node; if (!nodeList.Contains(currentNode.id)) { nodeList.Add(currentNode.id); } } else if (osmFileXmlReader.Name == "way") { string currentWayString = osmFileXmlReader.ReadOuterXml(); // turn the xml way representation into a way class representation way currentWay = waySerializer.Deserialize(new System.IO.StringReader(currentWayString)) as way; if (!wayList.Contains(currentWay.id)) { wayList.Add(currentWay.id); } //if (currentWay.nd != null) //{ // foreach (nd wayNd in currentWay.nd) // { // if (!nodeList.Contains(wayNd.@ref)) // { // string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_node"), wayNd.@ref); // message.AddMessage(resolveMessage); // requestURL = baseURL + "/api/0.6/node/" + wayNd.@ref + "/full"; // string nodeDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities); // parseOSMDocument(nodeDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities); // downloadedDocuments.Insert(1, nodeDownloadDocument); // } // } //} } else if (osmFileXmlReader.Name == "relation") { string currentRelationString = osmFileXmlReader.ReadOuterXml(); // turn the xml way representation into a way class representation relation currentRelation = relationSerializer.Deserialize(new System.IO.StringReader(currentRelationString)) as relation; if (!relationList.Contains(currentRelation.id)) { relationList.Add(currentRelation.id); } foreach (object relationItem in currentRelation.Items) { if (relationItem is member) { //if (((member)relationItem).type == memberType.node) //{ // string memberNodeID = ((member)relationItem).@ref; // if (!nodeList.Contains(memberNodeID)) // { // string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_node"), memberNodeID); // message.AddMessage(resolveMessage); // requestURL = baseURL + "/api/0.6/node/" + memberNodeID + "/full"; // string nodeDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities); // parseOSMDocument(nodeDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities); // downloadedDocuments.Insert(1, nodeDownloadDocument); // } //} if (((member)relationItem).type == memberType.way) { string memberWayID = ((member)relationItem).@ref; if (!wayList.Contains(memberWayID)) { string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_way"), memberWayID); message.AddMessage(resolveMessage); requestURL = baseURL + "/api/0.6/way/" + memberWayID + "/full"; string wayDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities); if (!String.IsNullOrEmpty(wayDownloadDocument)) { parseOSMDocument(wayDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities); downloadedDocuments.Insert(1, wayDownloadDocument); } } } else if (((member)relationItem).type == memberType.relation) { string memberRelationID = ((member)relationItem).@ref; if (!wayList.Contains(memberRelationID)) { string resolveMessage = string.Format(resourceManager.GetString("GPTools_OSMGPDownload_resolveid"), resourceManager.GetString("GPTools_OSM_relation"), memberRelationID); message.AddMessage(resolveMessage); requestURL = baseURL + "/api/0.6/relation/" + memberRelationID + "/full"; string relationDownloadDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities); if (!String.IsNullOrEmpty(relationDownloadDocument)) { parseOSMDocument(relationDownloadDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedDocuments, baseURL, apiCapabilities); downloadedDocuments.Insert(1, relationDownloadDocument); } } } } } } } } osmFileXmlReader.Close(); } } catch (Exception ex) { message.AddError(120051, ex.Message); } }
private void PopulateAverageSpeedAndBaseSpeedFields(string patternsTablePath, string day, Geoprocessor gp, IGPMessages messages, ITrackCancel trackcancel) { AddJoin addJoinTool = new AddJoin(); addJoinTool.in_layer_or_view = "Streets_Patterns_View"; addJoinTool.in_field = day; addJoinTool.join_table = patternsTablePath; addJoinTool.join_field = "PatternID"; gp.Execute(addJoinTool, trackcancel); AddMessage("Calculating the AverageSpeed_" + day + " field...", messages, trackcancel); CalculateField calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Patterns_View"; calcFieldTool.field = HistTrafficJoinTableName + ".AverageSpeed_" + day; calcFieldTool.expression = "[" + ProfilesTableName + ".AverageSpeed]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); AddMessage("Calculating the BaseSpeed_" + day + " field...", messages, trackcancel); calcFieldTool = new CalculateField(); calcFieldTool.in_table = "Streets_Patterns_View"; calcFieldTool.field = HistTrafficJoinTableName + ".BaseSpeed_" + day; calcFieldTool.expression = "[" + ProfilesTableName + ".BaseSpeed]"; calcFieldTool.expression_type = "VB"; gp.Execute(calcFieldTool, trackcancel); RemoveJoin removeJoinTool = new RemoveJoin(); removeJoinTool.in_layer_or_view = "Streets_Patterns_View"; removeJoinTool.join_name = ProfilesTableName; gp.Execute(removeJoinTool, trackcancel); return; }
private string downloadOSMDocument(ref IGPMessages message, string requestURL, api apiCapabilities) { string osmDownloadDocument = String.Empty; HttpWebResponse httpResponse = null; try { // OSM does not understand URL encoded query parameters HttpWebRequest httpClient = HttpWebRequest.Create(requestURL) as HttpWebRequest; httpClient = AssignProxyandCredentials(httpClient); // read the timeout parameter int secondsToTimeout = Convert.ToInt32(apiCapabilities.timeout.seconds); httpClient.Timeout = secondsToTimeout * 1000; httpResponse = httpClient.GetResponse() as HttpWebResponse; osmDownloadDocument = System.IO.Path.GetTempFileName(); using (System.IO.FileStream fileStream = new System.IO.FileStream(osmDownloadDocument, FileMode.Append, FileAccess.Write)) { using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream())) { UTF8Encoding encoding = new UTF8Encoding(); byte[] byteBuffer = encoding.GetBytes(streamReader.ReadToEnd()); fileStream.Write(byteBuffer, 0, byteBuffer.Length); } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); message.AddError(120009, ex.Message); if (ex is WebException) { WebException webException = ex as WebException; if (webException != null) { if (webException.Response != null) { string serverErrorMessage = webException.Response.Headers["Error"]; if (!String.IsNullOrEmpty(serverErrorMessage)) { message.AddError(120009, serverErrorMessage); } } } } } finally { if (httpResponse != null) { httpResponse.Close(); } } return osmDownloadDocument; }
/// <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 = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; // Prep to retrieve the users in the specified groups (if any were specified) string[] userNames = null; if (!string.IsNullOrEmpty(m_groupName)) { msgs.AddMessage("Users in group '" + m_groupName + "':"); string[] groupNameArray = new string[] { m_groupName }; userNames = configMgr.GetUserNamesForGroups(groupNameArray); } else { msgs.AddMessage("All users:"); userNames = new string[configMgr.Users.Count]; for (int i = 0; i < configMgr.Users.Count; i++) { userNames[i] = configMgr.Users.get_Item(i).UserName; } } // Sort the user list SortedList <string, string> sortedNames = new SortedList <string, string>(); foreach (string s in userNames) { sortedNames.Add(s, null); } // Retrieve the parameter in which the list of user names will be stored WmauParameterMap paramMap = new WmauParameterMap(paramValues); IGPParameter3 param = paramMap.GetParam(C_PARAM_USER_LIST); IGPParameterEdit3 paramEdit = paramMap.GetParamEdit(C_PARAM_USER_LIST); // Set up the multi-value objects IGPMultiValue mvValue = new GPMultiValueClass(); mvValue.MemberDataType = param.DataType; // Add the user list to the multivalue param foreach (string user in sortedNames.Keys) { msgs.AddMessage(" " + user); IGPString strVal = new GPStringClass(); strVal.Value = user; mvValue.AddValue(strVal as IGPValue); } paramEdit.Value = (IGPValue)mvValue; msgs.AddMessage(Properties.Resources.MSG_DONE); } catch (WmauException wmEx) { try { msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message); } catch { // Catch anything else that possibly happens } } catch (Exception ex) { try { WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR); msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message); } catch { // Catch anything else that possibly happens } } finally { // Release any COM objects here! } }