این سند انواع نقشه هایی را که می توانید با استفاده از Maps JavaScript API نمایش دهید، مورد بحث قرار می دهد. API از یک شی MapType
برای نگهداری اطلاعات در مورد این نقشه ها استفاده می کند. MapType
رابطی است که نمایش و استفاده از کاشی های نقشه و ترجمه سیستم های مختصات را از مختصات صفحه به مختصات جهانی (روی نقشه) تعریف می کند. هر MapType
باید شامل چند روش برای رسیدگی به بازیابی و رهاسازی کاشی ها و ویژگی هایی باشد که رفتار بصری آن را مشخص می کند.
عملکرد داخلی انواع نقشه در Maps JavaScript API یک موضوع پیشرفته است. اکثر توسعه دهندگان می توانند از انواع نقشه های اصلی که در زیر ذکر شده است استفاده کنند. با این حال، همچنین میتوانید ارائه انواع نقشههای موجود را با استفاده از Styled Maps تغییر دهید یا کاشیهای نقشه خود را با استفاده از انواع نقشه سفارشی تعریف کنید. هنگام ارائه انواع نقشه های سفارشی، باید بدانید که چگونه رجیستری نوع نقشه نقشه را تغییر دهید.
انواع نقشه های اساسی
چهار نوع نقشه در Maps JavaScript API موجود است. علاوه بر کاشی های آشنای نقشه راه "نقاشی شده"، Maps JavaScript API از انواع دیگر نقشه ها نیز پشتیبانی می کند.
انواع نقشه های زیر در Maps JavaScript API موجود است:
-
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
با استفاده از یک شناسه تنظیم می کنید. 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 درجه
می توانید با فراخوانی setTilt(0)
روی شی Map
، تصویر 45 درجه را غیرفعال کنید. برای فعال کردن تصاویر 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;
جاوا اسکریپت
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;
Sample را امتحان کنید
چرخش تصویر 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;
جاوا اسکریپت
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;
Sample را امتحان کنید
تغییر رجیستری نوع نقشه
mapTypeId
نقشه یک شناسه رشته ای است که برای مرتبط کردن MapType
با یک مقدار منحصر به فرد استفاده می شود. هر شی Map
یک MapTypeRegistry
دارد که شامل مجموعه MapType
های موجود برای آن نقشه است. از این رجیستری برای انتخاب انواع نقشه هایی که در کنترل MapType Maps موجود هستند، استفاده می شود.
شما مستقیماً از رجیستری نوع نقشه نمی خوانید. در عوض، رجیستری را با اضافه کردن انواع نقشه های سفارشی و مرتبط کردن آنها با یک شناسه رشته دلخواه تغییر می دهید. شما نمی توانید انواع اصلی نقشه را تغییر دهید یا تغییر دهید (البته می توانید با تغییر ظاهر نقشه 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
، به راهنمای نقشههای سبکدهی شده مراجعه کنید.
انواع نقشه سفارشی
Maps JavaScript API از نمایش و مدیریت انواع نقشههای سفارشی پشتیبانی میکند و به شما امکان میدهد تصاویر نقشه یا پوششهای کاشی خود را پیادهسازی کنید.
چندین پیاده سازی ممکن از نوع نقشه در Maps JavaScript API وجود دارد:
- مجموعههای کاشی استاندارد متشکل از تصاویری که در مجموع نقشههای کامل نقشهکشی را تشکیل میدهند. این مجموعه کاشی ها به عنوان انواع نقشه های پایه نیز شناخته می شوند. این انواع نقشه مانند انواع نقشه های پیش فرض موجود عمل می کنند و رفتار می کنند:
roadmap
،satellite
،hybrid
وterrain
. می توانید نوع نقشه سفارشی خود را به آرایهmapTypes
Map اضافه کنید تا به رابط کاربری در Maps JavaScript API اجازه دهید تا نوع نقشه سفارشی شما را به عنوان یک نوع نقشه استاندارد در نظر بگیرد (مثلاً با قرار دادن آن در کنترل MapType). - پوششهای کاشی تصویری که در بالای انواع نقشه پایه موجود نمایش داده میشوند. به طور کلی، این انواع نقشه برای تقویت یک نوع نقشه موجود برای نمایش اطلاعات اضافی استفاده می شود و اغلب به مکان های خاص و/یا سطوح زوم محدود می شود. توجه داشته باشید که این کاشیها ممکن است شفاف باشند و به شما امکان میدهند ویژگیهایی را به نقشههای موجود اضافه کنید.
- انواع نقشه های غیر تصویری، که به شما امکان می دهد نمایش اطلاعات نقشه را در اساسی ترین سطح آن دستکاری کنید.
هر یک از این گزینه ها متکی به ایجاد کلاسی است که رابط MapType
را پیاده سازی می کند. علاوه بر این، کلاس ImageMapType
برخی رفتارهای داخلی را برای ساده سازی ایجاد انواع نقشه های تصویری ارائه می دهد.
رابط MapType
قبل از ایجاد کلاسهایی که MapType
را پیادهسازی میکنند، مهم است که بدانید Google Maps چگونه مختصات را تعیین میکند و تصمیم میگیرد کدام قسمتهای نقشه را نشان دهد. شما باید منطق مشابهی را برای هر نوع نقشه پایه یا پوششی پیاده سازی کنید. راهنمای مختصات نقشه و کاشی را بخوانید.
انواع نقشه های سفارشی باید رابط MapType
را پیاده سازی کنند. این رابط ویژگیها و روشهای خاصی را مشخص میکند که به API اجازه میدهد زمانی که API تشخیص میدهد که باید کاشیهای نقشه را در نمای فعلی و سطح زوم نمایش دهد، درخواستهایی را برای نوع(های) نقشه شما آغاز کند. شما با این درخواست ها تصمیم می گیرید کدام کاشی را بارگیری کنید.
توجه : می توانید کلاس خود را برای پیاده سازی این رابط ایجاد کنید. از طرف دیگر، اگر تصاویر سازگار دارید، می توانید از کلاس ImageMapType
استفاده کنید که قبلاً این رابط را پیاده سازی می کند.
کلاس هایی که رابط MapType
را پیاده سازی می کنند نیاز دارند که ویژگی های زیر را تعریف و پر کنید:
-
tileSize
(الزامی) اندازه کاشی (از نوعgoogle.maps.Size
) را مشخص می کند. اندازه ها باید مستطیل شکل باشند، اگرچه نیازی به مربع ندارند. -
maxZoom
(الزامی) حداکثر سطح بزرگنمایی را برای نمایش کاشی های این نوع نقشه مشخص می کند. -
minZoom
(اختیاری) حداقل سطح بزرگنمایی را برای نمایش کاشی از این نوع نقشه مشخص می کند. به طور پیش فرض، این مقدار0
است که نشان می دهد حداقل سطح بزرگنمایی وجود ندارد. -
name
(اختیاری) نام این نوع نقشه را مشخص می کند. این ویژگی فقط در صورتی ضروری است که بخواهید این نوع نقشه در یک کنترل MapType قابل انتخاب باشد. ( افزودن کنترلهایMapType
را در زیر ببینید.) -
alt
(اختیاری) متن جایگزین را برای این نوع نقشه مشخص می کند که به عنوان متن شناور نمایش داده می شود. این ویژگی فقط در صورتی ضروری است که بخواهید این نوع نقشه در یک کنترل MapType قابل انتخاب باشد. ( افزودن کنترلهایMapType
را در زیر ببینید.)
علاوه بر این، کلاس هایی که رابط MapType
را پیاده سازی می کنند، باید متدهای زیر را پیاده سازی کنند:
getTile()
(الزامی) زمانی فراخوانی می شود که API تشخیص دهد که نقشه نیاز به نمایش کاشی های جدید برای نمای داده شده دارد. متدgetTile()
باید دارای امضای زیر باشد:getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node
API تعیین می کند که آیا نیاز به فراخوانی
getTile()
بر اساس ویژگی هایtileSize
،minZoom
، وmaxZoom
MapType
و نمای فعلی نقشه و سطح زوم است. کنترلکننده این روش باید یک عنصر HTML را با توجه به مختصات، سطح بزرگنمایی و عنصر DOM برگرداند تا تصویر کاشی را به آن اضافه کند.releaseTile()
(اختیاری) زمانی فراخوانی می شود که API تشخیص دهد که نقشه باید یک کاشی را حذف کند زیرا از دید خارج می شود. این روش باید دارای امضای زیر باشد:releaseTile(tile:Node)
شما معمولاً باید پس از اضافه شدن به نقشه، تمام عناصری را که به کاشی های نقشه متصل شده اند حذف کنید. برای مثال، اگر شنوندههای رویداد را به همپوشانیهای کاشی نقشه پیوست کردهاید، باید آنها را از اینجا حذف کنید.
متد getTile()
به عنوان کنترلکننده اصلی برای تعیین اینکه کدام کاشیها در یک Viewport بارگذاری شوند، عمل میکند.
انواع نقشه پایه
انواع نقشههایی که به این روش میسازید ممکن است به تنهایی یا با دیگر انواع نقشهها به عنوان همپوشانی ترکیب شوند. انواع نقشه های مستقل به عنوان انواع نقشه پایه شناخته می شوند. ممکن است بخواهید که API با 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;
جاوا اسکریپت
/* * 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;
Sample را امتحان کنید
انواع نقشه روکش
برخی از انواع نقشه برای کار بر روی انواع نقشه های موجود طراحی شده اند. این گونه نقشه ها ممکن است لایه های شفافی داشته باشند که نقاط مورد علاقه را نشان می دهد یا داده های اضافی را به کاربر نشان می دهد.
در این موارد، شما نمی خواهید که نوع نقشه به عنوان یک موجودیت جداگانه در نظر گرفته شود، بلکه به عنوان یک پوشش. می توانید این کار را با افزودن نوع نقشه به MapType
موجود مستقیماً با استفاده از ویژگی overlayMapTypes
Map
انجام دهید. این ویژگی حاوی یک MVCArray
از MapType
s است. همه انواع نقشه (پایه و روکش) در لایه 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;
جاوا اسکریپت
/* * 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;
Sample را امتحان کنید
انواع نقشه های تصویری
پیاده سازی MapType
برای عمل به عنوان یک نوع نقشه پایه می تواند یک کار وقت گیر و پر زحمت باشد. API کلاس خاصی را ارائه میکند که رابط MapType
را برای رایجترین انواع نقشه پیادهسازی میکند: انواع نقشه که از کاشیهایی تشکیل شده از فایلهای تصویری منفرد تشکیل شدهاند.
این کلاس، کلاس ImageMapType
، با استفاده از مشخصات شی ImageMapTypeOptions
که ویژگی های مورد نیاز زیر را تعریف می کند، ساخته می شود:
-
tileSize
(الزامی) اندازه کاشی (از نوعgoogle.maps.Size
) را مشخص می کند. اندازه ها باید مستطیل شکل باشند، اگرچه نیازی به مربع ندارند. -
getTileUrl
(الزامی) تابعی را مشخص میکند که معمولاً بهعنوان یک تابع درون خطی به صورت تحت اللفظی ارائه میشود، تا انتخاب کاشی تصویر مناسب را بر اساس مختصات جهان ارائهشده و سطح بزرگنمایی انجام دهد.
کد زیر یک ImageMapType
اولیه را با استفاده از کاشی های ماه گوگل پیاده سازی می کند. این مثال از یک تابع عادی سازی استفاده می کند تا اطمینان حاصل شود که کاشی ها در امتداد محور 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;
جاوا اسکریپت
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;
Sample را امتحان کنید
پیش بینی ها
زمین یک کره سه بعدی (تقریبا) است، در حالی که نقشه یک سطح دو بعدی صاف است. نقشه ای که در Maps JavaScript API مشاهده می کنید، مانند هر نقشه مسطحی از زمین، نمایش آن کره بر روی یک سطح صاف است. در ساده ترین عبارت، یک طرح ریزی را می توان به عنوان نگاشت مقادیر طول و عرض جغرافیایی به مختصات روی نقشه طرح ریزی تعریف کرد.
پیشبینیها در Maps JavaScript API باید رابط Projection
پیادهسازی کنند. یک پیاده سازی Projection
باید نه تنها یک نقشه برداری از یک سیستم مختصات به سیستم دیگر، بلکه یک نقشه برداری دو طرفه را نیز ارائه دهد. یعنی باید نحوه ترجمه از مختصات زمین (اشیاء LatLng
) به سیستم مختصات جهانی کلاس Projection
و بالعکس را تعریف کنید. Google Maps از طرح Mercator برای ایجاد نقشه های خود از داده های جغرافیایی و تبدیل رویدادهای روی نقشه به مختصات جغرافیایی استفاده می کند. شما می توانید با فراخوانی getProjection()
روی Map
(یا هر نوع از انواع MapType
پایه استاندارد) این Projection
را بدست آورید.
اجرای یک پروجکشن
هنگام اجرای یک طرح سفارشی، باید چند چیز را تعریف کنید:
- فرمول های نگاشت مختصات طول و عرض جغرافیایی در یک صفحه دکارتی و بالعکس. (رابط
Projection
فقط از تبدیل به مختصات مستطیلی پشتیبانی می کند.) - اندازه کاشی پایه تمام کاشی ها باید مستطیل شکل باشند.
- "اندازه جهانی" نقشه با استفاده از کاشی پایه در سطح زوم 0 تنظیم شده است. توجه داشته باشید که برای نقشه هایی که از یک کاشی با بزرگنمایی 0 تشکیل شده اند، اندازه جهانی و اندازه کاشی پایه یکسان است.
هماهنگی تحولات در پیش بینی ها
هر طرح دو روش را ارائه می دهد که بین این دو سیستم مختصات ترجمه می شود و به شما امکان می دهد بین مختصات جغرافیایی و جهانی تبدیل کنید:
- متد
Projection.fromLatLngToPoint()
یک مقدارLatLng
را به یک مختصات جهانی تبدیل می کند. این روش برای قرار دادن همپوشانی ها روی نقشه (و موقعیت خود نقشه) استفاده می شود. - متد
Projection.fromPointToLatLng()
یک مختصات جهانی را به مقدارLatLng
تبدیل می کند. این روش برای تبدیل رویدادهایی مانند کلیک هایی که روی نقشه اتفاق می افتد به مختصات جغرافیایی استفاده می شود.
نقشه های گوگل فرض می کند که پیش بینی ها مستطیل هستند.
به طور کلی، شما ممکن است از یک طرح برای دو مورد استفاده کنید: برای ایجاد یک نقشه از جهان، یا برای ایجاد یک نقشه از یک منطقه محلی. در حالت اول، باید اطمینان حاصل کنید که طرح شما در تمام طولهای جغرافیایی مستطیل و نرمال است. برخی از برجستگی ها (به ویژه برآمدگی های مخروطی) ممکن است "به صورت محلی عادی" باشند (یعنی نقطه شمال) اما از شمال واقعی منحرف شوند. برای مثال، هر چه نقشه نسبت به طول جغرافیایی مرجع بیشتر قرار گیرد. شما ممکن است از چنین طرح ریزی به صورت محلی استفاده کنید، اما توجه داشته باشید که طرح ریزی لزوماً نادقیق است و خطاهای تبدیل ظاهراً هر چه از طول جغرافیایی مرجع منحرف می شوید بیشتر می شود.
انتخاب کاشی نقشه در پیش بینی ها
پیش بینی ها نه تنها برای تعیین موقعیت مکان ها یا پوشش ها، بلکه برای تعیین موقعیت خود کاشی های نقشه مفید هستند. 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;
جاوا اسکریپت
// 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;