Google Haritalar Platformu (JavaScript) ile basit bir mağaza bulma aracı oluşturma

1. Başlamadan önce

Bir web sitesinin en yaygın özelliklerinden biri, bir işletme, kuruluş veya fiziksel varlığı olan başka bir tüzel kişiye ait bir veya daha fazla konumu vurgulayan bir Google Haritası göstermesidir. Bu haritaların uygulanma şekli, konum sayısı ve bunların değişme sıklığı gibi koşullara bağlı olarak büyük ölçüde değişebilir.

Bu codelab'de en basit kullanım alanına (bir mağazalar zincirine sahip işletmenin mağaza bulucusu gibi, nadiren değişen az sayıda konum) bakacaksınız. Bu durumda, sunucu tarafı programlama gerektirmeyen, nispeten düşük teknolojili bir yaklaşım kullanabilirsiniz. Ancak bu, yaratıcı olamayacağınız anlamına gelmez. Haritanızdaki her mağaza hakkında rastgele bilgileri depolamak ve oluşturmak için GeoJSON veri biçiminden yararlanarak ve işaretçileri ve haritanın genel stilini özelleştirerek yaratıcı olabilirsiniz.

Son olarak, ek bir avantaj olarak mağaza bulucunuzu geliştirmek ve barındırmak için Cloud Shell'i kullanırsınız. Bu aracı kullanmak zorunlu olmasa da bu sayede, web tarayıcısı çalıştıran herhangi bir cihazdan mağaza bulucuyu geliştirebilir ve herkese açık olarak internette kullanıma sunabilirsiniz.

489628918395c3d0.png

Ön koşullar

  • HTML ve JavaScript hakkında temel bilgi

Yapacaklarınız

  • GeoJSON biçiminde depolanan bir dizi mağaza konumu ve bilgisi içeren bir harita görüntüleyin.
  • İşaretçileri ve haritanın kendisini özelleştirin.
  • İşaretçisi tıklandığında mağaza hakkında ek bilgiler gösterin.
  • Web sayfasına yer otomatik tamamlama arama çubuğu ekleyin.
  • Kullanıcı tarafından sağlanan başlangıç noktasına en yakın mağaza konumunu belirleyin.

2. Hazırlanın

Aşağıdaki bölümün 3. adımında bu codelab için aşağıdaki üç API'yi etkinleştirin:

  • Maps JavaScript API
  • Places API
  • Distance Matrix API

Google Haritalar Platformu'nu kullanmaya başlayın

Google Haritalar Platformu'nu daha önce kullanmadıysanız aşağıdaki adımları tamamlamak için Google Haritalar Platformu'nu Kullanmaya Başlama Kılavuzu'nu inceleyin veya Google Haritalar Platformu'nu Kullanmaya Başlama oynatma listesini izleyin:

  1. Faturalandırma hesabı oluşturun.
  2. Proje oluşturun.
  3. Google Haritalar Platformu API'lerini ve SDK'larını (önceki bölümde listelenmiştir) etkinleştirin.
  4. API anahtarı oluşturun.

Cloud Shell'i etkinleştirme

Bu codelab'de, projenizi tamamen web tarayıcınızdan barındırıp çalıştırabilmeniz için Google Cloud'da çalışan ve Google Cloud'da çalışan ürünlere ve kaynaklara erişim sağlayan bir komut satırı ortamı olan Cloud Shell'i kullanacaksınız.

Cloud Shell'i Cloud Console'dan etkinleştirmek için Cloud Shell'i etkinleştir 'i 89665d8d348105cd.png tıklayın (ortamın sağlanması ve bağlantının kurulması yalnızca birkaç saniye sürer).

5f504766b9b3be17.png

Bu işlem, muhtemelen bir tanıtım geçiş reklamı gösterdikten sonra tarayıcınızın alt kısmında yeni bir kabuk açar.

d3bb67d514893d1f.png

Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin, kurulum sırasında seçtiğiniz proje kimliğine ayarlandığını görürsünüz.

$ gcloud auth list
Credentialed Accounts:
ACTIVE  ACCOUNT
  *     <myaccount>@<mydomain>.com
$ gcloud config list project
[core]
project = <YOUR_PROJECT_ID>

Herhangi bir nedenle proje ayarlanmamışsa aşağıdaki komutu çalıştırın:

$ gcloud config set project <YOUR_PROJECT_ID>

3. Haritalı "Hello, World!"

Harita ile geliştirmeye başlama

Cloud Shell'de, codelab'in geri kalanında temel olarak kullanılacak bir HTML sayfası oluşturarak başlayın.

  1. Yeni bir sekmede kod düzenleyiciyi açmak için Cloud Shell araç çubuğunda Launch Editor 'ı (Düzenleyiciyi Başlat) 996514928389de40.png tıklayın.

