@@ -111,7 +111,7 @@ class DatasyncManager {
111111 print ( " 📤 Syncing node ID: \( node. id) " )
112112 let payload = node. asOSMNode ( )
113113 do {
114- let status = try await syncNode ( node: payload, exclude_gig_tags: exclude_gig_tags)
114+ let status = try await syncNode ( node: payload, exclude_gig_tags: exclude_gig_tags, editedTags : node . tags . toDictionary ( ) )
115115 if status. result {
116116 DispatchQueue . main. async {
117117 self . dbInstance. assignChangesetId ( obj: key, changesetId: 0 , updatedVersion: status. version)
@@ -132,7 +132,7 @@ class DatasyncManager {
132132 print ( " 📤 Syncing way ID: \( way. id) " )
133133 let payload = way. asOSMWay ( )
134134 do {
135- let status = try await syncWay ( way: payload, exclude_gig_tags: exclude_gig_tags)
135+ let status = try await syncWay ( way: payload, exclude_gig_tags: exclude_gig_tags, editedTags : way . tags . toDictionary ( ) )
136136 if status. result {
137137 DispatchQueue . main. async {
138138 self . dbInstance. assignChangesetId ( obj: key, changesetId: 0 , updatedVersion: status. version)
@@ -288,7 +288,7 @@ class DatasyncManager {
288288 }
289289
290290 // utility function to act as substitute for osmConnection functions
291- func updateNode( node: OSMNode , exclude_gig_tags: Bool = false ) async throws -> Int {
291+ func updateNode( node: OSMNode , exclude_gig_tags: Bool ) async throws -> Int {
292292 var localNode = node
293293 let nodeBodyString = localNode. toPayload ( exclude_gig_tags: exclude_gig_tags)
294294 let changesetUploadBody = " <osmChange version= \" 0.6 \" generator= \" GIG Change generator \" > " + nodeBodyString + " </osmChange> "
@@ -356,7 +356,7 @@ class DatasyncManager {
356356 }
357357 }
358358
359- func updateWay2( way: OSMWay , exclude_gig_tags: Bool = false ) async throws -> Int {
359+ func updateWay2( way: OSMWay , exclude_gig_tags: Bool , editedTags : [ String : String ] ) async throws -> Int {
360360 var localWay = way
361361 let wayId = " \( localWay. id) "
362362 var updatedResult : Int = - 1
@@ -367,19 +367,24 @@ class DatasyncManager {
367367 switch error {
368368 case . conflict:
369369 let updatedWay = try await fetchway2 ( wayId: wayId)
370- var mergedWay = self . mergeWays ( localWay: localWay, latestWay: updatedWay)
371- print ( " Local way " )
372- print ( localWay)
373- print ( " Merged way " )
374- print ( mergedWay)
375- return try await updateWay ( way: mergedWay, exclude_gig_tags: exclude_gig_tags)
370+ if let mergedWay = self . mergeWays ( localWay: localWay, latestWay: updatedWay, exclude_gig_tags: exclude_gig_tags, editedTags: editedTags) {
371+ print ( " Local way " )
372+ print ( localWay)
373+ print ( " Merged way " )
374+ print ( mergedWay)
375+ return try await updateWay ( way: mergedWay, exclude_gig_tags: exclude_gig_tags)
376+ } else {
377+ print ( " Undo operation is not possible " )
378+ return updatedWay. version
379+ }
380+
376381 default :
377382 throw error
378383 }
379384 }
380385 }
381386
382- func updateNode2( node: OSMNode , exclude_gig_tags: Bool ) async throws -> Int {
387+ func updateNode2( node: OSMNode , exclude_gig_tags: Bool , editedTags : [ String : String ] ) async throws -> Int {
383388 var localNode = node
384389
385390 let nodeId = " \( localNode. id) "
@@ -396,13 +401,18 @@ class DatasyncManager {
396401 SyncLogger . shared. logStep ( " Fetching node due to conflict " )
397402 let fetchedResult = try await fetchNode2 ( nodeId: " \( localNode. id) " )
398403
399- var mergedNode = self . mergeNodes ( localNode: localNode, latestNode: fetchedResult)
400- print ( " Local Node: " )
401- print ( localNode)
402- print ( " Merged Node: " )
403- print ( mergedNode)
404- SyncLogger . shared. logStep ( " Nodes fetched and merged " )
405- return try await updateNode ( node: mergedNode)
404+ if let mergedNode = self . mergeNodes ( localNode: localNode, latestNode: fetchedResult, exclude_gig_tags: exclude_gig_tags, editedTags: editedTags) {
405+ print ( " Local Node: " )
406+ print ( localNode)
407+ print ( " Merged Node: " )
408+ print ( mergedNode)
409+ SyncLogger . shared. logStep ( " Nodes fetched and merged " )
410+ return try await updateNode ( node: mergedNode, exclude_gig_tags: exclude_gig_tags)
411+ } else {
412+ print ( " Undo operation is not possible " )
413+ return fetchedResult. version
414+ }
415+
406416 default :
407417 throw error
408418 }
@@ -411,19 +421,78 @@ class DatasyncManager {
411421 }
412422
413423
414- func mergeWays( localWay: OSMWay , latestWay: OSMWay ) -> OSMWay {
424+ func mergeTagsForUndo( originalTags: [ String : String ] , edited: [ String : String ] , serverTags: [ String : String ] ) -> [ String : String ] ? {
425+ var resultTags : [ String : String ] = [ : ]
426+ print ( " mergeTagsForUndo originalTags \( originalTags) \n edited \( edited) \n serverTags \( serverTags) " )
427+ for (key, value) in edited {
428+ if let orgValue = originalTags [ key] {
429+ if let serverVal = serverTags [ key] {
430+ if orgValue != serverVal, value != serverVal {
431+ return nil
432+ }
433+ } else {
434+ return nil
435+ }
436+ } else {
437+ if let serverVal = serverTags [ key] , value != serverVal {
438+ return nil
439+ }
440+ }
441+ }
442+
443+ let unionKeys = Set ( originalTags. keys) . union ( Set ( serverTags. keys) )
444+
445+ for key in unionKeys {
446+ if let serverValue = serverTags [ key] {
447+ if let editValue = edited [ key] {
448+ if editValue == serverValue {
449+ if let originalValue = originalTags [ key] {
450+ resultTags [ key] = originalValue
451+ continue
452+ }
453+ continue
454+ }
455+ }
456+ resultTags [ key] = serverValue
457+ } else {
458+ resultTags. removeValue ( forKey: key)
459+ }
460+ }
461+ resultTags. removeValue ( forKey: " ext:gig_last_updated " )
462+ resultTags. removeValue ( forKey: " ext:gig_complete " )
463+ print ( " mergeTagsForUndo resultTags \( resultTags) " )
464+ return resultTags
465+ }
466+
467+ func mergeWays( localWay: OSMWay , latestWay: OSMWay , exclude_gig_tags: Bool , editedTags: [ String : String ] ) -> OSMWay ? {
415468 var mergedWay = latestWay
416- for (key, value) in localWay. tags {
417- mergedWay. tags [ key] = value
418- }
469+ if exclude_gig_tags {
470+ if let resultTags = mergeTagsForUndo ( originalTags: localWay. tags, edited: editedTags, serverTags: latestWay. tags) {
471+ mergedWay. tags = resultTags
472+ } else {
473+ return nil
474+ }
475+ } else {
476+ for (key, value) in localWay. tags {
477+ mergedWay. tags [ key] = value
478+ }
479+ }
419480 mergedWay. changeset = localWay. changeset
420481 return mergedWay
421482 }
422483
423- func mergeNodes( localNode: OSMNode , latestNode: OSMNode ) -> OSMNode {
484+ func mergeNodes( localNode: OSMNode , latestNode: OSMNode , exclude_gig_tags : Bool , editedTags : [ String : String ] ) -> OSMNode ? {
424485 var mergedNode = latestNode
425- for (key, value) in localNode. tags {
426- mergedNode. tags [ key] = value
486+ if exclude_gig_tags {
487+ if let resultTags = mergeTagsForUndo ( originalTags: localNode. tags, edited: editedTags, serverTags: latestNode. tags) {
488+ mergedNode. tags = resultTags
489+ } else {
490+ return nil
491+ }
492+ } else {
493+ for (key, value) in localNode. tags {
494+ mergedNode. tags [ key] = value
495+ }
427496 }
428497 mergedNode. changeset = localNode. changeset
429498 return mergedNode
@@ -500,7 +569,7 @@ class DatasyncManager {
500569 Syncs the node along with the updated
501570 */
502571 @MainActor
503- func syncNode( node: OSMNode , exclude_gig_tags: Bool ) async throws -> ( result: Bool , version: Int ) {
572+ func syncNode( node: OSMNode , exclude_gig_tags: Bool , editedTags : [ String : String ] ) async throws -> ( result: Bool , version: Int ) {
504573 var localNode = node
505574
506575 SyncLogger . shared. logStep ( " Open Changeset " )
@@ -513,7 +582,7 @@ class DatasyncManager {
513582 localNode. changeset = changesetID
514583
515584 //Step 2: Update Node
516- let newVersion = try await updateNode2 ( node: localNode, exclude_gig_tags: exclude_gig_tags)
585+ let newVersion = try await updateNode2 ( node: localNode, exclude_gig_tags: exclude_gig_tags, editedTags : editedTags )
517586 localNode. version = newVersion
518587 DispatchQueue . main. async {
519588 self . dbInstance. updateNodeVersion ( nodeId: String ( localNode. id) , version: newVersion)
@@ -552,7 +621,7 @@ class DatasyncManager {
552621 }
553622
554623 @MainActor
555- func syncWay( way: OSMWay , exclude_gig_tags: Bool = false ) async throws -> ( result: Bool , version: Int ) {
624+ func syncWay( way: OSMWay , exclude_gig_tags: Bool , editedTags : [ String : String ] ) async throws -> ( result: Bool , version: Int ) {
556625 var localWay = way
557626
558627 do {
@@ -561,7 +630,7 @@ class DatasyncManager {
561630
562631 localWay. changeset = changesetID
563632
564- let newVersion = try await updateWay2 ( way: localWay, exclude_gig_tags: exclude_gig_tags)
633+ let newVersion = try await updateWay2 ( way: localWay, exclude_gig_tags: exclude_gig_tags, editedTags : editedTags )
565634
566635 localWay. version = newVersion
567636
0 commit comments