يتناول هذا المستند أنواع الخرائط التي يمكنك عرضها باستخدام واجهة برمجة تطبيقات JavaScript للخرائط. تستخدم واجهة برمجة التطبيقات كائن MapType
للاحتفاظ بمعلومات حول هذه الخرائط. MapType
هي واجهة تحدّد طريقة عرض مربعات الخرائط واستخدامها وترجمة أنظمة الإحداثيات من إحداثيات الشاشة إلى إحداثيات العالم (على الخريطة). يجب أن يتضمّن كل MapType
بضع طرق للتعامل مع عملية سحب المربّعات وإصدارها
والخصائص التي تحدّد سلوكها المرئي.
إن العمل الداخلي لأنواع الخرائط في واجهة برمجة تطبيقات JavaScript JavaScript هو موضوع متقدّم. يمكن لمعظم مطوّري البرامج استخدام أنواع الخرائط الأساسية الموضّحة أدناه. ومع ذلك، يمكنك أيضًا تعديل عرض أنواع الخرائط الحالية باستخدام خرائط نمطية أو تحديد مربعات الخرائط الخاصة بك باستخدام أنواع خرائط مخصصة. عند تقديم أنواع خرائط مخصصة، ستحتاج إلى استيعاب كيفية تعديل سجل نوع الخريطة.
أنواع الخرائط الأساسية
هناك أربعة أنواع من الخرائط متاحة ضمن واجهة برمجة تطبيقات JavaScript للخرائط. بالإضافة إلى مربعات خرائط الطرق "الملوّنة" المألوفة، تتيح واجهة برمجة تطبيقات JavaScript للخرائط أيضًا استخدام أنواع الخرائط الأخرى.
تتوفر أنواع الخرائط التالية في واجهة برمجة تطبيقات 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 درجة
تدعم واجهة برمجة تطبيقات JavaScript للخرائط صورًا خاصة بزاوية 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
المتاحة لهذه الخريطة. ويتم استخدام هذا السجلّ لاختيار أنواع الخرائط المتاحة في عنصر التحكّم في نوع الخريطة على سبيل المثال.
لا يمكنك القراءة مباشرة من سجل نوع الخريطة. بدلاً من ذلك، يمكنك تعديل قاعدة بيانات المسجّلين من خلال إضافة أنواع خرائط مخصّصة وربطها بمعرّف سلسلة من اختيارك. لا يمكنك تعديل أنواع الخرائط الأساسية أو تغييرها (ولكن يمكنك إزالتها من الخريطة عن طريق تغيير مظهر 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
، يمكنك الاطّلاع على دليل
الخرائط ذات الأنماط.
أنواع الخرائط المخصصة
وتدعم واجهة برمجة تطبيقات JavaScript للخرائط عرض وإدارة أنواع الخرائط المخصصة، مما يسمح لك بتنفيذ صور الخريطة أو تراكبات المربعات.
هناك العديد من عمليات تنفيذ نوع الخريطة الممكنة في واجهة برمجة تطبيقات JavaScript للخرائط:
- مجموعات المربعات العادية التي تتألف من صور
تشكّل مجتمعةً خرائط خرائط كاملة وتُعرف مجموعات المربعات هذه أيضًا باسم أنواع الخرائط الأساسية. تعمل أنواع الخريطة هذه وتتصرف مثل أنواع الخرائط التلقائية الحالية:
roadmap
وsatellite
وhybrid
وterrain
. يمكنك إضافة نوع الخريطة المخصّصة إلى المصفوفةmapTypes
على الخريطة للسماح لواجهة المستخدم في واجهة برمجة تطبيقات JavaScript بالخرائط باعتبار نوع الخريطة المخصّصة نوعًا عاديًا من الخريطة (من خلال تضمينه في عنصر التحكّم في نوع الخريطة على سبيل المثال). - تراكبات مربّعات الصور التي تظهر فوق أنواع الخرائط الأساسية الحالية. بشكل عام، تُستخدم أنواع الخرائط هذه لتعزيز نوع خريطة حالي لعرض معلومات إضافية وغالبًا ما يتم حصرها على مواقع جغرافية محددة و/أو مستويات تكبير/تصغير. تجدر الإشارة إلى أن هذه المربّعات قد تكون شفافة، ما يسمح لك بإضافة مواضع إلى الخرائط الحالية.
- أنواع الخريطة غير المصوّرة التي تتيح لك التحكم في عرض معلومات الخريطة على المستوى الأساسي لها
يعتمد كل خيار من هذه الخيارات على إنشاء فئة تستخدم واجهة MapType
. إضافةً إلى ذلك، توفّر الصف
ImageMapType
بعض
الإجراءات المدمجة لتبسيط إنشاء أنواع خرائط الصور.
واجهة MapType
قبل إنشاء الصفوف التي تطبِّق MapType
،
من المهم فهم كيفية تحديد "خرائط Google"
للإحداثيات وتحديد أجزاء الخريطة التي يتم عرضها. ويلزمك تطبيق منطق مماثل لأي نوع من أنواع الخرائط الأساسية أو التراكب.
اطّلِع على دليل إحداثيات الخريطة والمربع.
يجب أن تستخدم أنواع الخرائط المخصّصة واجهة MapType
. تحدد هذه الواجهة خصائص وطرقًا معينة تسمح لواجهة برمجة التطبيقات ببدء طلبات إلى أنواع الخرائط عندما تحدد واجهة برمجة التطبيقات أنها تحتاج إلى عرض مربعات الخرائط ضمن إطار العرض الحالي ومستوى التكبير/التصغير. ويمكنك التعامل مع هذه الطلبات لتحديد المربّع المطلوب تحميله.
ملاحظة: يمكنك إنشاء صف خاص بك لتطبيق هذه الواجهة. بدلاً من ذلك، إذا كانت لديك
صور متوافقة، يمكنك استخدام الفئة
ImageMapType
التي تنفّذ
هذه الواجهة مسبقًا.
تتطلّب الفئات التي تستخدم واجهة MapType
تعريف الخصائص التالية وتعبئتها:
- تحدّد السمة
tileSize
(مطلوبة) حجم المربّع (من النوعgoogle.maps.Size
). ويجب أن تكون الأحجام مستطيلة، على الرغم من أنّها ليست مربّعة. - تحدّد
maxZoom
(مطلوبة) الحد الأقصى لمستوى التكبير/التصغير الذي يتم فيه عرض مربعات من نوع الخريطة هذا. - تحدّد
minZoom
(اختيارية) الحد الأدنى لمستوى التكبير/التصغير الذي يتم عرض مربع نوع الخريطة هذا عنده. بشكل تلقائي، تكون هذه القيمة هي0
للإشارة إلى عدم وجود حد أدنى لمستوى التكبير أو التصغير. name
(اختياري) تحدد اسم نوع الخريطة هذا. هذه الخاصية ضرورية فقط إذا كنت تريد أن يكون نوع الخريطة هذا قابلاً للتحديد في عنصر تحكم MapType. (راجِع إضافةMapType
عناصر تحكُّم أدناه).alt
(اختياري) تحدد النص البديل لنوع الخريطة هذا، ويتم عرضه كنص متحرك. هذه الخاصية ضرورية فقط إذا كنت تريد أن يكون نوع الخريطة هذا قابلاً للتحديد في عنصر تحكم نوع الخريطة. (راجِع إضافةMapType
عناصر تحكُّم أدناه).
بالإضافة إلى ذلك، يجب أن يتم تطبيق الطرق التالية في الصفوف التي تستخدم واجهة MapType
:
-
يتم استدعاء
getTile()
(مطلوبة) عندما تحدد واجهة برمجة التطبيقات أن الخريطة تحتاج إلى عرض مربعات جديدة لإطار العرض المحدد. يجب أن تتضمّن طريقةgetTile()
التوقيع التالي:getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node
تحدّد واجهة برمجة التطبيقات ما إذا كان يجب استدعاء الدالة
getTile()
استنادًا إلى سماتMapType
وtileSize
وminZoom
وmaxZoom
بالإضافة إلى إطار العرض والتكبير/التصغير الحالي للخريطة. من المفترض أن يعرض المعالج لهذه الطريقة عنصر 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، مثل أي خريطة مسطّحة لكوكب الأرض، هي إسقاط لهذه الكرة الأرضية على سطح مستوٍ. ببساطة، يمكن تعريف الإسقاط على أنه ربط لقيم خطوط الطول/العرض في إحداثيات خريطة الإسقاط.
يجب أن تنفذ التوقعات في واجهة برمجة تطبيقات JavaScript للخرائط واجهة Projection
. يجب ألا يوفّر تنفيذ Projection
عملية ربط من نظام إحداثيات
إلى نظام آخر فقط، بل يجب أيضًا توفير عملية ربط ثنائية الاتجاه. أي أنه يجب تحديد طريقة الترجمة من إحداثيات Earth (كائنات LatLng
) إلى نظام الإحداثيات العالمية للصف Projection
والعكس صحيح. يستخدم تطبيق "خرائط Google"
إسقاط ماركاتور لإنشاء خرائطه من البيانات الجغرافية وتحويل الأحداث على الخريطة إلى
إحداثيات جغرافية. يمكنك الحصول على هذا الإسقاط
من خلال استدعاء getProjection()
في Map
(أو أي من أنواع MapType
الأساسية الأساسية). بالنسبة إلى معظم الاستخدامات، ستكون هذه الاستراتيجية Projection
العادية كافية، ولكن يمكنك أيضًا تحديد توقّعاتك المخصّصة واستخدامها.
تنفيذ إسقاط
عند تنفيذ إسقاط مخصّص، عليك تحديد بعض العناصر:
- صيغة ربط إحداثيات خطوط الطول والعرض في
طائرة ديكارتية والعكس صحيح. (لا تتيح واجهة
Projection
سوى عمليات التحويل إلى إحداثيات مستقيمة.) - حجم المربع الأساسي. يجب أن تكون جميع المربّعات مستطيلة.
- "الحجم العالمي" للخريطة باستخدام المربع الأساسي المعيّن في مستوى التكبير/التصغير 0. تجدر الإشارة إلى أنه بالنسبة إلى الخرائط التي تتكون من مربع واحد عند التكبير/التصغير 0، يكون الحجم العالمي وحجم المربع الأساسي متطابقين.
تنسيق التحويلات في التوقعات
يوفّر كل إسقاط طريقتين للترجمة بين هذين النظامين للإحداثيات، ما يسمح لك بالتبديل بين إحداثيات الموقع الجغرافي والعالم:
- تحوِّل الطريقة
Projection.fromLatLngToPoint()
قيمةLatLng
إلى إحداثي عالمي. ويتم استخدام هذه الطريقة لتحديد موضع التراكبات على الخريطة (ولتحديد موضع الخريطة نفسها). - تحوِّل الطريقة
Projection.fromPointToLatLng()
إحداثيًا عامًا إلى قيمةLatLng
. تُستخدم هذه الطريقة لتحويل الأحداث مثل النقرات التي تحدث على الخريطة إلى إحداثيات جغرافية.
تفترض خرائط Google أن عمليات الإسقاط مستقيمة.
بشكل عام، يمكنك استخدام إسقاط في حالتين: لإنشاء خريطة للعالم، أو لإنشاء خريطة لمنطقة محلية. في الحالة السابقة، يجب التأكّد من أنّ العرض مستقيم وطبيعي في جميع خطوط الطول. قد تكون بعض الإسقاطات (خصوصًا الإسقاطات المخروطية) "عادية على المستوى المحلي" (على سبيل المثال، تشير إلى الشمال) ولكنها تنحرف عن شمال صحيح، على سبيل المثال، كلما تم تحديد موضع الخريطة بشكل نسبي مع بعض خطوط الطول المرجعية. يمكنك استخدام هذا الإسقاط محليًا، ولكن انتبه إلى أنّ العرض لا يكون دقيقًا بالضرورة، وبالتالي ستزداد أخطاء التحول بشكل واضح كلما ابتعدت عن خط الطول المرجعي الذي تنحرف عنه.
اختيار مربعات الخرائط في الإسقاطات
ولا تُعد التوقعات مفيدة لتحديد مواضع المواقع الجغرافية أو التراكبات فحسب، بل تساعد أيضًا على تحديد موضع مربعات الخرائط.
تعرض واجهة برمجة تطبيقات JavaScript للخرائط الخرائط الأساسية باستخدام واجهة 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"), 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;