Bu web tabanlı kod düzenleyici, Cloud Shell'deki dosyaları kolayca düzenlemenize olanak tanır.

Screen Shot 2017-04-19 at 10.22.48 AM.png

  1. Dosya > Yeni Klasör'ü tıklayarak kod düzenleyicide uygulamanız için yeni bir store-locator dizini oluşturun.

NewFolder.png

  1. Yeni klasörü store-locator olarak adlandırın.

Ardından, harita içeren bir web sayfası oluşturursunuz.

  1. store-locator dizininde index.html adlı bir dosya oluşturun.

3c257603da5ab524.png

  1. index.html dosyasına aşağıdaki içeriği ekleyin:

index.html

<html>

<head>
    <title>Store Locator</title>
    <style>
        #map {
            height: 100%;
        }
        
        html,
        body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <!-- The div to hold the map -->
    <div id="map"></div>

    <script src="app.js"></script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap&solution_channel=GMP_codelabs_simplestorelocator_v1_a">
    </script>
</body>

</html>

Bu, haritayı gösteren HTML sayfasıdır. Haritanın görsel olarak sayfanın tamamını kaplamasını sağlamak için bazı CSS'ler, haritayı tutmak için bir <div> etiketi ve bir çift <script> etiketi içerir. İlk komut dosyası etiketi, tüm JavaScript kodunu içeren app.js adlı bir JavaScript dosyasını yükler. İkinci komut dosyası etiketi, API anahtarını yükler, daha sonra ekleyeceğiniz otomatik tamamlama işlevi için Places Kitaplığı'nın kullanımını içerir ve Maps JavaScript API yüklendikten sonra çalıştırılan JavaScript işlevinin adını (initMap) belirtir.

  1. Kod snippet'indeki YOUR_API_KEY metnini, bu codelab'de daha önce oluşturduğunuz API anahtarıyla değiştirin.
  2. Son olarak, aşağıdaki kodu kullanarak app.js adlı başka bir dosya oluşturun:

app.js

function initMap() {
   // Create the map.
    const map = new google.maps.Map(document.getElementById('map'), {
        zoom: 7,
        center: { lat: 52.632469, lng: -1.689423 },
    });

}

Bu, harita oluşturmak için gereken minimum koddur. Haritayı tutmak için <div> etiketinize bir referans iletir ve merkezi ile yakınlaştırma düzeyini belirtirsiniz.

Bu uygulamayı test etmek için Cloud Shell'de basit Python HTTP sunucusunu çalıştırabilirsiniz.

  1. Cloud Shell'e gidip aşağıdakileri yazın:
$ cd store-locator
$ python3 -m http.server 8080

Günlük çıktısında, web uygulaması localhost bağlantı noktası 8080'de dinlerken Cloud Shell'de basit HTTP sunucusunu gerçekten çalıştırdığınızı gösteren bazı satırlar görürsünüz.

  1. Cloud Console araç çubuğunda Web Önizlemesi'ni tıklayıp 8080 bağlantı noktasında önizle'yi seçerek bu uygulamada bir web tarayıcı sekmesi açın.95e419ae763a1d48.png

47b06e5169eb5add.png

bdab1f021a3b91d5.png

Bu menü öğesini tıkladığınızda, basit Python HTTP sunucusundan sunulan HTML içeriğiyle birlikte web tarayıcınızda yeni bir sekme açılır. Her şey yolunda gittiyse İngiltere'nin Londra şehrini merkezine alan bir harita görmeniz gerekir.

Basit HTTP sunucusunu durdurmak için Cloud Shell'de Control+C tuşuna basın.

4. Haritayı GeoJSON ile doldurma

Şimdi de mağazaların verilerine göz atın. GeoJSON, haritada noktalar, çizgiler veya poligonlar gibi basit coğrafi özellikleri temsil eden bir veri biçimidir. Özellikler rastgele veriler de içerebilir. Bu nedenle GeoJSON, mağazaları temsil etmek için mükemmel bir adaydır. Mağazalar, temelde mağaza adı, çalışma saatleri ve telefon numarası gibi ek veriler içeren bir harita üzerindeki noktalardır. En önemlisi, GeoJSON'un Google Haritalar'da birinci sınıf desteği vardır. Bu nedenle, bir GeoJSON dokümanını Google Haritası'na gönderebilirsiniz ve bu doküman haritada uygun şekilde oluşturulur.

  1. stores.json adlı yeni bir dosya oluşturun ve aşağıdaki kodu yapıştırın:

stores.json

