Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Source-driven attribution #5999

Merged
merged 8 commits into from
Dec 9, 2016
Merged

Conversation

1ec5
Copy link
Contributor

@1ec5 1ec5 commented Aug 13, 2016

The attribution view on macOS and the ℹ️ action sheet on iOS now display the correct attribution based on all the sources used in the current style, instead of the Mapbox and OpenStreetMap attribution that was previously hard-coded in each implementation of MGLMapView. This means DigitalGlobe is credited for Mapbox Satellite and Satellite Streets, and attribution for third-party sources added in Mapbox Studio or using the runtime styling API is also shown.

The attribution view on macOS updates immediately whenever the style changes and a new source is loaded. Developers can (should) now hook up an Improve This Map menu item to a new giveFeedback: action on MGLMapView, which opens in a Web browser any feedback URL it finds in a source’s attribution HTML code.

The ℹ️ action sheet on iOS fetches the current style’s attribution information on demand.

macos

Implemented observer callbacks so the style knows when the source’s attribution changes and the map knows when the style’s attribution changes. Also implemented a getter for a tile source’s attribution. Split out as #6431.

More to come:

Depends on #6431.

/cc @kkaefer @friedbunny

@1ec5 1ec5 added feature GL JS parity For feature parity with Mapbox GL JS iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS Core The cross-platform C++ core, aka mbgl labels Aug 13, 2016
@1ec5 1ec5 self-assigned this Aug 13, 2016
@friedbunny
Copy link
Contributor

This is a great change. 👍

Should the feedback item be contingent on the current style being Mapbox-hosted?

I also keep coming back to the UI, but adding more entries to the action sheet is something I think we should try to limit or avoid. The items that exist there now are all very important (and are all presented as equally important), but adding an arbitrary number of new items dilutes existing ones.

If a map were to have many sources and/or many attributions, this list could quickly grow out of control. A custom view is one way around this, but we could also consider following the current telemetry opt-out alert style: add a generic “Map data providers” item to the action sheet, which presents the user with an alert with items that link to the different map data providers.

@1ec5
Copy link
Contributor Author

1ec5 commented Aug 13, 2016

Should the feedback item be contingent on the current style being Mapbox-hosted?

This branch currently filters out the feedback link coming from TileJSON in favor of the built-in feedback item. On iOS, we could definitely drop the built-in item in favor of the TileJSON one, but we’ll need to customize the URL based on the current viewport and localize the item title (or at least title-case it).

