private void updateSource(ITable sourceTable, string action, long oldOSMFeatureID, long newOSMFeatureID, string userName, int userID, int osmVersion, int changeSetID, Dictionary<long, long> nodeIDLookup, Dictionary<long, long> wayIDLookup, Dictionary<long, long> relationIDLookup, int extensionVersion) { IOSMClassExtension osmExtension = sourceTable.Extension as IOSMClassExtension; try { if (osmExtension != null) { osmExtension.CanBypassChangeDetection = true; } // let's find all the matching row with the old osm feature ID IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.WhereClause = sourceTable.WhereClauseByExtensionVersion(oldOSMFeatureID, "osmID", extensionVersion); using (ComReleaser comReleaser = new ComReleaser()) { ICursor updateCursor = sourceTable.Update(queryFilter, false); comReleaser.ManageLifetime(updateCursor); IRow updateRow = updateCursor.NextRow(); comReleaser.ManageLifetime(updateRow); int osmIDFieldIndex = sourceTable.Fields.FindField("osmID"); int osmUserFieldIndex = sourceTable.Fields.FindField("osmuser"); int osmUIDFieldIndex = sourceTable.Fields.FindField("osmuid"); int osmVersionFieldIndex = sourceTable.Fields.FindField("osmversion"); int osmVisibleFieldIndex = sourceTable.Fields.FindField("osmvisible"); int osmChangesetIDFieldIndex = sourceTable.Fields.FindField("osmchangeset"); int osmTimeStampFieldIndex = sourceTable.Fields.FindField("osmtimestamp"); int osmMembersFieldIndex = sourceTable.FindField("osmMembers"); int osmisMemberOfFieldIndex = sourceTable.FindField("osmMemberOf"); int trackChangesFieldIndex = sourceTable.FindField("osmTrackChanges"); if (updateRow != null) { if (osmIDFieldIndex > -1) { if (extensionVersion == 1) updateRow.set_Value(osmIDFieldIndex, Convert.ToInt32(newOSMFeatureID)); else if (extensionVersion == 2) updateRow.set_Value(osmIDFieldIndex, Convert.ToString(newOSMFeatureID)); } if (osmUserFieldIndex > -1) { updateRow.set_Value(osmUserFieldIndex, userName); } if (osmUIDFieldIndex > -1) { updateRow.set_Value(osmUIDFieldIndex, userID); } if (osmVisibleFieldIndex > -1) { updateRow.set_Value(osmVisibleFieldIndex, "true"); } if (osmChangesetIDFieldIndex > -1) { updateRow.set_Value(osmChangesetIDFieldIndex, changeSetID); } if (osmTimeStampFieldIndex > -1) { updateRow.set_Value(osmTimeStampFieldIndex, DateTime.Now.ToUniversalTime()); } if (trackChangesFieldIndex > -1) { updateRow.set_Value(trackChangesFieldIndex, 1); } // if we are dealing with a row with a shape field (a feature), then change the IDs of the geometry as well IFeature updateFeature = updateRow as IFeature; if (updateFeature != null) { if (updateFeature.Shape.IsEmpty == false) { switch (updateFeature.Shape.GeometryType) { case esriGeometryType.esriGeometryAny: break; case esriGeometryType.esriGeometryBag: break; case esriGeometryType.esriGeometryBezier3Curve: break; case esriGeometryType.esriGeometryCircularArc: break; case esriGeometryType.esriGeometryEllipticArc: break; case esriGeometryType.esriGeometryEnvelope: break; case esriGeometryType.esriGeometryLine: break; case esriGeometryType.esriGeometryMultiPatch: break; case esriGeometryType.esriGeometryMultipoint: break; case esriGeometryType.esriGeometryNull: break; case esriGeometryType.esriGeometryPath: break; case esriGeometryType.esriGeometryPoint: IPoint featurePoint = updateFeature.Shape as IPoint; if (extensionVersion == 1) featurePoint.ID = Convert.ToInt32(newOSMFeatureID); else if (extensionVersion == 2) // nothing required as the ObjectID of there referenced feature doesn't change updateFeature.Shape = featurePoint; if (featurePoint != null) ComReleaser.ReleaseCOMObject(featurePoint); break; case esriGeometryType.esriGeometryPolygon: IPointCollection pointCollection = updateFeature.Shape as IPointCollection; IEnumVertex enumVertex = pointCollection.EnumVertices; enumVertex.Reset(); IPoint currentPoint = null; int vertexIndex = -1; int partIndex = -1; enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); while (currentPoint != null) { if (extensionVersion == 1) { if (nodeIDLookup.ContainsKey(currentPoint.ID)) { enumVertex.put_ID(Convert.ToInt32(nodeIDLookup[currentPoint.ID])); } } else if (extensionVersion == 2) { // nothing required as the ObjectIDs of referenced features don't change } enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); } updateFeature.Shape = (IGeometry)pointCollection; // if we are dealing with a multi-part feature then we will need to referenced members as well break; case esriGeometryType.esriGeometryPolyline: pointCollection = updateFeature.Shape as IPointCollection; enumVertex = pointCollection.EnumVertices; enumVertex.Reset(); currentPoint = null; vertexIndex = -1; partIndex = -1; enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); while (currentPoint != null) { if (extensionVersion == 1) { if (nodeIDLookup.ContainsKey(currentPoint.ID)) { enumVertex.put_ID(Convert.ToInt32(nodeIDLookup[currentPoint.ID])); } } else if (extensionVersion == 2) { // nothing required as the ObjectIDs of referenced features don't change } enumVertex.Next(out currentPoint, out partIndex, out vertexIndex); } updateFeature.Shape = (IGeometry)pointCollection; // if we are dealing with a multi-part feature then we will need to referenced members as well break; case esriGeometryType.esriGeometryRay: break; case esriGeometryType.esriGeometryRing: break; case esriGeometryType.esriGeometrySphere: break; case esriGeometryType.esriGeometryTriangleFan: break; case esriGeometryType.esriGeometryTriangleStrip: break; case esriGeometryType.esriGeometryTriangles: break; default: break; } } } if (osmisMemberOfFieldIndex > -1) { List<string> isMemberOfList = _osmUtility.retrieveIsMemberOf(updateRow, osmisMemberOfFieldIndex); if (isMemberOfList != null && isMemberOfList.Count > 0) { List<string> newIsMemberOfList = new List<string>(); if (((IDataset)sourceTable).Name.Contains("_osm_ln") || ((IDataset)sourceTable).Name.Contains("_osm_ply")) { // since version 1.1 is only dealing with homogeneous features - lines/polygons // or in other words only ways we only go through the way look up at this point foreach (string parentString in isMemberOfList) { long idToCheck = Convert.ToInt64(parentString); if (wayIDLookup.ContainsKey(idToCheck)) { newIsMemberOfList.Add(wayIDLookup[idToCheck].ToString()); } else { newIsMemberOfList.Add(parentString); } } } else { // in case we dealing with a relation the entity is assumed to be a hybrid and we need to check against node, way, and relations foreach (string parentString in isMemberOfList) { long idToCheck = Convert.ToInt64(parentString); if (wayIDLookup.ContainsKey(idToCheck)) { idToCheck = wayIDLookup[idToCheck]; } if (nodeIDLookup.ContainsKey(idToCheck)) { idToCheck = nodeIDLookup[idToCheck]; } if (relationIDLookup.ContainsKey(idToCheck)) { idToCheck = relationIDLookup[idToCheck]; } newIsMemberOfList.Add(idToCheck.ToString()); } } _osmUtility.insertIsMemberOf(osmisMemberOfFieldIndex, newIsMemberOfList, updateRow); } } if (osmMembersFieldIndex > -1) { member[] members = _osmUtility.retrieveMembers(updateRow, osmMembersFieldIndex); if (members != null) { for (int memberIndex = 0; memberIndex < members.Length; memberIndex++) { switch (members[memberIndex].type) { case memberType.way: long wayID = Convert.ToInt64(members[memberIndex].@ref); if (wayIDLookup.ContainsKey(wayID)) { members[memberIndex].@ref = wayIDLookup[wayID].ToString(); } break; case memberType.node: long nodeID = Convert.ToInt64(members[memberIndex].@ref); if (nodeIDLookup.ContainsKey(nodeID)) { members[memberIndex].@ref = nodeIDLookup[nodeID].ToString(); } break; case memberType.relation: long relationID = Convert.ToInt64(members[memberIndex].@ref); if (relationIDLookup.ContainsKey(relationID)) { members[memberIndex].@ref = relationIDLookup[relationID].ToString(); } break; default: break; } } _osmUtility.insertMembers(osmMembersFieldIndex, updateRow, members); } } if (osmVersionFieldIndex > -1) { updateRow.set_Value(osmVersionFieldIndex, osmVersion); } updateCursor.UpdateRow(updateRow); } } } catch { } finally { if (osmExtension != null) osmExtension.CanBypassChangeDetection = false; } }
private void ParseResultDiff(diffResult diffResultResponse, ITable revisionTable, IFeatureClass pointFeatureClass, IFeatureClass lineFeatureClass, IFeatureClass polygonFeatureClass, ITable relationTable, string userName, int userID, string changetSetID, Dictionary<long, long> nodeIDLookup, Dictionary<long, long> wayIDLookup, Dictionary<long, long> relationIDLookup, int extensionVersion) { if (diffResultResponse == null) return; if (diffResultResponse.Items == null) return; // let's find all the matching row with the old osm feature ID IQueryFilter queryFilter = new QueryFilterClass(); int sourceFCNameFieldIndex = revisionTable.Fields.FindField("sourcefcname"); int statusFieldIndex = revisionTable.Fields.FindField("osmstatus"); int statusCodeFieldIndex = revisionTable.Fields.FindField("osmstatuscode"); int newIDFieldIndex = revisionTable.Fields.FindField("osmnewid"); int osmVersionFieldIndex = revisionTable.Fields.FindField("osmversion"); int changesetIDFieldIndex = revisionTable.Fields.FindField("osmchangeset"); SQLFormatter sqlFormatter = new SQLFormatter(revisionTable); foreach (var item in diffResultResponse.Items) { if (item is diffResultNode) { diffResultNode diffNode = item as diffResultNode; long newID = -1; int newVersion = -1; long oldID = -1; long.TryParse(diffNode.new_id, out newID); int.TryParse(diffNode.new_version, out newVersion); long.TryParse(diffNode.old_id, out oldID); // if (nodeIDLookup.ContainsKey(oldID) == false) { nodeIDLookup.Add(oldID, newID); } updateSource((ITable)pointFeatureClass, determineAction(diffNode), Convert.ToInt64(diffNode.old_id), newID, userName, userID, newVersion, Convert.ToInt32(changetSetID), nodeIDLookup, wayIDLookup, relationIDLookup, extensionVersion); queryFilter.WhereClause = revisionTable.WhereClauseByExtensionVersion(diffNode.old_id, "osmoldid", extensionVersion) + " AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'node'" + " AND " + sqlFormatter.SqlIdentifier("osmstatuscode") + " IS NULL"; ; using (ComReleaser comReleaser = new ComReleaser()) { ICursor updateCursor = revisionTable.Update(queryFilter, false); comReleaser.ManageLifetime(updateCursor); IRow currentRow = updateCursor.NextRow(); if (currentRow == null) continue; if (statusFieldIndex > -1) { currentRow.set_Value(statusFieldIndex, HttpStatusCode.OK.ToString()); } if (statusCodeFieldIndex > -1) { currentRow.set_Value(statusCodeFieldIndex, (int)HttpStatusCode.OK); } if (newIDFieldIndex > -1) { currentRow.set_Value(newIDFieldIndex, newID); } if (osmVersionFieldIndex > -1) { currentRow.set_Value(osmVersionFieldIndex, newVersion); } if (changesetIDFieldIndex > -1) { currentRow.set_Value(changesetIDFieldIndex, changetSetID); } updateCursor.UpdateRow(currentRow); } } else if (item is diffResultWay) { diffResultWay diffWay = item as diffResultWay; queryFilter.WhereClause = revisionTable.WhereClauseByExtensionVersion(diffWay.old_id, "osmoldid", extensionVersion) + " AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'way'" + " AND " + sqlFormatter.SqlIdentifier("osmstatuscode") + " IS NULL"; long newID = -1; int newVersion = -1; long oldID = -1; long.TryParse(diffWay.new_id, out newID); int.TryParse(diffWay.new_version, out newVersion); long.TryParse(diffWay.old_id, out oldID); // if (wayIDLookup.ContainsKey(oldID) == false) { wayIDLookup.Add(oldID, newID); } using (ComReleaser comReleaser = new ComReleaser()) { ICursor updateCursor = revisionTable.Update(queryFilter, false); comReleaser.ManageLifetime(updateCursor); IRow currentRow = updateCursor.NextRow(); if (currentRow == null) continue; string sourceFCName = String.Empty; if (sourceFCNameFieldIndex > -1) { sourceFCName = currentRow.get_Value(sourceFCNameFieldIndex) as string; } if (string.IsNullOrEmpty(sourceFCName)) continue; if (sourceFCName.Contains("_osm_ln")) { updateSource((ITable)lineFeatureClass, determineAction(diffWay), Convert.ToInt64(diffWay.old_id), newID, userName, userID, newVersion, Convert.ToInt32(changetSetID), nodeIDLookup, wayIDLookup, relationIDLookup, extensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { updateSource((ITable)polygonFeatureClass, determineAction(diffWay), Convert.ToInt64(diffWay.old_id), newID, userName, userID, newVersion, Convert.ToInt32(changetSetID), nodeIDLookup, wayIDLookup, relationIDLookup, extensionVersion); } if (statusFieldIndex > -1) { currentRow.set_Value(statusFieldIndex, HttpStatusCode.OK.ToString()); } if (statusCodeFieldIndex > -1) { currentRow.set_Value(statusCodeFieldIndex, (int)HttpStatusCode.OK); } if (newIDFieldIndex > -1) { currentRow.set_Value(newIDFieldIndex, newID); } if (osmVersionFieldIndex > -1) { currentRow.set_Value(osmVersionFieldIndex, newVersion); } if (changesetIDFieldIndex > -1) { currentRow.set_Value(changesetIDFieldIndex, changetSetID); } updateCursor.UpdateRow(currentRow); } } else if (item is diffResultRelation) { diffResultRelation diffRelation = item as diffResultRelation; queryFilter.WhereClause = revisionTable.WhereClauseByExtensionVersion(diffRelation.old_id, "osmoldid", extensionVersion) + " AND " + sqlFormatter.SqlIdentifier("osmelementtype") + " = 'relation'" + " AND " + sqlFormatter.SqlIdentifier("osmstatuscode") + " IS NULL"; ; long newID = -1; int newVersion = -1; long oldID = -1; long.TryParse(diffRelation.new_id, out newID); int.TryParse(diffRelation.new_version, out newVersion); long.TryParse(diffRelation.old_id, out oldID); // if (relationIDLookup.ContainsKey(oldID) == false) { relationIDLookup.Add(oldID, newID); } using (ComReleaser comReleaser = new ComReleaser()) { ICursor updateCursor = revisionTable.Update(queryFilter, false); comReleaser.ManageLifetime(updateCursor); IRow currentRow = updateCursor.NextRow(); if (currentRow == null) continue; string sourceFCName = String.Empty; if (sourceFCNameFieldIndex > -1) { sourceFCName = currentRow.get_Value(sourceFCNameFieldIndex) as string; } if (string.IsNullOrEmpty(sourceFCName)) continue; if (sourceFCName.Contains("_osm_ln")) { updateSource((ITable)lineFeatureClass, determineAction(diffRelation), Convert.ToInt64(diffRelation.old_id), newID, userName, userID, newVersion, Convert.ToInt32(changetSetID), nodeIDLookup, wayIDLookup, relationIDLookup, extensionVersion); } else if (sourceFCName.Contains("_osm_ply")) { updateSource((ITable)polygonFeatureClass, determineAction(diffRelation), Convert.ToInt64(diffRelation.old_id), newID, userName, userID, newVersion, Convert.ToInt32(changetSetID), nodeIDLookup, wayIDLookup, relationIDLookup, extensionVersion); } else if (sourceFCName.Contains("_osm_relation")) { updateSource(relationTable, determineAction(diffRelation), Convert.ToInt64(diffRelation.old_id), newID, userName, userID, newVersion, Convert.ToInt32(changetSetID), nodeIDLookup, wayIDLookup, relationIDLookup, extensionVersion); } if (statusFieldIndex > -1) { currentRow.set_Value(statusFieldIndex, HttpStatusCode.OK.ToString()); } if (statusCodeFieldIndex > -1) { currentRow.set_Value(statusCodeFieldIndex, (int)HttpStatusCode.OK); } if (newIDFieldIndex > -1) { currentRow.set_Value(newIDFieldIndex, newID); } if (osmVersionFieldIndex > -1) { currentRow.set_Value(osmVersionFieldIndex, newVersion); } if (changesetIDFieldIndex > -1) { currentRow.set_Value(changesetIDFieldIndex, changetSetID); } updateCursor.UpdateRow(currentRow); } } } }
private osmRelationGeometryType walkRelationGeometry(IFeatureClass osmLineFeatureClass, IFeatureClass osmPolygonFeatureClass, ITable relationTable, relation currentRelation) { osmRelationGeometryType testedGeometry = osmRelationGeometryType.osmUnknownGeometry; // we use this dictionary to determine if we can fully walk this relation // - the assumption is that we can walk the geometry is all node counts are 2 Dictionary<int, int> nodeCountDictionary = new Dictionary<int, int>(); try { if (currentRelation.Items == null) return testedGeometry; foreach (var item in currentRelation.Items) { if (item is ESRI.ArcGIS.OSM.OSMClassExtension.member) { member memberItem = item as member; IQueryFilter osmIDQueryFilter = new QueryFilterClass(); using (ComReleaser comReleaser = new ComReleaser()) { if (osmLineFeatureClass != null) { osmIDQueryFilter.WhereClause = osmLineFeatureClass.WhereClauseByExtensionVersion(memberItem.@ref, "OSMID", 2); IFeatureCursor lineFeatureCursor = osmLineFeatureClass.Search(osmIDQueryFilter, false); comReleaser.ManageLifetime(lineFeatureCursor); IFeature foundLineFeature = lineFeatureCursor.NextFeature(); if (foundLineFeature != null) { IPointCollection pointCollection = foundLineFeature.Shape as IPointCollection; int firstPointID = pointCollection.get_Point(0).ID; int lastPointID = pointCollection.get_Point(pointCollection.PointCount - 1).ID; if (nodeCountDictionary.ContainsKey(firstPointID)) { nodeCountDictionary[firstPointID] = nodeCountDictionary[firstPointID] + 1; } else { nodeCountDictionary.Add(firstPointID, 1); } if (nodeCountDictionary.ContainsKey(lastPointID)) { nodeCountDictionary[lastPointID] = nodeCountDictionary[lastPointID] + 1; } else { nodeCountDictionary.Add(lastPointID, 1); } } osmIDQueryFilter.WhereClause = osmPolygonFeatureClass.WhereClauseByExtensionVersion(memberItem.@ref, "OSMID", 2); IFeatureCursor polygonFeatureCursor = osmPolygonFeatureClass.Search(osmIDQueryFilter, false); comReleaser.ManageLifetime(polygonFeatureCursor); IFeature foundPolygonFeature = polygonFeatureCursor.NextFeature(); if (foundPolygonFeature != null) { IPointCollection pointCollection = foundPolygonFeature.Shape as IPointCollection; int firstPointID = pointCollection.get_Point(0).ID; if (nodeCountDictionary.ContainsKey(firstPointID)) { nodeCountDictionary[firstPointID] = nodeCountDictionary[firstPointID] + 2; } else { nodeCountDictionary.Add(firstPointID, 2); } } osmIDQueryFilter.WhereClause = relationTable.WhereClauseByExtensionVersion(memberItem.@ref, "OSMID", 2); ICursor relationCursor = relationTable.Search(osmIDQueryFilter, false); comReleaser.ManageLifetime(relationCursor); IRow foundRelation = relationCursor.NextRow(); if (foundRelation != null) { // in order to be in the relation table is needs to be a either a super-relation or a mixed type entity (hence hybrid) testedGeometry = osmRelationGeometryType.osmHybridGeometry; break; } } } } } // check if there are any nodes counts other than 2, if there are then we cannot fully "walk" the geometry and it will be considered a line if (nodeCountDictionary.Values.Any(e => (e != 2))) { testedGeometry = osmRelationGeometryType.osmPolyline; } else { testedGeometry = osmRelationGeometryType.osmPolygon; } } catch { testedGeometry = osmRelationGeometryType.osmHybridGeometry; } return testedGeometry; }
/// <summary> /// This function assembles a version of the logged relation action from the revision table in the OsmChange format http://wiki.openstreetmap.org/wiki/OsmChange /// </summary> /// <param name="relationTable"></param> /// <param name="action"></param> /// <param name="osmID"></param> /// <param name="changeSetID"></param> /// <param name="osmVersion"></param> /// <param name="nodeosmIDLookup"></param> /// <param name="wayosmIDLookup"></param> /// <param name="relationosmIDLookup"></param> /// <param name="extensionVersion"></param> /// <returns></returns> private ESRI.ArcGIS.OSM.OSMClassExtension.relation CreateRelationRepresentation(ITable relationTable, string action, long osmID, string changeSetID, int osmVersion, Dictionary<long, long> nodeosmIDLookup, Dictionary<long, long> wayosmIDLookup, Dictionary<long, long> relationosmIDLookup, int extensionVersion) { ESRI.ArcGIS.OSM.OSMClassExtension.relation relationRepresentation = new ESRI.ArcGIS.OSM.OSMClassExtension.relation(); // let's find all the rows that have a different status than 200 - meaning success IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.WhereClause = relationTable.WhereClauseByExtensionVersion(osmID, "OSMID", extensionVersion); using (ComReleaser comReleaser = new ComReleaser()) { ICursor searchCursor = relationTable.Search(queryFilter, false); comReleaser.ManageLifetime(searchCursor); IRow relationRow = searchCursor.NextRow(); int osmTagsFieldIndex = relationTable.Fields.FindField("osmTags"); int osmIDFieldIndex = relationTable.Fields.FindField("osmID"); int osmUserFieldIndex = relationTable.Fields.FindField("osmuser"); int osmUIDFieldIndex = relationTable.Fields.FindField("osmuid"); int osmVisibleFieldIndex = relationTable.Fields.FindField("osmvisible"); int osmVersionFieldIndex = relationTable.Fields.FindField("osmversion"); int osmMembersFieldIndex = relationTable.Fields.FindField("osmMembers"); if (relationRow != null) { switch (action) { case "create": // the newly created node needs to carry the changeset info, the coordinate and the tags relationRepresentation.changeset = changeSetID; ESRI.ArcGIS.OSM.OSMClassExtension.tag[] tags = null; if (osmTagsFieldIndex > -1) { tags = _osmUtility.retrieveOSMTags(relationRow, osmTagsFieldIndex, ((IDataset)relationTable).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]); } } if (osmIDFieldIndex > -1) { relationRepresentation.id = osmID.ToString(); } ESRI.ArcGIS.OSM.OSMClassExtension.member[] members = null; if (osmMembersFieldIndex > -1) { members = _osmUtility.retrieveMembers(relationRow, osmMembersFieldIndex); // run the member ids through the lookup table for (int memberIndex = 0; memberIndex < members.Length; memberIndex++) { switch (members[memberIndex].type) { case ESRI.ArcGIS.OSM.OSMClassExtension.memberType.way: if (wayosmIDLookup.ContainsKey(Convert.ToInt64(members[memberIndex].@ref))) { members[memberIndex].@ref = Convert.ToString(wayosmIDLookup[Convert.ToInt64(members[memberIndex].@ref)]); } break; case ESRI.ArcGIS.OSM.OSMClassExtension.memberType.node: if (nodeosmIDLookup.ContainsKey(Convert.ToInt64(members[memberIndex].@ref))) { members[memberIndex].@ref = Convert.ToString(nodeosmIDLookup[Convert.ToInt64(members[memberIndex].@ref)]); } break; case ESRI.ArcGIS.OSM.OSMClassExtension.memberType.relation: if (relationosmIDLookup.ContainsKey(Convert.ToInt64(members[memberIndex].@ref))) { members[memberIndex].@ref = Convert.ToString(relationosmIDLookup[Convert.ToInt64(members[memberIndex].@ref)]); } break; default: break; } } _osmUtility.insertMembers(osmMembersFieldIndex, relationRow, members); } // add the member and the tags to the relation element List<object> relationItems = new List<object>(); relationItems.AddRange(members); relationItems.AddRange(valueOnlyTags.ToArray()); relationRepresentation.Items = relationItems.ToArray(); break; case "modify": // for an update the complete (full) relation needs to be returned relationRepresentation.changeset = changeSetID; if (osmIDFieldIndex > -1) { relationRepresentation.id = Convert.ToString(relationRow.get_Value(osmIDFieldIndex), new CultureInfo("en-US")); } if (osmUserFieldIndex > -1) { relationRepresentation.user = Convert.ToString(relationRow.get_Value(osmUserFieldIndex)); } if (osmUIDFieldIndex > -1) { relationRepresentation.uid = Convert.ToString(relationRow.get_Value(osmUIDFieldIndex), new CultureInfo("en-US")); } if (osmVersionFieldIndex > -1) { relationRepresentation.version = Convert.ToString(relationRow.get_Value(osmVersionFieldIndex)); } tags = null; if (osmTagsFieldIndex > -1) { tags = _osmUtility.retrieveOSMTags((IRow)relationRow, osmTagsFieldIndex, ((IDataset)relationTable).Workspace); } valueOnlyTags = new List<tag>(); for (int index = 0; index < tags.Length; index++) { if (!String.IsNullOrEmpty(tags[index].v)) { valueOnlyTags.Add(tags[index]); } } members = null; if (osmMembersFieldIndex > -1) { members = _osmUtility.retrieveMembers(relationRow, osmMembersFieldIndex); // run the member ids through the lookup table for (int memberIndex = 0; memberIndex < members.Length; memberIndex++) { switch (members[memberIndex].type) { case memberType.way: if (wayosmIDLookup.ContainsKey(Convert.ToInt64(members[memberIndex].@ref))) { members[memberIndex].@ref = Convert.ToString(wayosmIDLookup[Convert.ToInt64(members[memberIndex].@ref)]); } break; case memberType.node: if (nodeosmIDLookup.ContainsKey(Convert.ToInt64(members[memberIndex].@ref))) { members[memberIndex].@ref = Convert.ToString(nodeosmIDLookup[Convert.ToInt64(members[memberIndex].@ref)]); } break; case memberType.relation: if (relationosmIDLookup.ContainsKey(Convert.ToInt64(members[memberIndex].@ref))) { members[memberIndex].@ref = Convert.ToString(relationosmIDLookup[Convert.ToInt64(members[memberIndex].@ref)]); } break; default: break; } } _osmUtility.insertMembers(osmMembersFieldIndex, relationRow, members); } // add the member and the tags to the relation element relationItems = new List<object>(); relationItems.AddRange(valueOnlyTags.ToArray()); relationItems.AddRange(members); relationRepresentation.Items = relationItems.ToArray(); break; case "delete": relationRepresentation.changeset = changeSetID; relationRepresentation.id = Convert.ToString(osmID); relationRepresentation.version = Convert.ToString(osmVersion); break; default: break; } } else { if (action.Equals("delete", StringComparison.InvariantCultureIgnoreCase)) { relationRepresentation.changeset = changeSetID; relationRepresentation.id = Convert.ToString(osmID); relationRepresentation.version = Convert.ToString(osmVersion); } } } return relationRepresentation; }
//internal List<ESRI.ArcGIS.OSM.OSMClassExtension.tag> MergeTagsFromOuterPolygonToRelation(ESRI.ArcGIS.OSM.OSMClassExtension.relation currentRelation, IFeatureClass polygonFeatureClass) //{ // Dictionary<string, ESRI.ArcGIS.OSM.OSMClassExtension.tag> mergedTagList = new Dictionary<string, ESRI.ArcGIS.OSM.OSMClassExtension.tag>(); // IQueryFilter osmIDQueryFilter = new QueryFilterClass(); // try // { // int osmIDPolygonFieldIndex = polygonFeatureClass.FindField("OSMID"); // string sqlPolyOSMID = polygonFeatureClass.SqlIdentifier("OSMID"); // foreach (var relationItem in currentRelation.Items) // { // if (relationItem is ESRI.ArcGIS.OSM.OSMClassExtension.member) // { // ESRI.ArcGIS.OSM.OSMClassExtension.member currentRelationMember = relationItem as ESRI.ArcGIS.OSM.OSMClassExtension.member; // if (currentRelationMember.role.ToLower().Equals("outer")) // { // using (ComReleaser comReleaser = new ComReleaser()) // { // osmIDQueryFilter.WhereClause = sqlPolyOSMID + " = " + currentRelationMember.@ref; // IFeatureCursor featureCursor = polygonFeatureClass.Search(osmIDQueryFilter, false); // comReleaser.ManageLifetime(featureCursor); // IFeature foundPolygonFeature = featureCursor.NextFeature(); // if (foundPolygonFeature == null) // continue; // tag[] foundTags = OSMUtility.retrieveOSMTags(foundPolygonFeature, osmIDPolygonFieldIndex, ((IDataset)polygonFeatureClass).Workspace); // foreach (tag currentWayTag in foundTags) // { // // first one in wins // try // { // if (!mergedTagList.ContainsKey(currentWayTag.k)) // { // mergedTagList.Add(currentWayTag.k, currentWayTag); // } // } // catch { } // } // } // } // } // else if (relationItem is tag) // { // tag relationTag = relationItem as tag; // try // { // if (!mergedTagList.ContainsKey(relationTag.k)) // { // mergedTagList.Add(relationTag.k, relationTag); // } // } // catch { } // } // } // } // catch { } // return mergedTagList.Values.ToList(); //} internal osmRelationGeometryType determineOSMGeometryType(IFeatureClass lineFeatureClass, IFeatureClass polygonFeatureClass, ITable relationTable, string osmIDtoFind) { osmRelationGeometryType determinedGeometryType = osmRelationGeometryType.osmUnknownGeometry; try { IQueryFilter osmIDQueryFilter = new QueryFilterClass(); osmIDQueryFilter.SubFields = "OSMID"; using (ComReleaser comReleaser = new ComReleaser()) { if (lineFeatureClass != null) { osmIDQueryFilter.WhereClause = lineFeatureClass.WhereClauseByExtensionVersion(osmIDtoFind, "OSMID", 2); IFeatureCursor lineFeatureCursor = lineFeatureClass.Search(osmIDQueryFilter, false); comReleaser.ManageLifetime(lineFeatureCursor); IFeature foundLineFeature = lineFeatureCursor.NextFeature(); if (foundLineFeature != null) { determinedGeometryType = osmRelationGeometryType.osmPolyline; return determinedGeometryType; } osmIDQueryFilter.WhereClause = polygonFeatureClass.WhereClauseByExtensionVersion(osmIDtoFind, "OSMID", 2); IFeatureCursor polygonFeatureCursor = polygonFeatureClass.Search(osmIDQueryFilter, false); comReleaser.ManageLifetime(polygonFeatureCursor); IFeature foundPolygonFeature = polygonFeatureCursor.NextFeature(); if (foundPolygonFeature != null) { determinedGeometryType = osmRelationGeometryType.osmPolygon; return determinedGeometryType; } osmIDQueryFilter.WhereClause = relationTable.WhereClauseByExtensionVersion(osmIDtoFind, "OSMID", 2); ICursor relationCursor = relationTable.Search(osmIDQueryFilter, false); comReleaser.ManageLifetime(relationCursor); IRow foundRelation = relationCursor.NextRow(); if (foundRelation != null) { // in order to be in the relation table is needs to be a either a super-relation or a mixed type entity (hence hybrid) determinedGeometryType = osmRelationGeometryType.osmHybridGeometry; return determinedGeometryType; } } } } catch { } return determinedGeometryType; }