Harita Türleri

Platform seçin: Android iOS JavaScript

Bu belgede, Maps JavaScript API'yi kullanarak görüntüleyebileceğiniz harita türleri ele alınmaktadır. API, bu haritalarla ilgili bilgileri tutmak için bir MapType nesnesi kullanır. MapType, harita karolarının görüntülenmesini ve kullanımını, ayrıca koordinat sistemlerinin ekran koordinatlarından dünya koordinatlarına (harita üzerinde) çevrilmesini tanımlayan bir arayüzdür. Her MapType, karoların alınmasını ve serbest bırakılmasını yöneten birkaç yöntem ve görsel davranışını tanımlayan özellikler içermelidir.

Maps JavaScript API'deki harita türlerinin iç işleyişi ileri düzey bir konudur. Çoğu geliştirici, aşağıda belirtilen temel harita türlerini kullanabilir. Ancak stil özellikli haritaları kullanarak mevcut harita türlerinin sunumunu değiştirebilir veya özel harita türlerini kullanarak kendi harita karolarınızı tanımlayabilirsiniz. Özel harita türleri sağlarken haritanın Harita Türü Kayıt Defteri'ni nasıl değiştireceğinizi anlamanız gerekir.

Temel Harita Türleri

Maps JavaScript API'de dört tür harita kullanılabilir. Maps JavaScript API, bilinen "boyalı" yol haritası karolarının yanı sıra diğer harita türlerini de destekler.

Maps JavaScript API'de aşağıdaki harita türleri kullanılabilir:

  • roadmap, temel harita etiketleriyle varsayılan yol haritası görünümünü gösterir.
  • satellite, havadan görüntülere dayalı, fotoğraf gerçekliğinde bir harita gösterir.
  • hybrid, temel harita etiketleriyle uydu haritası görünümünü gösterir.
  • terrain, arazi bilgilerine dayalı bir fiziksel harita gösterir.

Kullanılan harita türünü Map ile değiştirmek için mapTypeId özelliğini ayarlayabilirsiniz. Bu işlemi, kurucu içinde Map options nesnesini ayarlayarak veya haritanın setMapTypeId() yöntemini çağırarak yapabilirsiniz. mapTypeID özelliği varsayılan olarak roadmap değerine ayarlanır.

Oluşturma sırasında mapTypeId değerini ayarlama:

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 öğesini dinamik olarak değiştirme:

map.setMapTypeId('terrain');

Haritanın harita türünü doğrudan ayarlamadığınızı, bunun yerine mapTypeId değerini bir tanımlayıcı kullanarak MapType değerine referans verecek şekilde ayarladığınızı unutmayın. Maps JavaScript API, bu referansları yönetmek için aşağıda açıklanan bir harita türü kayıt defteri kullanır.

3D Haritalar

Maps JavaScript API, 3D görüntüleri destekler. 2D haritalar için kullanılabilen işlemlerin ve özelleştirme özelliklerinin çoğu 3D haritalar için de kullanılabilir.

3D haritalara genel bakış bölümünde 3D haritalar hakkında daha fazla bilgi edinebilirsiniz.

Aşağıdaki örnekte San Francisco'nun 3D perspektif görünümü gösterilmektedir:

3D haritalara genel bakış bölümünde 3D haritalar hakkında daha fazla bilgi edinebilirsiniz.

45° Görüntüler (desteği sonlandırıldı)

Aşağıdaki örnekte, 3D haritalar kullanılarak San Francisco'nun 45° perspektif görünümünün nasıl elde edileceği gösterilmektedir:

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();

CSS