{
    "type": "FeatureCollection",
    "features": [{
            "geometry": {
                "type": "Point",
                "coordinates": [-0.1428115,
                    51.5125168
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "patisserie",
                "hours": "10am - 6pm",
                "description": "Modern twists on classic pastries. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Patisserie Mayfair",
                "phone": "+44 20 1234 5678",
                "storeid": "01"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-2.579623,
                    51.452251
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "patisserie",
                "hours": "10am - 6pm",
                "description": "Come and try our award-winning cakes and pastries. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Patisserie Bristol",
                "phone": "+44 117 121 2121",
                "storeid": "02"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [
                    1.273459,
                    52.638072
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "patisserie",
                "hours": "10am - 6pm",
                "description": "Whatever the occasion, whether it's a birthday or a wedding, Josie's Patisserie has the perfect treat for you. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Patisserie Norwich",
                "phone": "+44 1603 123456",
                "storeid": "03"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-1.9912838,
                    50.8000418
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "patisserie",
                "hours": "10am - 6pm",
                "description": "A gourmet patisserie that will delight your senses. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Patisserie Wimborne",
                "phone": "+44 1202 343434",
                "storeid": "04"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-2.985933,
                    53.408899
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "patisserie",
                "hours": "10am - 6pm",
                "description": "Spoil yourself or someone special with our classic pastries. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Patisserie Liverpool",
                "phone": "+44 151 444 4444",
                "storeid": "05"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-1.689423,
                    52.632469
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "patisserie",
                "hours": "10am - 6pm",
                "description": "Come and feast your eyes and tastebuds on our delicious pastries and cakes. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Patisserie Tamworth",
                "phone": "+44 5555 55555",
                "storeid": "06"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-3.155305,
                    51.479756
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "patisserie",
                "hours": "10am - 6pm",
                "description": "Josie's Patisserie is family-owned, and our delectable pastries, cakes, and great coffee are renowed. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Patisserie Cardiff",
                "phone": "+44 29 6666 6666",
                "storeid": "07"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-0.725019,
                    52.668891
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "cafe",
                "hours": "8am - 9:30pm",
                "description": "Oakham's favorite spot for fresh coffee and delicious cakes. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Cafe Oakham",
                "phone": "+44 7777 777777",
                "storeid": "08"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-2.477653,
                    53.735405
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "cafe",
                "hours": "8am - 9:30pm",
                "description": "Enjoy freshly brewed coffe, and home baked cakes in our homely cafe. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Cafe Blackburn",
                "phone": "+44 8888 88888",
                "storeid": "09"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-0.211363,
                    51.108966
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "cafe",
                "hours": "8am - 9:30pm",
                "description": "A delicious array of pastries with many flavours, and fresh coffee in an snug cafe. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Cafe Crawley",
                "phone": "+44 1010 101010",
                "storeid": "10"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-0.123559,
                    50.832679
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "cafe",
                "hours": "8am - 9:30pm",
                "description": "Grab a freshly brewed coffee, a decadent cake and relax in our idyllic cafe. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Cafe Brighton",
                "phone": "+44 1313 131313",
                "storeid": "11"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [-3.319575,
                    52.517827
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "cafe",
                "hours": "8am - 9:30pm",
                "description": "Come in and unwind at this idyllic cafe with fresh coffee and home made cakes. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Cafe Newtown",
                "phone": "+44 1414 141414",
                "storeid": "12"
            }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [
                    1.158167,
                    52.071634
                ]
            },
            "type": "Feature",
            "properties": {
                "category": "cafe",
                "hours": "8am - 9:30pm",
                "description": "Fresh coffee and delicious cakes in an snug cafe. We're part of a larger chain of patisseries and cafes.",
                "name": "Josie's Cafe Ipswich",
                "phone": "+44 1717 17171",
                "storeid": "13"
            }
        }
    ]
}

Bu çok fazla veri olsa da incelediğinizde her mağaza için aynı yapının tekrarlandığını görürsünüz. Her mağaza, koordinatları ve properties anahtarı altında bulunan ek verilerle birlikte bir GeoJSON Point olarak gösterilir. İlginç bir şekilde, GeoJSON, properties anahtarı altında rastgele adlandırılmış anahtarların eklenmesine izin verir. Bu codelab'de bu anahtarlar category, hours, description, name ve phone'dir.

  1. Şimdi app.js dosyasını, stores.js içindeki GeoJSON'u haritanıza yükleyecek şekilde düzenleyin.

app.js

function initMap() {
  // Create the map.
  const map = new google.maps.Map(document.getElementById('map'), {
    zoom: 7,
    center: {lat: 52.632469, lng: -1.689423},
  });

  // Load the stores GeoJSON onto the map.
  map.data.loadGeoJson('stores.json', {idPropertyName: 'storeid'});

  const apiKey = 'YOUR_API_KEY';
  const infoWindow = new google.maps.InfoWindow();

  // Show the information for a store when its marker is clicked.
  map.data.addListener('click', (event) => {
    const category = event.feature.getProperty('category');
    const name = event.feature.getProperty('name');
    const description = event.feature.getProperty('description');
    const hours = event.feature.getProperty('hours');
    const phone = event.feature.getProperty('phone');
    const position = event.feature.getGeometry().get();
    const content = `
      <h2>${name}</h2><p>${description}</p>
      <p><b>Open:</b> ${hours}<br/><b>Phone:</b> ${phone}</p>
    `;

    infoWindow.setContent(content);
    infoWindow.setPosition(position);
    infoWindow.setOptions({pixelOffset: new google.maps.Size(0, -30)});
    infoWindow.open(map);
  });
}

Kod örneğinde, loadGeoJson işlevini çağırıp JSON dosyasının adını ileterek GeoJSON'unuzu haritaya yüklediniz. Ayrıca, bir işaretçi her tıklandığında çalışacak bir işlev de tanımladınız. Ardından işlev, işaretçisi tıklanan mağazanın ek verilerine erişebilir ve bilgileri gösterilen bir bilgi penceresinde kullanabilir. Bu uygulamayı test etmek için basit Python HTTP sunucusunu daha önce kullandığınız komutla çalıştırabilirsiniz.

  1. Cloud Shell'e dönün ve aşağıdakileri yazın:
$ python3 -m http.server 8080
  1. Web Önizlemesi95e419ae763a1d48.png > 8080 numaralı bağlantı noktasında önizle'yi tekrar tıkladığınızda, her mağazayla ilgili ayrıntıları görüntülemek için tıklayabileceğiniz işaretlerle dolu bir harita görürsünüz. İlerleme durumu

c4507f7d3ea18439.png

5. Haritayı özelleştirme

Neredeyse tamamlandı. Tüm mağaza işaretçilerinizin bulunduğu ve tıklandığında ek bilgilerin gösterildiği bir haritanız olur. Ancak diğer tüm Google Haritalar gibi görünüyor. Ne kadar sıkıcı! Özel harita stili, işaretçiler, logolar ve Street View görüntüleriyle daha ilgi çekici hale getirin.

Özel stil eklenmiş yeni bir app.js sürümünü aşağıda bulabilirsiniz:

app.js

const mapStyle = [{
  'featureType': 'administrative',
  'elementType': 'all',
  'stylers': [{
    'visibility': 'on',
  },
  {
    'lightness': 33,
  },
  ],
},
{
  'featureType': 'landscape',
  'elementType': 'all',
  'stylers': [{
    'color': '#f2e5d4',
  }],
},
{
  'featureType': 'poi.park',
  'elementType': 'geometry',
  'stylers': [{
    'color': '#c5dac6',
  }],
},
{
  'featureType': 'poi.park',
  'elementType': 'labels',
  'stylers': [{
    'visibility': 'on',
  },
  {
    'lightness': 20,
  },
  ],
},
{
  'featureType': 'road',
  'elementType': 'all',
  'stylers': [{
    'lightness': 20,
  }],
},
{
  'featureType': 'road.highway',
  'elementType': 'geometry',
  'stylers': [{
    'color': '#c5c6c6',
  }],
},
{
  'featureType': 'road.arterial',
  'elementType': 'geometry',
  'stylers': [{
    'color': '#e4d7c6',
  }],
},
{
  'featureType': 'road.local',
  'elementType': 'geometry',
  'stylers': [{
    'color': '#fbfaf7',
  }],
},
{
  'featureType': 'water',
  'elementType': 'all',
  'stylers': [{
    'visibility': 'on',
  },
  {
    'color': '#acbcc9',
  },
  ],
},
];

function initMap() {
  // Create the map.
  const map = new google.maps.Map(document.getElementById('map'), {
    zoom: 7,
    center: {lat: 52.632469, lng: -1.689423},
    styles: mapStyle,
  });

  // Load the stores GeoJSON onto the map.
  map.data.loadGeoJson('stores.json', {idPropertyName: 'storeid'});

  // Define the custom marker icons, using the store's "category".
  map.data.setStyle((feature) => {
    return {
      icon: {
        url: `img/icon_${feature.getProperty('category')}.png`,
        scaledSize: new google.maps.Size(64, 64),
      },
    };
  });

  const apiKey = 'YOUR_API_KEY';
  const infoWindow = new google.maps.InfoWindow();

  // Show the information for a store when its marker is clicked.
  map.data.addListener('click', (event) => {
    const category = event.feature.getProperty('category');
    const name = event.feature.getProperty('name');
    const description = event.feature.getProperty('description');
    const hours = event.feature.getProperty('hours');
    const phone = event.feature.getProperty('phone');
    const position = event.feature.getGeometry().get();
    const content = `
      <img style="float:left; width:200px; margin-top:30px" src="img/logo_${category}.png">
      <div style="margin-left:220px; margin-bottom:20px;">
        <h2>${name}</h2><p>${description}</p>
        <p><b>Open:</b> ${hours}<br/><b>Phone:</b> ${phone}</p>
        <p><img src="https://maps.googleapis.com/maps/api/streetview?size=350x120&location=${position.lat()},${position.lng()}&key=${apiKey}&solution_channel=GMP_codelabs_simplestorelocator_v1_a"></p>
      </div>
      `;

    infoWindow.setContent(content);
    infoWindow.setPosition(position);
    infoWindow.setOptions({pixelOffset: new google.maps.Size(0, -30)});
    infoWindow.open(map);
  });

}

Ekledikleriniz:

  • mapStyle değişkeni, haritayı stilize etmeyle ilgili tüm bilgileri içerir. (İsterseniz kendi stilinizi de oluşturabilirsiniz.)
  • map.data.setStyle yöntemini kullanarak özel işaretçiler uyguladınız. GeoJSON'daki her category için farklı bir işaretçi kullandınız.
  • content değişkenini, bir logo (GeoJSON'daki category kullanılarak) ve mağazanın konumuna ait bir Street View görüntüsü içerecek şekilde değiştirdiniz.

Bu özelliği dağıtmadan önce birkaç adımı tamamlamanız gerekir:

  1. apiKey değişkeni için doğru değeri ayarlamak üzere app.js içindeki 'YOUR_API_KEY' dizesini daha önce kullandığınız API anahtarınızla (tırnak işaretlerini değiştirmeden index.html içine yapıştırdığınız anahtarla) değiştirin.
  2. İşaretçi ve logo grafiklerini indirmek için Cloud Shell'de aşağıdaki komutları çalıştırın. store-locator dizininde olduğunuzdan emin olun. Basit HTTP sunucusu çalışıyorsa durdurmak için Control+C tuşuna basın.
$ mkdir -p img; cd img
$ wget https://github.com/googlecodelabs/google-maps-simple-store-locator/raw/master/src/img/icon_cafe.png
$ wget https://github.com/googlecodelabs/google-maps-simple-store-locator/raw/master/src/img/icon_patisserie.png
$ wget https://github.com/googlecodelabs/google-maps-simple-store-locator/raw/master/src/img/logo_cafe.png
$ wget https://github.com/googlecodelabs/google-maps-simple-store-locator/raw/master/src/img/logo_patisserie.png
  1. Aşağıdaki komutu çalıştırarak tamamlanmış mağaza bulucuyu önizleyin:
$ python3 -m http.server 8080

Önizlemeyi yeniden yüklediğinizde, özel stil, özel işaretçi resimleri, geliştirilmiş bilgi penceresi biçimlendirmesi ve her konum için bir Street View resmi içeren aşağıdaki gibi bir harita görmeniz gerekir:

3d8d13da126021dd.png

6. Kullanıcı girişi alma

Mağaza bulucuları kullananlar genellikle kendilerine en yakın mağazayı veya yolculuklarına başlamayı planladıkları adresi öğrenmek ister. Kullanıcının başlangıç adresini kolayca girmesine olanak tanımak için otomatik yer tamamlama özelliğine sahip bir arama çubuğu ekleyin. Place Autocomplete, diğer Google arama çubuklarındaki otomatik tamamlama işlevine benzer bir önden yazma işlevi sunar. Ancak tahminler, Google Haritalar Platformu'ndaki tüm yerlerdir.

  1. Otomatik tamamlama arama çubuğu ve ilişkili sonuç yan paneli için stil eklemek üzere index.html düzenleme işlemine geri dönün. Eski kodunuzun üzerine yapıştırdıysanız API anahtarınızı değiştirmeyi unutmayın.

index.html

<html>

<head>
  <title>Store Locator</title>
  <style>
    #map {
      height: 100%;
    }
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }

    /* Styling for Autocomplete search bar */
    #pac-card {
      background-color: #fff;
      border-radius: 2px 0 0 2px;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
      box-sizing: border-box;
      font-family: Roboto;
      margin: 10px 10px 0 0;
      -moz-box-sizing: border-box;
      outline: none;
    }
    
    #pac-container {
      padding-top: 12px;
      padding-bottom: 12px;
      margin-right: 12px;
    }
    
    #pac-input {
      background-color: #fff;
      font-family: Roboto;
      font-size: 15px;
      font-weight: 300;
      margin-left: 12px;
      padding: 0 11px 0 13px;
      text-overflow: ellipsis;
      width: 400px;
    }
    
    #pac-input:focus {
      border-color: #4d90fe;
    }
    
    #title {
      color: #fff;
      background-color: #acbcc9;
      font-size: 18px;
      font-weight: 400;
      padding: 6px 12px;
    }
    
    .hidden {
      display: none;
    }

    /* Styling for an info pane that slides out from the left. 
     * Hidden by default. */
    #panel {
      height: 100%;
      width: null;
      background-color: white;
      position: fixed;
      z-index: 1;
      overflow-x: hidden;
      transition: all .2s ease-out;
    }
    
    .open {
      width: 250px;
    }
    
    .place {
      font-family: 'open sans', arial, sans-serif;
      font-size: 1.2em;
      font-weight: 500;
      margin-block-end: 0px;
      padding-left: 18px;
      padding-right: 18px;
    }
    
    .distanceText {
      color: silver;
      font-family: 'open sans', arial, sans-serif;
      font-size: 1em;
      font-weight: 400;
      margin-block-start: 0.25em;
      padding-left: 18px;
      padding-right: 18px;
    }
  </style>
