بلاطات خريطة الأساس Protomaps Basemap
خريطة الأساس Protomaps Basemap كاملةً، من مستوى التكبير 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 بلاطاته من مصدر بيانات. لاستخدام هذه البلاطات، غيِّر قيمة 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 جاهز يمكنك النسخ منه.
رابعًا. الخطوط والصور المجمعة (sprites) والمكتبات
تتكون الخريطة من البلاطات، ورابط glyphs للنصوص، واختياريًا رابط sprite للأيقونات، والمكتبات اللازمة لرسم ذلك كله. كل هذه العناصر متوفرة هنا في المسارات التي يتوقعها كل منها، بحيث يمكن تقديم الخريطة بالكامل من اسم مضيف واحد إذا أردت.
| العنصر | الرابط هنا | الرخصة |
|---|
ملفات MapLibre وPMTiles متوفرة على jsDelivr وهنا أيضًا. كلا الرابطين يعمل.
الصف الأخير لا تستخدمه هذه الصفحة. إنه مصيِّر البلاطات المتجهة لـ Leaflet، وهو منشور هنا ليكون الاستبدال مجرد وسم script واحد. أما مكتبة Leaflet نفسها فتبقى على شبكة CDN الخاصة بها.
حزمتا خطوط، Noto Sans Regular وNoto Sans Medium، مقسمتان إلى 256 نطاقًا يطلبها MapLibre، بواقع 256 نقطة ترميز في كل نطاق. النطاقات الـ 256 منشورة كلها، وليس اللاتينية فحسب: إذ تسمّي Protomaps المعالم بأسمائها المحلية، لذا تحتاج طوكيو أو القاهرة إلى نطاقات في عشرات الآلاف. إذا نشرت فقط ما تستخدمه خريطة باللغة الإنجليزية فستختفي تلك التسميات دون أي رسالة خطأ توضح السبب.
خمس لوحات صور مجمعة (sprites)، واحدة لكل مظهر من المصدر الأصلي، بدقتي 1x و2x. ترسم الأنماط أدناه الأيقونات منها، لذلك يتم جلبها. إذا أردت نقاط المدن أو دروع الطرق السريعة أو نقاط الاهتمام في نمطك الخاص، فوجِّه sprite إلى اللوحة الموافقة لمظهرك. أسماء الأيقونات في اللوحة مدرجة في ملف light.json الخاص بها.
ما ترسمه الخريطة، ومن أين يأتي كل عنصر
كل طبقة هي واحدة من طبقات المصدر التسع في هذا الأرشيف، لذا لا يحتاج أي شيء هنا إلى أرشيف ثانٍ. وهناك طبقتان تجدر الإشارة إليهما، لأن كلتيهما تبدوان كأن شيئًا مفقود بينما الأمر ليس كذلك:
| الطبقة | المصدر | في هذه النسخة؟ |
|---|---|---|
| الأشكال، الطرق، المباني، المياه، اليابسة | earth, landcover, landuse, water, roads, buildings | نعم |
| أسماء الأماكن والطرق والمسطحات المائية | حقل name في تلك الطبقات نفسها | نعم |
| أيقونات نقاط الاهتمام ونقاط المدن | pois.kind وplaces، إضافة إلى اللوحة الرسومية (sprite) | نعم |
| دروع أرقام الطرق | 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، لذا فإن الطبقة التي يبلغ الحد الأدنى لتكبيرها 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 الخاص باللوحة.
إذا كان لديك نمط يوجِّه محارفه (glyphs) إلى 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 نفسها الخط Noto Sans Medium للنص العريض؛ ولا يوجد Noto Sans Bold في هذه المجموعة، ولهذا فإن النمط الذي يطلبه يفقد كل التسميات بصمت.
أي مضيف أسرع، وما القرار الذي اتُّخذ بهذا الشأن. بالقياس لا بالافتراض: طلبات متداخلة، واحدًا تلو الآخر، عبر اتصال واحد، مع استبعاد أول ثلاث عينات، وفصل زمن وصول أول بايت عن زمن النقل. في هذا الاختبار استجابت شبكة CDN أسرع بـ 10 إلى 45 مللي ثانية لكل ملف من هذه الملفات، وهو ما يتجاوز قاعدة الـ 15% بهامش واضح في العينات. لهذا السبب تُحمَّل المكتبات من jsDelivr.
تُقدَّم الخطوط والصور المجمعة (sprites) من هنا على الرغم من أن القياس نفسه يُظهر أن شبكة CDN تستجيب أسرع بنحو 10 مللي ثانية. هذا قرار تصميمي وليس قياسًا. فالخريطة التي تأتي من اسم مضيف واحد لا تتعطل عندما يتعطل خادم طرف آخر، وتوقف خادم المحارف يعني خريطة بلا تسميات. إذا كنت تفضل كسب الـ 10 مللي ثانية، فوجِّه 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 preflight) لكل بلاطة، وخوادم البلاطات ترفض طلب التحقق المسبق هذا أيضًا. يختلف 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 بخط النظام. لا حاجة لرابط محارف (glyphs)، ولا يوجد خط يمكن أن يفشل بخطأ 404.
- z15 هو أعمق مستوى للبلاطات. تكبِّر الطبقة العرض بعد هذا المستوى تلقائيًا، والقيمة
maxDataZoom: 15هي الإعداد الافتراضي أصلًا.
مكتبة protomaps-leaflet في وضع الصيانة لدى المصدر الأصلي: إصلاحات للأخطاء فقط دون ميزات جديدة. وهي مناسبة لتطبيق Leaflet قائم، أما المشاريع الجديدة فيُفضَّل أن تبدأ باستخدام MapLibre GL.
البقاء على Leaflet والتصيير باستخدام MapLibre
تضع مكتبة @maplibre/maplibre-gl-leaflet خريطة MapLibre داخل جزء البلاطات في Leaflet. استخدمها عندما تريد أحد الأنماط أعلاه، أو التضاريس وتظليل التلال، في تطبيق يظل مبنيًا على 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. فبلاطاته بحجم 512 بكسل مقابل 256 بكسل في Leaflet، لذا فإن الطبقة التي تحمل
minzoomبقيمة 12 تظهر عندما يصل Leaflet إلى z13. - يظل Leaflet يرسم العناصر في الأعلى. توضع لوحة الرسم (canvas) في جزء البلاطات، لذا تتصرف العلامات والطبقات العلوية تمامًا كما تتصرف فوق طبقة نقطية.
الانتقال إلى 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”
هذه مرآة للاستخراج والمزامنة وليست خادم بلاطات. في أكتوبر 2026 حظرت المرآة عناوين بعد عمليات تنزيل جائرة، وذكر المشغلون أنهم سيعيدون الوصول لكل حالة على حدة. لا شيء هنا يعتمد عليها: فهذا الأرشيف مبني من إصدارات Protomaps، لذا لا تحتاج إلى تجميع ملفات .osm.pbf بنفسك. وإذا كنت تسحب بيانات OSM مباشرةً، فاستخدم مستخرجًا دوريًا بدلًا من التدفق الدقيقي.
الأنماط
البلاطات نفسها بألوان مختلفة. اختر نمطًا وانسخه وعدِّله كما تشاء.
| النمط | المظهر | الملف |
|---|
محتويات البلاطات
تُقرأ من البيانات الوصفية للأرشيف نفسه عند تحميل الصفحة. هذه هي أسماء الطبقات التي يجب أن يستخدمها النمط.
| طبقة المصدر | مستوى التكبير | الحقول |
|---|---|---|
| جارٍ التحميل… | ||
ما لا تقدمه هذه الخدمة
إجابات واضحة ومباشرة حتى لا يفاجئك شيء لاحقًا.
- لا يوجد ضمان لمستوى الخدمة. هذه خدمة مجانية بلا عقد ملزم. قد تصبح بطيئة، وقد تتوقف عن العمل، كما قد يتغير الرابط أو البيانات أو يختفيان دون إشعار مسبق. إذا كان منتجك يعتمد عليها، فاستضف نسختك الخاصة من البلاطات أو اشترك في خطة مدعومة لدى مزود خدمة.
- البيانات ليست محدَّثة ساعةً بساعة. هذه النسخة هي لقطة ثابتة من أحدث إصدار لـ Protomaps وليست بثًا مباشرًا. التعديلات التي أُجريت اليوم غير موجودة فيها. راجع ما مدى حداثة البيانات؟ لمعرفة مواعيد التحديث.
- لا يمكن تنزيل الملف بالكامل دفعة واحدة. تُجاب الطلبات على شكل نطاقات لا يتجاوز حجم الواحد منها 512 KiB، وهو كل ما يطلبه أي عميل PMTiles. طلب الأرشيف كاملًا في طلب واحد يُرجع الرمز
416، وهذا هو السلوك المقصود. - نسبة المصدر (الإسناد) مطلوبة. هذه البلاطات مشتقة من بيانات OpenStreetMap. احتفظ بسطر الإسناد في نمطك أو على خريطتك.
ما مدى حداثة البيانات؟
البلاطات هي نسخة من خريطة الأساس Protomaps Basemap، ويُعاد بناؤها مرة واحدة في الشهر.
- يُعاد البناء مرة في الشهر. تعمل عملية البناء في أول يوم أحد من كل شهر بين الساعة 00:30 و07:00 بالتوقيت العالمي المنسق (UTC)، وهي الفترة الزمنية الوحيدة التي لم ينشر فيها المشروع الأصلي أي إصدار خلال ثلاث سنوات من سجل الإصدارات. التحديث شهري وليس أسبوعيًا لأن الأرشيف الجديد يُبطل الأجزاء المخزنة مؤقتًا على شبكة CDN وفي كل متصفح احتفظ بها، ولأن كل عملية إعادة بناء تستهلك وقت معالجة.
- لا حاجة لأي إجراء في معظم الأشهر. لا تتم إعادة البناء إلا عندما ينشر المشروع الأصلي إصدارًا جديدًا.
- أي نسخة من المصدر الأصلي مستخدمة الآن؟ استخدم زر البيانات الوصفية للأرشيف في أعلى هذه الصفحة. يقرأ هذا الزر ترويسة الأرشيف مباشرةً، لذا تكون الإجابة محدَّثة دائمًا وليست معلومة قديمة في الصفحة.
- إعادة البناء ليست فورية. فهي تتكون من ثلاث عشرة عملية بناء منفصلة تمتد على مدار ست ساعات ونصف تقريبًا، واحدة تلو الأخرى. وخلال معظم هذه الفترة تكون النسخة مزيجًا من إصدارين من المصدر الأصلي. قد تأتي البلاطة التي تطلبها أثناء ذلك من النسخة الأحدث بدلًا من النسخة المعلنة في الترويسة، وهو ما يظهر كبلاطة من موضع غير متطابق وليس كخريطة معطلة.
- قد تفوت عملية إعادة بناء. فالتحديث يتم على أساس بذل أقصى جهد دون ضمان. إذا فشلت إحدى الخطوات، تبقى بقية النسخة على الإصدار السابق من المصدر الأصلي، وتظل الخريطة صالحة للعمل.