From 6f14fb12fffbace729e6f774a2981e8f015c144f Mon Sep 17 00:00:00 2001 From: lloydsheng Date: Sun, 11 Mar 2018 14:48:36 +0800 Subject: [PATCH 1/4] [ios] Fix an issue where wrong annotation may selected when annotations very close #10734 --- platform/ios/src/MGLMapView.mm | 49 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 5a68736ec55..18a69a34cd4 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -4148,51 +4148,48 @@ - (MGLAnnotationTag)annotationTagAtPoint:(CGPoint)point persistingResults:(BOOL) MGLAnnotationTag hitAnnotationTag = MGLAnnotationTagNotFound; if (nearbyAnnotations.size()) { - // The annotation tags need to be stable in order to compare them with - // the remembered tags. - std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end()); - + // The first selection in the cycle should be the one nearest to the + // tap. Also the annotation tags need to be stable in order to compare them with + // the remembered tags _annotationsNearbyLastTap. + CLLocationCoordinate2D currentCoordinate = [self convertPoint:point toCoordinateFromView:self]; + std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end(), [&](const MGLAnnotationTag tagA, const MGLAnnotationTag tagB) { + CLLocationCoordinate2D coordinateA = [[self annotationWithTag:tagA] coordinate]; + CLLocationCoordinate2D coordinateB = [[self annotationWithTag:tagB] coordinate]; + CLLocationDegrees deltaA = hypot(coordinateA.latitude - currentCoordinate.latitude, + coordinateA.longitude - currentCoordinate.longitude); + CLLocationDegrees deltaB = hypot(coordinateB.latitude - currentCoordinate.latitude, + coordinateB.longitude - currentCoordinate.longitude); + return deltaA < deltaB; + }); + if (nearbyAnnotations == _annotationsNearbyLastTap) { - // The first selection in the cycle should be the one nearest to the - // tap. - CLLocationCoordinate2D currentCoordinate = [self convertPoint:point toCoordinateFromView:self]; - std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end(), [&](const MGLAnnotationTag tagA, const MGLAnnotationTag tagB) { - CLLocationCoordinate2D coordinateA = [[self annotationWithTag:tagA] coordinate]; - CLLocationCoordinate2D coordinateB = [[self annotationWithTag:tagB] coordinate]; - CLLocationDegrees deltaA = hypot(coordinateA.latitude - currentCoordinate.latitude, - coordinateA.longitude - currentCoordinate.longitude); - CLLocationDegrees deltaB = hypot(coordinateB.latitude - currentCoordinate.latitude, - coordinateB.longitude - currentCoordinate.longitude); - return deltaA < deltaB; - }); - // The last time we persisted a set of annotations, we had the same // set of annotations as we do now. Cycle through them. if (_selectedAnnotationTag == MGLAnnotationTagNotFound - || _selectedAnnotationTag == _annotationsNearbyLastTap.back()) + || _selectedAnnotationTag == nearbyAnnotations.back()) { // Either no annotation is selected or the last annotation in // the set was selected. Wrap around to the first annotation in // the set. - hitAnnotationTag = _annotationsNearbyLastTap.front(); + hitAnnotationTag = nearbyAnnotations.front(); } else { - auto result = std::find(_annotationsNearbyLastTap.begin(), - _annotationsNearbyLastTap.end(), + auto result = std::find(nearbyAnnotations.begin(), + nearbyAnnotations.end(), _selectedAnnotationTag); - if (result == _annotationsNearbyLastTap.end()) + if (result == nearbyAnnotations.end()) { // An annotation from this set hasn’t been selected before. // Select the first (nearest) one. - hitAnnotationTag = _annotationsNearbyLastTap.front(); + hitAnnotationTag = nearbyAnnotations.front(); } else { // Step to the next annotation in the set. - auto distance = std::distance(_annotationsNearbyLastTap.begin(), result); - hitAnnotationTag = _annotationsNearbyLastTap[distance + 1]; + auto distance = std::distance(nearbyAnnotations.begin(), result); + hitAnnotationTag = nearbyAnnotations[distance + 1]; } } } @@ -4204,7 +4201,7 @@ - (MGLAnnotationTag)annotationTagAtPoint:(CGPoint)point persistingResults:(BOOL) { _annotationsNearbyLastTap = nearbyAnnotations; } - + // Choose the first nearby annotation. if (nearbyAnnotations.size()) { From 0daf983fde538c91a63daef50782a340562f635a Mon Sep 17 00:00:00 2001 From: Lloyd Sheng Date: Tue, 13 Mar 2018 11:09:25 +0800 Subject: [PATCH 2/4] [macos] Fix an issue where a wrong annotation may selected if annotations were set close together --- platform/macos/src/MGLMapView.mm | 47 +++++++++++++++----------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 7902fb5b644..e9bada316b8 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -2099,44 +2099,41 @@ - (MGLAnnotationTag)annotationTagAtPoint:(NSPoint)point persistingResults:(BOOL) MGLAnnotationTag hitAnnotationTag = MGLAnnotationTagNotFound; if (nearbyAnnotations.size()) { - // The annotation tags need to be stable in order to compare them with - // the remembered tags. - std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end()); - + // The first selection in the cycle should be the one nearest to the + // tap. Also the annotation tags need to be stable in order to compare them with + // the remembered tags _annotationsNearbyLastTap. + CLLocationCoordinate2D currentCoordinate = [self convertPoint:point toCoordinateFromView:self]; + std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end(), [&](const MGLAnnotationTag tagA, const MGLAnnotationTag tagB) { + CLLocationCoordinate2D coordinateA = [[self annotationWithTag:tagA] coordinate]; + CLLocationCoordinate2D coordinateB = [[self annotationWithTag:tagB] coordinate]; + CLLocationDegrees deltaA = hypot(coordinateA.latitude - currentCoordinate.latitude, + coordinateA.longitude - currentCoordinate.longitude); + CLLocationDegrees deltaB = hypot(coordinateB.latitude - currentCoordinate.latitude, + coordinateB.longitude - currentCoordinate.longitude); + return deltaA < deltaB; + }); + if (nearbyAnnotations == _annotationsNearbyLastClick) { - // The first selection in the cycle should be the one nearest to the - // click. - CLLocationCoordinate2D currentCoordinate = [self convertPoint:point toCoordinateFromView:self]; - std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end(), [&](const MGLAnnotationTag tagA, const MGLAnnotationTag tagB) { - CLLocationCoordinate2D coordinateA = [[self annotationWithTag:tagA] coordinate]; - CLLocationCoordinate2D coordinateB = [[self annotationWithTag:tagB] coordinate]; - CLLocationDegrees distanceA = hypot(coordinateA.latitude - currentCoordinate.latitude, - coordinateA.longitude - currentCoordinate.longitude); - CLLocationDegrees distanceB = hypot(coordinateB.latitude - currentCoordinate.latitude, - coordinateB.longitude - currentCoordinate.longitude); - return distanceA < distanceB; - }); - // The last time we persisted a set of annotations, we had the same // set of annotations as we do now. Cycle through them. if (_lastSelectedAnnotationTag == MGLAnnotationTagNotFound - || _lastSelectedAnnotationTag == _annotationsNearbyLastClick.back()) { + || _lastSelectedAnnotationTag == nearbyAnnotations.back()) { // Either no annotation is selected or the last annotation in // the set was selected. Wrap around to the first annotation in // the set. - hitAnnotationTag = _annotationsNearbyLastClick.front(); + hitAnnotationTag = nearbyAnnotations.front(); } else { - auto result = std::find(_annotationsNearbyLastClick.begin(), - _annotationsNearbyLastClick.end(), + auto result = std::find(nearbyAnnotations.begin(), + nearbyAnnotations.end(), _lastSelectedAnnotationTag); - if (result == _annotationsNearbyLastClick.end()) { + if (result == nearbyAnnotations.end()) { // An annotation from this set hasn’t been selected before. // Select the first (nearest) one. - hitAnnotationTag = _annotationsNearbyLastClick.front(); + hitAnnotationTag = nearbyAnnotations.front(); } else { // Step to the next annotation in the set. - auto distance = std::distance(_annotationsNearbyLastClick.begin(), result); - hitAnnotationTag = _annotationsNearbyLastClick[distance + 1]; + auto distance = std::distance(nearbyAnnotations.begin(), result); + hitAnnotationTag = nearbyAnnotations[distance + 1]; } } } else { From e19b8e54df2c0c6932042bad98314275dafd93f0 Mon Sep 17 00:00:00 2001 From: Lloyd Sheng Date: Tue, 13 Mar 2018 11:28:22 +0800 Subject: [PATCH 3/4] update the iOS change log and the macOS change log --- platform/ios/CHANGELOG.md | 1 + platform/macos/CHANGELOG.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 95759a2f9b7..e44e04d74ce 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -35,6 +35,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue preventing `MGLAnnotationImage.image` from being updated. ([#10372](https://github.com/mapbox/mapbox-gl-native/pull/10372)) * Improved performance of `MGLAnnotationView`-backed annotations that have `scalesWithViewingDistance` enabled. ([#10951](https://github.com/mapbox/mapbox-gl-native/pull/10951)) +* Fix an issue where a wrong annotation may selected if annotations were set close together. ([#11438](https://github.com/mapbox/mapbox-gl-native/pull/11438)) ### Map snapshots diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 872612aec15..6de2a4e87e6 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -23,6 +23,9 @@ * Improved the sharpness of raster tiles on Retina displays. ([#10984](https://github.com/mapbox/mapbox-gl-native/pull/10984)) * Fixed a crash parsing a malformed style. ([#11001](https://github.com/mapbox/mapbox-gl-native/pull/11001)) +### Annotations +* Fix an issue where a wrong annotation may selected if annotations were set close together. ([#11438](https://github.com/mapbox/mapbox-gl-native/pull/11438)) + ### Map snapshots * Fixed a memory leak that occurred when creating a map snapshot. ([#10585](https://github.com/mapbox/mapbox-gl-native/pull/10585)) From 44e2ad497d489013a6dba8196f7b4ce70c76f891 Mon Sep 17 00:00:00 2001 From: Lloyd Sheng Date: Tue, 13 Mar 2018 14:22:28 +0800 Subject: [PATCH 4/4] Fix an issue where the comment referenced to the wrong variable name --- platform/macos/src/MGLMapView.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index e9bada316b8..353b2bf2f10 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -2101,7 +2101,7 @@ - (MGLAnnotationTag)annotationTagAtPoint:(NSPoint)point persistingResults:(BOOL) if (nearbyAnnotations.size()) { // The first selection in the cycle should be the one nearest to the // tap. Also the annotation tags need to be stable in order to compare them with - // the remembered tags _annotationsNearbyLastTap. + // the remembered tags _annotationsNearbyLastClick. CLLocationCoordinate2D currentCoordinate = [self convertPoint:point toCoordinateFromView:self]; std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end(), [&](const MGLAnnotationTag tagA, const MGLAnnotationTag tagB) { CLLocationCoordinate2D coordinateA = [[self annotationWithTag:tagA] coordinate];