</head>

<body>
  <!-- The div to hold the map -->
  <div id="map"></div>

  <script src="app.js"></script>
  <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap&solution_channel=GMP_codelabs_simplestorelocator_v1_a">
  </script>
</body>

</html>

Hem otomatik tamamlama arama çubuğu hem de açılır panel, ihtiyaç duyulana kadar gizlidir.

  1. Şimdi, app.js içindeki initMap işlevinin sonuna, kapatma küme parantezinden hemen önce otomatik tamamlama widget'ını haritaya ekleyin.

app.js

  // Build and add the search bar
  const card = document.createElement('div');
  const titleBar = document.createElement('div');
  const title = document.createElement('div');
  const container = document.createElement('div');
  const input = document.createElement('input');
  const options = {
    types: ['address'],
    componentRestrictions: {country: 'gb'},
  };

  card.setAttribute('id', 'pac-card');
  title.setAttribute('id', 'title');
  title.textContent = 'Find the nearest store';
  titleBar.appendChild(title);
  container.setAttribute('id', 'pac-container');
  input.setAttribute('id', 'pac-input');
  input.setAttribute('type', 'text');
  input.setAttribute('placeholder', 'Enter an address');
  container.appendChild(input);
  card.appendChild(titleBar);
  card.appendChild(container);
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);

  // Make the search bar into a Places Autocomplete search bar and select
  // which detail fields should be returned about the place that
  // the user selects from the suggestions.
  const autocomplete = new google.maps.places.Autocomplete(input, options);

  autocomplete.setFields(
      ['address_components', 'geometry', 'name']);

