يتناول هذا المستند أنواع الخرائط التي يمكنك عرضها باستخدام واجهة برمجة التطبيقات
Maps JavaScript API. تستخدم واجهة برمجة التطبيقات العنصر MapType
للاحتفاظ بمعلومات عن هذه الخرائط. MapType
هي واجهة تحدّد عرض واستخدام مربّعات الخرائط
وترجمة أنظمة الإحداثيات من إحداثيات الشاشة إلى إحداثيات
العالم (على الخريطة). يجب أن تحتوي كل MapType
على
بضع طرق للتعامل مع استرداد وإطلاق المربّعات، والخصائص التي
تحدّد سلوكها المرئي.
يُعدّ العمل الداخلي لأنواع الخرائط ضمن Maps JavaScript API موضوعًا متقدّمًا. يمكن لمعظم المطورين استخدام أنواع الخرائط الأساسية المذكورة أدناه. ومع ذلك، يمكنك أيضًا تعديل طريقة عرض أنواع الخرائط الحالية باستخدام الخرائط المخصّصة أو تحديد مربّعات الخرائط الخاصة بك باستخدام أنواع الخرائط المخصّصة. عند تقديم أنواع خرائط مخصّصة، عليك معرفة كيفية تعديل سجلّ أنواع الخرائط.
أنواع الخرائط الأساسية
هناك أربعة أنواع من الخرائط متاحة ضمن Maps JavaScript API. بالإضافة إلى مربّعات خرائط الطرق "المرسومة" المألوفة، تتوافق واجهة برمجة التطبيقات JavaScript لـ "خرائط Google" أيضًا مع أنواع الخرائط الأخرى.
تتوفر أنواع الخرائط التالية في واجهة برمجة تطبيقات JavaScript للخرائط:
- يعرض
roadmap
طريقة العرض التلقائية لخريطة الطرق. هذا هو نوع الخريطة التلقائي. - يعرض
satellite
صور القمر الصناعي في Google Earth. - تعرض ميزة "
hybrid
" مزيجًا من العرض العادي وطريقة العرض عبر القمر الصناعي. terrain
تعرِض خريطة طبوغرافية استنادًا إلى معلوماتتضاريس الأرض.
يمكنك تعديل نوع الخريطة المستخدَم في Map
من خلال ضبط سمة
mapTypeId
، إما داخل الدالة الإنشائية من خلال ضبط
عنصر Map options
، أو من خلال استدعاء setMapTypeId()
في الخريطة. تكون القيمة التلقائية لسمة mapTypeID
هي roadmap
.
ضبط mapTypeId
عند إنشاء الحملة:
var myLatlng = new google.maps.LatLng(-34.397, 150.644); var mapOptions = { zoom: 8, center: myLatlng, mapTypeId: 'satellite' }; var map = new google.maps.Map(document.getElementById('map'), mapOptions);
تعديل mapTypeId
ديناميكيًا:
map.setMapTypeId('terrain');
يُرجى العِلم أنّه لا يتمّ ضبط نوع الخريطة مباشرةً،
ولكن يتمّ ضبط mapTypeId
للإشارة إلى
MapType
باستخدام معرّف.
تستخدم واجهة برمجة تطبيقات JavaScript للخرائط قاعدة بيانات المسجّلين لأنواع الخرائط، كما هو موضّح أدناه، لإدارة هذه المراجع.
صور بزاوية 45 درجة
تتيح واجهة برمجة التطبيقات Maps JavaScript API عرض صور بزاوية 45 درجة خاصة لمواقع جغرافية معيّنة. توفّر هذه الصور العالية الدقة عروضًا من منظور مختلف لكل اتجاه أساسي (الشمال والجنوب والشرق والغرب). تتوفّر هذه الصور عند مستويات تكبير أو تصغير أعلى لأنواع الخرائط المتوافقة.
تعرض الصورة التالية منظرًا بزاوية 45 درجة لمدينة نيويورك:
تتيح أنواع الخرائط satellite
وhybrid
عرض صور بزاوية 45 درجة
عند مستويات التكبير العالية (12 والمستويات الأعلى) متى توفّرت. في حال كبِّر المستخدم موقعًا جغرافيًا توجد فيه مثل هذه الصور، تغيّر أنواع الخرائط هذه
تلقائيًا طرق العرض على النحو التالي:
- يتم استبدال صور القمر الصناعي أو الصور المختلطة بصور تعرض منظورًا بزاوية 45 درجة،
تتمحور حول الموقع الجغرافي الحالي. تكون هذه العروض تلقائيًا
موجهة نحو الشمال. إذا كبّر المستخدم الصورة، تظهر صور الأقمار الصناعية أو
الصور الهجينة التلقائية مرة أخرى. يختلف السلوك حسب مستوى التكبير
وقيمة
tilt
: - بين مستوى التكبير 12 و18، يتم عرض الخريطة الأساسية من الأعلى للأسفل (0 درجة) بشكلٍ
تلقائي ما لم يتم ضبط
tilt
على 45. - عند مستويات التكبير 18 أو أكثر، يتم عرض الخريطة الأساسية بزاوية 45 درجة ما لم يتم ضبط
tilt
على 0. - يصبح عنصر التحكّم في التدوير مرئيًا. يوفّر عنصر التحكّم في التدوير خيارات
تتيح للمستخدم تبديل إمالة الشاشة وتدوير العرض بزيادات 90 درجة
في أي من الاتجاهين. لإخفاء عنصر التحكّم في التدوير، اضبط
rotateControl
علىfalse
.
يؤدي التصغير من نوع خريطة يعرض صورًا بزاوية 45 درجة إلى التراجع عن كل من هذه التغييرات، ما يؤدي إلى إعادة ضبط أنواع الخرائط الأصلية.
تفعيل صور بزاوية 45 درجة وإيقافها
يمكنك إيقاف الصور بزاوية 45 درجة من خلال طلب setTilt(0)
على العنصر
Map
. لتفعيل ميزة التقاط صور بزاوية 45 درجة لأنواع الخرائط المتوافقة،
اتصِل بالرقم setTilt(45)
. ستعكس طريقة getTilt()
في Map
دائمًا tilt
الحالي الذي يظهر على
الخريطة. إذا ضبطت tilt
على خريطة ثم أزلت
tilt
لاحقًا (من خلال تصغير الخريطة مثلاً)، ستُرجع طريقة
getTilt()
في الخريطة القيمة 0
.
ملاحظة مهمة: لا يمكن استخدام صور بزاوية 45 درجة إلا في الخرائط المركّبة، ولا يمكن استخدامها مع الخرائط المتجهّة.
يعرض المثال التالي عرضًا بزاوية 45 درجة لمدينة نيويورك:
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", } ); map.setTilt(45); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", }); map.setTilt(45); } window.initMap = initMap;
تجربة عيّنة
تدوير الصور بزاوية 45 درجة
تتألف صور بزاوية 45 درجة من مجموعة من الصور
لكل اتجاه أساسي (الشمال والجنوب والشرق والغرب). بعد أن تبدأ الخريطة في عرض صور بزاوية 45 درجة، يمكنك توجيه الصور نحو أحد الاتجاهات الأساسية من خلال استدعاء setHeading()
على العنصر Map
، مع تمرير قيمة عددية يتم التعبير عنها بالدرجات من الشمال.
يعرض المثال التالي خريطة جوية ويتم تدويرها تلقائيًا كل 3 ثوانٍ عند النقر على الزر:
TypeScript
let map: google.maps.Map; function initMap(): void { map = new google.maps.Map(document.getElementById("map") as HTMLElement, { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", heading: 90, tilt: 45, }); // add listener to button document.getElementById("rotate")!.addEventListener("click", autoRotate); } function rotate90(): void { const heading = map.getHeading() || 0; map.setHeading(heading + 90); } function autoRotate(): void { // Determine if we're showing aerial imagery. if (map.getTilt() !== 0) { window.setInterval(rotate90, 3000); } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
let map; function initMap() { map = new google.maps.Map(document.getElementById("map"), { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", heading: 90, tilt: 45, }); // add listener to button document.getElementById("rotate").addEventListener("click", autoRotate); } function rotate90() { const heading = map.getHeading() || 0; map.setHeading(heading + 90); } function autoRotate() { // Determine if we're showing aerial imagery. if (map.getTilt() !== 0) { window.setInterval(rotate90, 3000); } } window.initMap = initMap;
تجربة "عيّنة"
تعديل "قاعدة بيانات أنواع الخرائط"
mapTypeId
في الخريطة هو معرّف سلسلة
يتم استخدامه لربط MapType
بقيمة
فريدة. يحتفظ كل عنصر Map
بعنصر MapTypeRegistry
يحتوي على مجموعة MapType
من العناصر المتاحة لهذه الخريطة. يتم استخدام هذا السجلّ
لاختيار أنواع الخرائط المتاحة في
عنصر التحكّم MapType في الخريطة، على سبيل المثال.
لا تقرأ البيانات مباشرةً من سجلّ أنواع الخرائط. بدلاً من ذلك،
يمكنك تعديل السجلّ من خلال إضافة أنواع خرائط مخصّصة وربطها
بمعرّف سلسلة من اختيارك. لا يمكنك تعديل
أو تغيير أنواع الخرائط الأساسية (على الرغم من أنّه يمكنك إزالتها من
الخريطة من خلال تغيير مظهر
mapTypeControlOptions
المرتبط بها).
يضبط الرمز البرمجي التالي الخريطة لعرض نوعَي خريطة فقط في mapTypeControlOptions
الخريطة، ويُعدِّل السجلّ لإضافة الربط
بهذا المعرّف إلى التنفيذ الفعلي لواجهة
MapType
.
// Modify the control to only display two maptypes, the // default ROADMAP and the custom 'mymap'. // Note that because this is an association, we // don't need to modify the MapTypeRegistry beforehand. var MY_MAPTYPE_ID = 'mymaps'; var mapOptions = { zoom: 12, center: brooklyn, mapTypeControlOptions: { mapTypeIds: ['roadmap', MY_MAPTYPE_ID] }, mapTypeId: MY_MAPTYPE_ID }; // Create our map. This creation will implicitly create a // map type registry. map = new google.maps.Map(document.getElementById('map'), mapOptions); // Create your custom map type using your own code. // (See below.) var myMapType = new MyMapType(); // Set the registry to associate 'mymap' with the // custom map type we created, and set the map to // show that map type. map.mapTypes.set(MY_MAPTYPE_ID, myMapType);
خرائط ذات نمط
تتيح لك StyledMapType
إمكانية تخصيص طريقة عرض "خرائط Google الأساسية" العادية، مع تغيير العرض المرئي لهذه العناصر، مثل الطرق والمنتزهات ومناطق المباني، لتعكس نمطًا مختلفًا عن ذلك المستخدَم في نوع الخريطة التلقائي.
لمزيد من المعلومات عن StyledMapType
، اطّلِع على
استخدام ملفّات تعريف StyledMapType
المضمّنة في ملف JSON
.
أنواع الخرائط المخصصة
تتيح واجهة برمجة التطبيقات Maps JavaScript API عرض وإدارة أنواع الخرائط المخصّصة، ما يتيح لك تنفيذ صور الخرائط أو التراكبات المربّعة الخاصة بك.
تتوفّر عدة طرق لتنفيذ أنواع الخرائط المحتملة ضمن واجهة برمجة التطبيقات JavaScript لـ "خرائط Google":
- مجموعات المربّعات العادية التي تتألّف من صورتشكل معًا خرائط تصويرية كاملة تُعرف مجموعات المربّعات هذه أيضًا باسم أنواع الخرائط الأساسية. تعمل أنواع الخرائط هذه
بالطريقة نفسها التي تعمل بها أنواع الخرائط التلقائية الحالية:
roadmap
وsatellite
hybrid
وterrain
. يمكنك إضافة نوع الخريطة المخصّص إلى صفيفmapTypes
في الخريطة لسماح واجهة المستخدم ضمن واجهة برمجة التطبيقات JavaScript لـ "خرائط Google" بالتعامل مع نوع الخريطة المخصّص كنوع خريطة عادي (من خلال تضمينه في عنصر التحكّم في نوع الخريطة، على سبيل المثال). - تراكبات مربّعات الصور التي تظهر فوق أنواع الخرائط الأساسية الحالية بشكل عام، يتم استخدام أنواع الخرائط هذه لإضافة نوع خريطة حالي لعرض معلومات إضافية، وغالبًا ما تكون مقيّدة بمواقع جغرافية معيّنة و/أو مستويات تكبير معيّنة. يُرجى العِلم أنّ هذه المربّعات قد تكون شفافة، مما يتيح لك إضافة عناصر إلى الخرائط الحالية.
- أنواع الخرائط غير المستندة إلى الصور، والتي تتيح لك التحكّم في عرض معلومات الخريطة على المستوى الأساسي
يعتمد كل خيار من هذه الخيارات على إنشاء فئة تطبِّق واجهة MapType
. بالإضافة إلى ذلك، توفّر فئة
ImageMapType
بعض السلوك المضمّن
لتبسيط إنشاء أنواع الخرائط الصورية.
واجهة MapType
قبل إنشاء صفوف تستخدم MapType
، من المهم فهم كيفية تحديد "خرائط Google" للإحداثيات وتحديد أجزاء الخريطة التي سيتم عرضها. وتحتاج إلى تنفيذ منطق مماثل لأي نوع من أنواع الخرائط الأساسية أو المركّبة.
اطّلِع على دليل إحداثيات الخريطة
والمربّعات.
يجب أن تنفّذ أنواع الخرائط المخصّصة واجهة MapType
. تحدّد هذه الواجهة خصائص و methods معيّنة تسمح لواجهة برمجة التطبيقات ببدء طلبات إلى أنواع
الخرائط عندما تحدّد واجهة برمجة التطبيقات أنّها بحاجة إلى عرض وحدات ملف تعريف
الخريطة ضمن مساحة العرض ومستوى التكبير/التصغير الحاليَين. ويمكنك معالجة هذه الطلبات لتحديد المربّع الذي تريد تحميله.
ملاحظة: يمكنك إنشاء
فئة خاصة بك لتنفيذ هذه الواجهة. بدلاً من ذلك، إذا كانت لديك صور متوافقة، يمكنك استخدام الفئة
ImageMapType
التي تنفّذ هذه الواجهة.
تتطلّب الفصول التي تنفِّذ واجهة MapType
تحديد السمات التالية وتعبئتها:
tileSize
(مطلوبة) لتحديد حجم المربّع (من النوعgoogle.maps.Size
). يجب أن تكون الأحجام مستطيلة ولكن ليس بالضرورة أن تكون مربّعة.- تحدّد السمة
maxZoom
(مطلوبة) الحد الأقصى لمستوى التكبير أو التصغير الذي يمكن عنده عرض مربّعات من نوع الخريطة هذا. - تحدّد السمة
minZoom
(اختيارية) الحدّ الأدنى لمستوى التكبير/التصغير الذي يمكن عنده عرض مربّع من نوع الخريطة هذا. وتكون هذه القيمة بشكل تلقائي0
، وتشير إلى عدم توفّر حد أدنى لمستوى التكبير/التصغير. name
(اختياري) يحدّد اسم نوع هذه الخارطة لا تكون هذه السمة ضرورية إلا إذا أردت أن يكون نوع الخريطة هذا قابلاً للاختيار ضمن عنصر تحكّم من النوع MapType. (اطّلِع على خيارات التحكّم.)-
alt
(اختياري) لتحديد النص البديل لهذا نوع الخريطة، والذي يتم عرضه كنص مركّز. لا تكون هذه السمة ضرورية إلا إذا كنت تريد أن يكون نوع الخريطة هذا قابلاً للاختيار ضمن عنصر تحكّم من النوع MapType. (اطّلِع على خيارات التحكّم.)
بالإضافة إلى ذلك، يجب أن تنفِّذ الصفوف التي تنفِّذ واجهة MapType
الأساليب التالية:
-
يتمّ استدعاء
getTile()
(مطلوب) كلّما حدّدت واجهة برمجة التطبيقات أنّ الخريطة بحاجة إلى عرض شرائح جديدة لمساحة العرض المحدّدة. يجب أن تحتوي طريقةgetTile()
على التوقيع التالي :getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node
تحدِّد واجهة برمجة التطبيقات ما إذا كانت بحاجة إلى طلب
getTile()
استنادًا إلى سماتtileSize
minZoom
وmaxZoom
فيMapType
ومستوى عرض النافذة الحالي للخريطة ومستوى التكبير/التصغير. يجب أن يعرِض معالِج معالجة هذه الطريقة عنصر HTML استنادًا إلى الإحداثيات المرسَلة، ومستوى التكبير، وعنصر DOM الذي سيتم إلحاق صورة المربّع به. -
يتمّ استدعاء
releaseTile()
(اختياري) عندما تحدّد واجهة برمجة التطبيقات أنّ الخريطة بحاجة إلى إزالة مربّع عند خروجه من نطاق العرض. يجب أن تحتوي هذه الطريقة على التوقيع التالي:releaseTile(tile:Node)
وعليك عادةً معالجة إزالة أي عناصر تم إرفاقها بمربّعات الخريطة عند الإضافة إلى الخريطة. على سبيل المثال، في حال إرفاق أدوات معالجة الأحداث لربط طبقات مركّبة، عليك إزالتها هنا.
تعمل طريقة getTile()
كوحدة تحكّم رئيسية
لتحديد المربّعات التي سيتم تحميلها ضمن إطار عرض معيّن.
أنواع الخرائط الأساسية
يمكن أن تكون أنواع الخرائط التي تُنشئها بهذه الطريقة إما مستقلة أو يتم دمجها مع أنواع خرائط أخرى كتراكبات. تُعرف أنواع الخطط المُستقلة
باسم أنواع الخرائط الأساسية. قد تحتاج إلى أن تتعامل واجهة برمجة التطبيقات
مع MapType
المخصّصة هذه كما تتعامل مع أي نوع آخر من أنواع المخططات الأساسية
الحالية (ROADMAP
أو TERRAIN
أو غير ذلك). لإجراء ذلك، أضِف MapType
المخصّص إلى السمة mapTypes
في Map
. هذه السمة من النوع
MapTypeRegistry
.
ينشئ الرمز التالي سمة MapType
أساسية لعرض إحداثيات مربّع الخريطة ويرسم مخططًا لمربّعات الخريطة:
TypeScript
/* * This demo demonstrates how to replace default map tiles with custom imagery. * In this case, the CoordMapType displays gray tiles annotated with the tile * coordinates. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType { tileSize: google.maps.Size; maxZoom = 19; name = "Tile #s"; alt = "Tile Coordinate Map Type"; constructor(tileSize: google.maps.Size) { this.tileSize = tileSize; } getTile( coord: google.maps.Point, zoom: number, ownerDocument: Document ): HTMLElement { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; div.style.backgroundColor = "#E5E3DF"; return div; } releaseTile(tile: HTMLElement): void {} } function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 10, center: { lat: 41.85, lng: -87.65 }, streetViewControl: false, mapTypeId: "coordinate", mapTypeControlOptions: { mapTypeIds: ["coordinate", "roadmap"], style: google.maps.MapTypeControlStyle.DROPDOWN_MENU, }, } ); map.addListener("maptypeid_changed", () => { const showStreetViewControl = (map.getMapTypeId() as string) !== "coordinate"; map.setOptions({ streetViewControl: showStreetViewControl, }); }); // Now attach the coordinate map type to the map's registry. map.mapTypes.set( "coordinate", new CoordMapType(new google.maps.Size(256, 256)) ); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
/* * This demo demonstrates how to replace default map tiles with custom imagery. * In this case, the CoordMapType displays gray tiles annotated with the tile * coordinates. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType { tileSize; maxZoom = 19; name = "Tile #s"; alt = "Tile Coordinate Map Type"; constructor(tileSize) { this.tileSize = tileSize; } getTile(coord, zoom, ownerDocument) { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; div.style.backgroundColor = "#E5E3DF"; return div; } releaseTile(tile) {} } function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 10, center: { lat: 41.85, lng: -87.65 }, streetViewControl: false, mapTypeId: "coordinate", mapTypeControlOptions: { mapTypeIds: ["coordinate", "roadmap"], style: google.maps.MapTypeControlStyle.DROPDOWN_MENU, }, }); map.addListener("maptypeid_changed", () => { const showStreetViewControl = map.getMapTypeId() !== "coordinate"; map.setOptions({ streetViewControl: showStreetViewControl, }); }); // Now attach the coordinate map type to the map's registry. map.mapTypes.set( "coordinate", new CoordMapType(new google.maps.Size(256, 256)), ); } window.initMap = initMap;
تجربة عيّنة
أنواع الخرائط التي تظهر على سطح الصفحة
تم تصميم بعض أنواع الخرائط للعمل على أنواع الخرائط الحالية. قد تحتوي أنواع الخرائط هذه على طبقات شفافة تشير إلى نقاط الاهتمام، أو تعرض بيانات إضافية للمستخدم.
في هذه الحالات، لا تريد أن يتم التعامل مع نوع الخريطة ككيان منفصل بل كعنصر مركّب.
يمكنك إجراء ذلك من خلال إضافة نوع الخريطة إلى MapType
حالي مباشرةً باستخدام
سمة overlayMapTypes
في Map
. تحتوي هذه السمة على
MVCArray
من إجمالي MapType
. يتم عرض جميع أنواع الخرائط
(الأساسية والطبقات الإضافية) ضمن طبقة
mapPane
. سيتم عرض أنواع الخرائط التي تتداخل فوق الخريطة الأساسية التي
يتم إرفاقها بها، بالترتيب الذي تظهر به في صفيف
Map.overlayMapTypes
(يتم عرض التراكبات التي تحتوي على قيم فهرس
أعلى أمام التراكبات التي تحتوي على قيم فهرس أقل).
المثال التالي مطابق للمثال السابق
باستثناء أنّنا أنشأنا عنصرًا مركّبًا على الخريطة MapType
فوق نوع الخريطة ROADMAP
:
TypeScript
/* * This demo illustrates the coordinate system used to display map tiles in the * API. * * Tiles in Google Maps are numbered from the same origin as that for * pixels. For Google's implementation of the Mercator projection, the origin * tile is always at the northwest corner of the map, with x values increasing * from west to east and y values increasing from north to south. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType implements google.maps.MapType { tileSize: google.maps.Size; alt: string|null = null; maxZoom: number = 17; minZoom: number = 0; name: string|null = null; projection: google.maps.Projection|null = null; radius: number = 6378137; constructor(tileSize: google.maps.Size) { this.tileSize = tileSize; } getTile( coord: google.maps.Point, zoom: number, ownerDocument: Document ): HTMLElement { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; return div; } releaseTile(tile: Element): void {} } function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 10, center: { lat: 41.85, lng: -87.65 }, } ); // Insert this overlay map type as the first overlay map type at // position 0. Note that all overlay map types appear on top of // their parent base map. const coordMapType = new CoordMapType(new google.maps.Size(256, 256)) map.overlayMapTypes.insertAt( 0, coordMapType ); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
/* * This demo illustrates the coordinate system used to display map tiles in the * API. * * Tiles in Google Maps are numbered from the same origin as that for * pixels. For Google's implementation of the Mercator projection, the origin * tile is always at the northwest corner of the map, with x values increasing * from west to east and y values increasing from north to south. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType { tileSize; alt = null; maxZoom = 17; minZoom = 0; name = null; projection = null; radius = 6378137; constructor(tileSize) { this.tileSize = tileSize; } getTile(coord, zoom, ownerDocument) { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; return div; } releaseTile(tile) {} } function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 10, center: { lat: 41.85, lng: -87.65 }, }); // Insert this overlay map type as the first overlay map type at // position 0. Note that all overlay map types appear on top of // their parent base map. const coordMapType = new CoordMapType(new google.maps.Size(256, 256)); map.overlayMapTypes.insertAt(0, coordMapType); } window.initMap = initMap;
تجربة عيّنة
أنواع خرائط الصور
يمكن أن يكون تنفيذ MapType
ليكون بمثابة نوع خريطة أساسية
مهمة تستغرق وقتًا طويلاً وتتطلّب جهدًا كبيرًا. توفّر واجهة برمجة التطبيقات
فئة خاصة تنفِّذ واجهة MapType
لأنواع الخرائط الأكثر شيوعًا: أنواع الخرائط التي تتألّف
من شرائح مكوّنة من ملفات صور فردية.
تم إنشاء هذه الفئة، وهي فئة ImageMapType
،
باستخدام مواصفات عنصر ImageMapTypeOptions
التي تحدّد السمات المطلوبة التالية
:
- تحدّد السمة
tileSize
(مطلوبة) حجم المربّع (من النوعgoogle.maps.Size
). يجب أن تكون المقاسات مستطيلة رغم أنّها يجب ألا تكون مربّعة. - يحدّد
getTileUrl
(مطلوب) الدالة، التي يتم توفيرها عادةً كدالة مضمّنة حرفية، للتعامل مع اختيار مربّع الصورة المناسب استنادًا إلى إحداثيات العالم المقدَّمة ومستوى التكبير أو التصغير.
تنفِّذ التعليمة البرمجية التالية ImageMapType
أساسيًا باستخدام مربّعات القمر من Google. يستخدم المثال دالة تسوية لضمان تكرار المربّعات على طول المحور "س"، ولكن ليس على طول المحور "ص" في الخريطة.
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { center: { lat: 0, lng: 0 }, zoom: 1, streetViewControl: false, mapTypeControlOptions: { mapTypeIds: ["moon"], }, } ); const moonMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom): string { const normalizedCoord = getNormalizedCoord(coord, zoom); if (!normalizedCoord) { return ""; } const bound = Math.pow(2, zoom); return ( "https://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw" + "/" + zoom + "/" + normalizedCoord.x + "/" + (bound - normalizedCoord.y - 1) + ".jpg" ); }, tileSize: new google.maps.Size(256, 256), maxZoom: 9, minZoom: 0, // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions' radius: 1738000, name: "Moon", }); map.mapTypes.set("moon", moonMapType); map.setMapTypeId("moon"); } // Normalizes the coords that tiles repeat across the x axis (horizontally) // like the standard Google map tiles. function getNormalizedCoord(coord, zoom) { const y = coord.y; let x = coord.x; // tile range in one direction range is dependent on zoom level // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc const tileRange = 1 << zoom; // don't repeat across y-axis (vertically) if (y < 0 || y >= tileRange) { return null; } // repeat across x-axis if (x < 0 || x >= tileRange) { x = ((x % tileRange) + tileRange) % tileRange; } return { x: x, y: y }; } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 0, lng: 0 }, zoom: 1, streetViewControl: false, mapTypeControlOptions: { mapTypeIds: ["moon"], }, }); const moonMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom) { const normalizedCoord = getNormalizedCoord(coord, zoom); if (!normalizedCoord) { return ""; } const bound = Math.pow(2, zoom); return ( "https://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw" + "/" + zoom + "/" + normalizedCoord.x + "/" + (bound - normalizedCoord.y - 1) + ".jpg" ); }, tileSize: new google.maps.Size(256, 256), maxZoom: 9, minZoom: 0, // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions' radius: 1738000, name: "Moon", }); map.mapTypes.set("moon", moonMapType); map.setMapTypeId("moon"); } // Normalizes the coords that tiles repeat across the x axis (horizontally) // like the standard Google map tiles. function getNormalizedCoord(coord, zoom) { const y = coord.y; let x = coord.x; // tile range in one direction range is dependent on zoom level // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc const tileRange = 1 << zoom; // don't repeat across y-axis (vertically) if (y < 0 || y >= tileRange) { return null; } // repeat across x-axis if (x < 0 || x >= tileRange) { x = ((x % tileRange) + tileRange) % tileRange; } return { x: x, y: y }; } window.initMap = initMap;
تجربة عيّنة
التوقعات
الأرض هي كرة ثلاثية الأبعاد (تقريبًا)، في حين أنّ الخريطة هي سطح مستوٍ ثنائي الأبعاد. الخريطة التي تظهر لك في واجهة برمجة التطبيقات JavaScript لـ "خرائط Google"، مثل أي خريطة مسطّحة للأرض، هي إسقاط لكوكب الأرض على سطح مستوٍ. في أبسط مصطلحاته، يمكن تعريف الإسقاط على أنّه تعيين قيم خط العرض/الطول إلى إحداثيات على خريطة الإسقاط.
يجب أن تنفّذ الإسقاطات في واجهة برمجة التطبيقات Maps JavaScript API واجهة
Projection
. يجب ألا يقدّم تنفيذ Projection
عملية ربط من نظام إحداثيات
إلى آخر فقط، بل يجب أن يقدّم عملية ربط ثنائية الاتجاه. وهذا يعني أنّه عليك تحديد كيفية التحويل من إحداثيات الأرض (عناصر LatLng
) إلى نظام إحداثيات
العالم في فئة Projection
، ومن نظام إحداثيات العالم إلى إحداثيات الأرض.
تستخدِم "خرائط Google" إسقاط Mercator لإنشاء خرائطها
من البيانات الجغرافية وتحويل الأحداث على الخريطة إلى
إحداثيات جغرافية. يمكنك الحصول على هذه التوقّعات من خلال
الاتصال برقم getProjection()
على Map
(أو أيّ من أنواع MapType
الأساسية العادية). في معظم الاستخدامات،
سيكون هذا Projection
العادي كافيًا، ولكن يمكنك أيضًا
تحديد توقعاتك المخصّصة واستخدامها.
تنفيذ توقّع
عند تنفيذ عرض مخصّص، يجب تحديد بعض النقاط:
- صِيَغ ربط إحداثيات خط العرض وخط الطول في سطح مستوٍ ديكارتي (كارتيزيتي) وصِيَغ الربط المقابلة من سطح مستوٍ ديكارتي (كارتيزيتي) إلى إحداثيات خط العرض
وخط الطول (لا تتيح واجهة
Projection
سوى عمليات التحويل إلى إحداثيات مستقيمة). - حجم المربّع الأساسي يجب أن تكون جميع المربّعات مستطيلة.
- "حجم العالم" للخريطة باستخدام المربّع الأساسي الذي تم ضبطه على مستوى التكبير 0 يُرجى العِلم أنّه بالنسبة إلى الخرائط التي تتألف من مربّع واحد عند التكبير 0، يكون حجم الخريطة وحجم المربّع الأساسي متطابقَين.
تنسيق عمليات التحويل في التوقّعات
يوفّر كل إسقاط طريقتين تؤدّيان إلى الترجمة بين نظامَي الإحداثيات، ما يسمح لك بتحويل الإحداثيات الجغرافية وإحداثيات العالم:
- تحوّل الطريقة
Projection.fromLatLngToPoint()
قيمةLatLng
إلى إحداثيّات جغرافية. تُستخدَم هذه الطريقة لتحديد موضع العناصر التي تظهر على سطح الخريطة (وتحديد موضع الخريطة نفسها). - تحوّل الطريقة
Projection.fromPointToLatLng()
إحداثيًا عالميًا إلى قيمةLatLng
. وتُستخدم هذه الطريقة لتحويل الأحداث، مثل النقرات التي تتم على الخريطة إلى إحداثيات جغرافية.
تفترض "خرائط Google" أنّ الإسقاطات مستقيمة.
بشكل عام، يمكنك استخدام إسقاط في حالتَين: لإنشاء خريطة للعالم أو لإنشاء خريطة لمنطقة محلية. وفي الحالة السابقة، عليك التأكّد من أنّ توقّعاتك أيضًا مستقيمة وطبيعية على جميع خطوط الطول. قد تكون بعض الإسقاطات (خاصة الإسقاطات المخروطية) "عادية على المستوى المحلي" (أي تشير إلى الشمال) ولكنها تنحرف عن الشمال الحقيقي، على سبيل المثال، كلما زادت المسافة بين الخريطة وخط طول مرجعي معيّن. يمكنك استخدام هذا الإسقاط محليًا، ولكن يجب أن تكون على دراية بأنّ الإسقاط غير دقيق بالضرورة وأنّ أخطاء التحويل ستصبح أكثر وضوحًا كلما ابتعدت عن خط الطول المرجعي.
اختيار بلاط الخريطة في الإسقاطات
لا تكون الإسقاطات مفيدة فقط لتحديد مواضع
المواقع الجغرافية أو العناصر التي تظهر على سطح الخريطة، بل لتحديد مواضع مربّعات الخريطة نفسها.
تعرِض واجهة برمجة التطبيقات Maps JavaScript API الخرائط الأساسية باستخدام واجهة MapType
التي يجب أن تحدِّد كلّ من سمة projection
لتحديد إسقاط الخريطة وطريقة getTile()
لاسترداد شرائح الخريطة استنادًا إلى قيم إحداثيات
. تستند إحداثيات المربّع إلى
كلّ من حجم المربّع الأساسي (الذي يجب أن يكون مستطيلاً) و"حجم
العالم" في خريطتك، وهو حجم البكسل لعالم الخريطة
عند مستوى التكبير 0. (بالنسبة إلى الخرائط التي تتألف من مربّع واحد عند التكبير 0، يكون حجم المربّع
وحجم العالم متطابقَين).
يمكنك تحديد حجم مربّع القاعدة ضمن سمة tileSize
في MapType
. يمكنك تحديد حجم العالم بشكل ضمني
ضمن طريقتَي fromLatLngToPoint()
وfromPointToLatLng()
لإنشاء الخرائط.
بما أنّ اختيار الصور يعتمد على هذه القيم المرسَلة، من المفيد
تسمية الصور التي يمكن اختيارها آليًا استنادًا إلى تلك
القيم المرسَلة، مثل
map_zoom_tileX_tileY.png
.
يحدِّد المثال التالي ImageMapType
باستخدام إسقاط
Gall-Peters:
TypeScript
// This example defines an image map type using the Gall-Peters // projection. // https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection function initMap(): void { // Create a map. Use the Gall-Peters map type. const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 0, center: { lat: 0, lng: 0 }, mapTypeControl: false, } ); initGallPeters(); map.mapTypes.set("gallPeters", gallPetersMapType); map.setMapTypeId("gallPeters"); // Show the lat and lng under the mouse cursor. const coordsDiv = document.getElementById("coords") as HTMLElement; map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv); map.addListener("mousemove", (event: google.maps.MapMouseEvent) => { coordsDiv.textContent = "lat: " + Math.round(event.latLng!.lat()) + ", " + "lng: " + Math.round(event.latLng!.lng()); }); // Add some markers to the map. map.data.setStyle((feature) => { return { title: feature.getProperty("name") as string, optimized: false, }; }); map.data.addGeoJson(cities); } let gallPetersMapType; function initGallPeters() { const GALL_PETERS_RANGE_X = 800; const GALL_PETERS_RANGE_Y = 512; // Fetch Gall-Peters tiles stored locally on our server. gallPetersMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom) { const scale = 1 << zoom; // Wrap tiles horizontally. const x = ((coord.x % scale) + scale) % scale; // Don't wrap tiles vertically. const y = coord.y; if (y < 0 || y >= scale) return ""; return ( "https://developers.google.com/maps/documentation/" + "javascript/examples/full/images/gall-peters_" + zoom + "_" + x + "_" + y + ".png" ); }, tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y), minZoom: 0, maxZoom: 1, name: "Gall-Peters", }); // Describe the Gall-Peters projection used by these tiles. gallPetersMapType.projection = { fromLatLngToPoint: function (latLng) { const latRadians = (latLng.lat() * Math.PI) / 180; return new google.maps.Point( GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360), GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)) ); }, fromPointToLatLng: function (point, noWrap) { const x = point.x / GALL_PETERS_RANGE_X; const y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y)); return new google.maps.LatLng( (Math.asin(1 - 2 * y) * 180) / Math.PI, -180 + 360 * x, noWrap ); }, }; } // GeoJSON, describing the locations and names of some cities. const cities = { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "Point", coordinates: [-87.65, 41.85] }, properties: { name: "Chicago" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-149.9, 61.218] }, properties: { name: "Anchorage" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-99.127, 19.427] }, properties: { name: "Mexico City" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-0.126, 51.5] }, properties: { name: "London" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [28.045, -26.201] }, properties: { name: "Johannesburg" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [15.322, -4.325] }, properties: { name: "Kinshasa" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [151.207, -33.867] }, properties: { name: "Sydney" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [0, 0] }, properties: { name: "0°N 0°E" }, }, ], }; declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example defines an image map type using the Gall-Peters // projection. // https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection function initMap() { // Create a map. Use the Gall-Peters map type. const map = new google.maps.Map(document.getElementById("map"), { zoom: 0, center: { lat: 0, lng: 0 }, mapTypeControl: false, }); initGallPeters(); map.mapTypes.set("gallPeters", gallPetersMapType); map.setMapTypeId("gallPeters"); // Show the lat and lng under the mouse cursor. const coordsDiv = document.getElementById("coords"); map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv); map.addListener("mousemove", (event) => { coordsDiv.textContent = "lat: " + Math.round(event.latLng.lat()) + ", " + "lng: " + Math.round(event.latLng.lng()); }); // Add some markers to the map. map.data.setStyle((feature) => { return { title: feature.getProperty("name"), optimized: false, }; }); map.data.addGeoJson(cities); } let gallPetersMapType; function initGallPeters() { const GALL_PETERS_RANGE_X = 800; const GALL_PETERS_RANGE_Y = 512; // Fetch Gall-Peters tiles stored locally on our server. gallPetersMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom) { const scale = 1 << zoom; // Wrap tiles horizontally. const x = ((coord.x % scale) + scale) % scale; // Don't wrap tiles vertically. const y = coord.y; if (y < 0 || y >= scale) return ""; return ( "https://developers.google.com/maps/documentation/" + "javascript/examples/full/images/gall-peters_" + zoom + "_" + x + "_" + y + ".png" ); }, tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y), minZoom: 0, maxZoom: 1, name: "Gall-Peters", }); // Describe the Gall-Peters projection used by these tiles. gallPetersMapType.projection = { fromLatLngToPoint: function (latLng) { const latRadians = (latLng.lat() * Math.PI) / 180; return new google.maps.Point( GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360), GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)), ); }, fromPointToLatLng: function (point, noWrap) { const x = point.x / GALL_PETERS_RANGE_X; const y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y)); return new google.maps.LatLng( (Math.asin(1 - 2 * y) * 180) / Math.PI, -180 + 360 * x, noWrap, ); }, }; } // GeoJSON, describing the locations and names of some cities. const cities = { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "Point", coordinates: [-87.65, 41.85] }, properties: { name: "Chicago" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-149.9, 61.218] }, properties: { name: "Anchorage" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-99.127, 19.427] }, properties: { name: "Mexico City" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-0.126, 51.5] }, properties: { name: "London" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [28.045, -26.201] }, properties: { name: "Johannesburg" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [15.322, -4.325] }, properties: { name: "Kinshasa" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [151.207, -33.867] }, properties: { name: "Sydney" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [0, 0] }, properties: { name: "0°N 0°E" }, }, ], }; window.initMap = initMap;