يتناول هذا المستند أنواع الخرائط التي يمكنك عرضها باستخدام واجهة برمجة التطبيقات
Maps JavaScript API. تستخدِم واجهة برمجة التطبيقات عنصر MapType
لتخزين معلومات عن هذه الخرائط. MapType
هي واجهة تحدّد عرض واستخدام مربّعات الخريطة
وترجمة أنظمة الإحداثيات من إحداثيات الشاشة إلى إحداثيات
العالم (على الخريطة). يجب أن يحتوي كل MapType
على
بضع طرق لمعالجة استرداد المربّعات وإخلاءها، والخصائص
التي تحدّد سلوكها المرئي.
إنّ آلية عمل أنواع الخرائط ضمن واجهة برمجة التطبيقات Maps JavaScript API هي موضوع متقدّم. يمكن لمعظم المطوّرين استخدام أنواع الخرائط الأساسية المذكورة أدناه. ومع ذلك، يمكنك أيضًا تعديل طريقة عرض أنواع الخرائط الحالية باستخدام الخرائط المخصّصة أو تحديد مربّعات الخرائط الخاصة بك باستخدام أنواع الخرائط المخصّصة. عند تقديم أنواع خرائط مخصّصة، عليك معرفة كيفية تعديل سجلّ أنواع الخرائط.
أنواع الخرائط الأساسية
تتوفّر أربعة أنواع من الخرائط في واجهة برمجة التطبيقات Maps JavaScript API. بالإضافة إلى مربّعات خرائط الطرق "المرسومة" المألوفة، تتوافق واجهة برمجة التطبيقات JavaScript لـ "خرائط Google" أيضًا مع أنواع الخرائط الأخرى.
تتوفّر أنواع الخرائط التالية في واجهة برمجة التطبيقات JavaScript لـ "خرائط Google":
- يعرض
roadmap
طريقة العرض التلقائية لخريطة الطرق. هذا هو نوع الخريطة التلقائي. satellite
لعرض صور الأقمار الصناعية في Google Earthhybrid
يعرض مزيجًا من الاطِّلاع العادي واطّلاع القمر الصناعي.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
باستخدام معرّف.
تستخدِم واجهة برمجة التطبيقات Maps JavaScript API سجلّ أنواع الخرائط، описанًا أدناه، لإدارة هذه الإشارات.
الصور بزاوية 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. يستخدم المثال دالة معالجة طبيعية
لضمان تكرار المربّعات على طول محور x، ولكن ليس على طول محور
y في خريطتك.
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;