Kod, otomatik tamamlama önerilerini yalnızca adres döndürecek şekilde kısıtlar (çünkü yer otomatik tamamlama, kuruluş adları ve idari konumlarla eşleşebilir) ve döndürülen adresleri yalnızca Birleşik Krallık'taki adreslerle sınırlar. Bu isteğe bağlı özellikleri eklemek, kullanıcının aradığı adresi göstermek için tahminleri daraltmak üzere girmesi gereken karakter sayısını azaltır. Ardından, oluşturduğunuz otomatik tamamlama div öğesini haritanın sağ üst köşesine taşır ve yanıtta her yerle ilgili hangi alanların döndürülmesi gerektiğini belirtir.

  1. Aşağıdaki komutu çalıştırarak sunucunuzu yeniden başlatın ve önizlemenizi yenileyin:
$ python3 -m http.server 8080

Artık haritanızın sağ üst köşesinde, yazdıklarınızla eşleşen Birleşik Krallık adreslerini gösteren bir otomatik tamamlama widget'ı görmelisiniz.

5163f34a03910187.png

Şimdi, kullanıcının otomatik tamamlama widget'ından bir tahmin seçtiği durumu ele almanız ve bu konumu mağazalarınıza olan mesafeleri hesaplamak için temel olarak kullanmanız gerekir.

  1. Yeni yapıştırdığınız kodun ardından app.js içindeki initMap bölümünün sonuna aşağıdaki kodu ekleyin.

app.js

 // Set the origin point when the user selects an address
  const originMarker = new google.maps.Marker({map: map});
  originMarker.setVisible(false);
  let originLocation = map.getCenter();

  autocomplete.addListener('place_changed', async () => {
    originMarker.setVisible(false);
    originLocation = map.getCenter();
    const place = autocomplete.getPlace();

    if (!place.geometry) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      window.alert('No address available for input: \'' + place.name + '\'');
      return;
    }

    // Recenter the map to the selected address
    originLocation = place.geometry.location;
    map.setCenter(originLocation);
    map.setZoom(9);
    console.log(place);

    originMarker.setPosition(originLocation);
    originMarker.setVisible(true);

    // Use the selected address as the origin to calculate distances
    // to each of the store locations
    const rankedStores = await calculateDistances(map.data, originLocation);
    showStoresList(map.data, rankedStores);

    return;
  });

Kod, kullanıcı önerilerden birini tıkladığında haritanın seçilen adrese göre yeniden ortalanması ve mesafelerin hesaplanmasında başlangıç noktası olarak belirlenmesi için bir dinleyici ekler. Mesafe hesaplamalarını sonraki adımda uygulayacaksınız.

7. En yakın mağazaları listele

Directions API, Google Haritalar uygulamasında yol tarifi isteme deneyimine benzer şekilde çalışır. İki nokta arasındaki rotayı almak için tek bir başlangıç ve tek bir hedef girilir. Distance Matrix API, seyahat sürelerine ve mesafelere göre birden fazla olası başlangıç noktası ile birden fazla olası varış noktası arasındaki en uygun eşleşmeleri belirlemek için bu kavramı daha da ileriye taşır. Bu durumda, kullanıcının seçilen adrese en yakın mağazayı bulmasına yardımcı olmak için bir başlangıç noktası ve hedef olarak bir dizi mağaza konumu sağlarsınız.

  1. app.js'ya calculateDistances adlı yeni bir işlev ekleyin.