On macOS, the built-in “Improve This Map” item belongs in the Help menu. As part of upstreaming the item from macosapp to the macOS SDK (#5775), we could enable and disable the menu item based on the link’s presence in TileJSON. However, I’m still unsure how the SDK would even automatically add a menu item in the first place.

adding an arbitrary number of new items dilutes existing ones

Agreed. However, in practice, the number of attribution links in a source is always kept to a minimum in order to fit horizontally on a standard webpage. For parity with GL JS, I’ve implemented deduping logic in the iOS/macOS SDK to avoid showing redundant items when, for instance, multiple Mapbox-copyrighted sources are being used. Among the default styles, Satellite and Satellite Streets are currently the worst case:

iOS

macOS

(On iOS, “Improve This Map” would swap places with the DigitalGlobe attribution if we replace the built-in feedback item with the one coming from TileJSON.)

A single “Map Data Providers” item would be more elegant, but it would divorce attribution even further from the map view. UI design changes will require considerable thought, so let’s hash that out in a separate PR.

@1ec5 1ec5 added the ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold label Aug 13, 2016
@1ec5
Copy link
Contributor Author

1ec5 commented Aug 14, 2016

macOS now supports rich formatting besides links, including inline images:

OSM logo

@1ec5 1ec5 removed the ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold label Aug 14, 2016
@1ec5
Copy link
Contributor Author

1ec5 commented Aug 14, 2016

The Darwin unit tests are failing on iOS (but not macOS) due to network issues while running -[MGLOfflineStorageTests testAAALoadPacks]:

2016-08-14 12:08:30.022 xctest[78390:1809420] [ERROR] {}[Setup]: loading style failed: HTTP status code 401

I’m not sure why initializing an MGLOfflineStorage would trigger network requests, and none of this is related to the changes in this branch.

@1ec5
Copy link
Contributor Author

1ec5 commented Aug 14, 2016

Tracking the iOS test failure in #6006.

@1ec5 1ec5 force-pushed the 1ec5-attribution-callback-2723 branch 2 times, most recently from a73a191 to 1ecee06 Compare August 16, 2016 08:46
@@ -240,6 +251,26 @@ Source* Style::getSource(const std::string& id) const {
return it != sources.end() ? it->get() : nullptr;
}

std::vector<std::string> Style::getAttributions() const {
std::vector<std::string> result;
result.reserve(sources.size());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed IMO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, this will always allocated more memory than we need since we always have a annotation source that doesn't have attribution.

@tmpsantos
Copy link
Contributor

👍

@@ -149,9 +149,11 @@ class Map : private util::noncopyable {
void removeAnnotation(AnnotationID);

// Sources
std::vector<const style::Source*> getSources() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this API yet, do we?

@1ec5 1ec5 force-pushed the 1ec5-attribution-callback-2723 branch from 1ecee06 to db19063 Compare August 16, 2016 15:34
@@ -861,6 +870,10 @@ void Map::onLowMemory() {
impl->view.invalidate();
}

void Map::Impl::onSourceAttributionChanged(style::Source&, std::string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the parameters if not in use?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I struggled with this one. Semantically, I think it makes plenty of sense for the string to go along with the callback, for consistency with the other callbacks. But we aren’t currently plumbing the string all the way through because the notifyMapChange() mechanism doesn’t support additional data beyond a single MapChange enum.

@1ec5 1ec5 force-pushed the 1ec5-attribution-callback-2723 branch 2 times, most recently from 3b57a31 to df3e47b Compare August 22, 2016 03:01
@1ec5
Copy link
Contributor Author

1ec5 commented Aug 22, 2016

A Valgrind failure on Qt appears to have been uncovered by the addition of a simple unit test:

==10075== Conditional jump or move depends on uninitialised value(s)

==10075==    at 0x4C307C2: __memcmp_sse4_1 (in /home/travis/build/mapbox/mapbox-gl-native/mason_packages/linux-x86_64/valgrind/latest/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==10075==    by 0x75AB4E: mbgl::util::mapbox::isMapboxURL(std::string const&) (in /home/travis/build/mapbox/mapbox-gl-native/build/qt-linux-x86_64/Release/mbgl-test)

==10075==    by 0x6A8259: mbgl::style::TileSourceImpl::parseTileJSON(std::string const&, std::string const&, mbgl::SourceType, unsigned short) (in /home/travis/build/mapbox/mapbox-gl-native/build/qt-linux-x86_64/Release/mbgl-test)

==10075==    by 0x6A9F1D: std::_Function_handler<void (mbgl::Response), mbgl::style::TileSourceImpl::load(mbgl::FileSource&)::{lambda(mbgl::Response)#1}>::_M_invoke(std::_Any_data const&, mbgl::Response&&) (in /home/travis/build/mapbox/mapbox-gl-native/build/qt-linux-x86_64/Release/mbgl-test)

The test uses test as a tile URL, just like some of the other Source tests.

/cc @brunoabinader @tmpsantos

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 4, 2016

Feedback links are now derived from the current style’s sources instead of being hard-coded, as suggested in #5999 (comment). So in iOS applications displaying the Mapbox Satellite Streets style, the Improve This Map button in the ℹ️ sheet appears between the OpenStreetMap and DigitalGlobe attribution buttons. macOS applications can easily create a similar menu item by hooking it up to the first responder’s giveFeedback: action, which MGLMapView validates.

This PR is ready for review.

@1ec5 1ec5 force-pushed the 1ec5-attribution-callback-2723 branch from 6584f17 to 23acd17 Compare December 8, 2016 10:16
@1ec5 1ec5 requested a review from friedbunny December 8, 2016 10:17
Copy link
Contributor

@friedbunny friedbunny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the facetalk walkthrough!

@1ec5 1ec5 modified the milestones: ios-v3.4.0, ios-3.4.1 Dec 8, 2016
Refactored MGLSource initialization. Implemented a new private class, MGLAttributionInfo, that parses an HTML attribution string from TileJSON and stores the resulting structured data. Added methods to MGLTileSet and MGLStyle to aggregate MGLAttributionInfos.

On macOS, update the attribution view as soon as the source attribution changes. On iOS, fetch the current attribution information when displaying the action sheet.

Removed hard-coded attribution strings.
Apply a default font and color to attribution HTML as it is imported into an attributed string. Pass the attributed string into MGLAttributionButton as is, without stripping formatting. Avoid overriding the font and color after importing the HTML, in case these attributes are explicitly specified rather than intrinsic to a hyperlink.

Constrain the top of the attribution view to all the attribution buttons, in case one of them needs additional headspace.
Unlinked attribution strings are represented on macOS as buttons that have the default cursor and do nothing when clicked. On iOS, they are action sheet buttons that do nothing but dismiss the action sheet.
Auto Layout randomly finds itself unable to satisfy constraints when updating attribution, due to some spurious constraints between attribution buttons. Regenerate the entire attribution view every time the source attribution changes.
Also added a test to verify parity with the GL JS implementation. This implementation avoids sorting.
Included an emoji test to ensure that attribution strings are interpreted as UTF-8, to avoid mojibake. Included a test of removing the underline from a leading copyright symbol.
MGLAttributionInfo now detects feedback links in the attribution HTML code, and it is responsible for tailoring the feedback URL to the current viewport.

Removed the hard-coded feedback action from the attribution sheet on iOS in favor of a source-derived feedback title and URL. Moved the feedback action from macosapp to MGLMapView; applications are now expected to hook an Improve This Map menu item to an MGLMapView action.
@1ec5
Copy link
Contributor Author

1ec5 commented Dec 9, 2016

I was thinking about making MGLAttributionInfo public and turning MGLTileSet.attribution into an array of them, but I’ll address that separately in #7361.

@1ec5 1ec5 merged commit fe53af7 into release-ios-v3.4.0 Dec 9, 2016
@1ec5 1ec5 deleted the 1ec5-attribution-callback-2723 branch December 9, 2016 01:43
ericrwolfe added a commit that referenced this pull request Dec 13, 2016
* release-ios-v3.4.0:
  [ios] Fixed crash on launch in iosapp
  [ios] Fix iosapp runtime styling examples (#7395)
  [ios, macos] handle duplicate layer error
  [core] guard against duplicate layer ids
  [core] use raii to guard backend deactivation
  [ios, macos] Override references to property names in property requirements lists (#7391)
  [ios, macos] Load features into shape source if possible (#7339)
  [ios, macos] Expanded source documentation
  [ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334)
  [ios, macos] Silence -Wc++11-narrowing warning in open gl layer (#7355)
  [ios, macos] Source-driven attribution (#5999)
  [ios, macos] renamed raster-hue-rotate

# Conflicts:
#	platform/darwin/src/MGLRasterSource.h
#	platform/darwin/src/MGLShapeSource.h
#	platform/darwin/src/MGLSource.h
#	platform/darwin/src/MGLVectorSource.h
ericrwolfe added a commit that referenced this pull request Dec 13, 2016
* release-ios-v3.4.0:
  [ios] Fixed crash on launch in iosapp
  [ios] Fix iosapp runtime styling examples (#7395)
  [ios, macos] handle duplicate layer error
  [core] guard against duplicate layer ids
  [core] use raii to guard backend deactivation
  [ios, macos] Override references to property names in property requirements lists (#7391)
  [ios, macos] Load features into shape source if possible (#7339)
  [ios, macos] Expanded source documentation
  [ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334)
  [ios, macos] Silence -Wc++11-narrowing warning in open gl layer (#7355)
  [ios, macos] Source-driven attribution (#5999)
  [ios, macos] renamed raster-hue-rotate
ericrwolfe added a commit that referenced this pull request Dec 14, 2016
* release-ios-v3.4.0:
  [ios] Fixed crash on launch in iosapp
  [ios] Fix iosapp runtime styling examples (#7395)
  [ios, macos] handle duplicate layer error
  [core] guard against duplicate layer ids
  [core] use raii to guard backend deactivation
  [ios, macos] Override references to property names in property requirements lists (#7391)
  [ios, macos] Load features into shape source if possible (#7339)
  [ios, macos] Expanded source documentation
  [ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334)
  [ios, macos] Silence -Wc++11-narrowing warning in open gl layer (#7355)
  [ios, macos] Source-driven attribution (#5999)
  [ios, macos] renamed raster-hue-rotate

# Conflicts:
#	platform/ios/jazzy.yml
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature GL JS parity For feature parity with Mapbox GL JS iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants