public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message) { IFeatureClass osmPointFeatureClass = null; IFeatureClass osmLineFeatureClass = null; IFeatureClass osmPolygonFeatureClass = null; OSMToolHelper osmToolHelper = null; try { DateTime syncTime = DateTime.Now; IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); osmToolHelper = new OSMToolHelper(); if (TrackCancel == null) { TrackCancel = new CancelTrackerClass(); } IGPParameter osmFileParameter = paramvalues.get_Element(in_osmFileNumber) as IGPParameter; IGPValue osmFileLocationString = gpUtilities3.UnpackGPValue(osmFileParameter) as IGPValue; // ensure that the specified file does exist bool osmFileExists = false; try { osmFileExists = System.IO.File.Exists(osmFileLocationString.GetAsText()); } catch (Exception ex) { message.AddError(120029, String.Format(resourceManager.GetString("GPTools_OSMGPMultiLoader_problemaccessingfile"), ex.Message)); return; } if (osmFileExists == false) { message.AddError(120030, String.Format(resourceManager.GetString("GPTools_OSMGPFileReader_osmfiledoesnotexist"), osmFileLocationString.GetAsText())); return; } long nodeCapacity = 0; long wayCapacity = 0; long relationCapacity = 0; // this assume a clean, tidy XML file - if this is not the case, there will by sync issues later on osmToolHelper.countOSMStuffFast(osmFileLocationString.GetAsText(), ref nodeCapacity, ref wayCapacity, ref relationCapacity, ref TrackCancel); if (nodeCapacity == 0 && wayCapacity == 0 && relationCapacity == 0) { return; } message.AddMessage(String.Format(resourceManager.GetString("GPTools_OSMGPMultiLoader_countedElements"), nodeCapacity, wayCapacity, relationCapacity)); // determine the number of threads to be used IGPEnvironment parallelProcessingFactorEnvironment = OSMToolHelper.getEnvironment(envMgr, "parallelProcessingFactor"); IGPString parallelProcessingFactorString = parallelProcessingFactorEnvironment.Value as IGPString; // the default value is to use half the cores for additional threads - I am aware that we are comparing apples and oranges but I need a number int numberOfThreads = Convert.ToInt32(System.Environment.ProcessorCount / 2); if (!(parallelProcessingFactorEnvironment.Value.IsEmpty())) { if (!Int32.TryParse(parallelProcessingFactorString.Value, out numberOfThreads)) { // this case we have a percent string string resultString = Regex.Match(parallelProcessingFactorString.Value, @"\d+").Value; numberOfThreads = Convert.ToInt32(Int32.Parse(resultString) / 100 * System.Environment.ProcessorCount); } } // tread the special case of 0 if (numberOfThreads <= 0) numberOfThreads = 1; IGPEnvironment configKeyword = OSMToolHelper.getEnvironment(envMgr, "configKeyword"); IGPString gpString = configKeyword.Value as IGPString; string storageKeyword = String.Empty; if (gpString != null) { storageKeyword = gpString.Value; } // determine the temp folder to be use for the intermediate files IGPEnvironment scratchWorkspaceEnvironment = OSMToolHelper.getEnvironment(envMgr, "scratchWorkspace"); IDEWorkspace deWorkspace = scratchWorkspaceEnvironment.Value as IDEWorkspace; String scratchWorkspaceFolder = String.Empty; if (deWorkspace != null) { if (scratchWorkspaceEnvironment.Value.IsEmpty()) { scratchWorkspaceFolder = (new System.IO.FileInfo(osmFileLocationString.GetAsText())).DirectoryName; } else { if (deWorkspace.WorkspaceType == esriWorkspaceType.esriRemoteDatabaseWorkspace) { scratchWorkspaceFolder = System.IO.Path.GetTempPath(); } else if (deWorkspace.WorkspaceType == esriWorkspaceType.esriFileSystemWorkspace) { scratchWorkspaceFolder = ((IDataElement)deWorkspace).CatalogPath; } else { scratchWorkspaceFolder = (new System.IO.FileInfo(((IDataElement)deWorkspace).CatalogPath)).DirectoryName; } } } else { scratchWorkspaceFolder = (new System.IO.FileInfo(osmFileLocationString.GetAsText())).DirectoryName; } string metadataAbstract = resourceManager.GetString("GPTools_OSMGPFileReader_metadata_abstract"); string metadataPurpose = resourceManager.GetString("GPTools_OSMGPFileReader_metadata_purpose"); IGPParameter osmPointsFeatureClassParameter = paramvalues.get_Element(out_osmPointsNumber) as IGPParameter; IGPValue osmPointsFeatureClassGPValue = gpUtilities3.UnpackGPValue(osmPointsFeatureClassParameter) as IGPValue; IName workspaceName = gpUtilities3.CreateParentFromCatalogPath(osmPointsFeatureClassGPValue.GetAsText()); IWorkspace2 pointFeatureWorkspace = workspaceName.Open() as IWorkspace2; string[] pointFCNameElements = osmPointsFeatureClassGPValue.GetAsText().Split(System.IO.Path.DirectorySeparatorChar); IGPParameter tagPointCollectionParameter = paramvalues.get_Element(in_pointFieldNamesNumber) as IGPParameter; IGPMultiValue tagPointCollectionGPValue = gpUtilities3.UnpackGPValue(tagPointCollectionParameter) as IGPMultiValue; List<String> pointTagstoExtract = null; if (tagPointCollectionGPValue.Count > 0) { pointTagstoExtract = new List<string>(); for (int valueIndex = 0; valueIndex < tagPointCollectionGPValue.Count; valueIndex++) { string nameOfTag = tagPointCollectionGPValue.get_Value(valueIndex).GetAsText(); pointTagstoExtract.Add(nameOfTag); } } else { pointTagstoExtract = OSMToolHelper.OSMSmallFeatureClassFields(); } // points try { osmPointFeatureClass = osmToolHelper.CreateSmallPointFeatureClass(pointFeatureWorkspace, pointFCNameElements[pointFCNameElements.Length - 1], storageKeyword, metadataAbstract, metadataPurpose, pointTagstoExtract); } catch (Exception ex) { message.AddError(120035, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullpointfeatureclass"), ex.Message)); return; } if (osmPointFeatureClass == null) { return; } int osmPointIDFieldIndex = osmPointFeatureClass.FindField("OSMID"); Dictionary<string, int> mainPointAttributeFieldIndices = new Dictionary<string, int>(); foreach (string fieldName in OSMToolHelper.OSMSmallFeatureClassFields()) { int currentFieldIndex = osmPointFeatureClass.FindField(fieldName); if (currentFieldIndex != -1) { mainPointAttributeFieldIndices.Add(fieldName, currentFieldIndex); } } int tagCollectionPointFieldIndex = osmPointFeatureClass.FindField("osmTags"); int osmSupportingElementPointFieldIndex = osmPointFeatureClass.FindField("osmSupportingElement"); IGPParameter osmLineFeatureClassParameter = paramvalues.get_Element(out_osmLinesNumber) as IGPParameter; IGPValue osmLineFeatureClassGPValue = gpUtilities3.UnpackGPValue(osmLineFeatureClassParameter) as IGPValue; IName lineWorkspaceName = gpUtilities3.CreateParentFromCatalogPath(osmLineFeatureClassGPValue.GetAsText()); IWorkspace2 lineFeatureWorkspace = lineWorkspaceName.Open() as IWorkspace2; string[] lineFCNameElements = osmLineFeatureClassGPValue.GetAsText().Split(System.IO.Path.DirectorySeparatorChar); IGPParameter tagLineCollectionParameter = paramvalues.get_Element(in_lineFieldNamesNumber) as IGPParameter; IGPMultiValue tagLineCollectionGPValue = gpUtilities3.UnpackGPValue(tagLineCollectionParameter) as IGPMultiValue; List<String> lineTagstoExtract = null; if (tagLineCollectionGPValue.Count > 0) { lineTagstoExtract = new List<string>(); for (int valueIndex = 0; valueIndex < tagLineCollectionGPValue.Count; valueIndex++) { string nameOfTag = tagLineCollectionGPValue.get_Value(valueIndex).GetAsText(); lineTagstoExtract.Add(nameOfTag); } } else { lineTagstoExtract = OSMToolHelper.OSMSmallFeatureClassFields(); } // lines try { osmLineFeatureClass = osmToolHelper.CreateSmallLineFeatureClass(lineFeatureWorkspace, lineFCNameElements[lineFCNameElements.Length -1], storageKeyword, metadataAbstract, metadataPurpose, lineTagstoExtract); } catch (Exception ex) { message.AddError(120036, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nulllinefeatureclass"), ex.Message)); return; } if (osmLineFeatureClass == null) { return; } int osmLineIDFieldIndex = osmLineFeatureClass.FindField("OSMID"); Dictionary<string, int> mainLineAttributeFieldIndices = new Dictionary<string, int>(); foreach (string fieldName in OSMToolHelper.OSMSmallFeatureClassFields()) { int currentFieldIndex = osmLineFeatureClass.FindField(fieldName); if (currentFieldIndex != -1) { mainLineAttributeFieldIndices.Add(fieldName, currentFieldIndex); } } int tagCollectionPolylineFieldIndex = osmLineFeatureClass.FindField("osmTags"); int osmSupportingElementPolylineFieldIndex = osmLineFeatureClass.FindField("osmSupportingElement"); IGPParameter osmPolygonFeatureClassParameter = paramvalues.get_Element(out_osmPolygonsNumber) as IGPParameter; IGPValue osmPolygonFeatureClassGPValue = gpUtilities3.UnpackGPValue(osmPolygonFeatureClassParameter) as IGPValue; IName polygonWorkspaceName = gpUtilities3.CreateParentFromCatalogPath(osmPolygonFeatureClassGPValue.GetAsText()); IWorkspace2 polygonFeatureWorkspace = polygonWorkspaceName.Open() as IWorkspace2; string[] polygonFCNameElements = osmPolygonFeatureClassGPValue.GetAsText().Split(System.IO.Path.DirectorySeparatorChar); IGPParameter tagPolygonCollectionParameter = paramvalues.get_Element(in_polygonFieldNamesNumber) as IGPParameter; IGPMultiValue tagPolygonCollectionGPValue = gpUtilities3.UnpackGPValue(tagPolygonCollectionParameter) as IGPMultiValue; List<String> polygonTagstoExtract = null; if (tagPolygonCollectionGPValue.Count > 0) { polygonTagstoExtract = new List<string>(); for (int valueIndex = 0; valueIndex < tagPolygonCollectionGPValue.Count; valueIndex++) { string nameOfTag = tagPolygonCollectionGPValue.get_Value(valueIndex).GetAsText(); polygonTagstoExtract.Add(nameOfTag); } } else { polygonTagstoExtract = OSMToolHelper.OSMSmallFeatureClassFields(); } // polygons try { osmPolygonFeatureClass = osmToolHelper.CreateSmallPolygonFeatureClass(polygonFeatureWorkspace, polygonFCNameElements[polygonFCNameElements.Length -1], storageKeyword, metadataAbstract, metadataPurpose, polygonTagstoExtract); } catch (Exception ex) { message.AddError(120037, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullpolygonfeatureclass"), ex.Message)); return; } if (osmPolygonFeatureClass == null) { return; } int osmPolygonIDFieldIndex = osmPolygonFeatureClass.FindField("OSMID"); Dictionary<string, int> mainPolygonAttributeFieldIndices = new Dictionary<string, int>(); foreach (var fieldName in OSMToolHelper.OSMSmallFeatureClassFields()) { int currentFieldIndex = osmPolygonFeatureClass.FindField(fieldName); if (currentFieldIndex != -1) { mainPolygonAttributeFieldIndices.Add(fieldName, currentFieldIndex); } } int tagCollectionPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmTags"); int osmSupportingElementPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmSupportingElement"); ComReleaser.ReleaseCOMObject(osmPointFeatureClass); osmPointFeatureClass = null; ComReleaser.ReleaseCOMObject(osmLineFeatureClass); osmLineFeatureClass = null; ComReleaser.ReleaseCOMObject(osmPolygonFeatureClass); osmPolygonFeatureClass = null; List<string> nodeOSMFileNames = new List<string>(numberOfThreads); List<string> nodeGDBFileNames = new List<string>(numberOfThreads); List<string> wayOSMFileNames = new List<string>(numberOfThreads); List<string> wayGDBFileNames = new List<string>(numberOfThreads); List<string> relationOSMFileNames = new List<string>(numberOfThreads); List<string> relationGDBFileNames = new List<string>(numberOfThreads); if (TrackCancel.Continue() == false) { return; } // split the original OSM xml file into smaller pieces for the python processes osmToolHelper.splitOSMFile(osmFileLocationString.GetAsText(), scratchWorkspaceFolder, nodeCapacity, wayCapacity, relationCapacity, numberOfThreads, out nodeOSMFileNames, out nodeGDBFileNames, out wayOSMFileNames, out wayGDBFileNames, out relationOSMFileNames, out relationGDBFileNames); IGPParameter deleteSourceOSMFileParameter = paramvalues.get_Element(in_deleteOSMSourceFileNumber) as IGPParameter; IGPBoolean deleteSourceOSMFileGPValue = gpUtilities3.UnpackGPValue(deleteSourceOSMFileParameter) as IGPBoolean; if (deleteSourceOSMFileGPValue.Value) { try { System.IO.File.Delete(osmFileLocationString.GetAsText()); } catch (Exception ex) { message.AddWarning(ex.Message); } } if (TrackCancel.Continue() == false) { return; } if (nodeOSMFileNames.Count == 0) { nodeOSMFileNames.Add(osmFileLocationString.GetAsText()); nodeGDBFileNames.Add(osmPointsFeatureClassGPValue.GetAsText()); wayOSMFileNames.Add(osmFileLocationString.GetAsText()); wayGDBFileNames.Add(osmLineFeatureClassGPValue.GetAsText()); relationOSMFileNames.Add(osmFileLocationString.GetAsText()); relationGDBFileNames.Add(osmPolygonFeatureClassGPValue.GetAsText()); } else { // for the nodes let's load one of the parts directly into the target file geodatabase nodeGDBFileNames[0] = ((IWorkspace)pointFeatureWorkspace).PathName; } // define variables helping to invoke core tools for data management IGeoProcessorResult2 gpResults2 = null; IGeoProcessor2 geoProcessor = new GeoProcessorClass(); IGPParameter deleteSupportingNodesParameter = paramvalues.get_Element(in_deleteSupportNodesNumber) as IGPParameter; IGPBoolean deleteSupportingNodesGPValue = gpUtilities3.UnpackGPValue(deleteSupportingNodesParameter) as IGPBoolean; #region load points osmToolHelper.loadOSMNodes(nodeOSMFileNames, nodeGDBFileNames, pointFCNameElements[pointFCNameElements.Length - 1], osmPointsFeatureClassGPValue.GetAsText(), pointTagstoExtract, deleteSupportingNodesGPValue.Value, ref message, ref TrackCancel); #endregion if (TrackCancel.Continue() == false) { return; } #region load ways osmToolHelper.loadOSMWays(wayOSMFileNames, osmPointsFeatureClassGPValue.GetAsText(), wayGDBFileNames, lineFCNameElements[lineFCNameElements.Length - 1], polygonFCNameElements[polygonFCNameElements.Length - 1], lineTagstoExtract, polygonTagstoExtract, ref message, ref TrackCancel); #endregion #region for local geodatabases enforce spatial integrity bool storedOriginalLocal = geoProcessor.AddOutputsToMap; geoProcessor.AddOutputsToMap = false; try { osmLineFeatureClass = ((IFeatureWorkspace)lineFeatureWorkspace).OpenFeatureClass(lineFCNameElements[lineFCNameElements.Length - 1]); if (osmLineFeatureClass != null) { if (((IDataset)osmLineFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace) { gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; IGPParameter outLinesParameter = paramvalues.get_Element(out_osmLinesNumber) as IGPParameter; IGPValue lineFeatureClass = gpUtilities3.UnpackGPValue(outLinesParameter); DataManagementTools.RepairGeometry repairlineGeometry = new DataManagementTools.RepairGeometry(osmLineFeatureClass); IVariantArray repairGeometryParameterArray = new VarArrayClass(); repairGeometryParameterArray.Add(lineFeatureClass.GetAsText()); repairGeometryParameterArray.Add("DELETE_NULL"); gpResults2 = geoProcessor.Execute(repairlineGeometry.ToolName, repairGeometryParameterArray, TrackCancel) as IGeoProcessorResult2; message.AddMessages(gpResults2.GetResultMessages()); ComReleaser.ReleaseCOMObject(gpUtilities3); } } } catch { } finally { ComReleaser.ReleaseCOMObject(osmLineFeatureClass); } try { osmPolygonFeatureClass = ((IFeatureWorkspace)polygonFeatureWorkspace).OpenFeatureClass(polygonFCNameElements[polygonFCNameElements.Length - 1]); if (osmPolygonFeatureClass != null) { if (((IDataset)osmPolygonFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace) { gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; IGPParameter outPolygonParameter = paramvalues.get_Element(out_osmPolygonsNumber) as IGPParameter; IGPValue polygonFeatureClass = gpUtilities3.UnpackGPValue(outPolygonParameter); DataManagementTools.RepairGeometry repairpolygonGeometry = new DataManagementTools.RepairGeometry(osmPolygonFeatureClass); IVariantArray repairGeometryParameterArray = new VarArrayClass(); repairGeometryParameterArray.Add(polygonFeatureClass.GetAsText()); repairGeometryParameterArray.Add("DELETE_NULL"); gpResults2 = geoProcessor.Execute(repairpolygonGeometry.ToolName, repairGeometryParameterArray, TrackCancel) as IGeoProcessorResult2; message.AddMessages(gpResults2.GetResultMessages()); ComReleaser.ReleaseCOMObject(gpUtilities3); } } } catch { } finally { ComReleaser.ReleaseCOMObject(osmPolygonFeatureClass); } geoProcessor.AddOutputsToMap = storedOriginalLocal; #endregion if (TrackCancel.Continue() == false) { return; } #region load relations osmToolHelper.loadOSMRelations(relationOSMFileNames, osmLineFeatureClassGPValue.GetAsText(), osmPolygonFeatureClassGPValue.GetAsText(), relationGDBFileNames, lineTagstoExtract, polygonTagstoExtract, ref TrackCancel, ref message); #endregion // check for user interruption if (TrackCancel.Continue() == false) { return; } #region for local geodatabases enforce spatial integrity //storedOriginalLocal = geoProcessor.AddOutputsToMap; //geoProcessor.AddOutputsToMap = false; //try //{ // osmLineFeatureClass = ((IFeatureWorkspace)lineFeatureWorkspace).OpenFeatureClass(lineFCNameElements[lineFCNameElements.Length - 1]); // if (osmLineFeatureClass != null) // { // if (((IDataset)osmLineFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace) // { // gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; // IGPParameter outLinesParameter = paramvalues.get_Element(out_osmLinesNumber) as IGPParameter; // IGPValue lineFeatureClass = gpUtilities3.UnpackGPValue(outLinesParameter); // DataManagementTools.RepairGeometry repairlineGeometry = new DataManagementTools.RepairGeometry(osmLineFeatureClass); // IVariantArray repairGeometryParameterArray = new VarArrayClass(); // repairGeometryParameterArray.Add(lineFeatureClass.GetAsText()); // repairGeometryParameterArray.Add("DELETE_NULL"); // gpResults2 = geoProcessor.Execute(repairlineGeometry.ToolName, repairGeometryParameterArray, TrackCancel) as IGeoProcessorResult2; // message.AddMessages(gpResults2.GetResultMessages()); // ComReleaser.ReleaseCOMObject(gpUtilities3); // } // } //} //catch { } //finally //{ // ComReleaser.ReleaseCOMObject(osmLineFeatureClass); //} //try //{ // osmPolygonFeatureClass = ((IFeatureWorkspace)polygonFeatureWorkspace).OpenFeatureClass(polygonFCNameElements[polygonFCNameElements.Length - 1]); // if (osmPolygonFeatureClass != null) // { // if (((IDataset)osmPolygonFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace) // { // gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; // IGPParameter outPolygonParameter = paramvalues.get_Element(out_osmPolygonsNumber) as IGPParameter; // IGPValue polygonFeatureClass = gpUtilities3.UnpackGPValue(outPolygonParameter); // DataManagementTools.RepairGeometry repairpolygonGeometry = new DataManagementTools.RepairGeometry(osmPolygonFeatureClass); // IVariantArray repairGeometryParameterArray = new VarArrayClass(); // repairGeometryParameterArray.Add(polygonFeatureClass.GetAsText()); // repairGeometryParameterArray.Add("DELETE_NULL"); // gpResults2 = geoProcessor.Execute(repairpolygonGeometry.ToolName, repairGeometryParameterArray, TrackCancel) as IGeoProcessorResult2; // message.AddMessages(gpResults2.GetResultMessages()); // ComReleaser.ReleaseCOMObject(gpUtilities3); // } // } //} //catch { } //finally //{ // ComReleaser.ReleaseCOMObject(osmPolygonFeatureClass); //} //geoProcessor.AddOutputsToMap = storedOriginalLocal; #endregion if (TrackCancel.Continue() == false) { return; } if (deleteSupportingNodesGPValue.Value) { message.AddMessage(String.Format(resourceManager.GetString("GPTools_OSMGPMultiLoader_remove_supportNodes"))); storedOriginalLocal = geoProcessor.AddOutputsToMap; geoProcessor.AddOutputsToMap = false; // create a layer file to select the points that have attributes osmPointFeatureClass = ((IFeatureWorkspace)pointFeatureWorkspace).OpenFeatureClass(pointFCNameElements[pointFCNameElements.Length - 1]); IVariantArray makeFeatureLayerParameterArray = new VarArrayClass(); makeFeatureLayerParameterArray.Add(osmPointsFeatureClassGPValue.GetAsText()); string tempLayerFile = System.IO.Path.GetTempFileName(); makeFeatureLayerParameterArray.Add(tempLayerFile); makeFeatureLayerParameterArray.Add(String.Format("{0} = 'no'", osmPointFeatureClass.SqlIdentifier("osmSupportingElement"))); geoProcessor.Execute("MakeFeatureLayer_management", makeFeatureLayerParameterArray, TrackCancel); // copy the features into its own feature class IVariantArray copyFeatureParametersArray = new VarArrayClass(); copyFeatureParametersArray.Add(tempLayerFile); string tempFeatureClass = String.Join("\\", new string[] { ((IWorkspace)pointFeatureWorkspace).PathName, "t_" + pointFCNameElements[pointFCNameElements.Length - 1] }); copyFeatureParametersArray.Add(tempFeatureClass); geoProcessor.Execute("CopyFeatures_management", copyFeatureParametersArray, TrackCancel); // delete the temp file System.IO.File.Delete(tempLayerFile); // delete the original feature class IVariantArray deleteParameterArray = new VarArrayClass(); deleteParameterArray.Add(osmPointsFeatureClassGPValue.GetAsText()); geoProcessor.Execute("Delete_management", deleteParameterArray, TrackCancel); // rename the temp feature class back to the original IVariantArray renameParameterArray = new VarArrayClass(); renameParameterArray.Add(tempFeatureClass); renameParameterArray.Add(osmPointsFeatureClassGPValue.GetAsText()); geoProcessor.Execute("Rename_management", renameParameterArray, TrackCancel); geoProcessor.AddOutputsToMap = storedOriginalLocal; ComReleaser.ReleaseCOMObject(osmPointFeatureClass); ComReleaser.ReleaseCOMObject(geoProcessor); } gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; // repackage the feature class into their respective gp values IGPParameter pointFeatureClassParameter = paramvalues.get_Element(out_osmPointsNumber) as IGPParameter; IGPValue pointFeatureClassGPValue = gpUtilities3.UnpackGPValue(pointFeatureClassParameter); gpUtilities3.PackGPValue(pointFeatureClassGPValue, pointFeatureClassParameter); IGPParameter lineFeatureClassParameter = paramvalues.get_Element(out_osmLinesNumber) as IGPParameter; IGPValue line1FeatureClassGPValue = gpUtilities3.UnpackGPValue(lineFeatureClassParameter); gpUtilities3.PackGPValue(line1FeatureClassGPValue, lineFeatureClassParameter); IGPParameter polygonFeatureClassParameter = paramvalues.get_Element(out_osmPolygonsNumber) as IGPParameter; IGPValue polygon1FeatureClassGPValue = gpUtilities3.UnpackGPValue(polygonFeatureClassParameter); gpUtilities3.PackGPValue(polygon1FeatureClassGPValue, polygonFeatureClassParameter); ComReleaser.ReleaseCOMObject(osmFileLocationString); gpUtilities3.ReleaseInternals(); ComReleaser.ReleaseCOMObject(gpUtilities3); } catch (Exception ex) { message.AddError(120055, ex.Message); message.AddError(120055, ex.StackTrace); } finally { try { osmToolHelper = null; System.GC.Collect(); System.GC.WaitForPendingFinalizers(); } catch (Exception ex) { message.AddError(120056, ex.ToString()); } } }
public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message) { IFeatureClass osmPointFeatureClass = null; IFeatureClass osmLineFeatureClass = null; IFeatureClass osmPolygonFeatureClass = null; OSMToolHelper osmToolHelper = null; try { DateTime syncTime = DateTime.Now; IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); osmToolHelper = new OSMToolHelper(); if (TrackCancel == null) { TrackCancel = new CancelTrackerClass(); } IGPParameter osmFileParameter = paramvalues.get_Element(in_osmFileNumber) as IGPParameter; IGPValue osmFileLocationString = gpUtilities3.UnpackGPValue(osmFileParameter) as IGPValue; // ensure that the specified file does exist bool osmFileExists = false; try { osmFileExists = System.IO.File.Exists(osmFileLocationString.GetAsText()); } catch (Exception ex) { message.AddError(120029, String.Format(resourceManager.GetString("GPTools_OSMGPFileReader_problemaccessingfile"), ex.Message)); return; } if (osmFileExists == false) { message.AddError(120030, String.Format(resourceManager.GetString("GPTools_OSMGPFileReader_osmfiledoesnotexist"), osmFileLocationString.GetAsText())); return; } IGPParameter conserveMemoryParameter = paramvalues.get_Element(in_conserveMemoryNumber) as IGPParameter; IGPBoolean conserveMemoryGPValue = gpUtilities3.UnpackGPValue(conserveMemoryParameter) as IGPBoolean; if (conserveMemoryGPValue == null) { message.AddError(120031, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), conserveMemoryParameter.Name)); return; } message.AddMessage(resourceManager.GetString("GPTools_OSMGPFileReader_countingNodes")); long nodeCapacity = 0; long wayCapacity = 0; long relationCapacity = 0; Dictionary<esriGeometryType, List<string>> attributeTags = new Dictionary<esriGeometryType, List<string>>(); IGPParameter tagCollectionParameter = paramvalues.get_Element(in_attributeSelector) as IGPParameter; IGPMultiValue tagCollectionGPValue = gpUtilities3.UnpackGPValue(tagCollectionParameter) as IGPMultiValue; List<String> tagstoExtract = null; if (tagCollectionGPValue.Count > 0) { tagstoExtract = new List<string>(); for (int valueIndex = 0; valueIndex < tagCollectionGPValue.Count; valueIndex++) { string nameOfTag = tagCollectionGPValue.get_Value(valueIndex).GetAsText(); if (nameOfTag.ToUpper().Equals("ALL")) { tagstoExtract = new List<string>(); break; } else { tagstoExtract.Add(nameOfTag); } } } // if there is an "ALL" keyword then we scan for all tags, otherwise we only add the desired tags to the feature classes and do a 'quick' // count scan if (tagstoExtract != null) { if (tagstoExtract.Count > 0) { // if the number of tags is > 0 then do a simple feature count and take name tags names from the gp value osmToolHelper.countOSMStuff(osmFileLocationString.GetAsText(), ref nodeCapacity, ref wayCapacity, ref relationCapacity, ref TrackCancel); attributeTags.Add(esriGeometryType.esriGeometryPoint, tagstoExtract); attributeTags.Add(esriGeometryType.esriGeometryPolyline, tagstoExtract); attributeTags.Add(esriGeometryType.esriGeometryPolygon, tagstoExtract); } else { // the count should be zero if we encountered the "ALL" keyword // in this case count the features and create a list of unique tags attributeTags = osmToolHelper.countOSMCapacityAndTags(osmFileLocationString.GetAsText(), ref nodeCapacity, ref wayCapacity, ref relationCapacity, ref TrackCancel); } } else { // no tags we defined, hence we do a simple count and create an empty list indicating that no additional fields // need to be created osmToolHelper.countOSMStuff(osmFileLocationString.GetAsText(), ref nodeCapacity, ref wayCapacity, ref relationCapacity, ref TrackCancel); attributeTags.Add(esriGeometryType.esriGeometryPoint, new List<string>()); attributeTags.Add(esriGeometryType.esriGeometryPolyline, new List<string>()); attributeTags.Add(esriGeometryType.esriGeometryPolygon, new List<string>()); } if (nodeCapacity == 0 && wayCapacity == 0 && relationCapacity == 0) { return; } if (conserveMemoryGPValue.Value == false) { osmNodeDictionary = new Dictionary<string, OSMToolHelper.simplePointRef>(Convert.ToInt32(nodeCapacity)); } message.AddMessage(String.Format(resourceManager.GetString("GPTools_OSMGPFileReader_countedElements"), nodeCapacity, wayCapacity, relationCapacity)); // prepare the feature dataset and classes IGPParameter targetDatasetParameter = paramvalues.get_Element(out_targetDatasetNumber) as IGPParameter; IGPValue targetDatasetGPValue = gpUtilities3.UnpackGPValue(targetDatasetParameter); IDEDataset2 targetDEDataset2 = targetDatasetGPValue as IDEDataset2; if (targetDEDataset2 == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), targetDatasetParameter.Name)); return; } string targetDatasetName = ((IGPValue)targetDEDataset2).GetAsText(); IDataElement targetDataElement = targetDEDataset2 as IDataElement; IDataset targetDataset = gpUtilities3.OpenDatasetFromLocation(targetDataElement.CatalogPath); IName parentName = null; try { parentName = gpUtilities3.CreateParentFromCatalogPath(targetDataElement.CatalogPath); } catch { message.AddError(120033, resourceManager.GetString("GPTools_OSMGPFileReader_unable_to_create_fd")); return; } // test if the feature classes already exists, // if they do and the environments settings are such that an overwrite is not allowed we need to abort at this point IGeoProcessorSettings gpSettings = (IGeoProcessorSettings)envMgr; if (gpSettings.OverwriteOutput == true) { } else { if (gpUtilities3.Exists((IGPValue)targetDEDataset2) == true) { message.AddError(120032, String.Format(resourceManager.GetString("GPTools_OSMGPFileReader_basenamealreadyexists"), targetDataElement.Name)); return; } } // load the descriptions from which to derive the domain values OSMDomains availableDomains = null; // Reading the XML document requires a FileStream. System.Xml.XmlTextReader reader = null; string xmlDomainFile = ""; m_editorConfigurationSettings.TryGetValue("osmdomainsfilepath", out xmlDomainFile); if (System.IO.File.Exists(xmlDomainFile)) { reader = new System.Xml.XmlTextReader(xmlDomainFile); } if (reader == null) { message.AddError(120033, resourceManager.GetString("GPTools_OSMGPDownload_NoDomainConfigFile")); return; } System.Xml.Serialization.XmlSerializer domainSerializer = null; try { domainSerializer = new XmlSerializer(typeof(OSMDomains)); availableDomains = domainSerializer.Deserialize(reader) as OSMDomains; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); System.Diagnostics.Debug.WriteLine(ex.StackTrace); message.AddError(120034, ex.Message); return; } reader.Close(); message.AddMessage(resourceManager.GetString("GPTools_preparedb")); Dictionary<string, IDomain> codedValueDomains = new Dictionary<string, IDomain>(); foreach (var domain in availableDomains.domain) { ICodedValueDomain pointCodedValueDomain = new CodedValueDomainClass(); ((IDomain)pointCodedValueDomain).Name = domain.name + "_pt"; ((IDomain)pointCodedValueDomain).FieldType = esriFieldType.esriFieldTypeString; ICodedValueDomain lineCodedValueDomain = new CodedValueDomainClass(); ((IDomain)lineCodedValueDomain).Name = domain.name + "_ln"; ((IDomain)lineCodedValueDomain).FieldType = esriFieldType.esriFieldTypeString; ICodedValueDomain polygonCodedValueDomain = new CodedValueDomainClass(); ((IDomain)polygonCodedValueDomain).Name = domain.name + "_ply"; ((IDomain)polygonCodedValueDomain).FieldType = esriFieldType.esriFieldTypeString; for (int i = 0; i < domain.domainvalue.Length; i++) { for (int domainGeometryIndex = 0; domainGeometryIndex < domain.domainvalue[i].geometrytype.Length; domainGeometryIndex++) { switch (domain.domainvalue[i].geometrytype[domainGeometryIndex]) { case geometrytype.point: pointCodedValueDomain.AddCode(domain.domainvalue[i].value, domain.domainvalue[i].value); break; case geometrytype.line: lineCodedValueDomain.AddCode(domain.domainvalue[i].value, domain.domainvalue[i].value); break; case geometrytype.polygon: polygonCodedValueDomain.AddCode(domain.domainvalue[i].value, domain.domainvalue[i].value); break; default: break; } } } // add the domain tables to the domains collection codedValueDomains.Add(((IDomain)pointCodedValueDomain).Name, (IDomain)pointCodedValueDomain); codedValueDomains.Add(((IDomain)lineCodedValueDomain).Name, (IDomain)lineCodedValueDomain); codedValueDomains.Add(((IDomain)polygonCodedValueDomain).Name, (IDomain)polygonCodedValueDomain); } IWorkspaceDomains workspaceDomain = null; IFeatureWorkspace featureWorkspace = null; // if the target dataset already exists we can go ahead and QI to it directly if (targetDataset != null) { workspaceDomain = targetDataset.Workspace as IWorkspaceDomains; featureWorkspace = targetDataset.Workspace as IFeatureWorkspace; } else { // in case it doesn't exist yet we will open the parent (the workspace - geodatabase- itself) and // use it as a reference to create the feature dataset and the feature classes in it. IWorkspace newWorkspace = ((IName)parentName).Open() as IWorkspace; workspaceDomain = newWorkspace as IWorkspaceDomains; featureWorkspace = newWorkspace as IFeatureWorkspace; } foreach (var domain in codedValueDomains.Values) { IDomain testDomain = null; try { testDomain = workspaceDomain.get_DomainByName(domain.Name); } catch { } if (testDomain == null) { workspaceDomain.AddDomain(domain); } } // this determines the spatial reference as defined from the gp environment settings and the initial wgs84 SR ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass() as ISpatialReferenceFactory; ISpatialReference wgs84 = spatialReferenceFactory.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984) as ISpatialReference; ISpatialReference downloadSpatialReference = gpUtilities3.GetGPSpRefEnv(envMgr, wgs84, null, 0, 0, 0, 0, null); Marshal.ReleaseComObject(wgs84); Marshal.ReleaseComObject(spatialReferenceFactory); IGPEnvironment configKeyword = OSMGPDownload.getEnvironment(envMgr, "configKeyword"); IGPString gpString = configKeyword.Value as IGPString; string storageKeyword = String.Empty; if (gpString != null) { storageKeyword = gpString.Value; } IFeatureDataset targetFeatureDataset = null; if (gpUtilities3.Exists((IGPValue)targetDEDataset2)) { targetFeatureDataset = gpUtilities3.OpenDataset((IGPValue)targetDEDataset2) as IFeatureDataset; } else { targetFeatureDataset = featureWorkspace.CreateFeatureDataset(targetDataElement.Name, downloadSpatialReference); } downloadSpatialReference = ((IGeoDataset)targetFeatureDataset).SpatialReference; string metadataAbstract = resourceManager.GetString("GPTools_OSMGPFileReader_metadata_abstract"); string metadataPurpose = resourceManager.GetString("GPTools_OSMGPFileReader_metadata_purpose"); // assign the custom class extension for use with the OSM feature inspector UID osmClassUID = new UIDClass(); osmClassUID.Value = "{65CA4847-8661-45eb-8E1E-B2985CA17C78}"; // points try { osmPointFeatureClass = osmToolHelper.CreatePointFeatureClass((IWorkspace2)featureWorkspace, targetFeatureDataset, targetDataElement.Name + "_osm_pt", null, null, null, storageKeyword, availableDomains, metadataAbstract, metadataPurpose, attributeTags[esriGeometryType.esriGeometryPoint]); } catch (Exception ex) { message.AddError(120035, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullpointfeatureclass"), ex.Message)); return; } if (osmPointFeatureClass == null) { return; } // change the property set of the osm class extension to skip any change detection during the initial data load osmPointFeatureClass.RemoveOSMClassExtension(); 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"); // lines try { osmLineFeatureClass = osmToolHelper.CreateLineFeatureClass((IWorkspace2)featureWorkspace, targetFeatureDataset, targetDataElement.Name + "_osm_ln", null, null, null, storageKeyword, availableDomains, metadataAbstract, metadataPurpose, attributeTags[esriGeometryType.esriGeometryPolyline]); } catch (Exception ex) { message.AddError(120036, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nulllinefeatureclass"), ex.Message)); return; } if (osmLineFeatureClass == null) { return; } // change the property set of the osm class extension to skip any change detection during the initial data load osmLineFeatureClass.RemoveOSMClassExtension(); int osmLineIDFieldIndex = osmLineFeatureClass.FindField("OSMID"); Dictionary<string, int> osmLineDomainAttributeFieldIndices = new Dictionary<string, int>(); foreach (var domains in availableDomains.domain) { int currentFieldIndex = osmLineFeatureClass.FindField(domains.name); if (currentFieldIndex != -1) { osmLineDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex); } } 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"); // polygons try { osmPolygonFeatureClass = osmToolHelper.CreatePolygonFeatureClass((IWorkspace2)featureWorkspace, targetFeatureDataset, targetDataElement.Name + "_osm_ply", null, null, null, storageKeyword, availableDomains, metadataAbstract, metadataPurpose, attributeTags[esriGeometryType.esriGeometryPolygon]); } catch (Exception ex) { message.AddError(120037, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullpolygonfeatureclass"), ex.Message)); return; } if (osmPolygonFeatureClass == null) { return; } // change the property set of the osm class extension to skip any change detection during the initial data load osmPolygonFeatureClass.RemoveOSMClassExtension(); int osmPolygonIDFieldIndex = osmPolygonFeatureClass.FindField("OSMID"); Dictionary<string, int> osmPolygonDomainAttributeFieldIndices = new Dictionary<string, int>(); foreach (var domains in availableDomains.domain) { int currentFieldIndex = osmPolygonFeatureClass.FindField(domains.name); if (currentFieldIndex != -1) { osmPolygonDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex); } } 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"); // relation table ITable relationTable = null; try { relationTable = osmToolHelper.CreateRelationTable((IWorkspace2)featureWorkspace, targetDataElement.Name + "_osm_relation", null, storageKeyword, metadataAbstract, metadataPurpose); } catch (Exception ex) { message.AddError(120038, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullrelationtable"), ex.Message)); return; } if (relationTable == null) { return; } 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"); // revision table ITable revisionTable = null; try { revisionTable = osmToolHelper.CreateRevisionTable((IWorkspace2)featureWorkspace, targetDataElement.Name + "_osm_revision", null, storageKeyword); } catch (Exception ex) { message.AddError(120039, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullrevisiontable"), ex.Message)); return; } if (revisionTable == null) { return; } #region clean any existing data from loading targets ESRI.ArcGIS.Geoprocessing.IGeoProcessor2 gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass(); IGeoProcessorResult gpResult = new GeoProcessorResultClass(); try { IVariantArray truncateParameters = new VarArrayClass(); truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_pt"); gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel); truncateParameters = new VarArrayClass(); truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_ln"); gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel); truncateParameters = new VarArrayClass(); truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_ply"); gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel); truncateParameters = new VarArrayClass(); truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "_osm_relation"); gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel); truncateParameters = new VarArrayClass(); truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "_osm_revision"); gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel); } catch (Exception ex) { message.AddWarning(ex.Message); } #endregion bool fastLoad = false; //// check for user interruption //if (TrackCancel.Continue() == false) //{ // message.AddAbort(resourceManager.GetString("GPTools_toolabort")); // return; //} //IFeatureCursor deleteCursor = null; //using (ComReleaser comReleaser = new ComReleaser()) //{ // // let's make sure that we clean out any old data that might have existed in the feature classes // deleteCursor = osmPointFeatureClass.Update(null, false); // comReleaser.ManageLifetime(deleteCursor); // for (IFeature feature = deleteCursor.NextFeature(); feature != null; feature = deleteCursor.NextFeature()) // { // feature.Delete(); // // check for user interruption // if (TrackCancel.Continue() == false) // { // message.AddAbort(resourceManager.GetString("GPTools_toolabort")); // return; // } // } //} //using (ComReleaser comReleaser = new ComReleaser()) //{ // deleteCursor = osmLineFeatureClass.Update(null, false); // comReleaser.ManageLifetime(deleteCursor); // for (IFeature feature = deleteCursor.NextFeature(); feature != null; feature = deleteCursor.NextFeature()) // { // feature.Delete(); // // check for user interruption // if (TrackCancel.Continue() == false) // { // message.AddAbort(resourceManager.GetString("GPTools_toolabort")); // return; // } // } //} //using (ComReleaser comReleaser = new ComReleaser()) //{ // deleteCursor = osmPolygonFeatureClass.Update(null, false); // comReleaser.ManageLifetime(deleteCursor); // for (IFeature feature = deleteCursor.NextFeature(); feature != null; feature = deleteCursor.NextFeature()) // { // feature.Delete(); // // check for user interruption // if (TrackCancel.Continue() == false) // { // message.AddAbort(resourceManager.GetString("GPTools_toolabort")); // return; // } // } //} //ICursor tableCursor = null; //using (ComReleaser comReleaser = new ComReleaser()) //{ // tableCursor = relationTable.Update(null, false); // comReleaser.ManageLifetime(tableCursor); // for (IRow row = tableCursor.NextRow(); row != null; row = tableCursor.NextRow()) // { // row.Delete(); // // check for user interruption // if (TrackCancel.Continue() == false) // { // message.AddAbort(resourceManager.GetString("GPTools_toolabort")); // return; // } // } //} //using (ComReleaser comReleaser = new ComReleaser()) //{ // tableCursor = revisionTable.Update(null, false); // comReleaser.ManageLifetime(tableCursor); // for (IRow row = tableCursor.NextRow(); row != null; row = tableCursor.NextRow()) // { // row.Delete(); // // check for user interruption // if (TrackCancel.Continue() == false) // { // message.AddAbort(resourceManager.GetString("GPTools_toolabort")); // return; // } // } //} // define variables helping to invoke core tools for data management IGeoProcessorResult2 gpResults2 = null; IGeoProcessor2 geoProcessor = new GeoProcessorClass(); #region load points osmToolHelper.loadOSMNodes(osmFileLocationString.GetAsText(), ref TrackCancel, ref message, targetDatasetGPValue, osmPointFeatureClass, conserveMemoryGPValue.Value, fastLoad, Convert.ToInt32(nodeCapacity), ref osmNodeDictionary, featureWorkspace, downloadSpatialReference, availableDomains, false); #endregion if (TrackCancel.Continue() == false) { return; } #region load ways List<string> missingWays = osmToolHelper.loadOSMWays(osmFileLocationString.GetAsText(), ref TrackCancel, ref message, targetDatasetGPValue, osmPointFeatureClass, osmLineFeatureClass, osmPolygonFeatureClass, conserveMemoryGPValue.Value, fastLoad, Convert.ToInt32(wayCapacity), ref osmNodeDictionary, featureWorkspace, downloadSpatialReference, availableDomains, false); #endregion if (downloadSpatialReference != null) Marshal.ReleaseComObject(downloadSpatialReference); #region for local geodatabases enforce spatial integrity bool storedOriginalLocal = geoProcessor.AddOutputsToMap; geoProcessor.AddOutputsToMap = false; if (osmLineFeatureClass != null) { if (((IDataset)osmLineFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace) { gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; IGPParameter outLinesParameter = paramvalues.get_Element(out_osmLinesNumber) as IGPParameter; IGPValue lineFeatureClass = gpUtilities3.UnpackGPValue(outLinesParameter); DataManagementTools.RepairGeometry repairlineGeometry = new DataManagementTools.RepairGeometry(osmLineFeatureClass); IVariantArray repairGeometryParameterArray = new VarArrayClass(); repairGeometryParameterArray.Add(lineFeatureClass.GetAsText()); repairGeometryParameterArray.Add("DELETE_NULL"); gpResults2 = geoProcessor.Execute(repairlineGeometry.ToolName, repairGeometryParameterArray, TrackCancel) as IGeoProcessorResult2; message.AddMessages(gpResults2.GetResultMessages()); ComReleaser.ReleaseCOMObject(gpUtilities3); } } if (osmPolygonFeatureClass != null) { if (((IDataset)osmPolygonFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace) { gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; IGPParameter outPolygonParameter = paramvalues.get_Element(out_osmPolygonsNumber) as IGPParameter; IGPValue polygonFeatureClass = gpUtilities3.UnpackGPValue(outPolygonParameter); DataManagementTools.RepairGeometry repairpolygonGeometry = new DataManagementTools.RepairGeometry(osmPolygonFeatureClass); IVariantArray repairGeometryParameterArray = new VarArrayClass(); repairGeometryParameterArray.Add(polygonFeatureClass.GetAsText()); repairGeometryParameterArray.Add("DELETE_NULL"); gpResults2 = geoProcessor.Execute(repairpolygonGeometry.ToolName, repairGeometryParameterArray, TrackCancel) as IGeoProcessorResult2; message.AddMessages(gpResults2.GetResultMessages()); ComReleaser.ReleaseCOMObject(gpUtilities3); } } geoProcessor.AddOutputsToMap = storedOriginalLocal; #endregion if (TrackCancel.Continue() == false) { return; } #region load relations List<string> missingRelations = osmToolHelper.loadOSMRelations(osmFileLocationString.GetAsText(), ref TrackCancel, ref message, targetDatasetGPValue, osmPointFeatureClass, osmLineFeatureClass, osmPolygonFeatureClass, Convert.ToInt32(relationCapacity), relationTable, availableDomains, fastLoad, false); #endregion // check for user interruption if (TrackCancel.Continue() == false) { return; } //storedOriginalLocal = geoProcessor.AddOutputsToMap; //try //{ // geoProcessor.AddOutputsToMap = false; // // add indexes for revisions // //IGPValue revisionTableGPValue = gpUtilities3.MakeGPValueFromObject(revisionTable); // string revisionTableString = targetDatasetGPValue.GetAsText() + System.IO.Path.DirectorySeparatorChar + ((IDataset)revisionTable).BrowseName; // IVariantArray parameterArrary2 = osmToolHelper.CreateAddIndexParameterArray(revisionTableString, "osmoldid;osmnewid", "osmID_IDX", "", ""); // gpResults2 = geoProcessor.Execute("AddIndex_management", parameterArrary2, TrackCancel) as IGeoProcessorResult2; // message.AddMessages(gpResults2.GetResultMessages()); //} //catch (Exception ex) //{ // message.AddWarning(ex.Message); //} //finally //{ // geoProcessor.AddOutputsToMap = storedOriginalLocal; //} #region update the references counts and member lists for nodes message.AddMessage(resourceManager.GetString("GPTools_OSMGPFileReader_updatereferences")); IFeatureCursor pointUpdateCursor = null; IQueryFilter pointQueryFilter = new QueryFilterClass(); // adjust of number of all other reference counter from 0 to 1 if (conserveMemoryGPValue.Value == true) { pointQueryFilter.WhereClause = osmPointFeatureClass.SqlIdentifier("wayRefCount") + " = 0"; pointQueryFilter.SubFields = osmPointFeatureClass.OIDFieldName + ",wayRefCount"; } using (SchemaLockManager ptLockManager = new SchemaLockManager(osmPointFeatureClass as ITable)) { using (ComReleaser comReleaser = new ComReleaser()) { int updateCount = 0; if (conserveMemoryGPValue.Value == true) { pointUpdateCursor = osmPointFeatureClass.Update(pointQueryFilter, false); updateCount = ((ITable)osmPointFeatureClass).RowCount(pointQueryFilter); } else { pointUpdateCursor = osmPointFeatureClass.Update(null, false); updateCount = ((ITable)osmPointFeatureClass).RowCount(null); } IStepProgressor stepProgressor = TrackCancel as IStepProgressor; if (stepProgressor != null) { stepProgressor.MinRange = 0; stepProgressor.MaxRange = updateCount; stepProgressor.Position = 0; stepProgressor.Message = resourceManager.GetString("GPTools_OSMGPFileReader_updatepointrefcount"); stepProgressor.StepValue = 1; stepProgressor.Show(); } comReleaser.ManageLifetime(pointUpdateCursor); IFeature pointFeature = pointUpdateCursor.NextFeature(); int positionCounter = 0; while (pointFeature != null) { positionCounter++; string nodeID = Convert.ToString(pointFeature.get_Value(osmPointIDFieldIndex)); if (conserveMemoryGPValue.Value == false) { // let get the reference counter from the internal node dictionary if (osmNodeDictionary[nodeID].RefCounter == 0) { pointFeature.set_Value(osmWayRefCountFieldIndex, 1); } else { pointFeature.set_Value(osmWayRefCountFieldIndex, osmNodeDictionary[nodeID].RefCounter); } } else { // in the case of memory conservation let's go change the 0s to 1s pointFeature.set_Value(osmWayRefCountFieldIndex, 1); } pointUpdateCursor.UpdateFeature(pointFeature); if (pointFeature != null) Marshal.ReleaseComObject(pointFeature); pointFeature = pointUpdateCursor.NextFeature(); if (stepProgressor != null) { stepProgressor.Position = positionCounter; } } if (stepProgressor != null) { stepProgressor.Hide(); } Marshal.ReleaseComObject(pointQueryFilter); } } #endregion if (osmNodeDictionary != null) { // clear outstanding resources potentially holding points osmNodeDictionary = null; System.GC.Collect(2, GCCollectionMode.Forced); } if (missingRelations.Count > 0) { missingRelations.Clear(); missingRelations = null; } if (missingWays.Count > 0) { missingWays.Clear(); missingWays = null; } SyncState.StoreLastSyncTime(targetDatasetName, syncTime); gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3; // repackage the feature class into their respective gp values IGPParameter pointFeatureClassParameter = paramvalues.get_Element(out_osmPointsNumber) as IGPParameter; IGPValue pointFeatureClassGPValue = gpUtilities3.UnpackGPValue(pointFeatureClassParameter); gpUtilities3.PackGPValue(pointFeatureClassGPValue, pointFeatureClassParameter); IGPParameter lineFeatureClassParameter = paramvalues.get_Element(out_osmLinesNumber) as IGPParameter; IGPValue line1FeatureClassGPValue = gpUtilities3.UnpackGPValue(lineFeatureClassParameter); gpUtilities3.PackGPValue(line1FeatureClassGPValue, lineFeatureClassParameter); IGPParameter polygonFeatureClassParameter = paramvalues.get_Element(out_osmPolygonsNumber) as IGPParameter; IGPValue polygon1FeatureClassGPValue = gpUtilities3.UnpackGPValue(polygonFeatureClassParameter); gpUtilities3.PackGPValue(polygon1FeatureClassGPValue, polygonFeatureClassParameter); ComReleaser.ReleaseCOMObject(relationTable); ComReleaser.ReleaseCOMObject(revisionTable); ComReleaser.ReleaseCOMObject(targetFeatureDataset); ComReleaser.ReleaseCOMObject(featureWorkspace); ComReleaser.ReleaseCOMObject(osmFileLocationString); ComReleaser.ReleaseCOMObject(conserveMemoryGPValue); ComReleaser.ReleaseCOMObject(targetDataset); gpUtilities3.ReleaseInternals(); ComReleaser.ReleaseCOMObject(gpUtilities3); } catch (Exception ex) { message.AddError(120055, ex.Message); message.AddError(120055, ex.StackTrace); } finally { try { // TE -- 1/7/2015 // this is a 'breaking' change as the default loader won't no longer enable the edit extension // the reasoning here is that most users would like the OSM in a 'read-only' fashion, and don't need to track // changes to be properly transmitted back to the OSM server //if (osmPointFeatureClass != null) //{ // osmPointFeatureClass.ApplyOSMClassExtension(); // ComReleaser.ReleaseCOMObject(osmPointFeatureClass); //} //if (osmLineFeatureClass != null) //{ // osmLineFeatureClass.ApplyOSMClassExtension(); // ComReleaser.ReleaseCOMObject(osmLineFeatureClass); //} //if (osmPolygonFeatureClass != null) //{ // osmPolygonFeatureClass.ApplyOSMClassExtension(); // ComReleaser.ReleaseCOMObject(osmPolygonFeatureClass); //} osmToolHelper = null; System.GC.Collect(); System.GC.WaitForPendingFinalizers(); } catch (Exception ex) { message.AddError(120056, ex.ToString()); } } }