Protomaps Basemap ٹائلیں

مکمل Protomaps Basemap، زوم 0 سے 15 تک، سادہ HTTP پر ایک واحد PMTiles آرکائیو کے طور پر دستیاب ہے۔ کسی بھی PMTiles کلائنٹ کو اس URL سے جوڑیں اور یہ کام کرتا ہے۔

https://tiles.jasontally.com/basemap.pmtiles

کیا OpenStreetMap کی ٹائل بلاک ہو گئی ہے، یا tile.openstreetmap.org سے 403 آ رہا ہے؟ یہاں سے شروع کریں۔

آزمائیں

تین اسٹائلز میں وہی ایک آرکائیو۔ اسٹائل بدلیں تو پہلے سے لوڈ شدہ ٹائلیں اپنی جگہ رہتی ہیں، اس لیے تبدیلی فوری ہوتی ہے۔

z0

اپنا اسٹائل خود بنائیں

کوئی رنگ بدلیں یا کسی لیئر کو بند کریں تو نقشہ ساتھ ساتھ اپ ڈیٹ ہوتا رہے گا۔ پھر اسٹائل 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\">&copy; 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 موجود ہے، جو یہ تو بتاتا ہے کہ روٹ نمبر میں کتنے حروف ہیں لیکن یہ نہیں کہ وہ حروف کیا ہیں، اس لیے اس سے بنائی گئی شیلڈ ہر موٹروے پر ایک خالی شکل نظر آئے گی۔

خود لیئر لکھنا اور اس میں رنگ بھرنا

ایک لیئر فلٹر، زوم، شکل اور رنگ کا مجموعہ ہوتی ہے۔ فلٹر میں دو چیزیں ایسی ہیں جن میں ہر کوئی الجھتا ہے، اور دونوں بغیر کسی ایرر کے ناکام ہو جاتی ہیں:

چنانچہ ایک سڑک، اس کا نام، اور لائن کو بند کرنے کا ٹوگل کچھ یوں ہوگا:

{
  "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 ٹھیک کرنے سے یہ ختم نہیں ہوتی۔

لوگ سب سے پہلے کیا آزماتے ہیں:

دفاتر، اسکول، 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: '&copy; <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>

اپ اسٹریم پر 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>

MapLibre GL پر منتقل ہوں

ایک لائبریری، کوئی اڈاپٹر نہیں، اور اوپر دیے گئے اسٹائلز جوں کے توں کام کرتے ہیں۔ مکمل صفحہ ایک۔ صفحے پر نقشہ لگائیں میں موجود ہے۔ اس منتقلی میں زیادہ تر بس کوآرڈینیٹس کی ترتیب الٹنی پڑتی ہے:

LeafletMapLibre 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 ڈیٹا حاصل کرنا ہی ہو تو منٹ بہ منٹ اسٹریم کے بجائے وقفے وقفے سے جاری ہونے والا ایکسٹریکٹ لیں۔

اسٹائلز

وہی ٹائلیں، مختلف رنگ۔ کوئی ایک منتخب کریں، کاپی کریں، بدلیں، یہ آپ کا ہے۔

اسٹائلظاہری شکلفائل

ٹائلوں میں کیا موجود ہے

صفحہ لوڈ ہوتے وقت آرکائیو کے اپنے میٹا ڈیٹا سے پڑھا گیا۔ یہ ان لیئرز کے نام ہیں جو کسی بھی اسٹائل کو استعمال کرنے چاہئیں۔

سورس لیئرزومفیلڈز
لوڈ ہو رہا ہے…

یہ سروس کیا نہیں ہے

سیدھے جوابات، تاکہ بعد میں کوئی بات آپ کے لیے غیر متوقع نہ ہو۔

یہ ڈیٹا کتنا تازہ ہے؟

یہ ٹائلیں Protomaps Basemap کی ایک کاپی ہیں، جسے مہینے میں ایک بار دوبارہ بنایا جاتا ہے۔

اسٹائل JSON

open raw