/* 
 * 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

<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>
Örneği görüntüleyin

Harita Türü Kayıt Defteri'ni değiştirme

Haritanın mapTypeId değeri, MapType değerini benzersiz bir değerle ilişkilendirmek için kullanılan dize tanımlayıcısıdır. Her Map nesnesi, ilgili harita için kullanılabilir MapType koleksiyonunu içeren bir MapTypeRegistry tutar. Bu kayıt defteri, örneğin Harita'nın MapType kontrolünde kullanılabilen harita türlerini seçmek için kullanılır.

Harita türü kayıt defterinden doğrudan okuma yapmazsınız. Bunun yerine, özel harita türleri ekleyip bunları seçtiğiniz bir dize tanımlayıcıyla ilişkilendirerek kayıt defterini değiştirirsiniz. Temel harita türlerini değiştiremez veya değiştiremezsiniz (ancak haritanın ilişkili mapTypeControlOptions görünümünü değiştirerek bunları haritadan kaldırabilirsiniz).

Aşağıdaki kod, haritayı haritanın mapTypeControlOptions içinde yalnızca iki harita türü gösterecek şekilde ayarlar ve bu tanımlayıcıyla ilişkilendirmeyi MapType arayüzünün gerçek uygulamasına eklemek için kayıt defterini değiştirir.

// 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);

Stilli Haritalar

StyledMapType, standart Google temel haritalarının sunumunu özelleştirmenize olanak tanır. Böylece, varsayılan harita türünde kullanılan stilden farklı bir stili yansıtmak için yollar, parklar ve yerleşim alanları gibi öğelerin görsel görünümünü değiştirebilirsiniz. StyledMapType, yalnızca varsayılan roadmap harita türünü etkiler.

StyledMapType hakkında daha fazla bilgi için Yerleşik JSON stil bildirimlerini kullanma başlıklı makaleyi inceleyin.

Özel Harita Türleri

Maps JavaScript API, özel harita türlerinin görüntülenmesini ve yönetilmesini destekleyerek kendi harita görüntülerinizi veya karo yer paylaşımlarınızı uygulamanıza olanak tanır.

Maps JavaScript API'de birkaç olası harita türü uygulaması vardır:

  • Birlikte tam harita haritalarını oluşturan resimlerden oluşan standart karo kümeleri. Bu karo kümeleri, temel harita türleri olarak da bilinir. Bu harita türleri, mevcut varsayılan harita türleri gibi davranır: roadmap, satellite, hybrid ve terrain. Özel harita türünüzü bir haritanın mapTypes dizisine ekleyerek Maps JavaScript API'deki kullanıcı arayüzünün özel harita türünüzü standart bir harita türü olarak ele almasını (örneğin, MapType kontrolüne dahil ederek) sağlayabilirsiniz.
  • Mevcut temel harita türlerinin üzerinde gösterilen resim karosu yer paylaşımları. Genellikle bu harita türleri, ek bilgileri görüntülemek için mevcut bir harita türünü genişletmek amacıyla kullanılır ve genellikle belirli konumlar ve/veya yakınlaştırma seviyeleriyle sınırlıdır. Bu karoların şeffaf olabileceğini ve mevcut haritalara özellik eklemenize olanak tanıyabileceğini unutmayın.
  • Harita bilgisi görüntüsünü en temel düzeyde değiştirmenize olanak tanıyan, resim haritası olmayan türler.

Bu seçeneklerin her biri, MapType arayüzünü uygulayan bir sınıf oluşturmaya dayanır. Ayrıca ImageMapType sınıfı, resim haritası türlerinin oluşturulmasını basitleştirmek için bazı yerleşik davranışlar sağlar.

MapType Arayüzü

MapType uygulayan sınıflar oluşturmadan önce Google Haritalar'ın koordinatları nasıl belirlediğini ve haritanın hangi bölümlerini göstereceğine nasıl karar verdiğini anlamanız önemlidir. Herhangi bir temel veya yer paylaşımlı harita türü için benzer bir mantık uygulamanız gerekir. Harita ve parça koordinatları ile ilgili kılavuzu okuyun.

Özel harita türleri MapType arayüzünü uygulamalıdır. Bu arayüz, API'nin geçerli görüntü alanında ve yakınlaştırma seviyesinde harita parçaları göstermesi gerektiğini belirlediğinde harita türleriniz için istek başlatmasına olanak tanıyan belirli özellikleri ve yöntemleri belirtir. Hangi karonun yükleneceğine karar vermek için bu istekleri işlersiniz.

Not: Bu arayüzü uygulamak için kendi sınıfınızı oluşturabilirsiniz. Alternatif olarak, uyumlu görüntüleriniz varsa bu arayüzü zaten uygulayan ImageMapType sınıfını kullanabilirsiniz.

MapType arayüzünü uygulayan sınıflar, aşağıdaki özellikleri tanımlamanızı ve doldurmanızı gerektirir:

  • tileSize (zorunlu), karonun boyutunu belirtir (google.maps.Size türünde). Boyutlar dikdörtgen olmalıdır ancak kare olmaları gerekmez.
  • maxZoom (zorunlu), bu harita türünün parçalarının gösterileceği maksimum yakınlaştırma seviyesini belirtir.
  • minZoom (isteğe bağlı), bu harita türünün karosunun gösterileceği minimum yakınlaştırma seviyesini belirtir. Varsayılan olarak bu değer 0 olup minimum yakınlaştırma seviyesi olmadığını gösterir.
  • name (isteğe bağlı), bu harita türünün adını belirtir. Bu özellik yalnızca bu harita türünün bir MapType denetiminde seçilebilir olmasını istiyorsanız gereklidir. ( Kontrol Seçenekleri'ne bakın.)
  • alt (isteğe bağlı), bu harita türü için fareyle üzerine gelindiğinde gösterilen alternatif metni belirtir. Bu özellik yalnızca bu harita türünün bir MapType denetiminde seçilebilir olmasını istiyorsanız gereklidir. (Kontrol Seçenekleri'ne bakın.)

Ayrıca, MapType arayüzünü uygulayan sınıfların aşağıdaki yöntemleri uygulaması gerekir:

  • getTile() (gerekli), API haritanın belirli görüntü alanı için yeni karolar göstermesi gerektiğini belirlediğinde çağrılır. getTile() yönteminin aşağıdaki imzaya sahip olması gerekir:

    getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node

    API, MapType'nin tileSize, minZoom ve maxZoom özelliklerine ve haritanın mevcut görüntü alanına ve yakınlaştırma seviyesine göre getTile() işlevini çağırıp çağırmayacağını belirler. Bu yöntemin işleyicisi, karo resminin ekleneceği koordinat, yakınlaştırma seviyesi ve DOM öğesi verildiğinde bir HTML öğesi döndürmelidir.

  • releaseTile() (isteğe bağlı), API haritanın görünümden çıktığı için bir karoyu kaldırması gerektiğini belirlediğinde çağrılır. Bu yöntemin imzası aşağıdaki gibi olmalıdır:

    releaseTile(tile:Node)

    Genellikle, haritaya eklenirken harita karolarına eklenen tüm öğelerin kaldırılmasını yönetmeniz gerekir. Örneğin, harita karosu yer paylaşımlarına etkinlik işleyiciler eklediyseniz bunları burada kaldırmanız gerekir.

getTile() yöntemi, belirli bir görüntü alanına hangi karoların yükleneceğini belirleyen ana denetleyici olarak işlev görür.

Temel Harita Türleri

Bu şekilde oluşturduğunuz harita türleri tek başına kullanılabilir veya yer paylaşımları olarak diğer harita türleriyle birleştirilebilir. Bağımsız harita türleri, temel harita türleri olarak bilinir. API'nin bu tür özel MapType'leri diğer mevcut temel harita türleri (ROADMAP, TERRAIN vb.) gibi ele almasını isteyebilirsiniz. Bunu yapmak için özel MapType öğenizi Map öğesinin mapTypes özelliğine ekleyin. Bu mülk MapTypeRegistry türünde.

Aşağıdaki kod, bir haritanın parça koordinatlarını görüntülemek için temel bir MapType oluşturur ve parçaların ana hatlarını çizer:

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;
Örneği görüntüleyin

Yer Paylaşımlı Harita Türleri

Bazı harita türleri, mevcut harita türlerinin üzerinde çalışacak şekilde tasarlanmıştır. Bu tür harita türlerinde, önemli yerleri gösteren veya kullanıcıya ek veriler gösteren şeffaf katmanlar olabilir.

Bu durumlarda, harita türünün ayrı bir öğe olarak değil, yer paylaşımı olarak değerlendirilmesini istersiniz. Bunu yapmak için harita türünü doğrudan Map öğesinin overlayMapTypes özelliğini kullanarak mevcut bir MapType öğesine ekleyebilirsiniz. Bu özellik, MapType öğelerinden oluşan bir MVCArray içerir. Tüm harita türleri (temel ve yer paylaşımlı) mapPane katmanında oluşturulur. Yer paylaşımlı harita türleri, bağlı oldukları temel haritanın üstünde, Map.overlayMapTypes dizisinde göründükleri sırayla gösterilir (daha yüksek dizin değerlerine sahip yer paylaşımları, daha düşük dizin değerlerine sahip yer paylaşımlarının önünde gösterilir).

Aşağıdaki örnek, ROADMAP harita türünün üzerine bir karo yer paylaşımı MapType oluşturmamız dışında önceki örnekle aynıdır:

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;
Örneği görüntüleyin

Resim Haritası Türleri

Temel harita türü olarak kullanılacak bir MapType uygulamak, zaman alıcı ve zahmetli bir görev olabilir. API, en yaygın harita türleri için MapType arayüzünü uygulayan özel bir sınıf sağlar: tek resim dosyalarından oluşan karoların kullanıldığı harita türleri.

Bu sınıf (ImageMapType sınıfı), aşağıdaki zorunlu özellikleri tanımlayan bir ImageMapTypeOptions nesne spesifikasyonu kullanılarak oluşturulur:

  • tileSize (zorunlu), karonun boyutunu belirtir (google.maps.Size türünde). Boyutlar dikdörtgen olmalıdır ancak kare olmaları gerekmez.
  • getTileUrl (zorunlu), sağlanan dünya koordinatlarına ve yakınlaştırma seviyesine göre uygun resim karosunun seçimini işlemek için genellikle satır içi işlev değişmezi olarak sağlanan işlevi belirtir.

Aşağıdaki kod, Google'ın ay karolarını kullanarak temel bir ImageMapType uygular. Örnekte, karoların haritanızın x ekseni boyunca tekrarlanmasını ancak y ekseni boyunca tekrarlanmamasını sağlamak için bir normalleştirme işlevi kullanılır.

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;
Örneği görüntüleyin

Tahminler

Dünya (yaklaşık olarak) üç boyutlu bir küre, harita ise düz iki boyutlu bir yüzeydir. Maps JavaScript API'de gördüğünüz harita, Dünya'nın tüm düz haritaları gibi, bu kürenin düz bir yüzeye iz düşümüdür. En basit ifadeyle projeksiyon, enlem/boylam değerlerinin projeksiyon haritasındaki koordinatlarla eşlenmesi olarak tanımlanabilir.

Maps JavaScript API'deki projeksiyonlar Projection arayüzünü uygulamalıdır. Projection uygulamasının yalnızca bir koordinat sisteminden diğerine eşleme değil, iki yönlü eşleme sağlaması gerekir. Yani, Dünya koordinatlarından (LatLng nesneleri) Projection sınıfının dünya koordinat sistemine ve dünya koordinat sisteminden tekrar Dünya koordinatlarına nasıl çeviri yapılacağını tanımlamanız gerekir. Google Haritalar, coğrafi verilerden haritalarını oluşturmak ve haritadaki etkinlikleri coğrafi koordinatlara dönüştürmek için Mercator projeksiyonunu kullanır. Bu projeksiyonu, Map (veya standart temel MapType türlerinden herhangi biri) üzerinde getProjection() yöntemini çağırarak elde edebilirsiniz. Çoğu kullanım için bu standart Projection yeterli olacaktır ancak kendi özel projeksiyonlarınızı da tanımlayıp kullanabilirsiniz.

Tahmin uygulama

Özel bir projeksiyon uygularken birkaç şeyi tanımlamanız gerekir:

  • Enlem ve boylam koordinatlarını kartezyen düzleme eşleme formülleri ve kartezyen düzlemden enlem ve boylam koordinatlarına eşleme için karşılık gelen formüller. (Projection arayüzü yalnızca doğrusal koordinatlara dönüşümleri destekler.)
  • Temel karo boyutu. Tüm karolar dikdörtgen olmalıdır.
  • 0 yakınlaştırma seviyesinde temel karo kümesini kullanan bir haritanın "dünya boyutu". 0 yakınlaştırma düzeyinde bir karodan oluşan haritalar için dünya boyutunun ve temel karo boyutunun aynı olduğunu unutmayın.

Projeksiyonlarda Koordinat Dönüşümleri

Her projeksiyon, bu iki koordinat sistemi arasında çeviri yapan iki yöntem sunar. Bu yöntemler, coğrafi koordinatlar ile dünya koordinatları arasında dönüşüm yapmanıza olanak tanır:

  • Projection.fromLatLngToPoint() yöntemi, LatLng değerini dünya koordinatına dönüştürür. Bu yöntem, yer paylaşımlarını harita üzerinde konumlandırmak (ve haritanın kendisini konumlandırmak) için kullanılır.
  • Projection.fromPointToLatLng() yöntemi, dünya koordinatını LatLng değerine dönüştürür. Bu yöntem, haritada gerçekleşen tıklamalar gibi etkinlikleri coğrafi koordinatlara dönüştürmek için kullanılır.

Google Haritalar, projeksiyonların doğrusal olduğunu varsayar.

Genellikle iki durumda projeksiyon kullanabilirsiniz: dünya haritası oluşturmak veya yerel bir bölgenin haritasını oluşturmak. İlk durumda, projeksiyonunuzun tüm boylamlarda doğrusal ve normal olduğundan emin olmanız gerekir. Bazı projeksiyonlar (özellikle konik projeksiyonlar) "yerel olarak normal" (yani kuzeyi gösteren) olabilir ancak gerçek kuzeyden sapabilir. Örneğin, harita bir referans boylamına göre ne kadar uzağa konumlandırılırsa sapma o kadar fazla olur. Bu tür bir projeksiyonu yerel olarak kullanabilirsiniz ancak projeksiyonun mutlaka kesin olmadığını ve referans boylamdan ne kadar uzaklaşırsanız dönüşüm hatalarının o kadar belirgin hale geleceğini unutmayın.

Projeksiyonlarda Harita Karosu Seçimi

Projeksiyonlar yalnızca konumların veya yer paylaşımlarının konumlarını belirlemek için değil, harita karolarını konumlandırmak için de kullanışlıdır. Maps JavaScript API, temel haritaları MapType arayüzünü kullanarak oluşturur. Bu arayüz, haritanın projeksiyonunu tanımlamak için projection mülkünü ve parça koordinatı değerlerine göre harita parçalarını almak için getTile() yöntemini beyan etmelidir. Parça koordinatları, hem temel parça boyutunuza (dikdörtgen olmalıdır) hem de haritanızın "dünya boyutuna" (harita dünyanızın 0 yakınlaştırma seviyesindeki piksel boyutu) göre belirlenir. (0 yakınlaştırma düzeyinde bir karodan oluşan haritalar için karo boyutu ve dünya boyutu aynıdır.)

Temel karo boyutunu MapType öğenizin tileSize özelliğinde tanımlarsınız. Dünya boyutunu, projeksiyonunuzun fromLatLngToPoint() ve fromPointToLatLng() yöntemlerinde dolaylı olarak tanımlarsınız.

Resim seçimi bu iletilen değerlere bağlı olduğundan, bu iletilen değerler göz önüne alındığında programatik olarak seçilebilecek resimleri adlandırmak (ör. map_zoom_tileX_tileY.png) faydalı olur.

Aşağıdaki örnekte, Gall-Peters projeksiyonu kullanılarak bir ImageMapType tanımlanmaktadır:

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();
Örneği görüntüleyin