इस दस्तावेज़ में, Maps JavaScript API का इस्तेमाल करके दिखाए जा सकने वाले मैप के टाइप के बारे में बताया गया है. एपीआई, इन मैप की जानकारी सेव करने के लिए MapType
ऑब्जेक्ट का इस्तेमाल करता है. MapType
एक ऐसा इंटरफ़ेस है जो मैप टाइल के डिसप्ले और इस्तेमाल को तय करता है. साथ ही,
स्क्रीन कोऑर्डिनेट से वर्ल्ड कोऑर्डिनेट (मैप पर) में कोऑर्डिनेट सिस्टम के ट्रांसलेशन को तय करता है. हर MapType में, टाइल को वापस पाने और रिलीज़ करने के लिए कुछ तरीके होने चाहिए. साथ ही, इसमें ऐसी प्रॉपर्टी होनी चाहिए जो इसके विज़ुअल व्यवहार के बारे में बताती हों.
Maps JavaScript API में मैप टाइप के काम करने के तरीके को समझना, एक मुश्किल विषय है. ज़्यादातर डेवलपर, यहां दिए गए मैप के बुनियादी टाइप का इस्तेमाल कर सकते हैं. हालांकि, अलग-अलग स्टाइल में मैप का इस्तेमाल करके, मौजूदा मैप टाइप के प्रज़ेंटेशन में भी बदलाव किया जा सकता है. इसके अलावा, ज़रूरत के मुताबिक तैयार मैप का इस्तेमाल करके, अपने Map Tiles तय किए जा सकते हैं. ज़रूरत के मुताबिक तैयार मैप टाइप उपलब्ध कराते समय, आपको यह समझना होगा कि मैप की मैप टाइप रजिस्ट्री में बदलाव कैसे किया जाए.
मैप के बुनियादी टाइप
Maps JavaScript API में चार तरह के मैप उपलब्ध हैं. Maps JavaScript API, "पेंट की गई" रोड मैप टाइल के अलावा, अन्य तरह के मैप के साथ भी काम करता है.
Maps JavaScript API में, ये मैप टाइप उपलब्ध हैं:
roadmap, बुनियादी मैप के लेबल के साथ डिफ़ॉल्ट रोड मैप व्यू दिखाता है.satellite, प्लेन से ली गई तस्वीरों के आधार पर, फ़ोटो जैसा मैप दिखाता है.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');
ध्यान दें कि मैप का टाइप सीधे तौर पर सेट नहीं किया जाता. इसके बजाय, आइडेंटिफ़ायर का इस्तेमाल करके MapType को रेफ़रंस देने के लिए, mapTypeId को सेट किया जाता है.
Maps JavaScript API, इन रेफ़रंस को मैनेज करने के लिए, मैप टाइप रजिस्ट्री का इस्तेमाल करता है. इसके बारे में यहां बताया गया है.
3D मैप
Maps JavaScript API में 3D इमेजरी की सुविधा उपलब्ध है. 2D मैप के लिए उपलब्ध कई कार्रवाइयां और पसंद के मुताबिक बनाने की सुविधाएं, 3D मैप के लिए भी उपलब्ध हैं.
3D मैप के बारे में ज़्यादा जानने के लिए, 3D मैप की खास जानकारी पर जाएं.
यहां दिए गए उदाहरण में, सैन फ़्रांसिस्को का 3D पर्सपेक्टिव व्यू दिखाया गया है:
3D मैप की खास जानकारी में, 3D मैप के बारे में ज़्यादा जानें.
45° इमेजरी (अब सेवा में नहीं है)
यहां दिए गए सैंपल में, 3D मैप का इस्तेमाल करके, सैन फ़्रांसिस्को का 45° पर्सपेक्टिव व्यू पाने का तरीका बताया गया है:
TypeScript
async function init() { const { Map3DElement } = await google.maps.importLibrary('maps3d'); const map = new Map3DElement({ center: { lat: 37.789, lng: -122.401, altitude: 0, }, range: 2200, tilt: 45, heading: 188, }); map.mode = 'SATELLITE'; document.body.append(map); } void init();
JavaScript
async function init() { const { Map3DElement } = await google.maps.importLibrary('maps3d'); const map = new Map3DElement({ center: { lat: 37.789, lng: -122.401, altitude: 0, }, range: 2200, tilt: 45, heading: 188, }); map.mode = 'SATELLITE'; document.body.append(map); } void init();
सीएसएस
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #gmp-map-3d { height: 100%; } html, body { height: 100%; margin: 0; padding: 0; }
एचटीएमएल
<html>
<head>
<title>3d map 45-degree perspective</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
<script>
// prettier-ignore
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "GOOGLE_MAPS_API_KEY"
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>मैप टाइप रजिस्ट्री में बदलाव करना
मैप की 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 का असर सिर्फ़ डिफ़ॉल्ट roadmap मैप टाइप पर पड़ता है.
StyledMapType के बारे में ज़्यादा जानकारी के लिए, एम्बेड किए गए JSON स्टाइल डिक्लेरेशन का इस्तेमाल करना लेख पढ़ें.
ज़रूरत के मुताबिक तैयार मैप के टाइप
Maps JavaScript API, ज़रूरत के मुताबिक तैयार किए गए मैप टाइप को दिखाने और मैनेज करने की सुविधा देता है. इससे, अपनी मैप इमेज या टाइल ओवरले लागू किए जा सकते हैं.
Maps JavaScript API में, मैप टाइप को लागू करने के कई तरीके मौजूद हैं:
- स्टैंडर्ड टाइल सेट में ऐसी इमेज होती हैं जो मिलकर पूरे कार्टोग्राफ़िक मैप बनाती हैं. इन टाइल सेट को बुनियादी मैप टाइप भी कहा जाता है. ये मैप टाइप, मौजूदा डिफ़ॉल्ट मैप टाइप की तरह काम करते हैं:
roadmap,satellite,hybrid, औरterrain. आप अपने ज़रूरत के मुताबिक तैयार मैप टाइप को मैप केmapTypesकलेक्शन में जोड़ सकते हैं. इससे Maps JavaScript API के यूज़र इंटरफ़ेस (यूआई) को, आपके ज़रूरत के मुताबिक तैयार मैप टाइप को स्टैंडर्ड मैप टाइप के तौर पर इस्तेमाल करने की अनुमति मिलती है. उदाहरण के लिए, इसे MapType कंट्रोल में शामिल करके ऐसा किया जा सकता है. - इमेज टाइल ओवरले, जो मौजूदा बुनियादी मैप टाइप के ऊपर दिखते हैं. आम तौर पर, इन मैप टाइप का इस्तेमाल, किसी मौजूदा मैप टाइप को बेहतर बनाने के लिए किया जाता है, ताकि ज़्यादा जानकारी दिखाई जा सके. साथ ही, ये अक्सर खास जगहों और/या ज़ूम करने के लेवल तक सीमित होते हैं. ध्यान दें कि ये टाइल पारदर्शी हो सकती हैं. इससे आपको मौजूदा मैप में सुविधाएं जोड़ने की अनुमति मिलती है.
- नॉन-इमेज मैप टाइप, जिनकी मदद से मैप की जानकारी को सबसे बुनियादी लेवल पर बदला जा सकता है.
इनमें से हर विकल्प, ऐसी क्लास बनाने पर निर्भर करता है जो MapType इंटरफ़ेस को लागू करती है. इसके अलावा,
ImageMapType क्लास में कुछ पहले से मौजूद
सुविधाएं होती हैं. इनकी मदद से, इमेज मैप टाइप को आसानी से बनाया जा सकता है.
MapType इंटरफ़ेस
MapType को लागू करने वाली क्लास बनाने से पहले, यह समझना ज़रूरी है कि Google Maps, निर्देशांकों का पता कैसे लगाता है और मैप के किन हिस्सों को दिखाना है, यह कैसे तय करता है. आपको किसी भी बेस या ओवरले मैप टाइप के लिए, इसी तरह का लॉजिक लागू करना होगा.
मैप और टाइल कोऑर्डिनेट की गाइड पढ़ें.
ज़रूरत के मुताबिक तैयार मैप टाइप को MapType इंटरफ़ेस लागू करना होगा. यह इंटरफ़ेस कुछ प्रॉपर्टी और तरीकों के बारे में बताता है. इनकी मदद से, एपीआई आपके मैप टाइप के लिए अनुरोध शुरू कर सकता है. ऐसा तब होता है, जब एपीआई को लगता है कि उसे मौजूदा व्यूपोर्ट और ज़ूम करने के लेवल में मैप टाइल दिखाने की ज़रूरत है. इन अनुरोधों को मैनेज करके, यह तय किया जाता है कि कौनसी टाइल लोड करनी है.
ध्यान दें: इस इंटरफ़ेस को लागू करने के लिए, अपनी क्लास बनाई जा सकती है. इसके अलावा, अगर आपके पास
साथ काम करने वाली इमेज है, तो
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()को कॉल करने की ज़रूरत है या नहीं. यहMapTypeकीtileSize,minZoom, औरmaxZoomप्रॉपर्टी के साथ-साथ, मैप के मौजूदा व्यूपोर्ट और ज़ूम करने के लेवल के आधार पर तय किया जाता है. इस तरीके के हैंडलर को पास किए गए कोऑर्डिनेट, ज़ूम करने का लेवल, और डीओएम एलिमेंट के हिसाब से एचटीएमएल एलिमेंट दिखाना चाहिए. इस डीओएम एलिमेंट पर टाइल इमेज को जोड़ा जाएगा. -
releaseTile()(ज़रूरी नहीं) को तब कॉल किया जाता है, जब एपीआई को लगता है कि मैप से किसी टाइल को हटाना ज़रूरी है, क्योंकि वह व्यू से बाहर हो गई है. इस तरीके में यह सिग्नेचर होना चाहिए:releaseTile(tile:Node)आम तौर पर, आपको मैप में जोड़े गए उन सभी एलिमेंट को हटाने की ज़रूरत होती है जो मैप टाइल से जुड़े होते हैं. उदाहरण के लिए, अगर आपने मैप टाइल ओवरले में इवेंट लिसनर अटैच किए हैं, तो आपको उन्हें यहां हटाना चाहिए.
getTile() तरीका, मुख्य कंट्रोलर के तौर पर काम करता है. इससे यह तय किया जाता है कि किसी व्यूपोर्ट में कौनसी टाइल लोड करनी हैं.
बुनियादी मैप के टाइप
इस तरह से बनाए गए मैप टाइप, अलग से इस्तेमाल किए जा सकते हैं या उन्हें ओवरले के तौर पर अन्य मैप टाइप के साथ जोड़ा जा सकता है. अलग से मौजूद मैप टाइप को बुनियादी मैप टाइप कहा जाता है. ऐसा हो सकता है कि आपको एपीआई से, इस तरह के कस्टम MapType को किसी अन्य मौजूदा बुनियादी मैप टाइप (ROADMAP, TERRAIN वगैरह) की तरह इस्तेमाल करना हो. इसके लिए, Map की mapTypes प्रॉपर्टी में अपनी पसंद के मुताबिक MapType जोड़ें. यह प्रॉपर्टी 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;
ओवरले मैप टाइप
कुछ मैप टाइप, मौजूदा मैप टाइप के ऊपर काम करने के लिए डिज़ाइन किए गए हैं. इस तरह के मैप में पारदर्शी लेयर हो सकती हैं, जो दिलचस्प जगहों को दिखाती हैं या उपयोगकर्ता को अतिरिक्त डेटा दिखाती हैं.
ऐसे मामलों में, हो सकता है कि आपको मैप टाइप को एक अलग इकाई के तौर पर नहीं, बल्कि ओवरले के तौर पर इस्तेमाल करना हो.
ऐसा करने के लिए, Map की overlayMapTypes प्रॉपर्टी का इस्तेमाल करके, मैप टाइप को सीधे किसी मौजूदा MapType में जोड़ें. इस प्रॉपर्टी में, MapType का MVCArray शामिल होता है. सभी तरह के मैप (बेस और ओवरले), mapPane लेयर में रेंडर किए जाते हैं. ओवरले मैप टाइप, उस बुनियादी मैप के ऊपर दिखेंगे जिससे वे जुड़े हैं. ये मैप, Map.overlayMapTypes कलेक्शन में दिखने के क्रम में दिखेंगे. ज़्यादा इंडेक्स वैल्यू वाले ओवरले, कम इंडेक्स वैल्यू वाले ओवरले के सामने दिखते हैं.
नीचे दिया गया उदाहरण पिछले उदाहरण जैसा ही है.
हालांकि, हमने ROADMAP मैप टाइप के ऊपर
एक टाइल ओवरले MapType
बनाया है:
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(ज़रूरी है) फ़ंक्शन के बारे में बताता है. आम तौर पर, इसे इनलाइन फ़ंक्शन लिटरल के तौर पर दिया जाता है. इससे, दिए गए वर्ल्ड कोऑर्डिनेट और ज़ूम करने के लेवल के आधार पर, सही इमेज टाइल को चुनने में मदद मिलती है.
यहां दिया गया कोड, Google के मून टाइल का इस्तेमाल करके, एक बुनियादी 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;
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;
अनुमान
पृथ्वी, तीन डाइमेंशन वाला गोला है (लगभग), जबकि मैप, दो डाइमेंशन वाली समतल सतह है. Maps JavaScript API में दिखने वाला मैप, धरती के किसी भी फ़्लैट मैप की तरह, उस गोले का फ़्लैट सतह पर प्रोजेक्शन होता है. आसान शब्दों में कहें, तो प्रोजेक्शन को प्रोजेक्शन के मैप पर निर्देशांकों में अक्षांश/देशांतर वैल्यू की मैपिंग के तौर पर परिभाषित किया जा सकता है.
Maps JavaScript API में प्रोजेक्शन के लिए, Projection इंटरफ़ेस को लागू करना ज़रूरी है. Projection
को लागू करने के लिए, एक कोऑर्डिनेट सिस्टम से दूसरे कोऑर्डिनेट सिस्टम में मैपिंग के साथ-साथ, दोनों दिशाओं में मैपिंग की सुविधा भी होनी चाहिए. इसका मतलब है कि आपको यह तय करना होगा कि पृथ्वी के निर्देशांक (LatLng ऑब्जेक्ट) से Projection क्लास के वर्ल्ड कोऑर्डिनेट सिस्टम में और वर्ल्ड कोऑर्डिनेट सिस्टम से वापस पृथ्वी के निर्देशांक में कैसे अनुवाद किया जाए.
Google Maps, भौगोलिक डेटा से मैप बनाने और मैप पर मौजूद इवेंट को भौगोलिक निर्देशांकों में बदलने के लिए, मर्केटर प्रोजेक्शन का इस्तेमाल करता है. इस प्रोजेक्शन को पाने के लिए, Map (या किसी भी स्टैंडर्ड बेस MapType टाइप) पर getProjection() को कॉल करें. ज़्यादातर मामलों में, यह स्टैंडर्ड Projection काफ़ी होगा. हालांकि, आपके पास अपने हिसाब से कस्टम प्रोजेक्शन तय करने और उनका इस्तेमाल करने का विकल्प भी है.
प्रोजेक्शन लागू करना
कस्टम प्रोजेक्शन लागू करते समय, आपको कुछ चीज़ें तय करनी होंगी:
- अक्षांश और देशांतर निर्देशांकों को कार्टेशियन प्लेन में मैप करने के फ़ॉर्मूले और कार्टेशियन प्लेन से अक्षांश और देशांतर निर्देशांकों में मैप करने के फ़ॉर्मूले. (
Projectionइंटरफ़ेस, सिर्फ़ रेक्टिलिनियर कोऑर्डिनेट में ट्रांसफ़ॉर्मेशन के साथ काम करता है.) - बेस टाइल का साइज़. सभी टाइल रेक्टैंगल शेप में होनी चाहिए.
- ज़ूम लेवल 0 पर सेट किए गए बेस टाइल सेट का इस्तेमाल करने वाले मैप का "वर्ल्ड साइज़". ध्यान दें कि ज़ूम 0 पर एक टाइल वाले मैप के लिए, दुनिया का साइज़ और बेस टाइल का साइज़ एक जैसा होता है.
प्रोजेक्शन में कोऑर्डिनेट ट्रांसफ़ॉर्मेशन
हर प्रोजेक्शन में दो तरीके होते हैं, जो इन दोनों कोऑर्डिनेट सिस्टम के बीच अनुवाद करते हैं. इससे आपको भौगोलिक और वर्ल्ड कोऑर्डिनेट के बीच कन्वर्ज़न करने की सुविधा मिलती है:
Projection.fromLatLngToPoint()तरीका,LatLngवैल्यू को वर्ल्ड कोऑर्डिनेट में बदलता है. इस तरीके का इस्तेमाल, मैप पर ओवरले की पोज़िशन तय करने के लिए किया जाता है. साथ ही, इससे मैप की पोज़िशन भी तय की जाती है.Projection.fromPointToLatLng()तरीका, वर्ल्ड कोऑर्डिनेट कोLatLngवैल्यू में बदलता है. इस तरीके का इस्तेमाल, मैप पर होने वाले क्लिक जैसे इवेंट को भौगोलिक निर्देशांकों में बदलने के लिए किया जाता है.
Google Maps यह मानकर चलता है कि प्रोजेक्शन रेक्टिलिनियर हैं.
आम तौर पर, प्रोजेक्शन का इस्तेमाल दो मामलों में किया जा सकता है: दुनिया का मैप बनाने के लिए या किसी स्थानीय इलाके का मैप बनाने के लिए. पहले मामले में, आपको यह पक्का करना चाहिए कि आपका प्रोजेक्शन सभी देशांतरों पर रेक्टिलिनियर और सामान्य हो. कुछ प्रोजेक्शन (खास तौर पर कॉनिक प्रोजेक्शन) "स्थानीय तौर पर सामान्य" (यानी उत्तर की ओर) हो सकते हैं, लेकिन वे सही उत्तर से अलग होते हैं; उदाहरण के लिए, मैप को किसी रेफ़रंस देशांतर के हिसाब से जितना दूर रखा जाता है, वह उतना ही अलग होता है. इस तरह के प्रोजेक्शन का इस्तेमाल स्थानीय तौर पर किया जा सकता है. हालांकि, ध्यान रखें कि प्रोजेक्शन सटीक नहीं होता है और ट्रांसफ़ॉर्मेशन की गड़बड़ियां साफ़ तौर पर दिखेंगी. ऐसा तब होगा, जब रेफ़रंस देशांतर से आपकी दूरी ज़्यादा होगी.
प्रोजेक्शन में मैप टाइल चुनने की सुविधा
प्रोजेक्शन, जगहों या ओवरले की पोज़िशन तय करने के लिए ही नहीं, बल्कि मैप टाइल की पोज़िशन तय करने के लिए भी काम के होते हैं.
Maps JavaScript API, MapType इंटरफ़ेस का इस्तेमाल करके बुनियादी मैप रेंडर करता है. इस इंटरफ़ेस में, मैप के प्रोजेक्शन की पहचान करने के लिए projection प्रॉपर्टी और टाइल कोऑर्डिनेट वैल्यू के आधार पर मैप टाइल को वापस पाने के लिए getTile() तरीका, दोनों का एलान करना ज़रूरी है. टाइल कोऑर्डिनेट, आपकी टाइल के बेसिक साइज़ (जो रेक्टैंगल होना चाहिए) और आपके मैप के "वर्ल्ड साइज़" पर आधारित होते हैं. वर्ल्ड साइज़, ज़ूम करने के लेवल 0 पर आपके मैप वर्ल्ड का पिक्सल साइज़ होता है. (ज़ूम 0 पर एक टाइल वाले मैप के लिए, टाइल का साइज़ और दुनिया का साइज़ एक जैसा होता है.)
MapType की tileSize प्रॉपर्टी में, बेस टाइल का साइज़ तय किया जाता है. प्रोजेक्शन के fromLatLngToPoint() और fromPointToLatLng() तरीकों में, दुनिया के साइज़ को साफ़ तौर पर तय किया जाता है.
इमेज का चुनाव, पास की गई इन वैल्यू पर निर्भर करता है. इसलिए, उन इमेज को नाम देना फ़ायदेमंद होता है जिन्हें पास की गई वैल्यू के आधार पर, प्रोग्राम के हिसाब से चुना जा सकता है. जैसे, map_zoom_tileX_tileY.png.
यहां दिए गए उदाहरण में,
गॉल-पीटर्स प्रोजेक्शन का इस्तेमाल करके, ImageMapType को तय किया गया है:
TypeScript
// This example defines an image map type using the Gall-Peters // projection. // https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection const mapElement = document.querySelector('gmp-map')!; let innerMap: google.maps.Map; async function init() { // Request the needed libraries. await google.maps.importLibrary('maps'); // Create a map. innerMap = mapElement.innerMap; innerMap.setOptions({ mapTypeControl: false, }); // Set the Gall-Peters map type. const gallPetersMapType = await initGallPeters(); innerMap.mapTypes.set('gallPeters', gallPetersMapType); innerMap.setMapTypeId('gallPeters'); // Show the lat and lng under the mouse cursor. const coordsDiv = document.getElementById('coords')!; innerMap.addListener('mousemove', (event: google.maps.MapMouseEvent) => { coordsDiv.textContent = `lat: ${String(Math.round(event.latLng!.lat()))}, lng: ${String(Math.round(event.latLng!.lng()))}`; }); // Add some markers to the map. innerMap.data.setStyle((feature) => { return { title: feature.getProperty('name') as string, optimized: false, }; }); innerMap.data.addGeoJson(cities); } async function initGallPeters(): Promise<google.maps.ImageMapType> { const [{ ImageMapType }, { Size, Point, LatLng }] = await Promise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('core'), ]); const GALL_PETERS_RANGE_X = 800; const GALL_PETERS_RANGE_Y = 512; // Fetch Gall-Peters tiles stored locally on our server. const gallPetersMapType = new ImageMapType({ getTileUrl(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 `gall-peters_${String(zoom)}_${String(x)}_${String(y)}.png`; }, tileSize: new 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(latLng: google.maps.LatLng) { const latRadians = (latLng.lat() * Math.PI) / 180; return new Point( GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360), GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)) ); }, fromPointToLatLng(point: google.maps.Point, noWrap?: boolean) { const x = point.x / GALL_PETERS_RANGE_X; const y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y)); return new LatLng( (Math.asin(1 - 2 * y) * 180) / Math.PI, -180 + 360 * x, noWrap ); }, }; return gallPetersMapType; } // 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' }, }, ], }; void init();
JavaScript
// This example defines an image map type using the Gall-Peters // projection. // https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection const mapElement = document.querySelector('gmp-map'); let innerMap; async function init() { // Request the needed libraries. await google.maps.importLibrary('maps'); // Create a map. innerMap = mapElement.innerMap; innerMap.setOptions({ mapTypeControl: false, }); // Set the Gall-Peters map type. const gallPetersMapType = await initGallPeters(); innerMap.mapTypes.set('gallPeters', gallPetersMapType); innerMap.setMapTypeId('gallPeters'); // Show the lat and lng under the mouse cursor. const coordsDiv = document.getElementById('coords'); innerMap.addListener('mousemove', (event) => { coordsDiv.textContent = `lat: ${String(Math.round(event.latLng.lat()))}, lng: ${String(Math.round(event.latLng.lng()))}`; }); // Add some markers to the map. innerMap.data.setStyle((feature) => { return { title: feature.getProperty('name'), optimized: false, }; }); innerMap.data.addGeoJson(cities); } async function initGallPeters() { const [{ ImageMapType }, { Size, Point, LatLng }] = await Promise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('core'), ]); const GALL_PETERS_RANGE_X = 800; const GALL_PETERS_RANGE_Y = 512; // Fetch Gall-Peters tiles stored locally on our server. const gallPetersMapType = new ImageMapType({ getTileUrl(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 `gall-peters_${String(zoom)}_${String(x)}_${String(y)}.png`; }, tileSize: new 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(latLng) { const latRadians = (latLng.lat() * Math.PI) / 180; return new Point( GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360), GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)) ); }, fromPointToLatLng(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 LatLng( (Math.asin(1 - 2 * y) * 180) / Math.PI, -180 + 360 * x, noWrap ); }, }; return gallPetersMapType; } // 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' }, }, ], }; void init();