app.js

async function calculateDistances(data, origin) {
  const stores = [];
  const destinations = [];

  // Build parallel arrays for the store IDs and destinations
  data.forEach((store) => {
    const storeNum = store.getProperty('storeid');
    const storeLoc = store.getGeometry().get();

    stores.push(storeNum);
    destinations.push(storeLoc);
  });

  // Retrieve the distances of each store from the origin
  // The returned list will be in the same order as the destinations list
  const service = new google.maps.DistanceMatrixService();
  const getDistanceMatrix =
    (service, parameters) => new Promise((resolve, reject) => {
      service.getDistanceMatrix(parameters, (response, status) => {
        if (status != google.maps.DistanceMatrixStatus.OK) {
          reject(response);
        } else {
          const distances = [];
          const results = response.rows[0].elements;
          for (let j = 0; j < results.length; j++) {
            const element = results[j];
            const distanceText = element.distance.text;
            const distanceVal = element.distance.value;
            const distanceObject = {
              storeid: stores[j],
              distanceText: distanceText,
              distanceVal: distanceVal,
            };
            distances.push(distanceObject);
          }

          resolve(distances);
        }
      });
    });

  const distancesList = await getDistanceMatrix(service, {
    origins: [origin],
    destinations: destinations,
    travelMode: 'DRIVING',
    unitSystem: google.maps.UnitSystem.METRIC,
  });

  distancesList.sort((first, second) => {
    return first.distanceVal - second.distanceVal;
  });

  return distancesList;
}

İşlev, kendisine tek bir başlangıç noktası olarak iletilen başlangıç noktasını ve mağaza konumlarını hedef dizisi olarak kullanarak Distance Matrix API'yi çağırır. Ardından, mağazanın kimliğini, kullanıcıların okuyabileceği bir dize olarak ifade edilen mesafeyi, sayısal değer olarak metre cinsinden mesafeyi depolayan bir nesne dizisi oluşturur ve diziyi sıralar.

Kullanıcı, mağazaların en yakından en uzağa doğru sıralandığı bir liste görmeyi bekler. Mağazaların görüntülenme sırasını belirlemek için calculateDistances işlevinden döndürülen listeyi kullanarak her mağaza için bir yan panel girişi oluşturun.

  1. app.js'ya showStoresList adlı yeni bir işlev ekleyin.

app.js

function showStoresList(data, stores) {
  if (stores.length == 0) {
    console.log('empty stores');
    return;
  }

  let panel = document.createElement('div');
  // If the panel already exists, use it. Else, create it and add to the page.
  if (document.getElementById('panel')) {
    panel = document.getElementById('panel');
    // If panel is already open, close it
    if (panel.classList.contains('open')) {
      panel.classList.remove('open');
    }
  } else {
    panel.setAttribute('id', 'panel');
    const body = document.body;
    body.insertBefore(panel, body.childNodes[0]);
  }


  // Clear the previous details
  while (panel.lastChild) {
    panel.removeChild(panel.lastChild);
  }

  stores.forEach((store) => {
    // Add store details with text formatting
    const name = document.createElement('p');
    name.classList.add('place');
    const currentStore = data.getFeatureById(store.storeid);
    name.textContent = currentStore.getProperty('name');
    panel.appendChild(name);
    const distanceText = document.createElement('p');
    distanceText.classList.add('distanceText');
    distanceText.textContent = store.distanceText;
    panel.appendChild(distanceText);
  });

  // Open the panel
  panel.classList.add('open');

  return;
}
  1. Aşağıdaki komutu çalıştırarak sunucunuzu yeniden başlatın ve önizlemenizi yenileyin.
