Skip to content

Commit 25cf61a

Browse files
ianthetechieHarelMjosxhalhapaipaikeichan34
authored
Add links to tile provider authentication docs (#914)
This probably confused some people in the past, since vector tiles won't even display an access denied image ;) Before (no information on access keys and where to get them): <img width="411" alt="image" src="https://github.com/user-attachments/assets/8820fb20-bda4-460c-9cc9-8fec5daa480d"> After (add links to providers in info callout + add a field for Stadia Maps API keys): <img width="395" alt="image" src="https://github.com/user-attachments/assets/91ee732c-b3f5-45f8-81a6-8d896a93f644"> --------- Co-authored-by: Harel M <harel.mazor@gmail.com> Co-authored-by: Joscha <34318751+josxha@users.noreply.github.com> Co-authored-by: Hugues Tavernier <hugues.tavernier@protonmail.com> Co-authored-by: Keitaroh Kobayashi <keita@kbys.me>
1 parent 0f1000c commit 25cf61a

12 files changed

+102
-24
lines changed

cypress/e2e/modals.cy.ts

+12
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,18 @@ describe("modals", () => {
160160
).shouldInclude({ "maputnik:thunderforest_access_token": apiKey });
161161
});
162162

163+
it("stadia access token", () => {
164+
let apiKey = "testing123";
165+
when.setValue(
166+
"modal:settings.maputnik:stadia_access_token",
167+
apiKey
168+
);
169+
when.click("modal:settings.name");
170+
then(
171+
get.styleFromLocalStorage().then((style) => style.metadata)
172+
).shouldInclude({ "maputnik:stadia_access_token": apiKey });
173+
});
174+
163175
it("style renderer", () => {
164176
cy.on("uncaught:exception", () => false); // this is due to the fact that this is an invalid style for openlayers
165177
when.select("modal:settings.maputnik:renderer", "ol");

src/components/Block.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ export default class Block extends React.Component<BlockProps, BlockState> {
5656
if (event.nativeEvent.target.nodeName !== "INPUT" && !contains) {
5757
event.stopPropagation();
5858
}
59-
event.preventDefault();
59+
if (event.nativeEvent.target.nodeName !== "A") {
60+
event.preventDefault();
61+
}
6062
}
6163

6264
render() {

src/components/Doc.tsx

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ type DocProps = {
1818
'sdk-support'?: {
1919
[key: string]: typeof headers
2020
}
21+
docUrl?: string,
22+
docUrlLinkText?: string
2123
}
2224
};
2325

2426
export default class Doc extends React.Component<DocProps> {
2527
render () {
2628
const {fieldSpec} = this.props;
2729

28-
const {doc, values} = fieldSpec;
30+
const {doc, values, docUrl, docUrlLinkText} = fieldSpec;
2931
const sdkSupport = fieldSpec['sdk-support'];
3032

3133
const renderValues = (
@@ -85,7 +87,12 @@ export default class Doc extends React.Component<DocProps> {
8587
</table>
8688
</div>
8789
}
90+
{docUrl && docUrlLinkText &&
91+
<div className="SpecDoc__learn-more">
92+
<a href={docUrl} target="_blank" rel="noreferrer">{docUrlLinkText}</a>
93+
</div>
94+
}
8895
</>
8996
);
9097
}
91-
}
98+
}

src/components/ModalExport.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ class ModalExportInternal extends React.Component<ModalExportInternalProps> {
130130
value={(this.props.mapStyle.metadata || {} as any)['maputnik:thunderforest_access_token']}
131131
onChange={this.changeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
132132
/>
133+
<FieldString
134+
label={fsa.maputnik.stadia_access_token.label}
135+
fieldSpec={fsa.maputnik.stadia_access_token}
136+
value={(this.props.mapStyle.metadata || {} as any)['maputnik:stadia_access_token']}
137+
onChange={this.changeMetadataProperty.bind(this, "maputnik:stadia_access_token")}
138+
/>
133139
</div>
134140

135141
<div className="maputnik-modal-export-buttons">

src/components/ModalSettings.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
156156
onChange={onChangeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
157157
/>
158158

159+
<FieldString
160+
label={fsa.maputnik.stadia_access_token.label}
161+
fieldSpec={fsa.maputnik.stadia_access_token}
162+
data-wd-key="modal:settings.maputnik:stadia_access_token"
163+
value={metadata['maputnik:stadia_access_token']}
164+
onChange={onChangeMetadataProperty.bind(this, "maputnik:stadia_access_token")}
165+
/>
166+
159167
<FieldArray
160168
label={t("Center")}
161169
fieldSpec={latest.$root.center}

src/libs/field-spec-additional.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,25 @@ const spec = (t: TFunction) => ({
44
maputnik: {
55
maptiler_access_token: {
66
label: t("MapTiler Access Token"),
7-
doc: t("Public access token for MapTiler Cloud.")
7+
doc: t("Public access token for MapTiler Cloud."),
8+
docUrl: "https://docs.maptiler.com/cloud/api/authentication-key/",
9+
docUrlLinkText: t("Learn More")
810
},
911
thunderforest_access_token: {
1012
label: t("Thunderforest Access Token"),
11-
doc: t("Public access token for Thunderforest services.")
13+
doc: t("Public access token for Thunderforest services."),
14+
docUrl: "https://www.thunderforest.com/docs/apikeys/",
15+
docUrlLinkText: t("Learn More")
16+
},
17+
stadia_access_token: {
18+
label: t("Stadia Maps API Key"),
19+
doc: t("API key for Stadia Maps."),
20+
docUrl: "https://docs.stadiamaps.com/authentication/",
21+
docUrlLinkText: t("Learn More")
1222
},
1323
style_renderer: {
1424
label: t("Style Renderer"),
15-
doc: t("Choose the default Maputnik renderer for this style."),
25+
doc: t("Choose the default Maputnik renderer for this style.")
1626
},
1727
}
1828
})

src/libs/style.ts

+24-6
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ function indexOfLayer(layers: LayerSpecification[], layerId: string) {
5555
}
5656

5757
function getAccessToken(sourceName: string, mapStyle: StyleSpecification, opts: {allowFallback?: boolean}) {
58-
if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") {
59-
sourceName = "thunderforest"
60-
}
61-
6258
const metadata = mapStyle.metadata || {} as any;
6359
let accessToken = metadata[`maputnik:${sourceName}_access_token`]
6460

@@ -74,18 +70,38 @@ function replaceSourceAccessToken(mapStyle: StyleSpecification, sourceName: stri
7470
if(!source) return mapStyle
7571
if(!("url" in source) || !source.url) return mapStyle
7672

77-
const accessToken = getAccessToken(sourceName, mapStyle, opts)
73+
let authSourceName = sourceName
74+
if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") {
75+
authSourceName = "thunderforest"
76+
}
77+
else if (("url" in source) && source.url?.match(/\.stadiamaps\.com/)) {
78+
// The code currently usually assumes openmaptiles == MapTiler,
79+
// so we need to check the source URL.
80+
authSourceName = "stadia"
81+
}
82+
83+
const accessToken = getAccessToken(authSourceName, mapStyle, opts)
7884

7985
if(!accessToken) {
8086
// Early exit.
8187
return mapStyle;
8288
}
8389

90+
let sourceUrl: string
91+
if (authSourceName == "stadia") {
92+
// Stadia Maps does not always require an API key,
93+
// so there is no placeholder in our styles.
94+
// We append it at the end of the URL when exporting if necessary.
95+
sourceUrl = `${source.url}?api_key=${accessToken}`
96+
} else {
97+
sourceUrl = source.url.replace('{key}', accessToken)
98+
}
99+
84100
const changedSources = {
85101
...mapStyle.sources,
86102
[sourceName]: {
87103
...source,
88-
url: source.url.replace('{key}', accessToken)
104+
url: sourceUrl
89105
}
90106
}
91107
const changedStyle = {
@@ -120,6 +136,8 @@ function stripAccessTokens(mapStyle: StyleSpecification) {
120136
...mapStyle.metadata as any
121137
};
122138
delete changedMetadata['maputnik:openmaptiles_access_token'];
139+
delete changedMetadata['maputnik:thunderforest_access_token'];
140+
delete changedMetadata['maputnik:stadia_access_token'];
123141
return {
124142
...mapStyle,
125143
metadata: changedMetadata

src/locales/de/translation.json

+3
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,11 @@
176176
"Error:": "Fehler:",
177177
"MapTiler Access Token": "MapTiler Zugriffstoken",
178178
"Public access token for MapTiler Cloud.": "Öffentlicher Zugriffstoken für MapTiler Cloud.",
179+
"Learn More": "Mehr erfahren",
179180
"Thunderforest Access Token": "Thunderforest Zugriffstoken",
180181
"Public access token for Thunderforest services.": "Öffentlicher Zugriffstoken für Thunderforest-Dienste.",
182+
"Stadia Maps API Key": "Stadia Maps API-Schlüssel",
183+
"API key for Stadia Maps.": "API-Schlüssel für Stadia Maps.",
181184
"Style Renderer": "Stil-Renderer",
182185
"Choose the default Maputnik renderer for this style.": "Wähle den Standard-Renderer für diesen Stil aus.",
183186
"Language": "Sprache",

src/locales/fr/translation.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
"Style Settings": "Paramètres du style",
3535
"View": "Vue",
3636
"Color accessibility": "Accessibilité des couleurs",
37-
"Language": "Langue",
3837
"Help": "Aide",
3938
"Comments for the current layer. This is non-standard and not in the spec.": "Commentaires pour le calque actuel. Ceci n'est pas standard et n'est pas dans la spécification.",
4039
"Comments": "Commentaires",
@@ -73,8 +72,8 @@
7372
"Collapse": "Réduire",
7473
"Expand": "Développer",
7574
"Add Layer": "Ajouter un calque",
76-
"Zoom:": "Zoom :",
7775
"Search": "Recherche",
76+
"Zoom:": "Zoom :",
7877
"Close popup": "Fermer la fenêtre",
7978
"cursor:": "curseur :",
8079
"center:": "centre :",
@@ -177,10 +176,14 @@
177176
"Error:": "Erreur :",
178177
"MapTiler Access Token": "Jeton d'accès MapTiler",
179178
"Public access token for MapTiler Cloud.": "Jeton d'accès public pour MapTiler Cloud.",
179+
"Learn More": "En savoir plus",
180180
"Thunderforest Access Token": "Jeton d'accès Thunderforest",
181181
"Public access token for Thunderforest services.": "Jeton d'accès public pour les services Thunderforest.",
182+
"Stadia Maps API Key": "Clé d'API Stadia Maps",
183+
"API key for Stadia Maps.": "Clé d'API pour Stadia Maps.",
182184
"Style Renderer": "Moteur de rendu pour le style",
183185
"Choose the default Maputnik renderer for this style.": "Choisissez le moteur de rendu Maputnik par défaut pour ce style.",
186+
"Language": "Langue",
184187
"Layer options": "Options du calque",
185188
"Paint properties": "Propriétés de peinture",
186189
"Layout properties": "Propriétés de mise en page",

src/locales/he/translation.json

+7-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
"Style Settings": "הגדרות הסטייל",
3535
"View": "תצוגה",
3636
"Color accessibility": "נגישות צבעים",
37-
"Language": "שפה",
3837
"Help": "עזרה",
3938
"Comments for the current layer. This is non-standard and not in the spec.": "הערות על השכבה הנוכחית. זה לא חלק מהספסיפיקציות",
4039
"Comments": "הערות",
@@ -73,16 +72,15 @@
7372
"Collapse": "הקטנה",
7473
"Expand": "הגדלה",
7574
"Add Layer": "הוספת שכבה",
76-
"Zoom:": "זום:",
7775
"Search": "חיפוש",
76+
"Zoom:": "זום:",
7877
"Close popup": "סגירת החלון",
7978
"cursor:": "סמן",
8079
"center:": "מרכז:",
8180
"rotation:": "סיבוב:",
8281
"Close modal": "סגירת חלונית",
8382
"Debug": "דיבאג",
8483
"Options": "אפשרויות",
85-
"<0>Open in OSM</0> &mdash; Opens the current view on openstreetmap.org": "<0>פתיחה ב-OSM</0> - פתיחה של התצוגה הנוכחית ב- openstreetmap.org",
8684
"Export Style": "ייצוא של הסטייל",
8785
"Download Style": "הורדה של הסטייל",
8886
"Download a JSON style to your computer.": "הורדה של הסטייל למחשב",
@@ -177,8 +175,13 @@
177175
"Error:": "שגיאה",
178176
"MapTiler Access Token": "MapTiler Access Token",
179177
"Public access token for MapTiler Cloud.": "Public access token for MapTiler Cloud.",
178+
"Learn More": "מידע נוסף",
180179
"Thunderforest Access Token": "Thunderforest Access Token",
181180
"Public access token for Thunderforest services.": "Public access token for Thunderforest services.",
181+
"Stadia Maps API Key": "Stadia Maps API Key",
182+
"API key for Stadia Maps.": "API key for Stadia Maps",
182183
"Style Renderer": "צייר הסטייל",
183-
"Choose the default Maputnik renderer for this style.": "בחירת צייר ברירת המחדל של מפוטניק עבור הסטייל הזה"
184+
"Choose the default Maputnik renderer for this style.": "בחירת צייר ברירת המחדל של מפוטניק עבור הסטייל הזה",
185+
"Language": "שפה",
186+
"<0>Open in OSM</0> — Opens the current view on openstreetmap.org": "<0>פתיחה ב-OSM</0> - פתיחה של התצוגה הנוכחית ב- openstreetmap.org"
184187
}

src/locales/ja/translation.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
"Style Settings": "スタイル設定",
3535
"View": "表示",
3636
"Color accessibility": "色のアクセシビリティ",
37-
"Language": "言語",
3837
"Help": "ヘルプ",
3938
"Comments for the current layer. This is non-standard and not in the spec.": "現在のレイヤーのコメント。注意:この機能は標準ではないため、他のライブラリとの互換性状況はわかりません。",
4039
"Comments": "コメント",
@@ -73,16 +72,15 @@
7372
"Collapse": "畳む",
7473
"Expand": "展開",
7574
"Add Layer": "レイヤー追加",
76-
"Zoom:": "ズーム:",
7775
"Search": "検索",
76+
"Zoom:": "ズーム:",
7877
"Close popup": "ポップアップを閉じる",
7978
"cursor:": "カーソル",
8079
"center:": "中央:",
8180
"rotation:": "回転角度:",
8281
"Close modal": "モーダルを閉じる",
8382
"Debug": "デバッグ",
8483
"Options": "設定",
85-
"<0>Open in OSM</0> &mdash; Opens the current view on openstreetmap.org": "現在のビューを <0>openstreetmap.org で開く</0>",
8684
"Export Style": "スタイルをエクスポート",
8785
"Download Style": "スタイルをダウンロード",
8886
"Download a JSON style to your computer.": "パソコンにJSONスタイルをダウンロードします。",
@@ -177,10 +175,15 @@
177175
"Error:": "エラー:",
178176
"MapTiler Access Token": "MapTiler アクセストークン",
179177
"Public access token for MapTiler Cloud.": "MapTiler Cloud の公開用アクセストークン",
178+
"Learn More": "詳細はこちら",
180179
"Thunderforest Access Token": "Thunderforest アクセストークン",
181180
"Public access token for Thunderforest services.": "Thunderforest サービスの公開用アクセストークン",
181+
"Stadia Maps API Key": "Stadia Maps API キー",
182+
"API key for Stadia Maps.": "Stadia Maps の API キー",
182183
"Style Renderer": "スタイルレンダラ",
183184
"Choose the default Maputnik renderer for this style.": "このスタイルのデフォルトの Maputnik レンダラを選択してください",
185+
"Language": "言語",
186+
"<0>Open in OSM</0> — Opens the current view on openstreetmap.org": "現在のビューを <0>openstreetmap.org で開く</0>",
184187
"Layer options": "レイヤー設定",
185188
"Paint properties": "ペイントプロパティ",
186189
"Layout properties": "レイアウトプロパティ",

src/locales/zh/translation.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
"Style Settings": "样式设置",
3535
"View": "视图",
3636
"Color accessibility": "颜色可访问性",
37-
"Language": "语言",
3837
"Help": "帮助",
3938
"Comments for the current layer. This is non-standard and not in the spec.": "当前图层的注释。注意:这不是标准功能,可能与其他库不兼容。",
4039
"Comments": "注释",
@@ -73,16 +72,15 @@
7372
"Collapse": "折叠",
7473
"Expand": "展开",
7574
"Add Layer": "添加图层",
76-
"Zoom:": "缩放:",
7775
"Search": "搜索",
76+
"Zoom:": "缩放:",
7877
"Close popup": "关闭弹出窗口",
7978
"cursor:": "光标:",
8079
"center:": "中心:",
8180
"rotation:": "旋转:",
8281
"Close modal": "关闭模态框",
8382
"Debug": "调试",
8483
"Options": "选项",
85-
"<0>Open in OSM</0> — Opens the current view on openstreetmap.org": "在 openstreetmap.org 打开当前视图",
8684
"Export Style": "导出样式",
8785
"Download Style": "下载样式",
8886
"Download a JSON style to your computer.": "将JSON样式下载到您的电脑。",
@@ -177,10 +175,15 @@
177175
"Error:": "错误:",
178176
"MapTiler Access Token": "MapTiler 访问令牌",
179177
"Public access token for MapTiler Cloud.": "MapTiler Cloud 的公共访问令牌。",
178+
"Learn More": "__STRING_NOT_TRANSLATED__",
180179
"Thunderforest Access Token": "Thunderforest 访问令牌",
181180
"Public access token for Thunderforest services.": "Thunderforest 服务的公共访问令牌。",
181+
"Stadia Maps API Key": "Stadia Maps API 密钥",
182+
"API key for Stadia Maps.": "Stadia Maps 的 API 密钥",
182183
"Style Renderer": "样式渲染器",
183184
"Choose the default Maputnik renderer for this style.": "为这种样式选择默认的Maputnik渲染器。",
185+
"Language": "语言",
186+
"<0>Open in OSM</0> — Opens the current view on openstreetmap.org": "在 openstreetmap.org 打开当前视图",
184187
"Layer options": "图层选项",
185188
"Paint properties": "绘制属性",
186189
"Layout properties": "布局属性",

0 commit comments

Comments
 (0)