Skip to content

Commit 2132bd3

Browse files
authored
improve globe image (#8067)
* improve globe image * oops * tweaks
1 parent 5cec88b commit 2132bd3

File tree

2 files changed

+285
-22
lines changed

2 files changed

+285
-22
lines changed

sites/kit.svelte.dev/src/routes/edge.svg/+server.js

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { geoPath } from 'd3-geo';
22
import { geoSatellite } from 'd3-geo-projection';
33
import * as topojson from 'topojson-client';
44
import topology from './land-110m.json';
5+
import countries from './countries.json';
56

67
const land = topojson.feature(topology, topology.objects.land);
78

@@ -28,18 +29,27 @@ const projection = geoSatellite()
2829
const path = geoPath(projection);
2930

3031
/**
31-
* @param {number} lat
32-
* @param {number} lon
32+
* @param {string | null} lat
33+
* @param {string | null} lon
3334
* @param {string} city
3435
* @param {string} country
3536
*/
3637
function render(lat, lon, city, country) {
37-
projection.rotate([-lon - 10, -lat + 20, 0]);
38+
const coords = lat && lon ? [+lon, +lat] : [-74, 40.7];
3839

39-
const [x, y] = projection([lon, lat]);
40+
// spin globe a little west of the user's location so that it isn't
41+
// dead centre, and tilt them slightly towards the vertical center
42+
projection.rotate([-coords[0] - 30, -coords[1] * (30 / 90), 0]);
4043

41-
const sphere = path({ type: 'Sphere' });
42-
const label = `${city}, ${country}`;
44+
const dot = lon && lat ? projection([lon, lat]) : null;
45+
46+
const MAX_LABEL_LENGTH = 27;
47+
const DEFAULT_LABEL = 'Your location';
48+
49+
let label = [city, country].filter(Boolean).join(', ') || DEFAULT_LABEL;
50+
if (label.length > MAX_LABEL_LENGTH) label = city ?? DEFAULT_LABEL;
51+
if (label.length > MAX_LABEL_LENGTH) label = country ?? DEFAULT_LABEL;
52+
if (label.length > MAX_LABEL_LENGTH) label = DEFAULT_LABEL;
4353

4454
return `<?xml version="1.0" encoding="UTF-8"?>
4555
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${w} ${h}">
@@ -81,10 +91,13 @@ function render(lat, lon, city, country) {
8191
}
8292
</style>
8393
84-
<path d="${sphere}" class="ocean"/>
94+
<path d="${path({ type: 'Sphere' })}" class="ocean"/>
8595
<path d="${path(land)}" class="land"/>
8696
87-
<g transform="translate(${x},${y})">
97+
${
98+
dot
99+
? `
100+
<g transform="translate(${dot[0]},${dot[1]})">
88101
<circle r="20" class="dot"/>
89102
<rect x="50" y="-30" width="${font_size * 0.6 * label.length + 40}" height="60" class="highlight"/>
90103
<polygon points="35,0 50,-10 50,10" class="highlight" />
@@ -96,27 +109,26 @@ function render(lat, lon, city, country) {
96109
dominant-baseline="middle"
97110
style="font-family: 'Courier', 'Courier New'; font-size: ${font_size}px; font-weight: bold"
98111
>${label.toUpperCase()}</text>
99-
</g>
112+
</g>`
113+
: ''
114+
}
100115
</svg>
101116
`;
102117
}
103118

104119
/** @type {import('./$types').RequestHandler} */
105-
export function GET({ request, url }) {
106-
const q = url.searchParams;
120+
export function GET({ request }) {
107121
const h = request.headers;
108122

109-
const latitude = q.get('lat') ?? h.get('x-vercel-ip-latitude') ?? '40.7';
110-
const longitude = q.get('lon') ?? h.get('x-vercel-ip-longitude') ?? '-74';
111-
const city = q.get('city') ?? h.get('x-vercel-ip-city') ?? 'New York City';
112-
const country = q.get('country') ?? h.get('x-vercel-ip-country') ?? 'USA';
113-
114-
const svg = render(
115-
+latitude,
116-
+longitude,
117-
decodeURIComponent(city),
118-
decodeURIComponent(country)
119-
).replace(/\d\.\d+/g, (match) => match.slice(0, 4));
123+
const latitude = h.get('x-vercel-ip-latitude') ?? '';
124+
const longitude = h.get('x-vercel-ip-longitude') ?? '';
125+
const city = h.get('x-vercel-ip-city') ?? '';
126+
const country = countries[h.get('x-vercel-ip-country')];
127+
128+
const svg = render(latitude, longitude, decodeURIComponent(city), country).replace(
129+
/\d\.\d+/g,
130+
(match) => match.slice(0, 4)
131+
);
120132

121133
return new Response(svg, {
122134
headers: {
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
{
2+
"AF": "Afghanistan",
3+
"AL": "Albania",
4+
"DZ": "Algeria",
5+
"AS": "American Samoa",
6+
"AD": "Andorra",
7+
"AO": "Angola",
8+
"AI": "Anguilla",
9+
"AQ": "Antarctica",
10+
"AG": "Antigua and Barbuda",
11+
"AR": "Argentina",
12+
"AM": "Armenia",
13+
"AW": "Aruba",
14+
"AU": "Australia",
15+
"AT": "Austria",
16+
"AZ": "Azerbaijan",
17+
"BS": "Bahamas (the)",
18+
"BH": "Bahrain",
19+
"BD": "Bangladesh",
20+
"BB": "Barbados",
21+
"BY": "Belarus",
22+
"BE": "Belgium",
23+
"BZ": "Belize",
24+
"BJ": "Benin",
25+
"BM": "Bermuda",
26+
"BT": "Bhutan",
27+
"BO": "Bolivia",
28+
"BQ": "Bonaire, Sint Eustatius and Saba",
29+
"BA": "Bosnia and Herzegovina",
30+
"BW": "Botswana",
31+
"BV": "Bouvet Island",
32+
"BR": "Brazil",
33+
"IO": "British Indian Ocean Territory",
34+
"BN": "Brunei Darussalam",
35+
"BG": "Bulgaria",
36+
"BF": "Burkina Faso",
37+
"BI": "Burundi",
38+
"CV": "Cabo Verde",
39+
"KH": "Cambodia",
40+
"CM": "Cameroon",
41+
"CA": "Canada",
42+
"KY": "Cayman Islands",
43+
"CF": "Central African Republic",
44+
"TD": "Chad",
45+
"CL": "Chile",
46+
"CN": "China",
47+
"CX": "Christmas Island",
48+
"CC": "Cocos (Keeling) Islands",
49+
"CO": "Colombia",
50+
"KM": "Comoros",
51+
"CD": "Congo (Kinshasa)",
52+
"CG": "Congo (Brazzaville)",
53+
"CK": "Cook Islands",
54+
"CR": "Costa Rica",
55+
"HR": "Croatia",
56+
"CU": "Cuba",
57+
"CW": "Curaçao",
58+
"CY": "Cyprus",
59+
"CZ": "Czechia",
60+
"CI": "Côte d'Ivoire",
61+
"DK": "Denmark",
62+
"DJ": "Djibouti",
63+
"DM": "Dominica",
64+
"DO": "Dominican Republic",
65+
"EC": "Ecuador",
66+
"EG": "Egypt",
67+
"SV": "El Salvador",
68+
"GQ": "Equatorial Guinea",
69+
"ER": "Eritrea",
70+
"EE": "Estonia",
71+
"SZ": "Eswatini",
72+
"ET": "Ethiopia",
73+
"FK": "Falkland Islands",
74+
"FO": "Faroe Islands",
75+
"FJ": "Fiji",
76+
"FI": "Finland",
77+
"FR": "France",
78+
"GF": "French Guiana",
79+
"PF": "French Polynesia",
80+
"TF": "French Southern Territories",
81+
"GA": "Gabon",
82+
"GM": "Gambia",
83+
"GE": "Georgia",
84+
"DE": "Germany",
85+
"GH": "Ghana",
86+
"GI": "Gibraltar",
87+
"GR": "Greece",
88+
"GL": "Greenland",
89+
"GD": "Grenada",
90+
"GP": "Guadeloupe",
91+
"GU": "Guam",
92+
"GT": "Guatemala",
93+
"GG": "Guernsey",
94+
"GN": "Guinea",
95+
"GW": "Guinea-Bissau",
96+
"GY": "Guyana",
97+
"HT": "Haiti",
98+
"HM": "Heard Island and McDonald Islands",
99+
"VA": "Holy See",
100+
"HN": "Honduras",
101+
"HK": "Hong Kong",
102+
"HU": "Hungary",
103+
"IS": "Iceland",
104+
"IN": "India",
105+
"ID": "Indonesia",
106+
"IR": "Iran",
107+
"IQ": "Iraq",
108+
"IE": "Ireland",
109+
"IM": "Isle of Man",
110+
"IL": "Israel",
111+
"IT": "Italy",
112+
"JM": "Jamaica",
113+
"JP": "Japan",
114+
"JE": "Jersey",
115+
"JO": "Jordan",
116+
"KZ": "Kazakhstan",
117+
"KE": "Kenya",
118+
"KI": "Kiribati",
119+
"KP": "DPRK",
120+
"KR": "Republic of Korea",
121+
"KW": "Kuwait",
122+
"KG": "Kyrgyzstan",
123+
"LA": "Laos",
124+
"LV": "Latvia",
125+
"LB": "Lebanon",
126+
"LS": "Lesotho",
127+
"LR": "Liberia",
128+
"LY": "Libya",
129+
"LI": "Liechtenstein",
130+
"LT": "Lithuania",
131+
"LU": "Luxembourg",
132+
"MO": "Macao",
133+
"MG": "Madagascar",
134+
"MW": "Malawi",
135+
"MY": "Malaysia",
136+
"MV": "Maldives",
137+
"ML": "Mali",
138+
"MT": "Malta",
139+
"MH": "Marshall Islands",
140+
"MQ": "Martinique",
141+
"MR": "Mauritania",
142+
"MU": "Mauritius",
143+
"YT": "Mayotte",
144+
"MX": "Mexico",
145+
"FM": "Micronesia",
146+
"MD": "Moldova",
147+
"MC": "Monaco",
148+
"MN": "Mongolia",
149+
"ME": "Montenegro",
150+
"MS": "Montserrat",
151+
"MA": "Morocco",
152+
"MZ": "Mozambique",
153+
"MM": "Myanmar",
154+
"NA": "Namibia",
155+
"NR": "Nauru",
156+
"NP": "Nepal",
157+
"NL": "Netherlands",
158+
"NC": "New Caledonia",
159+
"NZ": "New Zealand",
160+
"NI": "Nicaragua",
161+
"NE": "Niger",
162+
"NG": "Nigeria",
163+
"NU": "Niue",
164+
"NF": "Norfolk Island",
165+
"MP": "Northern Mariana Islands",
166+
"NO": "Norway",
167+
"OM": "Oman",
168+
"PK": "Pakistan",
169+
"PW": "Palau",
170+
"PS": "Palestine",
171+
"PA": "Panama",
172+
"PG": "Papua New Guinea",
173+
"PY": "Paraguay",
174+
"PE": "Peru",
175+
"PH": "Philippines",
176+
"PN": "Pitcairn",
177+
"PL": "Poland",
178+
"PT": "Portugal",
179+
"PR": "Puerto Rico",
180+
"QA": "Qatar",
181+
"MK": "North Macedonia",
182+
"RO": "Romania",
183+
"RU": "Russian Federation",
184+
"RW": "Rwanda",
185+
"RE": "Réunion",
186+
"BL": "Saint Barthélemy",
187+
"SH": "Saint Helena, Ascension and Tristan da Cunha",
188+
"KN": "Saint Kitts and Nevis",
189+
"LC": "Saint Lucia",
190+
"MF": "Saint Martin (French part)",
191+
"PM": "Saint Pierre and Miquelon",
192+
"VC": "Saint Vincent and the Grenadines",
193+
"WS": "Samoa",
194+
"SM": "San Marino",
195+
"ST": "Sao Tome and Principe",
196+
"SA": "Saudi Arabia",
197+
"SN": "Senegal",
198+
"RS": "Serbia",
199+
"SC": "Seychelles",
200+
"SL": "Sierra Leone",
201+
"SG": "Singapore",
202+
"SX": "Sint Maarten (Dutch part)",
203+
"SK": "Slovakia",
204+
"SI": "Slovenia",
205+
"SB": "Solomon Islands",
206+
"SO": "Somalia",
207+
"ZA": "South Africa",
208+
"GS": "South Georgia and the South Sandwich Islands",
209+
"SS": "South Sudan",
210+
"ES": "Spain",
211+
"LK": "Sri Lanka",
212+
"SD": "Sudan (the)",
213+
"SR": "Suriname",
214+
"SJ": "Svalbard and Jan Mayen",
215+
"SE": "Sweden",
216+
"CH": "Switzerland",
217+
"SY": "Syrian Arab Republic",
218+
"TW": "Taiwan",
219+
"TJ": "Tajikistan",
220+
"TZ": "Tanzania",
221+
"TH": "Thailand",
222+
"TL": "Timor-Leste",
223+
"TG": "Togo",
224+
"TK": "Tokelau",
225+
"TO": "Tonga",
226+
"TT": "Trinidad and Tobago",
227+
"TN": "Tunisia",
228+
"TR": "Turkey",
229+
"TM": "Turkmenistan",
230+
"TC": "Turks and Caicos Islands (the)",
231+
"TV": "Tuvalu",
232+
"UG": "Uganda",
233+
"UA": "Ukraine",
234+
"AE": "UAE",
235+
"GB": "UK",
236+
"UM": "United States Minor Outlying Islands",
237+
"US": "USA",
238+
"UY": "Uruguay",
239+
"UZ": "Uzbekistan",
240+
"VU": "Vanuatu",
241+
"VE": "Venezuela",
242+
"VN": "Vietnam",
243+
"VG": "British Virgin Islands",
244+
"VI": "US Virgin Islands",
245+
"WF": "Wallis and Futuna",
246+
"EH": "Western Sahara",
247+
"YE": "Yemen",
248+
"ZM": "Zambia",
249+
"ZW": "Zimbabwe",
250+
"AX": "Åland Islands"
251+
}

0 commit comments

Comments
 (0)