$ python3 -m http.server 8080
  1. Son olarak, otomatik tamamlama arama çubuğuna Birleşik Krallık adresi girin ve önerilerden birini tıklayın.

Harita, bu adresin merkezinde olmalı ve seçilen adrese olan uzaklığa göre mağaza konumlarının listelendiği bir kenar çubuğu görünmelidir. Bir örnek aşağıda gösterilmiştir:

489628918395c3d0.png

8. İsteğe bağlı: Web sayfanızı barındırın

Bu noktaya kadar, haritanızı yalnızca Python HTTP sunucunuzu etkin olarak çalıştırdığınızda görüntülüyorsunuz. Haritanızı etkin Cloud Shell oturumunuzun ötesinde görüntülemek veya haritanızın URL'sini başkalarıyla paylaşabilmek için web sayfanızı barındırmak üzere Cloud Storage'ı kullanmayı düşünebilirsiniz. Cloud Storage, Google'ın altyapısında veri depolamak ve verilere erişmek için kullanılan online bir dosya depolama web hizmetidir. Bu hizmet, Google Cloud'un performans ve ölçeklenebilirliğini gelişmiş güvenlik ve paylaşım özellikleriyle birleştirir. Ayrıca, basit mağaza bulucunuzu barındırmak için ideal olan bir ücretsiz katman da sunar.

Cloud Storage'da dosyalar, bilgisayarınızdaki dizinlere benzer şekilde paketlerde depolanır. Web sayfanızı barındırmak için önce bir paket oluşturmanız gerekir. Paketiniz için benzersiz bir ad seçmeniz gerekir. Örneğin, paket adının bir parçası olarak adınızı kullanabilirsiniz.

  1. Bir ad belirledikten sonra Cloud Shell'de aşağıdaki komutu çalıştırın:
$ gsutil mb gs://yourname-store-locator

gsutil, Cloud Storage ile etkileşim kurmak için kullanılan araçtır. mb komutu, yaratıcı bir şekilde "make bucket" (paket oluştur) anlamına gelir. Kullandıklarınız da dahil olmak üzere tüm komutlar hakkında daha fazla bilgi için gsutil aracı başlıklı makaleyi inceleyin.

Varsayılan olarak, Cloud Storage'da barındırılan paketleriniz ve dosyalarınız özeldir. Ancak mağaza bulucunuz için tüm dosyaların herkese açık olmasını istersiniz. Böylece bu dosyalara internet üzerinden herkes erişebilir. Yüklediğiniz her dosyayı herkese açık hâle getirebilirsiniz ancak bu işlem çok zaman alır. Bunun yerine, oluşturduğunuz paket için varsayılan erişim düzeyini ayarlayabilirsiniz. Pakete yüklediğiniz tüm dosyalar bu erişim düzeyini devralır.

  1. Aşağıdaki komutu çalıştırın ve yourname-store-locator kısmını paketiniz için seçtiğiniz adla değiştirin:
$ gsutil defacl ch -u AllUsers:R gs://yourname-store-locator
  1. Artık aşağıdaki komutla geçerli dizindeki tüm dosyalarınızı (şu anda yalnızca index.html ve app.js dosyalarınız) yükleyebilirsiniz:
$ gsutil -h "Cache-Control:no-cache" cp * gs://yourname-store-locator

Artık internette harita içeren bir web sayfanız olmalıdır. Görüntülemek için kullanılacak URL, http://storage.googleapis.com/yourname-store-locator/index.html olacaktır. Burada yourname-store-locator kısmı, daha önce seçtiğiniz paket adıyla değiştirilir.

Temizleme

Bu projede oluşturulan tüm kaynakları temizlemenin en kolay yolu, bu eğitimin başında oluşturduğunuz Google Cloud projesini kapatmaktır:

  • Cloud Console'da Ayarlar sayfasını açın.
  • Bir proje seçin'i tıklayın.
  • Bu eğitimin başında oluşturduğunuz projeyi seçin ve 'ı tıklayın.
  • Proje kimliğini girin ve Kapat'ı tıklayın.

9. Tebrikler

Tebrikler! Bu codelab'i tamamladınız.

Öğrendikleriniz

Daha fazla bilgi

Başka hangi codelab'leri görmek istersiniz?

Haritalarda veri görselleştirme Haritalarımın stilini özelleştirme hakkında daha fazla bilgi Haritalarda 3D etkileşimler için geliştirme

İstediğiniz codelab yukarıda listelenmiyor mu? Buradan yeni bir sorunla ilgili istekte bulunun.

Kodu daha ayrıntılı incelemek isterseniz https://github.com/googlecodelabs/google-maps-simple-store-locator adresindeki kaynak kodu deposuna göz atın.