کاشیهای نقشه پایه Protomaps
تمام نقشه پایه Protomaps، از زوم 0 تا 15، در قالب یک آرشیو PMTiles روی HTTP ساده ارائه میشود. هر کلاینت PMTiles را به این نشانی وصل کنید تا کار کند.
https://tiles.jasontally.com/basemap.pmtiles
- بدون کلید APIنیازی به ثبتنام یا قرار دادن توکن در کد نیست.
- بدون محدودیت نرخ درخواستبدون کندسازی، بدون سهمیه، بدون سقف لحظهای.
- ماهانهماهی یک بار از جدیدترین انتشار Protomaps بازسازی میشود.
کاشی مسدودشده در OpenStreetMap، یا خطای 403 از tile.openstreetmap.org؟ از اینجا شروع کنید.
امتحان کنید
همان آرشیو در سه استایل. با تغییر استایل، کاشیهای بارگذاریشده سر جای خود میمانند و تغییر در لحظه انجام میشود.
استایل خودتان را بسازید
رنگی را تغییر دهید یا لایهای را خاموش کنید تا نقشه همزمان بهروز شود. سپس JSON استایل را کپی کنید؛ این یک استایل معمولی MapLibre است که میتوانید خودتان میزبانی کنید. این استایل به همین کاشیها اشاره میکند، بنابراین هر جا قرارش دهید کار میکند.
نحوه استفاده
این آرشیو از درخواستهای بازهای HTTP پشتیبانی میکند، بنابراین هر کلاینت PMTiles میتواند آن را بخواند.
یک. قرار دادن نقشه در صفحه
این فایل را کپی کنید. کل نمونه همین است: سه تگ، یک نشانی استایل، یک نقشه. هر دو کتابخانه روی نسخه مشخصی قفل شدهاند و مجوز BSD-3-Clause دارند، و اگر ترجیح میدهید از CDN استفاده نکنید، همین فایلها از روی این میزبان هم ارائه میشوند.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Basemap</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css">
<script src="https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pmtiles@3.2.1/dist/pmtiles.js"></script>
<style>html, body, #map { margin: 0; height: 100%; }</style>
</head>
<body>
<div id="map"></div>
<script>
// Teach MapLibre how to read a PMTiles archive.
const protocol = new pmtiles.Protocol();
maplibregl.addProtocol("pmtiles", protocol.tile);
new maplibregl.Map({
container: "map",
style: "https://tiles.jasontally.com/styles/light.json",
center: [2.35, 48.85], // Paris
zoom: 4
});
</script>
</body>
</html>
دو. جایگزینی کاشیها در استایلی که از قبل دارید
هر استایل MapLibre کاشیهای خود را از یک منبع (source) میخواند. برای استفاده از این کاشیها، فقط همان یک url را تغییر دهید. هیچ چیز دیگری در استایل تغییر نمیکند.
"sources": {
"protomaps": {
"type": "vector",
- "url": "pmtiles://https://demo-bucket.protomaps.com/v4.pmtiles",
+ "url": "pmtiles://https://tiles.jasontally.com/basemap.pmtiles",
"attribution": "<a href=\"https://www.openstreetmap.org/copyright\">© OpenStreetMap contributors</a>"
}
}
یا این کار را در کد انجام دهید؛ این روش زمانی کاربردی است که استایل از سروری میآید که در اختیار شما نیست:
// Rewrite every PMTiles source in a style to point at these tiles.
const style = await (await fetch("https://your-server/style.json")).json();
for (const source of Object.values(style.sources)) {
if (source.url?.startsWith("pmtiles://")) {
source.url = "pmtiles://https://tiles.jasontally.com/basemap.pmtiles";
}
}
new maplibregl.Map({ container: "map", style, center: [2.35, 48.85], zoom: 4 });
سه. استایلی را که ساختهاید کجا قرار دهید
دکمه JSON استایل در سازنده بالا، استایلی را که نقشه در همین لحظه رسم میکند به همراه ویرایشها باز میکند و پنجره آن دکمه کپی دارد. دو راه برای استفاده از خروجی آن وجود دارد و هر دو صفحات وب معمولی هستند.
آن را به صورت یک فایل در کنار صفحه خود ذخیره کنید و style را به آن ارجاع دهید، درست به همان شکلی که سه استایل روی این میزبان استفاده شدهاند. اگر استایل مال خودتان است و همراه با سایتتان تغییر میکند، این روش را انتخاب کنید:
// Save the copied JSON as my-basemap.json beside this file.
new maplibregl.Map({
container: "map",
style: "my-basemap.json", // relative, same origin
center: [2.35, 48.85],
zoom: 4
});
یا آن را داخل HTML نگه دارید تا فقط یک فایل برای جابهجایی داشته باشید و نیازی به میزبانی فایل جداگانه نباشد. استایل همان است و فقط محل قرارگیری آن فرق میکند:
// The copied JSON, pasted straight into the page.
const myStyle = {
"version": 8,
"name": "Protomaps Basemap — custom",
"glyphs": "https://tiles.jasontally.com/font/{fontstack}/{range}.pbf",
"sprite": "https://tiles.jasontally.com/sprites/v4/light",
"sources": { /* ... as copied ... */ },
"layers": [ /* ... as copied ... */ ]
};
new maplibregl.Map({ container: "map", style: myStyle, zoom: 4 });
خطهای glyphs و sprite را به همان شکل نگه دارید. این خطها برچسبها و آیکونها را رسم میکنند و به این میزبان اشاره دارند، بنابراین استایلی که در صفحه خودتان قرار میدهید از هر جایی که ارائه شود به کار خود ادامه میدهد. اگر ترجیح میدهید اصلاً به این میزبان وابسته نباشید، آنها را به protomaps.github.io/basemaps-assets ارجاع دهید.
یک نکته که پیش از جایگزینی باید بررسی کنید. این آرشیو از طرحواره Protomaps نسخه v3 استفاده میکند. استایلی که برای طرحواره دیگری نوشته شده باشد بارگذاری میشود اما چیزی رسم نمیکند، چون نام لایههای منبع همخوانی ندارند. نام نُه لایه در پایین فهرست شده است و یک استایل آماده v3 هم برای کپی کردن قرار دارد.
چهار. فونتها، اسپرایتها و کتابخانهها
یک نقشه از کاشیها، نشانی glyphs برای متن، در صورت نیاز نشانی sprite برای آیکونها، و کتابخانههایی برای رسم آنها تشکیل میشود. همه این موارد در مسیرهایی که هر بخش انتظار دارد در اینجا موجود است، تا اگر بخواهید کل نقشه از یک نام میزبان بارگذاری شود.
| مورد | نشانی در این میزبان | مجوز |
|---|
فایلهای MapLibre و PMTiles هم روی jsDelivr و هم در اینجا قرار دارند. هر دو نشانی کار میکنند.
ردیف آخر در این صفحه استفاده نشده است. این فایل رندرکننده برداری Leaflet است که در اینجا منتشر شده تا جایگزینی فقط با یک تگ اسکریپت انجام شود. خود Leaflet روی CDN خودش باقی میماند.
دو پشته فونت Noto Sans Regular و Noto Sans Medium به ۲۵۶ بازهای که MapLibre درخواست میکند تقسیم شدهاند، هر کدام شامل ۲۵۶ نقطه کد. هر ۲۵۶ بازه منتشر شدهاند، نه فقط بازههای لاتین: Protomaps عوارض نقشه را با نام محلی آنها برچسبگذاری میکند، بنابراین توکیو یا قاهره به بازههایی در حدود دهها هزار نیاز دارند. اگر فقط بازههای مورد نیاز نقشه انگلیسی منتشر شوند، آن برچسبها بدون هیچ پیغام خطایی ناپدید میشوند.
پنج برگه اسپرایت، یکی برای هر تم بالادستی، در اندازههای 1x و 2x. استایلهای زیر آیکونها را از آنها رسم میکنند، بنابراین این فایلها واکشی میشوند. اگر در استایل خودتان نقاط شهرها، تابلوهای بزرگراه یا نقاط مکانها را میخواهید، sprite را به فایل متناظر با تم خود ارجاع دهید. نام آیکونهای هر برگه در فایل light.json آن فهرست شده است.
نقشه چه چیزهایی را رسم میکند و هر کدام از کجا میآید
هر لایه یکی از نُه لایه منبع در این آرشیو است، بنابراین هیچ بخشی در اینجا به آرشیو دومی نیاز ندارد. دو مورد از آنها نیاز به توضیح دارند، چون ممکن است به نظر برسد دادهای کم است در حالی که اینطور نیست:
| لایه | منبع | در این نسخه هست؟ |
|---|---|---|
| اشکال، راهها، ساختمانها، آب، زمین | earth, landcover, landuse, water, roads, buildings | بله |
| نام مکانها، راهها و پهنههای آبی | فیلد name در همان لایهها | بله |
| آیکون نقاط مکانها، نقاط شهرها | pois.kind، places، به همراه اسپرایت | بله |
| تابلوهای مسیر | roads.shield_text | نه. نسخهای که اکنون ارائه میشود این فیلد را ندارد |
| شماره پلاکها | buildings.kind=address و buildings.addr_housenumber | نه، به همان دلیل |
هیچ آرشیو جدایی برای نشانیها و هیچ لایه نشانی جداگانهای برای واکشی وجود ندارد. پروژه بالادستی نقاط نشانی را درون لایه buildings به صورت عوارضی با kind=address و فیلد addr_housenumber قرار میدهد. این فیلد در نسخهای از Protomaps اضافه شده که جدیدتر از نسخه فعلی این نقشه است؛ بنابراین لایه شماره پلاکها ساخته شده و با بهروزرسانی ماهانه بعدی خودبهخود فعال میشود. همین موضوع برای متن تابلوهای مسیر هم صادق است: نسخه فعلی دارای shield_text_length است که تعداد نویسههای شماره مسیر را مشخص میکند نه خود متن آن را، بنابراین تابلویی که از روی آن رسم شود یک شکل خالی روی هر آزادراه خواهد بود.
نوشتن یک لایه توسط خودتان و رنگآمیزی آن
یک لایه شامل فیلتر، زوم، شکل و رنگ است. دو نکته در فیلتر اکثر افراد را به اشتباه میاندازد و هر دو بدون هیچ خطایی باعث رسم نشدن لایه میشوند:
kindنام دسته کلی است. برای راهها، مقدار آن یکی ازhighway،major_road،minor_road،pathیاrailاست. نامهای موجود در مستندات بالادستی — یعنیmotorway،primary،residential— مقادیرkind_detailهستند، و لایهای کهkindرا بر اساس آنها فیلتر کند هیچ چیزی رسم نمیکند و هیچ خطایی هم نمیدهد.- هیچ لایهای پایینتر از
minzoomخودش رسم نمیشود. این آرشیو در z15 متوقف میشود، بنابراین لایهای که minzoom آن 16 باشد هرگز رسم نخواهد شد. بیشتر عوارض همچنین فیلدmin_zoomخودشان را دارند که نشان میدهد از چه زومی ارزش نمایش دارند، و استایلهای موجود این مورد را هم بررسی میکنند.
بنابراین یک راه، نام آن، و کلیدی برای خاموش کردن خط به این صورت است:
{
"id": "road-major",
"type": "line",
"source": "protomaps",
"source-layer": "roads", // one of the nine
"minzoom": 4, // not drawn below this
"filter": ["==", ["get", "kind"], "major_road"],
"layout": {
"line-cap": "round",
"visibility": "visible" // "none" to hide it
},
"paint": {
"line-color": "#f7c44d", // any CSS colour
"line-width": ["interpolate", ["linear"], ["zoom"], 4, 1.7, 12, 6]
}
}
نام، یک لایه نماد (symbol) است که فیلد name را با هاله یا بدون هاله در پسزمینه میخواند. نبودن گلیف هیچ خطایی ایجاد نمیکند، بنابراین پشته فونتی که درخواست میکنید باید یکی از دو مورد موجود روی این میزبان باشد:
{
"id": "road-label-major",
"type": "symbol",
"source": "protomaps",
"source-layer": "roads",
"minzoom": 11,
"layout": {
"text-field": ["coalesce", ["get", "name:en"], ["get", "name"]],
"text-font": ["Noto Sans Medium"], // or Noto Sans Regular
"text-size": 10,
"symbol-placement": "line" // follow the road
},
"paint": {
"text-color": "#2b2a26",
"text-halo-color": "#ffffff",
"text-halo-width": 1.1
}
}
لایهای که چیزی رسم نمیکند خطا محسوب نمیشود و MapLibre هم اعلام نمیکند کدام شرط برقرار نبوده است. اگر لایه شما خالی است، به این ترتیب بررسی کنید: نام فیلد، minzoom لایه، پشته فونت، و در نهایت نام آیکون در مقایسه با light.json خود برگه اسپرایت.
اگر استایلی دارید که گلیفهای آن به demotiles.maplibre.org اشاره میکنند، تمام کاری که باید بکنید جایگزین کردن همان نام میزبان است. مسیر فایلها از قصد یکسان در نظر گرفته شده است.
"glyphs": "https://tiles.jasontally.com/font/{fontstack}/{range}.pbf",
"sprite": "https://tiles.jasontally.com/sprites/v4/light"
// before, in a style you already have
- "glyphs": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
+ "glyphs": "https://tiles.jasontally.com/font/{fontstack}/{range}.pbf",
اگر استایلی پشته فونتی غیر از دو مورد بالا را درخواست کند، هیچ متنی برای آن رسم نخواهد شد. استایلهای خود Protomaps برای متن توپر (bold) از Noto Sans Medium استفاده میکنند؛ در این مجموعه Noto Sans Bold وجود ندارد و به همین دلیل استایلی که آن را درخواست کند، تمام برچسبها را بدون اعلام خطا از دست میدهد.
کدام میزبان سریعتر است و چه تصمیمی درباره آن گرفته شد. بر اساس اندازهگیری نه حدس و گمان: درخواستهای یکیدرمیان، تکبهتک، روی یک اتصال، با کنار گذاشتن سه نمونه اول و تفکیک زمان دریافت اولین بایت از زمان انتقال. در این آزمایش، CDN برای تکتک این فایلها ۱۰ تا ۴۵ میلیثانیه زودتر پاسخ داد که به روشنی از قاعده ۱۵٪ عبور میکند. به همین دلیل کتابخانهها از jsDelivr بارگذاری میشوند.
فونتها و اسپرایتها از همین میزبان ارائه میشوند، هرچند همان اندازهگیری نشان میدهد که CDN حدود ۱۰ میلیثانیه زودتر به آنها پاسخ میدهد. این یک تصمیم است، نه یک اندازهگیری. نقشهای که از یک نام میزبان واحد بارگذاری شود، با از کار افتادن سرور دیگران خراب نمیشود، و از کار افتادن سرور گلیف یعنی نقشهای بدون هیچ برچسب. اگر آن ۱۰ میلیثانیه برایتان مهمتر است، glyphs را به protomaps.github.io/basemaps-assets/fonts ارجاع دهید تا با همان مسیر کار کند. این ارقام مربوط به یک کاربر در یک شهر است و اجرای دوباره این مقایسه تنها با یک دستور انجام میشود.
پنج. درباره Leaflet
تابع L.tileLayer در Leaflet تصویر رسم میکند، در حالی که اینها کاشیهای برداری هستند. با این حال نقشه Leaflet همچنان میتواند از آنها استفاده کند و در هر دو روش، نشانگرها، پاپآپها و کنترلهای شما حفظ میشوند. هر دو روش جایگزینی در بخش مهاجرت از کاشیهای OpenStreetMap آمدهاند.
شش. خواندن آرشیو با کتابخانه PMTiles
بدون نقشه، فقط داده. مناسب برای اسکریپتها، تستها و هر چیزی که تصویر نیست.
import { PMTiles, FetchSource } from "pmtiles";
const archive = new PMTiles(new FetchSource("https://tiles.jasontally.com/basemap.pmtiles"));
const header = await archive.getHeader();
console.log(header.minZoom, header.maxZoom); // 0 15
console.log(header.numAddressedTiles); // 1431655765
const metadata = await archive.getMetadata();
console.log(metadata.name); // "Protomaps Basemap"
const tile = await archive.getZxy(3, 4, 2); // z, x, y
console.log(tile.data.byteLength);
به دو کلاس دقت کنید. FetchSource خواننده بایتها روی HTTP است و PMTiles خوانندهای است که روی آن قرار میگیرد و قالب فایل را میفهمد. FileSource معادل محلی FetchSource برای فایلهای روی دیسک است و اگر رشته URL به آن بدهید کار نخواهد کرد.
این آرشیو یک نسخه ثابت است، نه یک جریان زنده. زمانبندی آن در بخش این دادهها چقدر جدید هستند؟ آمده است.
مهاجرت از کاشیهای OpenStreetMap
مسدودیت ناشی از سیاست استفاده از کاشیها، خطای 403، و راهحل آنها. بدون کلید، بدون سهمیه.
چرا نقشه پیام مسدودیت نشان میدهد
App is not following the tile usage policy of OpenStreetMap’s volunteer-run servers
General block: app is not following the tile usage policy of openstreetmap volunteer-run servers
403 Forbidden — tile.openstreetmap.org
سرورهای کاشی بر اساس سیاست استفاده از کاشیها، از قصد آن تصویر را به جای نقشه فرستادهاند. این یک خرابی فنی نیست و اصلاح نشانی هم آن را برطرف نمیکند.
کارهایی که معمولاً اول امتحان میکنند:
- تغییر دادن
a/b/cبه میزبان اصلی، مسدودیت شما را رفع نمیکند. استفاده از نشانی اصلی الزامی است، اما مسدودیت به برنامه یا هدر Referer مشاهدهشده متصل است، نه به نام میزبان. - تلاش مجدد وضع را بدتر میکند. حجم درخواستها بخشی از دلیل اعمال مسدودیت است.
- هیچ ترفند هدری صفحهای را که از روی دیسک باز شده نجات نمیدهد. پروتکل
file://هیچ هدرRefererای نمیفرستد. ارسالX-Requested-Withبه جای آن نیازمند یک درخواست پیشپرواز CORS برای هر کاشی است و سرورهای کاشی آن پیشپرواز را هم رد میکنند. Firefox و Chromium در هدرهایی که میفرستند تفاوت دارند، اما قانون برای هر دو یکسان است. - روی
localhostکار میکند اما روی سایت اصلی مسدود است؟ علت همان مبدأ (origin) است. هدر Referer دامنه شما مسدود شده است وlocalhostمقدار متفاوتی میفرستد.
شرکتها، مدارس، VPNها و شبکههای موبایل از نشانیهای مشترک استفاده میکنند و مسدودیتها علاوه بر برنامهها روی نشانیها هم اعمال میشوند. از سمت خودتان نمیتوانید تشخیص دهید کدام مورد شامل حال شما شده است.
بنابراین ارسال درخواست به آن سرورها را متوقف کنید. سه راه برای بینیاز شدن از آنها وجود دارد.
نگه داشتن Leaflet
کتابخانه protomaps-leaflet کاشیهای برداری را در Leaflet رسم میکند. این کتابخانه خودش آرشیو را میخواند و به عنوان یک لایه معمولی اضافه میشود، بنابراین نشانگرها، پاپآپها، GeoJSON و کنترلها سر جای خود میمانند. یک نسخه آزمایششده با این آرشیو در اینجا قرار دارد: https://tiles.jasontally.com/vendor/protomaps-leaflet.js.
قبل:
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
const map = L.map("map").setView([48.85, 2.35], 12);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
</script>
بعد:
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
+ <script src="https://tiles.jasontally.com/vendor/protomaps-leaflet.js"></script>
<script>
const map = L.map("map").setView([48.85, 2.35], 12);
- L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { ... }).addTo(map);
+ protomapsL.leafletLayer({
+ url: "https://tiles.jasontally.com/basemap.pmtiles",
+ flavor: "light",
+ lang: "en"
+ }).addTo(map);
</script>
- مقدار
flavorیکی ازlight،dark،white،grayscaleیاblackاست. اینها تمهای خود کتابخانه هستند نه استایلهای بالا، بنابراین رنگها دقیقاً یکسان نخواهند بود. - برچسبها متنِ بوم (canvas) با فونت سیستم هستند. نیازی به نشانی گلیف نیست و هیچ فونتی خطای 404 نمیدهد.
- z15 عمیقترین کاشی است. لایه در سطوح بالاتر از آن، کاشیها را بزرگنمایی میکند و
maxDataZoom: 15از پیش مقدار پیشفرض است.
پروژه protomaps-leaflet در منبع اصلی در حالت نگهداری است: فقط رفع اشکال، بدون قابلیت جدید. برای یک برنامه موجود با Leaflet مناسب است. کارهای جدید بهتر است با MapLibre GL شروع شوند.
نگه داشتن Leaflet، رندر با MapLibre
کتابخانه @maplibre/maplibre-gl-leaflet یک نقشه MapLibre را در قاب کاشیهای Leaflet قرار میدهد. زمانی از آن استفاده کنید که یکی از استایلهای بالا، یا عوارض زمین و سایهروشن پستیوبلندیها (hillshade) را در برنامهای میخواهید که همچنان بر پایه Leaflet است.
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<link rel="stylesheet" href="https://tiles.jasontally.com/vendor/maplibre-gl.css">
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://tiles.jasontally.com/vendor/maplibre-gl.js"></script>
<script src="https://tiles.jasontally.com/vendor/pmtiles.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-leaflet@0.1.4/dist/leaflet-maplibre-gl.js"></script>
<script>
// The style's source is pmtiles://, so MapLibre needs the protocol first.
maplibregl.addProtocol("pmtiles", new pmtiles.Protocol().tile);
const map = L.map("map", { minZoom: 1 }).setView([48.85, 2.35], 12);
const gl = L.maplibreGL({
style: "https://tiles.jasontally.com/styles/light.json"
}).addTo(map);
// gl.getMaplibreMap() is the MapLibre map, for sources and layers.
</script>
- اول پروتکل را ثبت کنید. بدون خط
addProtocol، کنسول پیامURL scheme "pmtiles" is not supportedرا نشان میدهد و نقشه خالی میماند. - MapLibre یک سطح زوم پایینتر از Leaflet رسم میکند. کاشیهای آن ۵۱۲ پیکسل در برابر ۲۵۶ پیکسل در Leaflet هستند، بنابراین لایهای با
minzoomبرابر 12 زمانی ظاهر میشود که Leaflet به z13 برسد. - Leaflet همچنان روی نقشه رسم میکند. بوم نقشه در قاب کاشیها قرار میگیرد، بنابراین نشانگرها و لایههای رویی درست مانند زمانی که روی لایه رستر هستند عمل میکنند.
مهاجرت به MapLibre GL
یک کتابخانه، بدون مبدل، و استایلهای بالا همانطور که هستند کار میکنند. کد کامل صفحه در بخش یک. قرار دادن نقشه در صفحه آمده است. تغییر اصلی، جابهجایی ترتیب مختصات است:
| Leaflet | MapLibre GL |
|---|---|
L.map("map").setView([lat, lng], z) | new maplibregl.Map({ container: "map", center: [lng, lat], zoom: z }) |
L.tileLayer(url).addTo(map) | یک استایل با منبع برداری؛ بخش بالا را ببینید |
L.marker([lat, lng]).bindPopup(html) | new maplibregl.Marker().setLngLat([lng, lat]).setPopup(new maplibregl.Popup().setHTML(html)) |
L.geoJSON(data) | addSource(id, { type: "geojson", data })، سپس addLayer |
L.control.scale() | new maplibregl.ScaleControl() |
map.invalidateSize() | map.resize() |
تابع setView([lat, lng]) ابتدا عرض جغرافیایی را میگیرد، اما تمام فراخوانیهای MapLibre به صورت [lng, lat] هستند. اگر نقشه در نیمکره اشتباهی نمایش داده میشود، علت همین است نه کاشیها. منابع و لایههایی که پیش از بارگذاری استایل اضافه شوند بدون خطا نادیده گرفته میشوند، پس آنها را داخل map.on("load", …) اضافه کنید.
“archive contains MVT vector tiles, but leafletRasterLayer is for displaying raster tiles”
این خطا مربوط به pmtiles.leafletRasterLayer است که فایلهای PMTiles رستر را به صورت تصویر رسم میکند. این کاشیها برداری هستند، بنابراین آنها را نمیپذیرد. هیچ تنظیمی این رفتار را تغییر نمیدهد و هیچ نسخه رستری هم در اینجا وجود ندارد. از یکی از روشهای بالا استفاده کنید.
“download.openstreetmap.fr returned 403”
این نشانی یک آینه (mirror) برای دریافت برشها و همگامسازی داده است، نه سرور کاشی. در اکتبر ۲۰۲۶ پس از دانلودهای بیرویه، نشانیها را مسدود کرد و گردانندگان آن اعلام کردند که دسترسی را به صورت موردی بازمیگردانند. هیچ بخشی در اینجا به آن نیاز ندارد: این آرشیو از انتشارهای Protomaps میآید، بنابراین نیازی نیست خودتان فایلهای .osm.pbf را سرهم کنید. اگر دادههای OSM را دریافت میکنید، به جای جریان لحظهایِ دقیقهای، از برشهای دورهای استفاده کنید.
استایلها
همان کاشیها، با رنگهای متفاوت. یکی را انتخاب کنید، کپی کنید و تغییر دهید؛ مال خودتان است.
| استایل | نمای ظاهری | فایل |
|---|
درون کاشیها چه چیزهایی هست
هنگام بارگذاری صفحه از فراداده خود آرشیو خوانده میشود. اینها نام لایههایی هستند که یک استایل باید از آنها استفاده کند.
| لایه منبع | زوم | فیلدها |
|---|---|---|
| در حال بارگذاری… | ||
این سرویس چه چیزی نیست
پاسخهای صریح، تا بعداً چیزی غافلگیرتان نکند.
- هیچ تضمین سطح سرویسی وجود ندارد. این یک سرویس رایگان بدون هیچ قراردادی در پشت آن است. ممکن است کند شود، از دسترس خارج شود، و نشانی یا دادههای آن بدون اطلاع قبلی تغییر کنند یا حذف شوند. اگر محصول شما به آن وابسته است، نسخه خودتان را از کاشیها میزبانی کنید یا یک سرویس پشتیبانیشده بخرید.
- هرگز در لحظه و ساعتبهساعت بهروز نیست. این نسخه یک تصویر ثابت از جدیدترین انتشار Protomaps است، نه یک جریان زنده. ویرایشهایی که امروز انجام شدهاند در آن وجود ندارند. زمانبندی در بخش این دادهها چقدر جدید هستند؟ آمده است.
- دانلود یکجای کل فایل ممکن نیست. درخواستها در بازههای حداکثر 512 KiB پاسخ داده میشوند، که تمام چیزی است که یک کلاینت PMTiles نیاز دارد. درخواست کل آرشیو در یک نشست کد
416برمیگرداند که رفتار درستی است. - ذکر منبع الزامی است. این کاشیها از دادههای OpenStreetMap استخراج شدهاند. خط ذکر منبع را در استایل یا روی نقشه خود حفظ کنید.
این دادهها چقدر جدید هستند؟
این کاشیها نسخهای از نقشه پایه Protomaps هستند که ماهی یک بار بازسازی میشوند.
- بازسازی ماهانه. فرآیند ساخت در اولین یکشنبه هر ماه، بین ساعت 00:30 تا 07:00 به وقت UTC اجرا میشود؛ تنها بازه زمانی که پروژه بالادستی در سه سال سابقه انتشار خود نسخهای در آن منتشر نکرده است. بازسازی ماهانه است نه هفتگی، چون هر آرشیو جدید بخشهای کششده در CDN و مرورگر کاربران را نامعتبر میکند و هر بار بازسازی زمان ساخت مصرف میکند.
- در بیشتر ماهها نیازی به کار خاصی نیست. بازسازی تنها زمانی انجام میشود که پروژه بالادستی نسخه جدیدی منتشر کرده باشد.
- در حال حاضر کدام نسخه بالادستی در حال استفاده است؟ از دکمه فراداده آرشیو در بالای همین صفحه استفاده کنید. این دکمه هدر خود آرشیو را میخواند، بنابراین پاسخ آن همیشه بهروز است و به متن ثابتی در این صفحه که ممکن است قدیمی شود وابسته نیست.
- بازسازی آنی نیست. این فرآیند شامل سیزده بازسازی جداگانه است که یکییکی در طول حدود شش ساعت و نیم انجام میشوند. در بیشتر این بازه زمانی، نسخه موجود ترکیبی از دو ساخت بالادستی است. کاشیای که در این مدت درخواست میکنید ممکن است از ساخت جدیدتر بیاید نه ساختی که هدر اعلام کرده است؛ این حالت به شکل یک کاشی از جای نادرست دیده میشود، نه یک نقشه خراب.
- یک نوبت بازسازی ممکن است انجام نشود. این فرآیند بر اساس بیشترین تلاش (best-effort) است، نه یک تعهد قطعی. اگر یکی از مراحل با خطا مواجه شود، بقیه نسخه روی همان ساخت بالادستی قبلی باقی میماند و نقشه همچنان کار میکند.