private ESRI.ArcGIS.OSM.OSMClassExtension.way CreateWayRepresentation(IFeatureClass featureClass, string action, long osmID, string changeSetID, int osmVersion, Dictionary<long, long> osmIDLookup, IFeatureClass pointFeatureClass, int pointOSMIDFieldIndex, int extensionVersion) { way wayRepresentation = new way(); // let's find all the rows that have a different status than 200 - meaning success IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.WhereClause = featureClass.WhereClauseByExtensionVersion(osmID, "OSMID", extensionVersion); using (ComReleaser comReleaser = new ComReleaser()) { IFeatureCursor searchCursor = featureClass.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); IFeature wayFeature = searchCursor.NextFeature(); int osmTagsFieldIndex = featureClass.Fields.FindField("osmTags"); int osmIDFieldIndex = featureClass.Fields.FindField("osmID"); int osmUserFieldIndex = featureClass.Fields.FindField("osmuser"); int osmUIDFieldIndex = featureClass.Fields.FindField("osmuid"); int osmVisibleFieldIndex = featureClass.Fields.FindField("osmvisible"); int osmVersionFieldIndex = featureClass.Fields.FindField("osmversion"); if (wayFeature != null) { switch (action) { case "create": // the newly created node needs to carry the changeset info, the coordinate and the tags wayRepresentation.changeset = changeSetID; tag[] tags = null; if (osmTagsFieldIndex > -1) { tags = _osmUtility.retrieveOSMTags((IRow)wayFeature, osmTagsFieldIndex, ((IDataset)featureClass).Workspace); } List<tag> valueOnlyTags = new List<tag>(); for (int index = 0; index < tags.Length; index++) { if (!String.IsNullOrEmpty(tags[index].v)) { valueOnlyTags.Add(tags[index]); } } wayRepresentation.tag = valueOnlyTags.ToArray(); if (osmIDFieldIndex > -1) { wayRepresentation.id = osmID.ToString(); } List<nd> nodeList = new List<nd>(); IPointCollection pointCollection = wayFeature.Shape as IPointCollection; IEnumVertex enumVertex = pointCollection.EnumVertices; enumVertex.Reset(); IPoint currentPoint = null; int vertexIndex = -1; int partIndex = -1; bool isStoreRequired = false; enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); while (currentPoint != null) { if (osmIDLookup.ContainsKey(currentPoint.ID)) { if (extensionVersion == 1) { enumVertex.put_ID(Convert.ToInt32(osmIDLookup[currentPoint.ID])); isStoreRequired = true; } else if (extensionVersion == 2) { // the initial established ObjectIDs don't change } } nd ndElement = new nd(); ndElement.@ref = OSMToolHelper.retrieveNodeID(pointFeatureClass, osmIDFieldIndex, extensionVersion, pointCollection.get_Point(vertexIndex)); nodeList.Add(ndElement); enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); } // only do a store operation if the vertex IDs have actually changed if (isStoreRequired) { wayFeature.Shape = (IGeometry)pointCollection; wayFeature.Store(); } nodeList = CorrectNodeIDs(nodeList); wayRepresentation.nd = nodeList.ToArray(); break; case "modify": // for an update the complete (full) way needs to be returned wayRepresentation.changeset = changeSetID; if (osmIDFieldIndex > -1) { wayRepresentation.id = Convert.ToString(wayFeature.get_Value(osmIDFieldIndex), new CultureInfo("en-US")); } if (osmUserFieldIndex > -1) { wayRepresentation.user = Convert.ToString(wayFeature.get_Value(osmUserFieldIndex)); } if (osmUIDFieldIndex > -1) { wayRepresentation.uid = Convert.ToString(wayFeature.get_Value(osmUIDFieldIndex), new CultureInfo("en-US")); } if (osmVisibleFieldIndex > -1) { try { wayRepresentation.visible = (wayVisible)Enum.Parse(typeof(wayVisible), Convert.ToString(wayFeature.get_Value(osmVisibleFieldIndex))); } catch { wayRepresentation.visible = wayVisible.@true; } } if (osmVersionFieldIndex > -1) { wayRepresentation.version = Convert.ToString(wayFeature.get_Value(osmVersionFieldIndex)); } tags = null; if (osmTagsFieldIndex > -1) { tags = _osmUtility.retrieveOSMTags((IRow)wayFeature, osmTagsFieldIndex, ((IDataset)featureClass).Workspace); } valueOnlyTags = new List<tag>(); for (int index = 0; index < tags.Length; index++) { if (!String.IsNullOrEmpty(tags[index].v)) { valueOnlyTags.Add(tags[index]); } } pointCollection = wayFeature.Shape as IPointCollection; enumVertex = pointCollection.EnumVertices; enumVertex.Reset(); currentPoint = null; vertexIndex = -1; partIndex = -1; // use flag if we need to call store on the update feature // it is somewhat of a costly operation and we would like to avoid it if possible isStoreRequired = false; nodeList = new List<nd>(); enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); while (currentPoint != null) { if (osmIDLookup.ContainsKey(currentPoint.ID)) { if (extensionVersion == 1) { enumVertex.put_ID(Convert.ToInt32(osmIDLookup[currentPoint.ID])); isStoreRequired = true; } else if (extensionVersion == 2) { // the ObjectIDs of the referenced features don't change } } nd ndElement = new nd(); ndElement.@ref = OSMToolHelper.retrieveNodeID(pointFeatureClass, osmIDFieldIndex, extensionVersion, pointCollection.get_Point(vertexIndex)); nodeList.Add(ndElement); enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); } if (isStoreRequired) { wayFeature.Shape = (IGeometry)pointCollection; wayFeature.Store(); } nodeList = CorrectNodeIDs(nodeList); wayRepresentation.nd = nodeList.ToArray(); wayRepresentation.tag = valueOnlyTags.ToArray(); break; case "delete": wayRepresentation.changeset = changeSetID; wayRepresentation.id = Convert.ToString(osmID); wayRepresentation.version = Convert.ToString(osmVersion); break; default: break; } } else { if (action.Equals("delete", StringComparison.InvariantCultureIgnoreCase)) { wayRepresentation.changeset = changeSetID; wayRepresentation.id = Convert.ToString(osmID); wayRepresentation.version = Convert.ToString(osmVersion); } } } return wayRepresentation; }
private way ConvertFeatureToOSMWay(IFeature currentFeature, IWorkspace featureWorkspace, IFeatureClass pointFeatureClass, int osmIDPointFieldIndex, int tagsFieldIndex, int osmIDFieldIndex, int changesetIDFieldIndex, int osmVersionFieldIndex, int userIDFieldIndex, int userNameFieldIndex, int timeStampFieldIndex, int visibleFieldIndex, int extensionVersion) { if (currentFeature == null) throw new ArgumentNullException("currentFeature"); way osmWay = new way(); object featureValue = DBNull.Value; List<nd> vertexIDs = new List<nd>(); if (currentFeature.Shape.IsEmpty == false) { IPointCollection pointCollection = currentFeature.Shape as IPointCollection; if (currentFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon) { for (int pointIndex = 0; pointIndex < pointCollection.PointCount - 1; pointIndex++) { nd vertex = new nd(); vertex.@ref = OSMToolHelper.retrieveNodeID(pointFeatureClass, osmIDPointFieldIndex, extensionVersion, pointCollection.get_Point(pointIndex)); vertexIDs.Add(vertex); } // the last node is the first one again even though it doesn't have an internal ID nd lastVertex = new nd(); lastVertex.@ref = OSMToolHelper.retrieveNodeID(pointFeatureClass, osmIDPointFieldIndex, extensionVersion, pointCollection.get_Point(0)); vertexIDs.Add(lastVertex); } else { for (int pointIndex = 0; pointIndex < pointCollection.PointCount; pointIndex++) { nd vertex = new nd(); vertex.@ref = OSMToolHelper.retrieveNodeID(pointFeatureClass, osmIDPointFieldIndex, extensionVersion, pointCollection.get_Point(pointIndex)); vertexIDs.Add(vertex); } } osmWay.nd = vertexIDs.ToArray(); } if (osmIDFieldIndex != -1) { osmWay.id = Convert.ToString(currentFeature.get_Value(osmIDFieldIndex)); } if (changesetIDFieldIndex != -1) { featureValue = currentFeature.get_Value(changesetIDFieldIndex); if (featureValue != DBNull.Value) { osmWay.changeset = Convert.ToString(currentFeature.get_Value(changesetIDFieldIndex)); } } if (osmVersionFieldIndex != -1) { featureValue = currentFeature.get_Value(osmVersionFieldIndex); if (featureValue != DBNull.Value) { osmWay.version = Convert.ToString(featureValue); } } if (userIDFieldIndex != -1) { featureValue = currentFeature.get_Value(userIDFieldIndex); if (featureValue != DBNull.Value) { osmWay.uid = Convert.ToString(featureValue); } } if (userNameFieldIndex != -1) { featureValue = currentFeature.get_Value(userNameFieldIndex); if (featureValue != DBNull.Value) { osmWay.user = Convert.ToString(featureValue); } } if (timeStampFieldIndex != -1) { featureValue = currentFeature.get_Value(timeStampFieldIndex); if (featureValue != DBNull.Value) { osmWay.timestamp = Convert.ToDateTime(featureValue).ToUniversalTime().ToString("u"); } } if (visibleFieldIndex != -1) { featureValue = currentFeature.get_Value(visibleFieldIndex); if (featureValue != DBNull.Value) { try { osmWay.visible = (wayVisible)Enum.Parse(typeof(wayVisible), Convert.ToString(featureValue)); } catch { osmWay.visible = wayVisible.@true; } } } if (tagsFieldIndex > -1) { tag[] tags = null; tags = _osmUtility.retrieveOSMTags((IRow)currentFeature, tagsFieldIndex, featureWorkspace); if (tags.Length != 0) { osmWay.tag = tags; } } return osmWay; }