Protomaps Basemap ٹائلیں
مکمل Protomaps Basemap، زوم 0 سے 15 تک، سادہ HTTP پر ایک واحد PMTiles آرکائیو کے طور پر دستیاب ہے۔ کسی بھی PMTiles کلائنٹ کو اس URL سے جوڑیں اور یہ کام کرتا ہے۔
https://tiles.jasontally.com/basemap.pmtiles
- کوئی API کلید نہیںسائن اپ کرنے کی ضرورت نہیں، آپ کے کوڈ میں کوئی ٹوکن نہیں۔
- کوئی ریٹ لمٹ نہیںنہ رفتار کی پابندی، نہ کوٹہ، نہ برسٹ کی حد۔
- ماہانہمہینے میں ایک بار تازہ ترین Protomaps ریلیز سے دوبارہ بنایا جاتا ہے۔
کیا OpenStreetMap کی ٹائل بلاک ہو گئی ہے، یا tile.openstreetmap.org سے 403 آ رہا ہے؟ یہاں سے شروع کریں۔
آزمائیں
تین اسٹائلز میں وہی ایک آرکائیو۔ اسٹائل بدلیں تو پہلے سے لوڈ شدہ ٹائلیں اپنی جگہ رہتی ہیں، اس لیے تبدیلی فوری ہوتی ہے۔
اپنا اسٹائل خود بنائیں
کوئی رنگ بدلیں یا کسی لیئر کو بند کریں تو نقشہ ساتھ ساتھ اپ ڈیٹ ہوتا رہے گا۔ پھر اسٹائل JSON کاپی کر لیں، جو ایک عام MapLibre اسٹائل ہے جسے آپ خود ہوسٹ کر سکتے ہیں۔ یہ انہی ٹائلوں کی طرف اشارہ کرتا ہے، اس لیے آپ اسے جہاں بھی رکھیں یہ کام کرتا رہے گا۔
استعمال کا طریقہ
یہ آرکائیو HTTP رینج ریکویسٹس پر کام کرتا ہے، اس لیے ہر PMTiles کلائنٹ اسے پڑھ سکتا ہے۔
ایک۔ صفحے پر نقشہ لگائیں
اس فائل کو کاپی کریں۔ یہ مکمل مثال ہے: تین ٹیگز، ایک اسٹائل URL، اور ایک نقشہ۔ دونوں لائبریریاں مخصوص ورژن پر پن ہیں اور 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 اسٹائل اپنی ٹائلیں ایک سورس سے پڑھتا ہے۔ ان ٹائلوں کو استعمال کرنے کے لیے بس اس ایک 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 schema v3 ہے۔ کسی مختلف اسکیما کے لیے لکھا گیا اسٹائل لوڈ تو ہو جائے گا لیکن کچھ دکھائے گا نہیں، کیونکہ سورس لیئرز کے نام میل نہیں کھاتے۔ نو لیئرز کے نام نیچے درج ہیں، اور ساتھ ہی ایک تیار شدہ v3 اسٹائل بھی موجود ہے جس سے آپ کاپی کر سکتے ہیں۔
چار۔ فونٹس، اسپرائٹس اور لائبریریاں
ایک نقشہ دراصل ٹائلوں، متن کے لیے glyphs URL، اختیاری طور پر آئیکنز کے لیے sprite URL، اور ان سب کو دکھانے والی لائبریریوں پر مشتمل ہوتا ہے۔ یہ سب کچھ یہاں ان متوقع پاتھس پر موجود ہے، تاکہ اگر آپ چاہیں تو پورا نقشہ ایک ہی ہوسٹ نام سے لوڈ ہو سکے۔
| کیا | یہاں کا URL | لائسنس |
|---|
MapLibre اور PMTiles کی فائلیں jsDelivr پر بھی ہیں اور یہاں بھی۔ دونوں میں سے کوئی بھی URL کام کرے گا۔
آخری قطار اس صفحے پر استعمال نہیں ہوئی۔ یہ Leaflet کا ویکٹر رینڈرر ہے، جسے یہاں اس لیے شائع کیا گیا ہے تاکہ تبدیلی صرف ایک اسکرپٹ ٹیگ سے ہو سکے۔ Leaflet بذاتِ خود اپنے CDN پر رہتا ہے۔
دو فونٹ اسٹیکس، Noto Sans Regular اور Noto Sans Medium، ان 256 رینجز میں تقسیم ہیں جن کی MapLibre کو ضرورت ہوتی ہے، ایک وقت میں 256 کوڈ پوائنٹس۔ صرف لاطینی نہیں بلکہ تمام 256 رینجز شائع کی گئی ہیں: 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]
}
}
نام دراصل ایک سمبل لیئر ہے جو name فیلڈ کو پڑھتی ہے، جس کے پیچھے ہالہ (halo) ہوتا ہے یا کچھ نہیں۔ اگر کوئی گلف موجود نہ ہو تو خاموشی سے نظر انداز کر دیا جاتا ہے، اس لیے آپ جس فونٹ اسٹیک کی درخواست کریں وہ اس ہوسٹ پر موجود دو میں سے ہی ایک ہونا چاہیے:
{
"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 نے ان میں سے ہر فائل کے لیے 10 سے 45 ملی سیکنڈ جلدی جواب دیا، جو 15% کے اصول کو واضح فرق سے پورا کرتا ہے۔ اسی وجہ سے لائبریریاں jsDelivr سے لوڈ کی جاتی ہیں۔
فونٹس اور اسپرائٹس یہیں سے فراہم کیے جاتے ہیں، حالانکہ اسی پیمائش کے مطابق CDN ان کا جواب بھی تقریباً 10 ملی سیکنڈ جلدی دیتا۔ یہ ایک فیصلہ ہے، پیمائش نہیں۔ ایک ہی ہوسٹ نام سے آنے والا نقشہ کسی دوسرے سرور کے بند ہونے سے خراب نہیں ہوتا، اور گلف سرور بند ہو تو پورا نقشہ لیبلز کے بغیر رہ جاتا ہے۔ اگر آپ کو وہ 10 ملی سیکنڈ بچانا پسند ہے تو glyphs کا رخ protomaps.github.io/basemaps-assets/fonts کی طرف کر دیں، وہ اسی پاتھ کے ساتھ کام کرے گا۔ یہ ایک شہر سے ایک قاری کے اعداد و شمار ہیں، اور موازنہ دوبارہ چلانا صرف ایک کمانڈ کا کام ہے۔
پانچ۔ Leaflet کے بارے میں
Leaflet کا L.tileLayer تصویریں دکھاتا ہے؛ جبکہ یہ ویکٹر ٹائلیں ہیں۔ پھر بھی 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
ٹائل سرورز نے ٹائل کے استعمال کی پالیسی کے تحت جان بوجھ کر نقشے کے بجائے وہ تصویر بھیجی ہے۔ یہ کوئی تکنیکی خرابی نہیں ہے، اور URL ٹھیک کرنے سے یہ ختم نہیں ہوتی۔
لوگ سب سے پہلے کیا آزماتے ہیں:
a/b/cکو بدل کر اصل (canonical) ہوسٹ کرنے سے بلاک ختم نہیں ہوتا۔ اصل URL لازمی ضرور ہے، لیکن بلاک کا تعلق ہوسٹ نام سے نہیں بلکہ اس ایپ یا Referer سے ہوتا ہے جو سرور نے دیکھا۔- بار بار کوشش کرنے سے صورتحال مزید خراب ہوتی ہے۔ ریکویسٹس کی زیادتی خود اس بلاک کی وجوہات میں شامل ہے۔
- ڈسک سے کھولے گئے صفحے کو کوئی ہیڈر ٹرک نہیں بچا سکتا۔
file://کوئیRefererنہیں بھیجتا۔ اس کے بجائےX-Requested-Withبھیجنے کے لیے ہر ٹائل پر CORS پری فلائٹ درکار ہوگی، اور ٹائل سرورز اس پری فلائٹ کو بھی مسترد کر دیتے ہیں۔ Firefox اور Chromium کون سے ہیڈر بھیجتے ہیں اس میں فرق ہے، لیکن اصول دونوں کے لیے ایک ہی ہے۔ localhostپر چلتا ہے، مگر لائیو سائٹ پر بلاک ہے؟ وجہ اوریجن ہے۔ بلاک آپ کے ڈومین کے Referer پر لگایا جاتا ہے، جبکہlocalhostمختلف Referer بھیجتا ہے۔
دفاتر، اسکول، 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ہیں۔ یہ اس لائبریری کی اپنی تھیمز ہیں، اوپر دیے گئے اسٹائلز نہیں، اس لیے رنگ ہوبہو ایک جیسے نہیں ہوں گے۔- لیبل سسٹم فونٹ میں کینوس ٹیکسٹ کے طور پر لکھے جاتے ہیں۔ نہ کوئی گلف URL، نہ کوئی فونٹ جس پر 404 آئے۔
- z15 سب سے گہری ٹائل ہے۔ لیئر اس سے آگے اوور زوم کرتی ہے، اور
maxDataZoom: 15پہلے سے ہی ڈیفالٹ ہے۔
اپ اسٹریم پر protomaps-leaflet اب صرف دیکھ بھال (maintenance) کے مرحلے میں ہے: اس میں نئی خصوصیات نہیں بلکہ صرف اصلاحات آتی ہیں۔ پہلے سے موجود Leaflet ایپ کے لیے یہ ٹھیک ہے۔ نیا کام MapLibre GL پر شروع کرنا چاہیے۔
Leaflet برقرار رکھیں، رینڈرنگ MapLibre سے کریں
@maplibre/maplibre-gl-leaflet ایک MapLibre نقشے کو Leaflet کے ٹائل پین (tile pane) میں رکھ دیتا ہے۔ اسے تب استعمال کریں جب آپ کی ایپ Leaflet پر ہی رہے لیکن آپ کو اوپر دیے گئے اسٹائلز میں سے کوئی ایک، یا ٹیرین (terrain) اور ہل شیڈ (hillshade) چاہیے ہو۔
<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 کے 256 کے مقابلے میں 512 پکسل کی ہوتی ہیں، اس لیے جس لیئر کا
minzoom12 ہو وہ تب ظاہر ہوتی ہے جب 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]) پہلے عرض البلد (latitude) لیتا ہے؛ جبکہ 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”
یہ ڈیٹا ایکسٹریکٹ اور ریپلیکیشن مرر ہے، ٹائل سرور نہیں۔ اکتوبر 2026 میں بے جا ڈاؤن لوڈز کے بعد اس نے ایڈریسز بلاک کر دیے تھے، اور منتظمین نے کہا کہ وہ ہر کیس کا الگ جائزہ لے کر رسائی بحال کریں گے۔ یہاں کسی چیز کو اس کی ضرورت نہیں ہے: یہ آرکائیو Protomaps کی ریلیزز سے آتا ہے، اس لیے آپ کو خود .osm.pbf جوڑنے کی ضرورت نہیں پڑتی۔ اگر آپ کو OSM ڈیٹا حاصل کرنا ہی ہو تو منٹ بہ منٹ اسٹریم کے بجائے وقفے وقفے سے جاری ہونے والا ایکسٹریکٹ لیں۔
اسٹائلز
وہی ٹائلیں، مختلف رنگ۔ کوئی ایک منتخب کریں، کاپی کریں، بدلیں، یہ آپ کا ہے۔
| اسٹائل | ظاہری شکل | فائل |
|---|
ٹائلوں میں کیا موجود ہے
صفحہ لوڈ ہوتے وقت آرکائیو کے اپنے میٹا ڈیٹا سے پڑھا گیا۔ یہ ان لیئرز کے نام ہیں جو کسی بھی اسٹائل کو استعمال کرنے چاہئیں۔
| سورس لیئر | زوم | فیلڈز |
|---|---|---|
| لوڈ ہو رہا ہے… | ||
یہ سروس کیا نہیں ہے
سیدھے جوابات، تاکہ بعد میں کوئی بات آپ کے لیے غیر متوقع نہ ہو۔
- سروس کے معیار کی کوئی ضمانت نہیں ہے۔ یہ ایک مفت سروس ہے جس کے پیچھے کوئی معاہدہ نہیں ہے۔ یہ سست ہو سکتی ہے، بند ہو سکتی ہے، اور URL یا ڈیٹا بغیر کسی پیشگی اطلاع کے بدل سکتا ہے یا ختم ہو سکتا ہے۔ اگر آپ کی پروڈکٹ کا انحصار اس پر ہے تو ٹائلوں کی اپنی کاپی خود ہوسٹ کریں یا کسی سے سپورٹ شدہ پلان خریدیں۔
- یہ ہر گھنٹے اپ ڈیٹ نہیں ہوتی۔ یہ کاپی تازہ ترین Protomaps ریلیز کا ایک اسنیپ شاٹ ہے، لائیو فیڈ نہیں۔ آج کی گئی تبدیلیاں اس میں شامل نہیں ہیں۔ وقت کی تفصیل یہ ڈیٹا کتنا تازہ ہے؟ میں موجود ہے۔
- پوری فائل ایک ساتھ ڈاؤن لوڈ نہیں ہوتی۔ ریکویسٹس کا جواب زیادہ سے زیادہ 512 KiB کی رینج میں دیا جاتا ہے، اور ایک PMTiles کلائنٹ کو ہمیشہ اتنی ہی ضرورت ہوتی ہے۔ ایک ہی ریکویسٹ میں پورا آرکائیو مانگنے پر
416ملتا ہے، جو کہ درست ہے۔ - ایٹریبیوشن (حوالہ) دینا لازمی ہے۔ یہ ٹائلیں OpenStreetMap سے اخذ شدہ ہیں۔ اپنے اسٹائل میں یا اپنے نقشے پر ایٹریبیوشن والی سطر برقرار رکھیں۔
یہ ڈیٹا کتنا تازہ ہے؟
یہ ٹائلیں Protomaps Basemap کی ایک کاپی ہیں، جسے مہینے میں ایک بار دوبارہ بنایا جاتا ہے۔
- مہینے میں ایک بار دوبارہ تیاری۔ یہ بلڈ مہینے کے پہلے اتوار کو 00:30 اور 07:00 UTC کے درمیان چلتی ہے، جو تین سالہ ریلیز کی تاریخ میں واحد ایسا دورانیہ ہے جس میں اپ اسٹریم نے کبھی اشاعت نہیں کی۔ اسے ہفتہ وار کے بجائے ماہانہ اس لیے رکھا گیا ہے کیونکہ نیا آرکائیو CDN پر اور ہر اس براؤزر میں جہاں پہلے سے کیش موجود ہو، کیش شدہ حصوں کو کالعدم کر دیتا ہے، اور ہر بار دوبارہ بنانے میں بلڈ کا وقت صرف ہوتا ہے۔
- اکثر مہینوں میں کچھ کرنے کی ضرورت نہیں پڑتی۔ دوبارہ تیاری صرف تب ہوتی ہے جب اپ اسٹریم نے کوئی نئی ریلیز شائع کی ہو۔
- اس وقت کون سی اپ اسٹریم بلڈ زیرِ استعمال ہے؟ اس صفحے کے اوپری حصے میں موجود آرکائیو میٹا ڈیٹا بٹن استعمال کریں۔ یہ براہِ راست آرکائیو کا اپنا ہیڈر پڑھتا ہے، اس لیے جواب ہمیشہ تازہ ترین ہوتا ہے نہ کہ اس صفحے پر لکھی کوئی پرانی معلومات۔
- دوبارہ تیاری فوراً مکمل نہیں ہوتی۔ یہ تقریباً ساڑھے چھ گھنٹوں پر محیط تیرہ الگ الگ مراحل ہیں جو ایک ایک کر کے چلتے ہیں۔ اس دورانیے کے بیشتر حصے میں یہ کاپی دو اپ اسٹریم بلڈز کا مرکب ہوتی ہے۔ اس دوران آپ جو ٹائل طلب کرتے ہیں وہ ہیڈر میں بتائی گئی بلڈ کے بجائے نئی بلڈ سے آ سکتی ہے، جو ٹوٹے ہوئے نقشے کے طور پر نہیں بلکہ غلط جگہ کی ٹائل کے طور پر دکھائی دیتی ہے۔
- دوبارہ تیاری چھوٹ بھی سکتی ہے۔ یہ حتی الامکان کوشش (best-effort) پر مبنی کام ہے، کوئی ضمانت نہیں۔ اگر کوئی ایک مرحلہ ناکام ہو جائے تو باقی کاپی پچھلی اپ اسٹریم بلڈ پر ہی رہتی ہے۔ نقشہ پھر بھی کام کرتا رہتا ہے۔