public void UpdateMessages(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager pEnvMgr, ESRI.ArcGIS.Geodatabase.IGPMessages Messages) { IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); for (int i = 0; i < Messages.Count; i++) { IGPMessage blah = Messages.GetMessage(i); if (blah.IsError()) { IGPMessage something = new GPMessageClass(); something.Description = String.Empty; something.Type = esriGPMessageType.esriGPMessageTypeInformative; something.ErrorCode = 0; Messages.Replace(i, something); } } IGPParameter inputOSMParameter = paramvalues.get_Element(in_osmFeatureClassNumber) as IGPParameter; IGPValue inputOSMGPValue = gpUtilities3.UnpackGPValue(inputOSMParameter); if (inputOSMGPValue.IsEmpty() == false) { IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { gpUtilities3.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { gpUtilities3.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { return; } // find the field that holds tag binary/xml field int osmTagCollectionFieldIndex = osmInputTable.FindField("osmTags"); if (osmTagCollectionFieldIndex == -1) { Messages.ReplaceAbort(in_osmFeatureClassNumber, resourceManager.GetString("GPTools_OSMGPCombineAttributes_inputlayer_missingtagfield")); return; } } }
public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message) { _message = message; // classes to carry out the basic client/server communication HttpWebResponse httpResponse = null; string changeSetID = "-1"; IGPString baseURLGPString = new GPStringClass(); ICursor searchCursor = null; IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); if (TrackCancel == null) { TrackCancel = new CancelTrackerClass(); } IGPParameter userNameParameter = paramvalues.get_Element(in_userNameNumber) as IGPParameter; IGPString userNameGPValue = gpUtilities3.UnpackGPValue(userNameParameter) as IGPString; IHttpBasicGPValue userCredentialGPValue = new HttpBasicGPValue(); if (userNameGPValue != null) { userCredentialGPValue.UserName = userNameGPValue.Value; } else { return; } IGPParameter passwordParameter = paramvalues.get_Element(in_passwordNumber) as IGPParameter; IGPStringHidden passwordGPValue = gpUtilities3.UnpackGPValue(passwordParameter) as IGPStringHidden; if (passwordGPValue != null) { userCredentialGPValue.PassWord = passwordGPValue.Value; } else { return; } ITable revisionTable = null; int secondsToTimeout = 10; try { UpdateMessages(paramvalues, envMgr, message); if ((message.MaxSeverity == esriGPMessageSeverity.esriGPMessageSeverityAbort) || (message.MaxSeverity == esriGPMessageSeverity.esriGPMessageSeverityError)) { message.AddMessages(message); return; } IGPParameter baseURLParameter = paramvalues.get_Element(in_uploadURLNumber) as IGPParameter; baseURLGPString = gpUtilities3.UnpackGPValue(baseURLParameter) as IGPString; IGPParameter commentParameter = paramvalues.get_Element(in_uploadCommentNumber) as IGPParameter; IGPString uploadCommentGPString = gpUtilities3.UnpackGPValue(commentParameter) as IGPString; ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass() as ISpatialReferenceFactory; m_wgs84 = spatialReferenceFactory.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984) as ISpatialReference; System.Xml.Serialization.XmlSerializer serializer = null; serializer = new XmlSerializer(typeof(osm)); osm createChangeSetOSM = new osm(); string user_displayname = ""; int userID = -1; // set the "default" value of the OSM server int maxElementsinChangeSet = 50000; HttpWebRequest httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/capabilities") as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); httpClient.Timeout = secondsToTimeout * 1000; createChangeSetOSM.generator = m_Generator; createChangeSetOSM.version = "0.6"; changeset createChangeSet = new changeset(); createChangeSet.id = "0"; createChangeSet.open = changesetOpen.@false; List<tag> changeSetTags = new List<tag>(); tag createdByTag = new tag(); createdByTag.k = "created_by"; createdByTag.v = "ArcGIS Editor for OpenStreetMap"; changeSetTags.Add(createdByTag); tag commentTag = new tag(); commentTag.k = "comment"; commentTag.v = uploadCommentGPString.Value; changeSetTags.Add(commentTag); createChangeSet.tag = changeSetTags.ToArray(); createChangeSetOSM.Items = new object[] { createChangeSet }; api apiCapabilities = null; // retrieve some server settings try { httpResponse = httpClient.GetResponse() as HttpWebResponse; osm osmCapabilities = null; Stream stream = httpResponse.GetResponseStream(); XmlTextReader xmlReader = new XmlTextReader(stream); osmCapabilities = serializer.Deserialize(xmlReader) as osm; xmlReader.Close(); apiCapabilities = osmCapabilities.Items[0] as api; httpResponse.Close(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); message.AddWarning(ex.Message); } if (apiCapabilities != null) { // read the timeout parameter secondsToTimeout = Convert.ToInt32(apiCapabilities.timeout.seconds); httpClient.Timeout = secondsToTimeout * 1000; // update the setting of allowed features per changeset from the actual capabilities response maxElementsinChangeSet = Convert.ToInt32(apiCapabilities.changesets.maximum_elements); } // retrieve some information about the user try { httpClient = null; httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/user/details") as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); httpResponse = httpClient.GetResponse() as HttpWebResponse; osm osmCapabilities = null; Stream stream = httpResponse.GetResponseStream(); XmlTextReader xmlReader = new XmlTextReader(stream); osmCapabilities = serializer.Deserialize(xmlReader) as osm; xmlReader.Close(); user userInformation = osmCapabilities.Items[0] as user; if (userInformation != null) { user_displayname = userInformation.display_name; userID = Convert.ToInt32(userInformation.id); } } catch (ArgumentOutOfRangeException ex) { message.AddError(120044, ex.Message); return; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); message.AddWarning(ex.Message); } IGPParameter revisionTableParameter = paramvalues.get_Element(in_changesTablesNumber) as IGPParameter; int featureUpdateCounter = 0; IQueryFilter revisionTableQueryFilter = null; try { gpUtilities3.DecodeTableView(gpUtilities3.UnpackGPValue(revisionTableParameter), out revisionTable, out revisionTableQueryFilter); } catch { message.AddError(120045,resourceManager.GetString("GPTools_OSMGPUpload_missingRevisionTable")); return; } int revChangeSetIDFieldIndex = revisionTable.Fields.FindField("osmchangeset"); int revActionFieldIndex = revisionTable.Fields.FindField("osmaction"); int revElementTypeFieldIndex = revisionTable.Fields.FindField("osmelementtype"); int revVersionFieldIndex = revisionTable.Fields.FindField("osmversion"); int revFCNameFieldIndex = revisionTable.Fields.FindField("sourcefcname"); int revOldIDFieldIndex = revisionTable.Fields.FindField("osmoldid"); int revNewIDFieldIndex = revisionTable.Fields.FindField("osmnewid"); int revStatusFieldIndex = revisionTable.Fields.FindField("osmstatus"); int revStatusCodeFieldIndex = revisionTable.Fields.FindField("osmstatuscode"); int revErrorMessageFieldIndex = revisionTable.Fields.FindField("osmerrormessage"); int revLongitudeFieldIndex = revisionTable.Fields.FindField("osmlon"); int revLatitudeFieldIndex = revisionTable.Fields.FindField("osmlat"); // let's find all the rows that have a different status than OK - meaning success IQueryFilter queryFilter = new QueryFilterClass(); searchCursor = revisionTable.Search(queryFilter, false); IRow searchRowToUpdate = null; // lookup table to adjust all osm ID references if there are know entities Dictionary<long, long> nodeosmIDLookup = new Dictionary<long, long>(); Dictionary<long, long> wayosmIDLookup = new Dictionary<long, long>(); Dictionary<long, long> relationosmIDLookup = new Dictionary<long, long>(); // let's pre-populate the lookup IDs with already know entities // it is necessary if the revision table is used more than once and in different sessions queryFilter.WhereClause = "NOT " + revisionTable.SqlIdentifier("osmnewid") + " IS NULL"; using (ComReleaser comReleaser = new ComReleaser()) { ICursor searchIDCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchIDCursor); IRow searchRow = searchIDCursor.NextRow(); comReleaser.ManageLifetime(searchRow); while (searchRow != null) { if (revOldIDFieldIndex > -1 && revNewIDFieldIndex > -1) { string elementType = Convert.ToString(searchRow.get_Value(revElementTypeFieldIndex)); switch (elementType) { case "node": if (nodeosmIDLookup.ContainsKey(Convert.ToInt64(searchRow.get_Value(revOldIDFieldIndex))) == false) { nodeosmIDLookup.Add(Convert.ToInt64(searchRow.get_Value(revOldIDFieldIndex)), Convert.ToInt64(searchRow.get_Value(revNewIDFieldIndex))); } break; case "way": if (wayosmIDLookup.ContainsKey(Convert.ToInt64(searchRow.get_Value(revOldIDFieldIndex))) == false) { wayosmIDLookup.Add(Convert.ToInt64(searchRow.get_Value(revOldIDFieldIndex)), Convert.ToInt64(searchRow.get_Value(revNewIDFieldIndex))); } break; case "relation": if (relationosmIDLookup.ContainsKey(Convert.ToInt64(searchRow.get_Value(revOldIDFieldIndex))) == false) { relationosmIDLookup.Add(Convert.ToInt64(searchRow.get_Value(revOldIDFieldIndex)), Convert.ToInt64(searchRow.get_Value(revNewIDFieldIndex))); } break; default: break; } } searchRow = searchIDCursor.NextRow(); } } IFeatureClass pointFeatureClass = null; int pointOSMIDFieldIndex = -1; IFeatureClass lineFeatureClass = null; IFeatureClass polygonFeatureClass = null; ITable relationTable = null; int osmDelimiterPosition = ((IDataset)revisionTable).Name.IndexOf("_osm_"); string osmBaseName = ((IDataset)revisionTable).Name.Substring(0, osmDelimiterPosition); IFeatureWorkspace osmFeatureWorkspace = ((IDataset)revisionTable).Workspace as IFeatureWorkspace; if (osmFeatureWorkspace != null) { pointFeatureClass = osmFeatureWorkspace.OpenFeatureClass(osmBaseName + "_osm_pt"); pointOSMIDFieldIndex = pointFeatureClass.FindField("OSMID"); lineFeatureClass = osmFeatureWorkspace.OpenFeatureClass(osmBaseName + "_osm_ln"); polygonFeatureClass = osmFeatureWorkspace.OpenFeatureClass(osmBaseName + "_osm_ply"); relationTable = osmFeatureWorkspace.OpenTable(osmBaseName + "_osm_relation"); } // determine version of extension int internalExtensionVersion = pointFeatureClass.OSMExtensionVersion(); string sData = OsmRest.SerializeUtils.CreateXmlSerializable(createChangeSetOSM, serializer, Encoding.ASCII, "text/xml"); HttpWebRequest httpClient2 = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/changeset/create") as HttpWebRequest; httpClient2.Method = "PUT"; httpClient2 = OSMGPDownload.AssignProxyandCredentials(httpClient2); SetBasicAuthHeader(httpClient2, userCredentialGPValue.EncodedUserNamePassWord); httpClient2.Timeout = secondsToTimeout * 1000; try { Stream requestStream = httpClient2.GetRequestStream(); StreamWriter mywriter = new StreamWriter(requestStream); mywriter.Write(sData); mywriter.Close(); WebResponse clientResponse = httpClient2.GetResponse(); Stream readStream = clientResponse.GetResponseStream(); StreamReader streamReader = new StreamReader(readStream); changeSetID = streamReader.ReadToEnd(); streamReader.Close(); message.AddMessage(String.Format(resourceManager.GetString("GPTools_OSMGPUpload_openChangeSet"), changeSetID)); } catch (Exception ex) { if (httpResponse != null) { if (httpResponse.StatusCode != System.Net.HttpStatusCode.OK) { foreach (var errorItem in httpResponse.Headers.GetValues("Error")) { message.AddError(120009, errorItem); } message.AddError(120009, httpResponse.StatusCode.ToString()); message.AddError(120009, ex.Message); } } else { message.AddError(120047, ex.Message); } return; } IGPParameter uploadFormatParameter = paramvalues.get_Element(in_uploadFormatNumber) as IGPParameter; IGPBoolean useOSMChangeFormatGPValue = gpUtilities3.UnpackGPValue(uploadFormatParameter) as IGPBoolean; // Al Hack if (useOSMChangeFormatGPValue == null) { useOSMChangeFormatGPValue = new GPBoolean(); useOSMChangeFormatGPValue.Value = false; } SQLFormatter sqlFormatter = new SQLFormatter(revisionTable); if (useOSMChangeFormatGPValue.Value == true) { #region osmchange upload format osmChange osmChangeDocument = new osmChange(); osmChangeDocument.generator = m_Generator; osmChangeDocument.version = "0.6"; // xml elements to describe the changeset create uploadCreates = null; modify uploadModify = null; delete uploadDelete = null; // helper classes to keep track of elements entered into a changeset List<object> listOfCreates = null; List<object> listOfModifies = null; List<object> listOfDeletes = null; List<object> changeSetItems = new List<object>(); #region upload create actions // loop through creates queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'create'"; using (ComReleaser comReleaser = new ComReleaser()) { searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); searchRowToUpdate = searchCursor.NextRow(); comReleaser.ManageLifetime(searchRowToUpdate); // if we have at least one entry with a create action, then add the 'create' element to the changeset representation if (searchRowToUpdate != null) { uploadCreates = new create(); listOfCreates = new List<object>(); } while (searchRowToUpdate != null) { try { if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } string action = String.Empty; if (revActionFieldIndex != -1) { action = searchRowToUpdate.get_Value(revActionFieldIndex) as string; } string elementType = String.Empty; if (revElementTypeFieldIndex != -1) { elementType = searchRowToUpdate.get_Value(revElementTypeFieldIndex) as string; } string sourceFCName = String.Empty; if (revFCNameFieldIndex != -1) { sourceFCName = searchRowToUpdate.get_Value(revFCNameFieldIndex) as string; } long osmOldID = -1; if (revOldIDFieldIndex != -1) { osmOldID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if (featureUpdateCounter > 0 & (featureUpdateCounter % maxElementsinChangeSet) == 0) { // add any outstanding creations to the changeset items if (listOfCreates != null && uploadCreates != null) { uploadCreates.Items = listOfCreates.ToArray(); // in case there are any creates let's add them to the changeset document changeSetItems.Add(uploadCreates); } // add all the changeset items to the changeset document osmChangeDocument.Items = changeSetItems.ToArray(); // submit changeset try { httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/changeset/" + changeSetID + "/upload") as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); httpClient.Method = "POST"; SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); httpClient.Timeout = secondsToTimeout * 1000; string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(osmChangeDocument, null, Encoding.UTF8, "text/xml"); message.AddMessage(String.Format(resourceManager.GetString("GPTools_OSMGPUpload_featureSubmit"), featureUpdateCounter)); OsmRest.HttpUtils.Post(httpClient, sContent); httpResponse = httpClient.GetResponse() as HttpWebResponse; diffResult diffResultResonse = OsmRest.HttpUtils.GetResponse(httpResponse); // parse changes locally and update local data sources if (diffResultResonse != null) { ParseResultDiff(diffResultResonse, revisionTable, pointFeatureClass, lineFeatureClass, polygonFeatureClass, relationTable, user_displayname, userID, changeSetID, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } } catch (Exception ex) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); message.AddError(120009, ex.Message); if (ex is WebException) { WebException webException = ex as WebException; string serverErrorMessage = webException.Response.Headers["Error"]; if (!String.IsNullOrEmpty(serverErrorMessage)) { message.AddError(120009, serverErrorMessage); } } if (httpResponse != null) { httpResponse.Close(); } return; } finally { // reset the list and containers of modifications for the next batch listOfCreates.Clear(); changeSetItems.Clear(); if (httpResponse != null) { httpResponse.Close(); } } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } switch (elementType) { case "node": node createNode = CreateNodeRepresentation(pointFeatureClass, action, osmOldID, changeSetID, 1, null, internalExtensionVersion); listOfCreates.Add(createNode); break; case "way": way createWay = null; if (sourceFCName.Contains("_osm_ln")) { createWay = CreateWayRepresentation(lineFeatureClass, action, osmOldID, changeSetID, 1, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { createWay = CreateWayRepresentation(polygonFeatureClass, action, osmOldID, changeSetID, 1, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } listOfCreates.Add(createWay); break; case "relation": relation createRelation = null; if (sourceFCName.Contains("_osm_ln")) { createRelation = CreateRelationRepresentation((ITable)lineFeatureClass, action, osmOldID, changeSetID, 1, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { createRelation = CreateRelationRepresentation((ITable)polygonFeatureClass, action, osmOldID, changeSetID, 1, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_relation")) { createRelation = CreateRelationRepresentation(relationTable, action, osmOldID, changeSetID, 1, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } listOfCreates.Add(createRelation); break; default: break; } // increment the counter keeping track of the submitted changes featureUpdateCounter = featureUpdateCounter + 1; } catch { } searchRowToUpdate = searchCursor.NextRow(); } if (listOfCreates != null && uploadCreates != null) { // sort the list of created elements in the order of nodes, ways, relations listOfCreates.Sort(new OSMElementComparer()); uploadCreates.Items = listOfCreates.ToArray(); // in case there are any creates let's add them to the changeset document changeSetItems.Add(uploadCreates); } } #endregion #region upload modify actions // loop through modifies using (ComReleaser comReleaser = new ComReleaser()) { queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'modify'"; searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); searchRowToUpdate = searchCursor.NextRow(); if (searchRowToUpdate != null) { uploadModify = new modify(); listOfModifies = new List<object>(); } while (searchRowToUpdate != null) { if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } try { string action = String.Empty; if (revActionFieldIndex != -1) { action = searchRowToUpdate.get_Value(revActionFieldIndex) as string; } string elementType = String.Empty; if (revElementTypeFieldIndex != -1) { elementType = searchRowToUpdate.get_Value(revElementTypeFieldIndex) as string; } string sourceFCName = String.Empty; if (revFCNameFieldIndex != -1) { sourceFCName = searchRowToUpdate.get_Value(revFCNameFieldIndex) as string; } long osmOldID = -1; if (revOldIDFieldIndex != -1) { osmOldID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } // if the overall number of uploaded elements is too big for a single changeset we do need to split it up long modifyID = -1; if (revNewIDFieldIndex != -1) { object osmIDValue = searchRowToUpdate.get_Value(revNewIDFieldIndex); if (osmIDValue == DBNull.Value) { osmIDValue = osmOldID; } try { modifyID = Convert.ToInt64(osmIDValue); } catch { } // modifies should only happen to osm IDs > 0 // if that condition is not met let's skip this feature as something is not right if (modifyID < 0) { searchRowToUpdate = searchCursor.NextRow(); continue; } } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { // add any outstanding modifications to the changeset items if (listOfModifies != null && uploadModify != null) { uploadModify.Items = listOfModifies.ToArray(); // in case there are any creates let's add them to the changeset document changeSetItems.Add(uploadModify); } // add all the changeset items to the changeset document osmChangeDocument.Items = changeSetItems.ToArray(); // submit changeset try { httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/changeset/" + changeSetID + "/upload") as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); httpClient.Method = "POST"; SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); httpClient.Timeout = secondsToTimeout * 1000; string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(osmChangeDocument, null, Encoding.UTF8, "text/xml"); OsmRest.HttpUtils.Post(httpClient, sContent); httpResponse = httpClient.GetResponse() as HttpWebResponse; diffResult diffResultResonse = OsmRest.HttpUtils.GetResponse(httpResponse); // parse changes locally and update local data sources if (diffResultResonse != null) { ParseResultDiff(diffResultResonse, revisionTable, pointFeatureClass, lineFeatureClass, polygonFeatureClass, relationTable, user_displayname, userID, changeSetID, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } } catch (Exception ex) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); message.AddError(120009, ex.Message); if (ex is WebException) { WebException webException = ex as WebException; string serverErrorMessage = webException.Response.Headers["Error"]; if (!String.IsNullOrEmpty(serverErrorMessage)) { message.AddError(120009, serverErrorMessage); } if (httpResponse != null) { httpResponse.Close(); } } return; } finally { // reset the list and containers of modifications for the next batch listOfModifies.Clear(); changeSetItems.Clear(); if (httpResponse != null) { httpResponse.Close(); } } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } switch (elementType) { case "node": node updateNode = CreateNodeRepresentation(pointFeatureClass, action, modifyID, changeSetID, osmVersion, null, internalExtensionVersion); listOfModifies.Add(updateNode); break; case "way": way updateWay = null; if (sourceFCName.Contains("_osm_ln")) { updateWay = CreateWayRepresentation(lineFeatureClass, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { updateWay = CreateWayRepresentation(polygonFeatureClass, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } listOfModifies.Add(updateWay); break; case "relation": relation updateRelation = null; if (sourceFCName.Contains("_osm_ln")) { updateRelation = CreateRelationRepresentation((ITable)lineFeatureClass, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { updateRelation = CreateRelationRepresentation((ITable)polygonFeatureClass, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_relation")) { updateRelation = CreateRelationRepresentation(relationTable, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } listOfModifies.Add(updateRelation); break; default: break; } // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; } catch { } searchRowToUpdate = searchCursor.NextRow(); } if (listOfModifies != null && uploadModify != null) { uploadModify.Items = listOfModifies.ToArray(); // in case there are any creates let's add them to the changeset document changeSetItems.Add(uploadModify); } } #endregion #region upload delete actions // loop through deletes in "reverse" - relation, then way, then node string[] elementTypes = new string[] { "relation", "way", "node" }; foreach (string osmElementType in elementTypes) { using (ComReleaser comReleaser = new ComReleaser()) { queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'delete' AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = '" + osmElementType + "'"; searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); searchRowToUpdate = searchCursor.NextRow(); if (searchRowToUpdate != null) { if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } if (uploadDelete == null) { uploadDelete = new delete(); listOfDeletes = new List<object>(); } } while (searchRowToUpdate != null) { try { string action = String.Empty; if (revActionFieldIndex != -1) { action = searchRowToUpdate.get_Value(revActionFieldIndex) as string; } string elementType = String.Empty; if (revElementTypeFieldIndex != -1) { elementType = searchRowToUpdate.get_Value(revElementTypeFieldIndex) as string; } string sourceFCName = String.Empty; if (revFCNameFieldIndex != -1) { sourceFCName = searchRowToUpdate.get_Value(revFCNameFieldIndex) as string; } long osmOldID = -1; if (revOldIDFieldIndex != -1) { osmOldID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { // add any outstanding creations to the changeset items if (listOfDeletes != null && uploadDelete != null) { uploadDelete.Items = listOfDeletes.ToArray(); // in case there are any creates let's add them to the changeset document changeSetItems.Add(uploadDelete); } // add all the changeset items to the changeset document osmChangeDocument.Items = changeSetItems.ToArray(); // submit changeset try { httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/changeset/" + changeSetID + "/upload") as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); httpClient.Method = "POST"; SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); httpClient.Timeout = secondsToTimeout * 1000; string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(osmChangeDocument, null, Encoding.UTF8, "text/xml"); OsmRest.HttpUtils.Post(httpClient, sContent); httpResponse = httpClient.GetResponse() as HttpWebResponse; diffResult diffResultResonse = OsmRest.HttpUtils.GetResponse(httpResponse); // parse changes locally and update local data sources if (diffResultResonse != null) { ParseResultDiff(diffResultResonse, revisionTable, pointFeatureClass, lineFeatureClass, polygonFeatureClass, relationTable, user_displayname, userID, changeSetID, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } } catch (Exception ex) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); message.AddError(120009, ex.Message); if (ex is WebException) { WebException webException = ex as WebException; string serverErrorMessage = webException.Response.Headers["Error"]; if (!String.IsNullOrEmpty(serverErrorMessage)) { message.AddError(120009, serverErrorMessage); } } if (httpResponse != null) { httpResponse.Close(); } return; } finally { // reset the list and containers of modifications for the next batch listOfDeletes.Clear(); changeSetItems.Clear(); if (httpResponse != null) { httpResponse.Close(); } } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } switch (elementType) { case "node": IPoint deletePoint = null; if (revLongitudeFieldIndex != -1 && revLatitudeFieldIndex != -1) { try { // let's reconstruct the delete point deletePoint = new PointClass(); deletePoint.X = Convert.ToDouble(searchRowToUpdate.get_Value(revLongitudeFieldIndex)); deletePoint.Y = Convert.ToDouble(searchRowToUpdate.get_Value(revLatitudeFieldIndex)); deletePoint.SpatialReference = m_wgs84; } catch (Exception ex) { message.AddWarning(ex.Message); } if (deletePoint == null) { // inform the about the issue - no successful creation of point and continue on to the next delete instruction // in the revision table message.AddWarning(resourceManager.GetString("GPTools_OSMGPUpload_invalidPoint")); searchRowToUpdate = searchCursor.NextRow(); continue; } } node deleteNode = CreateNodeRepresentation(pointFeatureClass, action, osmOldID, changeSetID, osmVersion, deletePoint, internalExtensionVersion); listOfDeletes.Add(deleteNode); break; case "way": way deleteWay = null; if (sourceFCName.Contains("_osm_ln")) { deleteWay = CreateWayRepresentation(lineFeatureClass, action, osmOldID, changeSetID, osmVersion, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { deleteWay = CreateWayRepresentation(polygonFeatureClass, action, osmOldID, changeSetID, osmVersion, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } listOfDeletes.Add(deleteWay); break; case "relation": relation deleteRelation = null; if (sourceFCName.Contains("_osm_ln")) { deleteRelation = CreateRelationRepresentation((ITable)lineFeatureClass, action, osmOldID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { deleteRelation = CreateRelationRepresentation((ITable)polygonFeatureClass, action, osmOldID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_relation")) { deleteRelation = CreateRelationRepresentation(relationTable, action, osmOldID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } listOfDeletes.Add(deleteRelation); break; default: break; } // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; } catch { } searchRowToUpdate = searchCursor.NextRow(); } } } if (listOfDeletes != null && uploadDelete != null) { uploadDelete.Items = listOfDeletes.ToArray(); // in case there are any creates let's add them to the changeset document changeSetItems.Add(uploadDelete); } #endregion if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } // add all the changeset items to the changeset document osmChangeDocument.Items = changeSetItems.ToArray(); // submit changeset try { httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/changeset/" + changeSetID + "/upload") as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); httpClient.Method = "POST"; SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); httpClient.Timeout = secondsToTimeout * 1000; message.AddMessage(String.Format(resourceManager.GetString("GPTools_OSMGPUpload_featureSubmit"), featureUpdateCounter)); string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(osmChangeDocument, null, Encoding.UTF8, "text/xml"); OsmRest.HttpUtils.Post(httpClient, sContent); httpResponse = httpClient.GetResponse() as HttpWebResponse; //Exception with an error HTTP 400 diffResult diffResultResonse = OsmRest.HttpUtils.GetResponse(httpResponse); message.AddMessage(resourceManager.GetString("GPTools_OSMGPUpload_updatelocalData")); // parse changes locally and update local data sources if (diffResultResonse != null) { ParseResultDiff(diffResultResonse, revisionTable, pointFeatureClass, lineFeatureClass, polygonFeatureClass, relationTable, user_displayname, userID, changeSetID, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } } catch (Exception ex) { message.AddError(120009, ex.Message); try { if (ex is WebException) { WebException webException = ex as WebException; string serverErrorMessage = webException.Response.Headers["Error"]; if (!String.IsNullOrEmpty(serverErrorMessage)) { message.AddError(120009, serverErrorMessage); } } } catch (Exception innerexception) { message.AddError(120009, innerexception.Message); } } finally { if (httpResponse != null) { httpResponse.Close(); } } #endregion } else { #region single upload format #region submit the create nodes first queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'create' AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'node'"; using (ComReleaser comReleaser = new ComReleaser()) { searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); while ((searchRowToUpdate = searchCursor.NextRow()) != null) { try { string action = String.Empty; if (revActionFieldIndex != -1) { action = searchRowToUpdate.get_Value(revActionFieldIndex) as string; } string elementType = String.Empty; if (revElementTypeFieldIndex != -1) { elementType = searchRowToUpdate.get_Value(revElementTypeFieldIndex) as string; } string sourceFCName = String.Empty; if (revFCNameFieldIndex != -1) { sourceFCName = searchRowToUpdate.get_Value(revFCNameFieldIndex) as string; } long osmOldID = -1; if (revOldIDFieldIndex != -1) { osmOldID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } osm createNode = CreateOSMNodeRepresentation(pointFeatureClass, action, osmOldID, changeSetID, -1, null, internalExtensionVersion); httpClient = null; httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/" + elementType + "/create") as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); httpClient.Method = "PUT"; SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); httpClient.Timeout = secondsToTimeout * 1000; httpResponse = null; string nodeContent = OsmRest.SerializeUtils.CreateXmlSerializable(createNode, serializer, Encoding.UTF8, "text/xml"); if (String.IsNullOrEmpty(nodeContent)) { continue; } OsmRest.HttpUtils.Put(httpClient, nodeContent); httpResponse = httpClient.GetResponse() as HttpWebResponse; createNode = null; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; if (httpResponse != null) { string newIDString = OsmRest.HttpUtils.GetResponseContent(httpResponse); nodeosmIDLookup.Add(osmOldID, Convert.ToInt64(newIDString)); // update the revision table if (revNewIDFieldIndex != -1) { searchRowToUpdate.set_Value(revNewIDFieldIndex, Convert.ToString(newIDString)); } if (revVersionFieldIndex != -1) { searchRowToUpdate.set_Value(revVersionFieldIndex, 1); } if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, httpResponse.StatusCode.ToString()); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (revChangeSetIDFieldIndex != -1) { searchRowToUpdate.set_Value(revChangeSetIDFieldIndex, Convert.ToString(changeSetID)); } // update the source point feature class as well updateSource((ITable)pointFeatureClass, action, osmOldID, Convert.ToInt64(newIDString), user_displayname, userID, 1, Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup,internalExtensionVersion); } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } finally { try { searchRowToUpdate.Store(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } if (httpResponse != null) { httpResponse.Close(); } } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } } } #endregion #region next the create ways queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'create' AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'way'"; using (ComReleaser comReleaser = new ComReleaser()) { searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); while ((searchRowToUpdate = searchCursor.NextRow()) != null) { try { string action = String.Empty; if (revActionFieldIndex != -1) { action = searchRowToUpdate.get_Value(revActionFieldIndex) as string; } string elementType = String.Empty; if (revElementTypeFieldIndex != -1) { elementType = searchRowToUpdate.get_Value(revElementTypeFieldIndex) as string; } string sourceFCName = String.Empty; if (revFCNameFieldIndex != -1) { sourceFCName = searchRowToUpdate.get_Value(revFCNameFieldIndex) as string; } long osmOldID = -1; if (revOldIDFieldIndex != -1) { osmOldID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } bool isPolygon = false; if (sourceFCName.IndexOf("_osm_ply") > -1) { isPolygon = true; } // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } osm createWay = new osm(); if (isPolygon == false) { createWay = CreateOSMWayRepresentation(lineFeatureClass, action, osmOldID, changeSetID, -1, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } else { createWay = CreateOSMWayRepresentation(polygonFeatureClass, action, osmOldID, changeSetID, -1, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } try { HttpWebRequest httpClient3 = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/" + elementType + "/create") as HttpWebRequest; httpClient3 = OSMGPDownload.AssignProxyandCredentials(httpClient3); httpClient3.Method = "PUT"; SetBasicAuthHeader(httpClient3, userCredentialGPValue.EncodedUserNamePassWord); httpClient.Timeout = secondsToTimeout * 1000; string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(createWay, serializer, Encoding.UTF8, "text/xml"); OsmRest.HttpUtils.Put(httpClient3, sContent); createWay = null; httpResponse = null; httpResponse = httpClient3.GetResponse() as HttpWebResponse; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } if (httpResponse != null) { string newIDString = OsmRest.HttpUtils.GetResponseContent(httpResponse); wayosmIDLookup.Add(osmOldID, Convert.ToInt64(newIDString)); // update the revision table if (revNewIDFieldIndex != -1) { searchRowToUpdate.set_Value(revNewIDFieldIndex, Convert.ToString(newIDString)); } if (revVersionFieldIndex != -1) { searchRowToUpdate.set_Value(revVersionFieldIndex, 1); } if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, httpResponse.StatusCode.ToString()); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (revChangeSetIDFieldIndex != -1) { searchRowToUpdate.set_Value(revChangeSetIDFieldIndex, Convert.ToString(changeSetID)); } // update the source line/polygon feature class as well if (isPolygon == false) { updateSource((ITable)lineFeatureClass, action, osmOldID, Convert.ToInt64(newIDString), user_displayname, userID, 1, Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else { updateSource((ITable)polygonFeatureClass, action, osmOldID, Convert.ToInt64(newIDString), user_displayname, userID, 1, Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } finally { try { searchRowToUpdate.Store(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } if (httpResponse != null) { httpResponse.Close(); } } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } } } #endregion #region and then create relations queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'create' AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'relation'"; using (ComReleaser comReleaser = new ComReleaser()) { searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); while ((searchRowToUpdate = searchCursor.NextRow()) != null) { try { string action = String.Empty; if (revActionFieldIndex != -1) { action = searchRowToUpdate.get_Value(revActionFieldIndex) as string; } string elementType = String.Empty; if (revElementTypeFieldIndex != -1) { elementType = searchRowToUpdate.get_Value(revElementTypeFieldIndex) as string; } string sourceFCName = String.Empty; if (revFCNameFieldIndex != -1) { sourceFCName = searchRowToUpdate.get_Value(revFCNameFieldIndex) as string; } long osmOldID = -1; if (revOldIDFieldIndex != -1) { osmOldID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } bool isPolygon = false; if (sourceFCName.IndexOf("_osm_ply") > -1) { isPolygon = true; } // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } osm createRelation = null; // the relation is acutally multi-part line if (sourceFCName.Contains("_osm_ln")) { createRelation = CreateOSMRelationRepresentation((ITable)lineFeatureClass, action, osmOldID, changeSetID, -1, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { createRelation = CreateOSMRelationRepresentation((ITable)polygonFeatureClass, action, osmOldID, changeSetID, -1, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else { createRelation = CreateOSMRelationRepresentation(relationTable, action, osmOldID, changeSetID, -1, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } try { HttpWebRequest httpClient4 = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/" + elementType + "/create") as HttpWebRequest; httpClient4 = OSMGPDownload.AssignProxyandCredentials(httpClient4); SetBasicAuthHeader(httpClient4, userCredentialGPValue.EncodedUserNamePassWord); httpClient4.Timeout = secondsToTimeout * 1000; string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(createRelation, serializer, Encoding.UTF8, "text/xml"); OsmRest.HttpUtils.Put(httpClient4, sContent); httpResponse = null; httpResponse = httpClient4.GetResponse() as HttpWebResponse; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } if (httpResponse != null) { string newIDString = OsmRest.HttpUtils.GetResponseContent(httpResponse); relationosmIDLookup.Add(osmOldID, Convert.ToInt64(newIDString)); // update the revision table if (revNewIDFieldIndex != -1) { searchRowToUpdate.set_Value(revNewIDFieldIndex, Convert.ToString(newIDString)); } if (revVersionFieldIndex != -1) { searchRowToUpdate.set_Value(revVersionFieldIndex, 1); } if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, httpResponse.StatusCode.ToString()); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (revChangeSetIDFieldIndex != -1) { searchRowToUpdate.set_Value(revChangeSetIDFieldIndex, Convert.ToInt32(changeSetID)); } if (sourceFCName.Contains("_osm_ln")) { updateSource((ITable)lineFeatureClass, action, osmOldID, Convert.ToInt64(newIDString), user_displayname, userID, 1, Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { updateSource((ITable)polygonFeatureClass, action, osmOldID, Convert.ToInt64(newIDString), user_displayname, userID, 1, Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else { // update the source table holding the relation information class as well updateSource(relationTable, action, osmOldID, Convert.ToInt64(newIDString), user_displayname, userID, 1, Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } finally { try { searchRowToUpdate.Store(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } } } #endregion #region after that submit the modify node, way, relation using (ComReleaser comReleaser = new ComReleaser()) { queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'modify'"; searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); while ((searchRowToUpdate = searchCursor.NextRow()) != null) { try { string action = String.Empty; if (revActionFieldIndex != -1) { action = searchRowToUpdate.get_Value(revActionFieldIndex) as string; } string elementType = String.Empty; if (revElementTypeFieldIndex != -1) { elementType = searchRowToUpdate.get_Value(revElementTypeFieldIndex) as string; } string sourceFCName = String.Empty; if (revFCNameFieldIndex != -1) { sourceFCName = searchRowToUpdate.get_Value(revFCNameFieldIndex) as string; } long osmOldID = -1; if (revOldIDFieldIndex != -1) { osmOldID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } switch (elementType) { case "node": #region submit nodes to OSM server switch (action) { case "modify": long modifyID = -1; if (revNewIDFieldIndex != -1) { object osmIDValue = searchRowToUpdate.get_Value(revNewIDFieldIndex); if (osmIDValue == DBNull.Value) { osmIDValue = osmOldID; } try { modifyID = Convert.ToInt64(osmIDValue); } catch { } // modifies should only happen to osm IDs > 0 // if that condition is not met let's skip this feature as something is not right if (modifyID < 0) { continue; } } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } try { HttpWebRequest httpClient5 = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/" + elementType + "/" + modifyID.ToString()) as HttpWebRequest; httpClient5 = OSMGPDownload.AssignProxyandCredentials(httpClient5); SetBasicAuthHeader(httpClient5, userCredentialGPValue.EncodedUserNamePassWord); osm updateNode = CreateOSMNodeRepresentation(pointFeatureClass, action, modifyID, changeSetID, osmVersion, null, internalExtensionVersion); string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(updateNode, serializer, Encoding.UTF8, "text/xml"); // if the serialized node at this time is a null or an empty string let's continue to the next point if (String.IsNullOrEmpty(sContent)) { continue; } OsmRest.HttpUtils.Put(httpClient5, sContent); httpResponse = httpClient5.GetResponse() as HttpWebResponse; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; if (httpResponse != null) { string newVersionString = OsmRest.HttpUtils.GetResponseContent(httpResponse); // update the revision table if (revVersionFieldIndex != -1) { searchRowToUpdate.set_Value(revVersionFieldIndex, Convert.ToString(newVersionString)); } if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, httpResponse.StatusCode.ToString()); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (revChangeSetIDFieldIndex != -1) { searchRowToUpdate.set_Value(revChangeSetIDFieldIndex, Convert.ToInt32(changeSetID)); } // for a modify the old id is still the new id if (revNewIDFieldIndex != -1 && revOldIDFieldIndex != -1) { searchRowToUpdate.set_Value(revNewIDFieldIndex, searchRowToUpdate.get_Value(revOldIDFieldIndex)); } // update the source point feature class as well updateSource((ITable)pointFeatureClass, action, modifyID, modifyID, user_displayname, userID, Convert.ToInt32(newVersionString), Convert.ToInt32(changeSetID), null, null, null, internalExtensionVersion); httpResponse.Close(); } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } break; case "delete": // the delete operations are handled separately break; default: break; } break; #endregion case "way": #region submit ways to the OSM server // determine if we have a polygon or a polyline feature class bool isPolygon = false; if (sourceFCName.IndexOf("_osm_ply") > -1) { isPolygon = true; } switch (action) { case "modify": long modifyID = -1; if (revNewIDFieldIndex != -1) { object osmIDValue = searchRowToUpdate.get_Value(revNewIDFieldIndex); if (osmIDValue == DBNull.Value) { osmIDValue = osmOldID; } try { modifyID = Convert.ToInt64(osmIDValue); } catch { } // modifies should only happen to osm IDs > 0 // if that condition is not met let's skip this feature as something is not right if (modifyID < 0) { continue; } } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } osm updateWay = new osm(); if (isPolygon == false) { updateWay = CreateOSMWayRepresentation(lineFeatureClass, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } else { updateWay = CreateOSMWayRepresentation(polygonFeatureClass, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); } try { string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(updateWay, serializer, Encoding.UTF8, "text/xml"); httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/" + elementType + "/" + modifyID.ToString()) as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); OsmRest.HttpUtils.Put(httpClient, sContent); httpResponse = httpClient.GetResponse() as HttpWebResponse; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; if (httpResponse != null) { string newVersionString = OsmRest.HttpUtils.GetResponseContent(httpResponse); // update the revision table if (revVersionFieldIndex != -1) { searchRowToUpdate.set_Value(revVersionFieldIndex, Convert.ToString(newVersionString)); } if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, httpResponse.StatusCode.ToString()); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (revChangeSetIDFieldIndex != -1) { searchRowToUpdate.set_Value(revChangeSetIDFieldIndex, Convert.ToInt32(changeSetID)); } // for a modify the old id is still the new id if (revNewIDFieldIndex != -1 && revOldIDFieldIndex != -1) { searchRowToUpdate.set_Value(revNewIDFieldIndex, searchRowToUpdate.get_Value(revOldIDFieldIndex)); } // update the source line/polygon feature class as well if (isPolygon == false) { updateSource((ITable)lineFeatureClass, action, modifyID, modifyID, user_displayname, userID, Convert.ToInt32(newVersionString), Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } else { updateSource((ITable)polygonFeatureClass, action, modifyID, modifyID, user_displayname, userID, Convert.ToInt32(newVersionString), Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); } httpResponse.Close(); } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } break; case "delete": // the delete operations are handled separately break; default: break; } break; #endregion case "relation": #region submit relations to the OSM server switch (action) { case "create": break; case "modify": long modifyID = -1; if (revNewIDFieldIndex != -1) { object osmIDValue = searchRowToUpdate.get_Value(revNewIDFieldIndex); if (osmIDValue == DBNull.Value) { osmIDValue = osmOldID; } try { modifyID = Convert.ToInt64(osmIDValue); } catch { } // modifies should only happen to osm IDs > 0 // if that condition is not met let's skip this feature as something is not right if (modifyID < 0) { continue; } } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } osm updateRelation = CreateOSMRelationRepresentation(relationTable, action, modifyID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); try { string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(updateRelation, serializer, Encoding.UTF8, "text/xml"); httpClient = HttpWebRequest.Create(baseURLGPString.Value + "/api/0.6/" + elementType + "/" + modifyID.ToString()) as HttpWebRequest; httpClient = OSMGPDownload.AssignProxyandCredentials(httpClient); SetBasicAuthHeader(httpClient, userCredentialGPValue.EncodedUserNamePassWord); OsmRest.HttpUtils.Put(httpClient, sContent); httpResponse = httpClient.GetResponse() as HttpWebResponse; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; if (httpResponse != null) { string newVersionString = OsmRest.HttpUtils.GetResponseContent(httpResponse); // update the revision table if (revVersionFieldIndex != -1) { searchRowToUpdate.set_Value(revVersionFieldIndex, Convert.ToInt32(newVersionString)); } if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, httpResponse.StatusCode.ToString()); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (revChangeSetIDFieldIndex != -1) { searchRowToUpdate.set_Value(revChangeSetIDFieldIndex, Convert.ToInt32(changeSetID)); } // for a modify the old id is still the new id if (revNewIDFieldIndex != -1 && revOldIDFieldIndex != -1) { searchRowToUpdate.set_Value(revNewIDFieldIndex, searchRowToUpdate.get_Value(revOldIDFieldIndex)); } // update the source table holding the relation information class as well updateSource(relationTable, action, modifyID, modifyID, user_displayname, userID, Convert.ToInt32(newVersionString), Convert.ToInt32(changeSetID), nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); httpResponse.Close(); } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } break; case "delete": // the delete operations are handled separately break; default: break; } break; #endregion default: break; } } catch (Exception ex) { message.AddAbort(ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } } finally { try { searchRowToUpdate.Store(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } if (httpResponse != null) { httpResponse.Close(); } } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } } } #endregion #region now let's handle the delete in the reverse order - relation first, then ways, and then nodes as the last entity #region delete relations // now let's handle the delete in the reverse order - relation first, then ways, and then nodes as the last entity queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'delete' AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'relation'"; using (ComReleaser comReleaser = new ComReleaser()) { searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); while ((searchRowToUpdate = searchCursor.NextRow()) != null) { // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } long osmID = -1; if (revOldIDFieldIndex != -1) { osmID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } osm deleteRelation = CreateOSMRelationRepresentation(relationTable, "delete", osmID, changeSetID, osmVersion, nodeosmIDLookup, wayosmIDLookup, relationosmIDLookup, internalExtensionVersion); string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(deleteRelation, serializer, Encoding.UTF8, "text/xml"); string errorMessage = String.Empty; try { httpResponse = OsmRest.HttpUtils.Delete(baseURLGPString.Value + "/api/0.6/relation/" + Convert.ToString(osmID), sContent, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout) as HttpWebResponse; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, (int)httpResponse.StatusCode); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (httpResponse != null) { httpResponse.Close(); } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } if (httpResponse != null) { httpResponse.Close(); } } try { searchRowToUpdate.Store(); } catch { } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } } } #endregion #region handle delete ways queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'delete' AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'way'"; using (ComReleaser comReleaser = new ComReleaser()) { searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); while ((searchRowToUpdate = searchCursor.NextRow()) != null) { // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } long osmID = -1; if (revOldIDFieldIndex != -1) { osmID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } osm deleteWay = CreateOSMWayRepresentation(lineFeatureClass, "delete", osmID, changeSetID, osmVersion, wayosmIDLookup, pointFeatureClass, pointOSMIDFieldIndex, internalExtensionVersion); string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(deleteWay, serializer, Encoding.UTF8, "text/xml"); try { httpResponse = null; httpResponse = OsmRest.HttpUtils.Delete(baseURLGPString.Value + "/api/0.6/way/" + Convert.ToString(osmID), sContent, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout) as HttpWebResponse; // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; string errorMessage = String.Empty; // just grab the response and set it on the database if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, (int)httpResponse.StatusCode); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (httpResponse != null) { httpResponse.Close(); } } catch (Exception ex) { message.AddError(1200009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } if (httpResponse != null) { httpResponse.Close(); } } try { searchRowToUpdate.Store(); } catch { } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } } } #endregion #region handle delete points queryFilter.WhereClause = "(" + sqlFormatter.SqlIdentifier("osmstatuscode") + " <> 200 OR " + sqlFormatter.SqlIdentifier("osmstatus") + " IS NULL) AND " + sqlFormatter.SqlIdentifier("osmaction") + " = 'delete' AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'node'"; using (ComReleaser comReleaser = new ComReleaser()) { searchCursor = revisionTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); while ((searchRowToUpdate = searchCursor.NextRow()) != null) { // if the overall number of uploaded elements is too big for a single changeset we do need to split it up // into multiple sets if ((featureUpdateCounter % maxElementsinChangeSet) == 0) { CreateNextChangeSet(message, createChangeSetOSM, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, ref changeSetID, baseURLGPString, ref featureUpdateCounter); } long osmID = -1; if (revOldIDFieldIndex != -1) { osmID = Convert.ToInt64(searchRowToUpdate.get_Value(revOldIDFieldIndex)); } int osmVersion = -1; if (revVersionFieldIndex != -1) { osmVersion = Convert.ToInt32(searchRowToUpdate.get_Value(revVersionFieldIndex)); } IPoint deletePoint = null; if (revLongitudeFieldIndex != -1 && revLatitudeFieldIndex != -1) { try { // let's reconstruct the delete point deletePoint = new PointClass(); deletePoint.X = Convert.ToDouble(searchRowToUpdate.get_Value(revLongitudeFieldIndex)); deletePoint.Y = Convert.ToDouble(searchRowToUpdate.get_Value(revLatitudeFieldIndex)); deletePoint.SpatialReference = m_wgs84; } catch (Exception ex) { message.AddWarning(ex.Message); } if (deletePoint == null) { // inform the about the issue - no successful creation of point and continue on to the next delete instruction // in the revision table message.AddWarning(resourceManager.GetString("GPTools_OSMGPUpload_invalidPoint")); continue; } } osm deleteNode = CreateOSMNodeRepresentation(pointFeatureClass, "delete", osmID, changeSetID, osmVersion, deletePoint, internalExtensionVersion); string sContent = OsmRest.SerializeUtils.CreateXmlSerializable(deleteNode, serializer, Encoding.UTF8, "text/xml"); if (String.IsNullOrEmpty(sContent)) { continue; } string errorMessage = String.Empty; try { httpResponse = OsmRest.HttpUtils.Delete(baseURLGPString.Value + "/api/0.6/node/" + Convert.ToString(osmID), sContent, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout) as HttpWebResponse; if (revStatusFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusFieldIndex, (int)httpResponse.StatusCode); } if (revStatusCodeFieldIndex != -1) { searchRowToUpdate.set_Value(revStatusCodeFieldIndex, (int)httpResponse.StatusCode); } if (httpResponse != null) { httpResponse.Close(); } } catch (Exception ex) { message.AddError(120009, ex.Message); if (ex is WebException) { updateErrorStatus(message, revStatusFieldIndex, revStatusCodeFieldIndex, revErrorMessageFieldIndex, ref searchRowToUpdate, ex); } if (httpResponse != null) { httpResponse.Close(); } } // track the update/sync requests against the server featureUpdateCounter = featureUpdateCounter + 1; try { searchRowToUpdate.Store(); } catch { } if (TrackCancel.Continue() == false) { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); return; } } } #endregion #endregion #endregion } } catch (Exception ex) { message.AddError(120058, ex.Message); message.AddError(120058, ex.StackTrace); } finally { closeChangeSet(message, userCredentialGPValue.EncodedUserNamePassWord, secondsToTimeout, changeSetID, baseURLGPString); if (revisionTable != null) { try { ISchemaLock tableSchemaLock = revisionTable as ISchemaLock; if (tableSchemaLock != null) { tableSchemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock); } } catch (Exception eLock) { message.AddError(120059, resourceManager.GetString("GPTools_OSMGPUpload_LockErrorTitle") + eLock.Message); } } if (revisionTable != null) { Marshal.FinalReleaseComObject(revisionTable); } // if the searchCursor still has a reference somewhere do release it now - and as a result release any remaining table locks if (searchCursor != null) { Marshal.FinalReleaseComObject(searchCursor); } gpUtilities3.RemoveInternalData(); gpUtilities3.ReleaseInternals(); //Marshal.ReleaseComObject(gpUtilities3); } }
public void UpdateMessages(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager pEnvMgr, ESRI.ArcGIS.Geodatabase.IGPMessages Messages) { IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); // check for a valid download url IGPParameter uploadURLParameter = paramvalues.get_Element(in_uploadURLNumber) as IGPParameter; IGPString uploadURLGPString = uploadURLParameter.Value as IGPString; if (uploadURLGPString == null) { Messages.ReplaceError(in_uploadURLNumber, -198, String.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), uploadURLParameter.Value.GetAsText())); } else { try { if (uploadURLParameter.HasBeenValidated == false) { Uri downloadURI = new Uri(uploadURLGPString.Value); // check base url api osmAPICapabilities = OSMGPDownload.CheckValidServerURL(uploadURLGPString.Value); // if we can construct a valid URI class then we are accepting the value and store it in the user settings as well if (m_editorConfigurationSettings != null) { if (m_editorConfigurationSettings.ContainsKey("osmbaseurl")) { m_editorConfigurationSettings["osmbaseurl"] = uploadURLGPString.Value; } else { m_editorConfigurationSettings.Add("osmbaseurl", uploadURLGPString.Value); } OSMGPFactory.StoreOSMEditorSettings(m_editorConfigurationSettings); } } } catch (Exception ex) { StringBuilder errorMessage = new StringBuilder(); errorMessage.AppendLine(resourceManager.GetString("GPTools_OSMGPUpload_invaliduploadurl")); errorMessage.AppendLine(ex.Message); Messages.ReplaceError(in_uploadURLNumber, -3, errorMessage.ToString()); } } IGPParameter revisionTableParameter = paramvalues.get_Element(in_changesTablesNumber) as IGPParameter; IGPValue revisionTableGPValue = gpUtilities3.UnpackGPValue(revisionTableParameter); if (revisionTableGPValue.IsEmpty()) return; ITable revisionTable = null; IQueryFilter revisionTableQueryFilter = null; try { using (ComReleaser comReleaser = new ComReleaser()) { gpUtilities3.DecodeTableView(revisionTableGPValue, out revisionTable, out revisionTableQueryFilter); comReleaser.ManageLifetime(revisionTable); if (revisionTable is IFeatureClass) { Messages.ReplaceError(in_changesTablesNumber, -4, resourceManager.GetString("GPTools_OSMGPUpload_notarevisiontable")); return; } IDatasetEdit datasetEdit = revisionTable as IDatasetEdit; comReleaser.ManageLifetime(datasetEdit); if (datasetEdit == null) { return; } if (datasetEdit.IsBeingEdited()) { Messages.ReplaceError(in_changesTablesNumber, -4, resourceManager.GetString("GPTools_OSMGPUpload_inputnotvalidduringedit")); } } gpUtilities3.ReleaseInternals(); } catch { // check if we are dealing with a variable -- if we do then leave this string alone string tableName = revisionTableGPValue.GetAsText(); string tableNameModified = tableName.Replace("%", String.Empty); if (((tableName.Length - tableNameModified.Length) % 2) == 0) { Messages.Replace(in_changesTablesNumber, new GPMessageClass()); } } }
public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message) { try { IGPUtilities3 execute_Utilities = new GPUtilitiesClass(); if (TrackCancel == null) { TrackCancel = new CancelTrackerClass(); } IGPParameter inputOSMParameter = paramvalues.get_Element(in_osmFeatureClass) as IGPParameter; IGPValue inputOSMGPValue = execute_Utilities.UnpackGPValue(inputOSMParameter); IGPParameter tagCollectionParameter = paramvalues.get_Element(in_attributeSelector) as IGPParameter; IGPMultiValue tagCollectionGPValue = execute_Utilities.UnpackGPValue(tagCollectionParameter) as IGPMultiValue; if (tagCollectionGPValue == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), tagCollectionParameter.Name)); return; } bool useUpdateCursor = false; IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { execute_Utilities.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); if (osmFeatureClass != null) { if (osmFeatureClass.Extension is IOSMClassExtension) { useUpdateCursor = false; } else { useUpdateCursor = true; } } osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { execute_Utilities.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { string errorMessage = String.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelecto_unableopentable"), inputOSMGPValue.GetAsText()); message.AddError(120053, errorMessage); return; } // find the field that holds tag binary/xml field int osmTagCollectionFieldIndex = osmInputTable.FindField("osmTags"); // if the Field doesn't exist - wasn't found (index = -1) get out if (osmTagCollectionFieldIndex == -1) { message.AddError(120005, resourceManager.GetString("GPTools_OSMGPAttributeSelector_notagfieldfound")); return; } // check if the tag collection includes the keyword "ALL", if does then we'll need to extract all tags bool extractAll = false; for (int valueIndex = 0; valueIndex < tagCollectionGPValue.Count; valueIndex++) { if (tagCollectionGPValue.get_Value(valueIndex).GetAsText().Equals("ALL")) { extractAll = true; break; } } //if (extractAll) //{ // if (osmTagKeyCodedValues == null) // extractAllTags(ref osmTagKeyCodedValues, osmInputTable, osmQueryFilter, osmTagCollectionFieldIndex, false); // if (osmTagKeyCodedValues == null) // { // message.AddAbort(resourceManager.GetString("GPTools_OSMGPAttributeSelector_Unable2RetrieveTags")); // return; // } // // empty the existing gp multivalue object // tagCollectionGPValue = new GPMultiValueClass(); // // fill the coded domain in gp multivalue object // for (int valueIndex = 0; valueIndex < osmTagKeyCodedValues.CodeCount; valueIndex++) // { // tagCollectionGPValue.AddValue(osmTagKeyCodedValues.get_Value(valueIndex)); // } //} // get an overall feature count as that determines the progress indicator int featureCount = osmInputTable.RowCount(osmQueryFilter); // set up the progress indicator IStepProgressor stepProgressor = TrackCancel as IStepProgressor; if (stepProgressor != null) { stepProgressor.MinRange = 0; stepProgressor.MaxRange = featureCount; stepProgressor.Position = 0; stepProgressor.Message = resourceManager.GetString("GPTools_OSMGPAttributeSelector_progressMessage"); stepProgressor.StepValue = 1; stepProgressor.Show(); } // let's get all the indices of the desired fields // if the field already exists get the index and if it doesn't exist create it Dictionary <string, int> tagsAttributesIndices = new Dictionary <string, int>(); Dictionary <int, int> attributeFieldLength = new Dictionary <int, int>(); IFeatureWorkspaceManage featureWorkspaceManage = ((IDataset)osmInputTable).Workspace as IFeatureWorkspaceManage; String illegalCharacters = String.Empty; ISQLSyntax sqlSyntax = ((IDataset)osmInputTable).Workspace as ISQLSyntax; if (sqlSyntax != null) { illegalCharacters = sqlSyntax.GetInvalidCharacters(); } IFieldsEdit fieldsEdit = osmInputTable.Fields as IFieldsEdit; using (SchemaLockManager lockMgr = new SchemaLockManager(osmInputTable)) { try { string tagKey = String.Empty; ESRI.ArcGIS.Geoprocessing.IGeoProcessor2 gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass(); // if we have explicitly defined tags to extract then go through the list of values now if (extractAll == false) { for (int valueIndex = 0; valueIndex < tagCollectionGPValue.Count; valueIndex++) { if (TrackCancel.Continue() == false) { return; } try { // Check if the input field already exists. string nameofTag = tagCollectionGPValue.get_Value(valueIndex).GetAsText(); tagKey = convert2AttributeFieldName(nameofTag, illegalCharacters); int fieldIndex = osmInputTable.FindField(tagKey); if (fieldIndex < 0) { // generate a new attribute field IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = tagKey; fieldEdit.AliasName_2 = nameofTag + resourceManager.GetString("GPTools_OSMGPAttributeSelector_aliasaddition"); fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; fieldEdit.Length_2 = 100; osmInputTable.AddField(fieldEdit); message.AddMessage(string.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelector_addField"), tagKey, nameofTag)); // re-generate the attribute index fieldIndex = osmInputTable.FindField(tagKey); } if (fieldIndex > 0) { tagsAttributesIndices.Add(nameofTag, fieldIndex); attributeFieldLength.Add(fieldIndex, osmInputTable.Fields.get_Field(fieldIndex).Length); } } catch (Exception ex) { // the key is already there, this might result because from multiple upper and lower-case combinations of the same key message.AddWarning(ex.Message + " (" + convert2OSMKey(tagKey, illegalCharacters) + ")"); } } } else { List <string> listofAllTags = extractAllTags(osmInputTable, osmQueryFilter, osmTagCollectionFieldIndex); foreach (string nameOfTag in listofAllTags) { if (TrackCancel.Continue() == false) { return; } try { // Check if the input field already exists. tagKey = convert2AttributeFieldName(nameOfTag, illegalCharacters); int fieldIndex = osmInputTable.FindField(tagKey); if (fieldIndex < 0) { // generate a new attribute field IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = tagKey; fieldEdit.AliasName_2 = nameOfTag + resourceManager.GetString("GPTools_OSMGPAttributeSelector_aliasaddition"); fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; fieldEdit.Length_2 = 100; osmInputTable.AddField(fieldEdit); message.AddMessage(string.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelector_addField"), tagKey, nameOfTag)); // re-generate the attribute index fieldIndex = osmInputTable.FindField(tagKey); } if (fieldIndex > 0) { tagsAttributesIndices.Add(nameOfTag, fieldIndex); attributeFieldLength.Add(fieldIndex, osmInputTable.Fields.get_Field(fieldIndex).Length); } } catch (Exception ex) { // the key is already there, this might result because from multiple upper and lower-case combinations of the same key message.AddWarning(ex.Message + " (" + convert2OSMKey(tagKey, illegalCharacters) + ")"); } } } } catch (Exception ex) { message.AddWarning(ex.Message); } } try { execute_Utilities.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); if (osmFeatureClass != null) { if (osmFeatureClass.Extension is IOSMClassExtension) { useUpdateCursor = false; } else { useUpdateCursor = true; } } osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { execute_Utilities.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { string errorMessage = String.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelecto_unableopentable"), inputOSMGPValue.GetAsText()); message.AddError(120053, errorMessage); return; } using (ComReleaser comReleaser = new ComReleaser()) { using (SchemaLockManager lockMgr = new SchemaLockManager(osmInputTable)) { // get an update cursor for all the features to process ICursor rowCursor = null; if (useUpdateCursor) { rowCursor = osmInputTable.Update(osmQueryFilter, false); } else { rowCursor = osmInputTable.Search(osmQueryFilter, false); } comReleaser.ManageLifetime(rowCursor); IRow osmRow = null; Dictionary <string, string> tagKeys = new Dictionary <string, string>(); int progessIndex = 0; #if DEBUG message.AddMessage("useUpdateCursor: " + useUpdateCursor.ToString()); #endif // as long as there are features.... while ((osmRow = rowCursor.NextRow()) != null) { // retrieve the tags of the current feature tag[] storedTags = _osmUtility.retrieveOSMTags(osmRow, osmTagCollectionFieldIndex, ((IDataset)osmInputTable).Workspace); bool rowChanged = false; if (storedTags != null) { foreach (tag tagItem in storedTags) { // Check for matching values so we only change a minimum number of rows if (tagsAttributesIndices.ContainsKey(tagItem.k)) { int fieldIndex = tagsAttributesIndices[tagItem.k]; //...then stored the value in the attribute field // ensure that the content of the tag actually does fit into the field length...otherwise do truncate it string tagValue = tagItem.v; int fieldLength = attributeFieldLength[fieldIndex]; if (tagValue.Length > fieldLength) { tagValue = tagValue.Substring(0, fieldLength); } osmRow.set_Value(fieldIndex, tagValue); rowChanged = true; } else { #if DEBUG //message.AddWarning(tagItem.k); #endif } } } storedTags = null; try { if (rowChanged) { if (useUpdateCursor) { rowCursor.UpdateRow(osmRow); } else { // update the feature through the cursor osmRow.Store(); } } progessIndex++; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); message.AddWarning(ex.Message); } if (osmRow != null) { Marshal.ReleaseComObject(osmRow); } if (stepProgressor != null) { // update the progress UI stepProgressor.Position = progessIndex; } // check for user cancellation (every 100 rows) if ((progessIndex % 100 == 0) && (TrackCancel.Continue() == false)) { return; } } if (stepProgressor != null) { stepProgressor.Hide(); } } } execute_Utilities.ReleaseInternals(); Marshal.ReleaseComObject(execute_Utilities); } catch (Exception ex) { message.AddError(120054, ex.Message); } }
public void UpdateParameters(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager pEnvMgr) { try { IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); IGPValue inputOSMGPValue = gpUtilities3.UnpackGPValue(paramvalues.get_Element(in_osmFeatureClass)); IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { gpUtilities3.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { gpUtilities3.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { return; } String illegalCharacters = String.Empty; ISQLSyntax sqlSyntax = ((IDataset)osmInputTable).Workspace as ISQLSyntax; if (sqlSyntax != null) { illegalCharacters = sqlSyntax.GetInvalidCharacters(); } // find the field that holds tag binary/xml field int osmTagCollectionFieldIndex = osmInputTable.FindField("osmTags"); // if the Field doesn't exist - wasn't found (index = -1) get out if (osmTagCollectionFieldIndex == -1) { return; } if (((IGPParameter)paramvalues.get_Element(in_attributeSelector)).Altered) { IGPParameter tagCollectionParameter = paramvalues.get_Element(in_attributeSelector) as IGPParameter; IGPMultiValue tagCollectionGPValue = gpUtilities3.UnpackGPValue(tagCollectionParameter) as IGPMultiValue; IGPCodedValueDomain codedTagDomain = tagCollectionParameter.Domain as IGPCodedValueDomain; for (int attributeValueIndex = 0; attributeValueIndex < tagCollectionGPValue.Count; attributeValueIndex++) { string valueString = tagCollectionGPValue.get_Value(attributeValueIndex).GetAsText(); IGPValue testFieldValue = codedTagDomain.FindValue(valueString); if (testFieldValue == null) { codedTagDomain.AddStringCode(valueString, valueString); } } // Get the derived output feature class schema and empty the additional fields. This ensures // that you don't get dublicate entries. // Derived output is the third parameter, so use index 2 for get_Element. IGPParameter3 derivedFeatures = (IGPParameter3)paramvalues.get_Element(out_osmFeatureClass); IGPFeatureSchema schema = (IGPFeatureSchema)derivedFeatures.Schema; schema.AdditionalFields = null; IFieldsEdit fieldsEdit = new FieldsClass(); for (int valueIndex = 0; valueIndex < tagCollectionGPValue.Count; valueIndex++) { string tagString = tagCollectionGPValue.get_Value(valueIndex).GetAsText(); if (tagString != "ALL") { // Check if the input field already exists. string cleanedTagKey = convert2AttributeFieldName(tagString, illegalCharacters); IField tagField = gpUtilities3.FindField(inputOSMGPValue, cleanedTagKey); if (tagField == null) { IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = cleanedTagKey; fieldEdit.AliasName_2 = tagCollectionGPValue.get_Value(valueIndex).GetAsText(); fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; fieldEdit.Length_2 = 100; fieldsEdit.AddField(fieldEdit); } } } // Add the additional field to the derived output. IFields fields = fieldsEdit as IFields; schema.AdditionalFields = fields; } //if (inputOSMGPValue.IsEmpty() == false) //{ // if (((IGPParameter)paramvalues.get_Element(in_osmFeatureClass)).HasBeenValidated == false) // { // IGPParameter tagCollectionGPParameter = paramvalues.get_Element(in_attributeSelector) as IGPParameter; // IGPValue tagCollectionGPValue = gpUtilities3.UnpackGPValue(tagCollectionGPParameter); // IGPCodedValueDomain osmTagKeyCodedValues = new GPCodedValueDomainClass(); // if (((IGPMultiValue)tagCollectionGPValue).Count == 0) // { // if (osmTagKeyCodedValues == null) // extractAllTags(ref osmTagKeyCodedValues, osmInputTable, osmQueryFilter, osmTagCollectionFieldIndex, true); // if (osmTagKeyCodedValues != null) // { // tagsParameter = tagCollectionGPParameter as IGPParameterEdit; // tagsParameter.Domain = (IGPDomain)osmTagKeyCodedValues; // } // } // else // { // // let's take the given values and make then part of the domain -- if they are not already // // if we don't do this step then we won't pass the internal validation // IGPCodedValueDomain gpTagDomain = tagCollectionGPParameter.Domain as IGPCodedValueDomain; // if (gpTagDomain != null) // { // if (gpTagDomain.CodeCount == 0) // { // // let's add the value existing in the mentioned multi value to the domain // for (int i = 0; i < ((IGPMultiValue)tagCollectionGPValue).Count; i++) // { // string tagStringValue = ((IGPMultiValue)tagCollectionGPValue).get_Value(i).GetAsText(); // gpTagDomain.AddStringCode(tagStringValue, tagStringValue); // } // ((IGPParameterEdit)tagCollectionGPParameter).Domain = gpTagDomain as IGPDomain; // } // } // } // // Get the derived output feature class schema and empty the additional fields. This ensures // // that you don't get dublicate entries. // // Derived output is the third parameter, so use index 2 for get_Element. // IGPParameter3 derivedFeatures = (IGPParameter3)paramvalues.get_Element(out_osmFeatureClass); // IGPFeatureSchema schema = (IGPFeatureSchema)derivedFeatures.Schema; // schema.AdditionalFields = null; // // Area field name is the second parameter, so use index 1 for get_Element. // IGPMultiValue tagsGPMultiValue = gpUtilities3.UnpackGPValue(paramvalues.get_Element(in_attributeSelector)) as IGPMultiValue; // IFieldsEdit fieldsEdit = new FieldsClass(); // bool extractALLTags = false; // // check if the list contains the "ALL" keyword // for (int valueIndex = 0; valueIndex < tagsGPMultiValue.Count; valueIndex++) // { // if (tagsGPMultiValue.get_Value(valueIndex).GetAsText().Equals("ALL")) // { // extractALLTags = true; // } // } // if (extractALLTags) // { // if (osmTagKeyCodedValues == null) // { // extractAllTags(ref osmTagKeyCodedValues, osmInputTable, osmQueryFilter, osmTagCollectionFieldIndex, false); // } // if (osmTagKeyCodedValues != null) // { // for (int valueIndex = 0; valueIndex < osmTagKeyCodedValues.CodeCount; valueIndex++) // { // // Check if the input field already exists. // string cleanedTagKey = convert2AttributeFieldName(osmTagKeyCodedValues.get_Value(valueIndex).GetAsText(), illegalCharacters); // IField tagField = gpUtilities3.FindField(inputOSMGPValue, cleanedTagKey); // if (tagField == null) // { // IFieldEdit fieldEdit = new FieldClass(); // fieldEdit.Name_2 = cleanedTagKey; // fieldEdit.AliasName_2 = osmTagKeyCodedValues.get_Value(valueIndex).GetAsText(); // fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; // fieldEdit.Length_2 = 100; // fieldsEdit.AddField(fieldEdit); // } // } // } // } // else // { // for (int valueIndex = 0; valueIndex < tagsGPMultiValue.Count; valueIndex++) // { // // Check if the input field already exists. // string cleanedTagKey = convert2AttributeFieldName(tagsGPMultiValue.get_Value(valueIndex).GetAsText(), illegalCharacters); // IField tagField = gpUtilities3.FindField(inputOSMGPValue, cleanedTagKey); // if (tagField == null) // { // IFieldEdit fieldEdit = new FieldClass(); // fieldEdit.Name_2 = cleanedTagKey; // fieldEdit.AliasName_2 = tagsGPMultiValue.get_Value(valueIndex).GetAsText(); // fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; // fieldEdit.Length_2 = 100; // fieldsEdit.AddField(fieldEdit); // } // } // } // // Add the additional field to the derived output. // IFields fields = fieldsEdit as IFields; // schema.AdditionalFields = fields; // } //} } catch { } }
public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message) { try { IGPUtilities3 execute_Utilities = new GPUtilitiesClass(); if (TrackCancel == null) { TrackCancel = new CancelTrackerClass(); } IGPParameter inputOSMParameter = paramvalues.get_Element(in_osmFeatureClass) as IGPParameter; IGPValue inputOSMGPValue = execute_Utilities.UnpackGPValue(inputOSMParameter); IGPParameter tagCollectionParameter = paramvalues.get_Element(in_attributeSelector) as IGPParameter; IGPMultiValue tagCollectionGPValue = execute_Utilities.UnpackGPValue(tagCollectionParameter) as IGPMultiValue; if (tagCollectionGPValue == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), tagCollectionParameter.Name)); return; } bool useUpdateCursor = false; IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { execute_Utilities.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); if (osmFeatureClass != null) { if (osmFeatureClass.Extension is IOSMClassExtension) { useUpdateCursor = false; } else { useUpdateCursor = true; } } osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { execute_Utilities.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { string errorMessage = String.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelecto_unableopentable"), inputOSMGPValue.GetAsText()); message.AddError(120053, errorMessage); return; } // find the field that holds tag binary/xml field int osmTagCollectionFieldIndex = osmInputTable.FindField("osmTags"); // if the Field doesn't exist - wasn't found (index = -1) get out if (osmTagCollectionFieldIndex == -1) { message.AddError(120005, resourceManager.GetString("GPTools_OSMGPAttributeSelector_notagfieldfound")); return; } // check if the tag collection includes the keyword "ALL", if does then we'll need to extract all tags bool extractAll = false; for (int valueIndex = 0; valueIndex < tagCollectionGPValue.Count; valueIndex++) { if (tagCollectionGPValue.get_Value(valueIndex).GetAsText().Equals("ALL")) { extractAll = true; break; } } //if (extractAll) //{ // if (osmTagKeyCodedValues == null) // extractAllTags(ref osmTagKeyCodedValues, osmInputTable, osmQueryFilter, osmTagCollectionFieldIndex, false); // if (osmTagKeyCodedValues == null) // { // message.AddAbort(resourceManager.GetString("GPTools_OSMGPAttributeSelector_Unable2RetrieveTags")); // return; // } // // empty the existing gp multivalue object // tagCollectionGPValue = new GPMultiValueClass(); // // fill the coded domain in gp multivalue object // for (int valueIndex = 0; valueIndex < osmTagKeyCodedValues.CodeCount; valueIndex++) // { // tagCollectionGPValue.AddValue(osmTagKeyCodedValues.get_Value(valueIndex)); // } //} // get an overall feature count as that determines the progress indicator int featureCount = osmInputTable.RowCount(osmQueryFilter); // set up the progress indicator IStepProgressor stepProgressor = TrackCancel as IStepProgressor; if (stepProgressor != null) { stepProgressor.MinRange = 0; stepProgressor.MaxRange = featureCount; stepProgressor.Position = 0; stepProgressor.Message = resourceManager.GetString("GPTools_OSMGPAttributeSelector_progressMessage"); stepProgressor.StepValue = 1; stepProgressor.Show(); } // let's get all the indices of the desired fields // if the field already exists get the index and if it doesn't exist create it Dictionary<string, int> tagsAttributesIndices = new Dictionary<string, int>(); Dictionary<int, int> attributeFieldLength = new Dictionary<int, int>(); IFeatureWorkspaceManage featureWorkspaceManage = ((IDataset)osmInputTable).Workspace as IFeatureWorkspaceManage; String illegalCharacters = String.Empty; ISQLSyntax sqlSyntax = ((IDataset)osmInputTable).Workspace as ISQLSyntax; if (sqlSyntax != null) { illegalCharacters = sqlSyntax.GetInvalidCharacters(); } IFieldsEdit fieldsEdit = osmInputTable.Fields as IFieldsEdit; using (SchemaLockManager lockMgr = new SchemaLockManager(osmInputTable)) { try { string tagKey = String.Empty; ESRI.ArcGIS.Geoprocessing.IGeoProcessor2 gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass(); // if we have explicitly defined tags to extract then go through the list of values now if (extractAll == false) { for (int valueIndex = 0; valueIndex < tagCollectionGPValue.Count; valueIndex++) { if (TrackCancel.Continue() == false) return; try { // Check if the input field already exists. string nameofTag = tagCollectionGPValue.get_Value(valueIndex).GetAsText(); tagKey = convert2AttributeFieldName(nameofTag, illegalCharacters); int fieldIndex = osmInputTable.FindField(tagKey); if (fieldIndex < 0) { // generate a new attribute field IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = tagKey; fieldEdit.AliasName_2 = nameofTag + resourceManager.GetString("GPTools_OSMGPAttributeSelector_aliasaddition"); fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; fieldEdit.Length_2 = 100; osmInputTable.AddField(fieldEdit); message.AddMessage(string.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelector_addField"), tagKey, nameofTag)); // re-generate the attribute index fieldIndex = osmInputTable.FindField(tagKey); } if (fieldIndex > 0) { tagsAttributesIndices.Add(nameofTag, fieldIndex); attributeFieldLength.Add(fieldIndex, osmInputTable.Fields.get_Field(fieldIndex).Length); } } catch (Exception ex) { // the key is already there, this might result because from multiple upper and lower-case combinations of the same key message.AddWarning(ex.Message + " (" + convert2OSMKey(tagKey, illegalCharacters) + ")"); } } } else { List<string> listofAllTags = extractAllTags(osmInputTable, osmQueryFilter, osmTagCollectionFieldIndex); foreach (string nameOfTag in listofAllTags) { if (TrackCancel.Continue() == false) return; try { // Check if the input field already exists. tagKey = convert2AttributeFieldName(nameOfTag, illegalCharacters); int fieldIndex = osmInputTable.FindField(tagKey); if (fieldIndex < 0) { // generate a new attribute field IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = tagKey; fieldEdit.AliasName_2 = nameOfTag + resourceManager.GetString("GPTools_OSMGPAttributeSelector_aliasaddition"); fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; fieldEdit.Length_2 = 100; osmInputTable.AddField(fieldEdit); message.AddMessage(string.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelector_addField"), tagKey, nameOfTag)); // re-generate the attribute index fieldIndex = osmInputTable.FindField(tagKey); } if (fieldIndex > 0) { tagsAttributesIndices.Add(nameOfTag, fieldIndex); attributeFieldLength.Add(fieldIndex, osmInputTable.Fields.get_Field(fieldIndex).Length); } } catch (Exception ex) { // the key is already there, this might result because from multiple upper and lower-case combinations of the same key message.AddWarning(ex.Message + " (" + convert2OSMKey(tagKey, illegalCharacters) + ")"); } } } } catch (Exception ex) { message.AddWarning(ex.Message); } } try { execute_Utilities.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); if (osmFeatureClass != null) { if (osmFeatureClass.Extension is IOSMClassExtension) { useUpdateCursor = false; } else { useUpdateCursor = true; } } osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { execute_Utilities.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { string errorMessage = String.Format(resourceManager.GetString("GPTools_OSMGPAttributeSelecto_unableopentable"), inputOSMGPValue.GetAsText()); message.AddError(120053, errorMessage); return; } using (ComReleaser comReleaser = new ComReleaser()) { using (SchemaLockManager lockMgr = new SchemaLockManager(osmInputTable)) { // get an update cursor for all the features to process ICursor rowCursor = null; if (useUpdateCursor) { rowCursor = osmInputTable.Update(osmQueryFilter, false); } else { rowCursor = osmInputTable.Search(osmQueryFilter, false); } comReleaser.ManageLifetime(rowCursor); IRow osmRow = null; Dictionary<string, string> tagKeys = new Dictionary<string, string>(); int progessIndex = 0; #if DEBUG message.AddMessage("useUpdateCursor: " + useUpdateCursor.ToString()); #endif // as long as there are features.... while ((osmRow = rowCursor.NextRow()) != null) { // retrieve the tags of the current feature tag[] storedTags = _osmUtility.retrieveOSMTags(osmRow, osmTagCollectionFieldIndex, ((IDataset)osmInputTable).Workspace); bool rowChanged = false; if (storedTags != null) { foreach (tag tagItem in storedTags) { // Check for matching values so we only change a minimum number of rows if (tagsAttributesIndices.ContainsKey(tagItem.k)) { int fieldIndex = tagsAttributesIndices[tagItem.k]; //...then stored the value in the attribute field // ensure that the content of the tag actually does fit into the field length...otherwise do truncate it string tagValue = tagItem.v; int fieldLength = attributeFieldLength[fieldIndex]; if (tagValue.Length > fieldLength) tagValue = tagValue.Substring(0, fieldLength); osmRow.set_Value(fieldIndex, tagValue); rowChanged = true; } else { #if DEBUG //message.AddWarning(tagItem.k); #endif } } } storedTags = null; try { if (rowChanged) { if (useUpdateCursor) { rowCursor.UpdateRow(osmRow); } else { // update the feature through the cursor osmRow.Store(); } } progessIndex++; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); message.AddWarning(ex.Message); } if (osmRow != null) { Marshal.ReleaseComObject(osmRow); } if (stepProgressor != null) { // update the progress UI stepProgressor.Position = progessIndex; } // check for user cancellation (every 100 rows) if ((progessIndex % 100 == 0) && (TrackCancel.Continue() == false)) { return; } } if (stepProgressor != null) { stepProgressor.Hide(); } } } execute_Utilities.ReleaseInternals(); Marshal.ReleaseComObject(execute_Utilities); } catch (Exception ex) { message.AddError(120054, ex.Message); } }
public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message) { try { IGPUtilities3 execute_Utilities = new GPUtilitiesClass(); OSMUtility osmUtility = new OSMUtility(); if (TrackCancel == null) { TrackCancel = new CancelTrackerClass(); } IGPParameter inputOSMParameter = paramvalues.get_Element(in_osmFeatureClassNumber) as IGPParameter; IGPValue inputOSMGPValue = execute_Utilities.UnpackGPValue(inputOSMParameter); IGPParameter tagFieldsParameter = paramvalues.get_Element(in_attributeSelectorNumber) as IGPParameter; IGPMultiValue tagCollectionGPValue = execute_Utilities.UnpackGPValue(tagFieldsParameter) as IGPMultiValue; if (tagCollectionGPValue == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), tagFieldsParameter.Name)); return; } IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { execute_Utilities.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { execute_Utilities.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { return; } // find the field that holds tag binary/xml field int osmTagCollectionFieldIndex = osmInputTable.FindField("osmTags"); // if the Field doesn't exist - wasn't found (index = -1) get out if (osmTagCollectionFieldIndex == -1) { message.AddError(120005, resourceManager.GetString("GPTools_OSMGPAttributeSelector_notagfieldfound")); return; } // set up the progress indicator IStepProgressor stepProgressor = TrackCancel as IStepProgressor; if (stepProgressor != null) { int featureCount = osmInputTable.RowCount(osmQueryFilter); stepProgressor.MinRange = 0; stepProgressor.MaxRange = featureCount; stepProgressor.Position = 0; stepProgressor.Message = resourceManager.GetString("GPTools_OSMGPCombineAttributes_progressMessage"); stepProgressor.StepValue = 1; stepProgressor.Show(); } String illegalCharacters = String.Empty; ISQLSyntax sqlSyntax = ((IDataset)osmInputTable).Workspace as ISQLSyntax; if (sqlSyntax != null) { illegalCharacters = sqlSyntax.GetInvalidCharacters(); } // establish the list of field indexes only once Dictionary <string, int> fieldIndexes = new Dictionary <string, int>(); for (int selectedGPValueIndex = 0; selectedGPValueIndex < tagCollectionGPValue.Count; selectedGPValueIndex++) { // find the field index int fieldIndex = osmInputTable.FindField(tagCollectionGPValue.get_Value(selectedGPValueIndex).GetAsText()); if (fieldIndex != -1) { string tagKeyName = osmInputTable.Fields.get_Field(fieldIndex).Name; tagKeyName = OSMToolHelper.convert2OSMKey(tagKeyName, illegalCharacters); fieldIndexes.Add(tagKeyName, fieldIndex); } } ICursor updateCursor = null; IRow osmRow = null; using (ComReleaser comReleaser = new ComReleaser()) { updateCursor = osmInputTable.Update(osmQueryFilter, false); comReleaser.ManageLifetime(updateCursor); osmRow = updateCursor.NextRow(); int progressIndex = 0; while (osmRow != null) { // get the current tag collection from the row ESRI.ArcGIS.OSM.OSMClassExtension.tag[] osmTags = osmUtility.retrieveOSMTags(osmRow, osmTagCollectionFieldIndex, ((IDataset)osmInputTable).Workspace); Dictionary <string, string> tagsDictionary = new Dictionary <string, string>(); for (int tagIndex = 0; tagIndex < osmTags.Length; tagIndex++) { tagsDictionary.Add(osmTags[tagIndex].k, osmTags[tagIndex].v); } // look if the tag needs to be updated or added bool tagsUpdated = false; foreach (var fieldItem in fieldIndexes) { object fldValue = osmRow.get_Value(fieldItem.Value); if (fldValue != System.DBNull.Value) { if (tagsDictionary.ContainsKey(fieldItem.Key)) { if (!tagsDictionary[fieldItem.Key].Equals(fldValue)) { tagsDictionary[fieldItem.Key] = Convert.ToString(fldValue); tagsUpdated = true; } } else { tagsDictionary.Add(fieldItem.Key, Convert.ToString(fldValue)); tagsUpdated = true; } } else { if (tagsDictionary.ContainsKey(fieldItem.Key)) { tagsDictionary.Remove(fieldItem.Key); tagsUpdated = true; } } } if (tagsUpdated) { List <ESRI.ArcGIS.OSM.OSMClassExtension.tag> updatedTags = new List <ESRI.ArcGIS.OSM.OSMClassExtension.tag>(); foreach (var tagItem in tagsDictionary) { ESRI.ArcGIS.OSM.OSMClassExtension.tag newTag = new ESRI.ArcGIS.OSM.OSMClassExtension.tag(); newTag.k = tagItem.Key; newTag.v = tagItem.Value; updatedTags.Add(newTag); } // insert the tags back into the collection field if (updatedTags.Count != 0) { osmUtility.insertOSMTags(osmTagCollectionFieldIndex, osmRow, updatedTags.ToArray(), ((IDataset)osmInputTable).Workspace); updateCursor.UpdateRow(osmRow); } } progressIndex++; if (stepProgressor != null) { stepProgressor.Position = progressIndex; } if (osmRow != null) { Marshal.ReleaseComObject(osmRow); } osmRow = updateCursor.NextRow(); } if (stepProgressor != null) { stepProgressor.Hide(); } } } catch (Exception ex) { message.AddError(120007, ex.Message); } }
public void UpdateParameters(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager pEnvMgr) { try { IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); IGPParameter inputOSMParameter = paramvalues.get_Element(in_osmFeatureClassNumber) as IGPParameter; IGPValue inputOSMGPValue = gpUtilities3.UnpackGPValue(inputOSMParameter); if (inputOSMGPValue.IsEmpty() == false) { if (inputOSMParameter.Altered == true) { IGPParameter attributeCollectionParameter = paramvalues.get_Element(in_attributeSelectorNumber) as IGPParameter; IGPValue attributeCollectionGPValue = gpUtilities3.UnpackGPValue(attributeCollectionParameter); if (inputOSMParameter.HasBeenValidated == false && ((IGPMultiValue)attributeCollectionGPValue).Count == 0) { IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { gpUtilities3.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { gpUtilities3.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { return; } using (ComReleaser comReleaser = new ComReleaser()) { ICursor osmCursor = osmInputTable.Search(osmQueryFilter, true); comReleaser.ManageLifetime(osmCursor); IRow osmRow = osmCursor.NextRow(); List <string> potentialOSMFields = new List <string>(); if (osmRow != null) { IFields osmFields = osmRow.Fields; for (int fieldIndex = 0; fieldIndex < osmFields.FieldCount; fieldIndex++) { if (osmFields.get_Field(fieldIndex).Name.Substring(0, 4).Equals("osm_")) { potentialOSMFields.Add(osmFields.get_Field(fieldIndex).Name); } } } if (potentialOSMFields.Count == 0) { return; } IGPCodedValueDomain osmTagKeyCodedValues = new GPCodedValueDomainClass(); foreach (string tagOSMField in potentialOSMFields) { osmTagKeyCodedValues.AddStringCode(tagOSMField, tagOSMField); } ((IGPParameterEdit)attributeCollectionParameter).Domain = (IGPDomain)osmTagKeyCodedValues; } } } } } catch { } }
public void UpdateParameters(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager pEnvMgr) { try { IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); IGPParameter inputOSMParameter = paramvalues.get_Element(in_osmFeatureClassNumber) as IGPParameter; IGPValue inputOSMGPValue = gpUtilities3.UnpackGPValue(inputOSMParameter); if (inputOSMGPValue.IsEmpty() == false) { if (inputOSMParameter.Altered == true) { IGPParameter attributeCollectionParameter = paramvalues.get_Element(in_attributeSelectorNumber) as IGPParameter; IGPValue attributeCollectionGPValue = gpUtilities3.UnpackGPValue(attributeCollectionParameter); if (inputOSMParameter.HasBeenValidated == false && ((IGPMultiValue)attributeCollectionGPValue).Count == 0) { IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { gpUtilities3.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { gpUtilities3.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { return; } using (ComReleaser comReleaser = new ComReleaser()) { ICursor osmCursor = osmInputTable.Search(osmQueryFilter, true); comReleaser.ManageLifetime(osmCursor); IRow osmRow = osmCursor.NextRow(); List<string> potentialOSMFields = new List<string>(); if (osmRow != null) { IFields osmFields = osmRow.Fields; for (int fieldIndex = 0; fieldIndex < osmFields.FieldCount; fieldIndex++) { if (osmFields.get_Field(fieldIndex).Name.Substring(0, 4).Equals("osm_")) { potentialOSMFields.Add(osmFields.get_Field(fieldIndex).Name); } } } if (potentialOSMFields.Count == 0) { return; } IGPCodedValueDomain osmTagKeyCodedValues = new GPCodedValueDomainClass(); foreach (string tagOSMField in potentialOSMFields) { osmTagKeyCodedValues.AddStringCode(tagOSMField, tagOSMField); } ((IGPParameterEdit)attributeCollectionParameter).Domain = (IGPDomain)osmTagKeyCodedValues; } } } } } catch { } }
public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message) { try { IGPUtilities3 execute_Utilities = new GPUtilitiesClass(); OSMUtility osmUtility = new OSMUtility(); if (TrackCancel == null) { TrackCancel = new CancelTrackerClass(); } IGPParameter inputOSMParameter = paramvalues.get_Element(in_osmFeatureClassNumber) as IGPParameter; IGPValue inputOSMGPValue = execute_Utilities.UnpackGPValue(inputOSMParameter); IGPParameter tagFieldsParameter = paramvalues.get_Element(in_attributeSelectorNumber) as IGPParameter; IGPMultiValue tagCollectionGPValue = execute_Utilities.UnpackGPValue(tagFieldsParameter) as IGPMultiValue; if (tagCollectionGPValue == null) { message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), tagFieldsParameter.Name)); return; } IFeatureClass osmFeatureClass = null; ITable osmInputTable = null; IQueryFilter osmQueryFilter = null; try { execute_Utilities.DecodeFeatureLayer(inputOSMGPValue, out osmFeatureClass, out osmQueryFilter); osmInputTable = osmFeatureClass as ITable; } catch { } try { if (osmInputTable == null) { execute_Utilities.DecodeTableView(inputOSMGPValue, out osmInputTable, out osmQueryFilter); } } catch { } if (osmInputTable == null) { return; } // find the field that holds tag binary/xml field int osmTagCollectionFieldIndex = osmInputTable.FindField("osmTags"); // if the Field doesn't exist - wasn't found (index = -1) get out if (osmTagCollectionFieldIndex == -1) { message.AddError(120005, resourceManager.GetString("GPTools_OSMGPAttributeSelector_notagfieldfound")); return; } // set up the progress indicator IStepProgressor stepProgressor = TrackCancel as IStepProgressor; if (stepProgressor != null) { int featureCount = osmInputTable.RowCount(osmQueryFilter); stepProgressor.MinRange = 0; stepProgressor.MaxRange = featureCount; stepProgressor.Position = 0; stepProgressor.Message = resourceManager.GetString("GPTools_OSMGPCombineAttributes_progressMessage"); stepProgressor.StepValue = 1; stepProgressor.Show(); } String illegalCharacters = String.Empty; ISQLSyntax sqlSyntax = ((IDataset)osmInputTable).Workspace as ISQLSyntax; if (sqlSyntax != null) { illegalCharacters = sqlSyntax.GetInvalidCharacters(); } // establish the list of field indexes only once Dictionary<string, int> fieldIndexes = new Dictionary<string, int>(); for (int selectedGPValueIndex = 0; selectedGPValueIndex < tagCollectionGPValue.Count; selectedGPValueIndex++) { // find the field index int fieldIndex = osmInputTable.FindField(tagCollectionGPValue.get_Value(selectedGPValueIndex).GetAsText()); if (fieldIndex != -1) { string tagKeyName = osmInputTable.Fields.get_Field(fieldIndex).Name; tagKeyName = OSMToolHelper.convert2OSMKey(tagKeyName, illegalCharacters); fieldIndexes.Add(tagKeyName, fieldIndex); } } ICursor updateCursor = null; IRow osmRow = null; using (ComReleaser comReleaser = new ComReleaser()) { updateCursor = osmInputTable.Update(osmQueryFilter, false); comReleaser.ManageLifetime(updateCursor); osmRow = updateCursor.NextRow(); int progressIndex = 0; while (osmRow != null) { // get the current tag collection from the row ESRI.ArcGIS.OSM.OSMClassExtension.tag[] osmTags = osmUtility.retrieveOSMTags(osmRow, osmTagCollectionFieldIndex, ((IDataset)osmInputTable).Workspace); Dictionary<string, string> tagsDictionary = new Dictionary<string, string>(); for (int tagIndex = 0; tagIndex < osmTags.Length; tagIndex++) { tagsDictionary.Add(osmTags[tagIndex].k, osmTags[tagIndex].v); } // look if the tag needs to be updated or added bool tagsUpdated = false; foreach (var fieldItem in fieldIndexes) { object fldValue = osmRow.get_Value(fieldItem.Value); if (fldValue != System.DBNull.Value) { if (tagsDictionary.ContainsKey(fieldItem.Key)) { if (!tagsDictionary[fieldItem.Key].Equals(fldValue)) { tagsDictionary[fieldItem.Key] = Convert.ToString(fldValue); tagsUpdated = true; } } else { tagsDictionary.Add(fieldItem.Key, Convert.ToString(fldValue)); tagsUpdated = true; } } } if (tagsUpdated) { List<ESRI.ArcGIS.OSM.OSMClassExtension.tag> updatedTags = new List<ESRI.ArcGIS.OSM.OSMClassExtension.tag>(); foreach (var tagItem in tagsDictionary) { ESRI.ArcGIS.OSM.OSMClassExtension.tag newTag = new ESRI.ArcGIS.OSM.OSMClassExtension.tag(); newTag.k = tagItem.Key; newTag.v = tagItem.Value; updatedTags.Add(newTag); } // insert the tags back into the collection field if (updatedTags.Count != 0) { osmUtility.insertOSMTags(osmTagCollectionFieldIndex, osmRow, updatedTags.ToArray(), ((IDataset)osmInputTable).Workspace); updateCursor.UpdateRow(osmRow); } } progressIndex++; if (stepProgressor != null) { stepProgressor.Position = progressIndex; } if (osmRow != null) Marshal.ReleaseComObject(osmRow); osmRow = updateCursor.NextRow(); } if (stepProgressor != null) { stepProgressor.Hide(); } } } catch (Exception ex) { message.AddError(120007, ex.Message); } }