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

1. Başlamadan önce

Web sitelerinin en yaygın özelliklerinden biri, fiziksel olarak var olan bir işletme, kuruluş veya başka bir tüzel kişinin bir ya da daha fazla konumunu öne çıkaran bir Google haritasıdır. Bu haritaların uygulanma biçimi, konum sayısı ve değişme sıklığı gibi şartlara bağlı olarak büyük farklılıklar gösterebilir.

Bu codelab'de, en basit kullanım örneğini görürsünüz. Nadiren değişen az sayıda konuma (ör. mağaza zinciri olan bir işletmeye ait mağaza bulma aracı) bakarsınız. Bu durumda, sunucu tarafında programlama olmadan nispeten düşük teknolojili bir yaklaşım kullanabilirsiniz. Bunu yaratıcı olamayacağınızı da söylemeden yapmak yok. Bunu yapmak için GeoJSON veri biçimini kullanarak haritadaki her bir mağazayla ilgili rastgele bilgileri depolayabilir ve oluşturabilir, ayrıca işaretçileri ve haritanın genel stilini özelleştirebilirsiniz.

Son olarak, ek bir avantaj olarak mağaza bulma aracınızı geliştirmek ve barındırmak için Cloud Shell'i kullanırsınız. Bu aracın kullanılması kesin bir zorunluluk olmasa da, bir web tarayıcısı çalıştıran herhangi bir cihazdan mağaza bulma aracını geliştirmenizi ve bu aracı herkesin kullanımına sunmanızı sağlar.

489628918395c3d0.png

Ön koşullar

  • HTML ve JavaScript ile ilgili temel bilgiler

Ne yaparsınız?

  • Bir grup mağaza konumunu ve GeoJSON biçiminde depolanan bilgileri 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österir.
  • Web sayfasına Yer Otomatik tamamlama arama çubuğu ekleyin.
  • Kullanıcı tarafından sağlanan bir 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 Google Haritalar Platformu'nu Kullanmaya Başlama rehberini izleyerek veya Google Haritalar Platformu oynatma listesini izleyerek aşağıdaki adımları tamamlayın:

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

Cloud Shell'i etkinleştirme

Bu codelab'de, Google Cloud'da çalışan ve Google Cloud'da çalışan ürün ve kaynaklara erişim sağlayan bir komut satırı ortamı olan Cloud Shell'i kullanırsınız. Böylece, projenizi web tarayıcınızda tamamen barındırabilir ve çalıştırabilirsiniz.

Cloud Shell'i Cloud Console'dan etkinleştirmek için Cloud Shell'i Etkinleştir 89665d8d348105cd.png seçeneğini tıklayın (temel hazırlığının yapılması ve ortama bağlanması yalnızca birkaç dakika sürer).

5f504766b9b3be17.png

Böylece, muhtemelen bir geçiş reklamı gösterildikten sonra tarayıcınızın alt kısmında yeni bir kabuk açılır.

d3bb67d514893d1f.png

Cloud Shell'e bağlandıktan sonra kimliğinizin zaten doğrulandığını ve projenin, kurulum sırasında seçtiğiniz proje kimliğine ayarlanmış olduğunu görmeniz gerekir.

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

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

$ gcloud config set project <YOUR_PROJECT_ID>

3. Haritayla birlikte "Merhaba, Dünya!"

Harita ile geliştirmeye başlayın

Cloud Shell'de işe codelab'in geri kalanı için temel oluşturacak bir HTML sayfası oluşturarak başlarsınız.

  1. Cloud Shell'in araç çubuğunda, kod düzenleyiciyi yeni bir sekmede açmak için Düzenleyiciyi Başlat996514928389de40.png'ı tıklayın.

Bu web tabanlı kod düzenleyici, Cloud Shell'de dosyaları kolayca düzenlemenize olanak sağlar.

Ekran Görüntüsü, 19.04.2017 10.22.48.png

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

NewKlasörü.png

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

Daha sonra, 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 yerleştirin:

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. Harita, sayfanın tamamını kapladığından emin olmak 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 Yerler Kitaplığının kullanımını içerir ve Haritalar JavaScript API'si yüklendikten sonra çalışan 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 kodla app.js adlı başka bir dosya oluşturun:

uygulama.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ı içermesi için <div> etiketinize bir referans iletecek, orta ve yakınlaştırma düzeyini belirteceksiniz.

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

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

Gerçek zamanlı web sunucusunu Cloudhost'un 8080 numaralı bağlantı noktasında dinleyen basit HTTP sunucusunu çalıştırdığınızı gösteren bazı günlük kaydı satırları görürsünüz.

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

47b06e5169eb5add.png

bdab1f021a3b91d5.png

Bu menü öğesini tıkladığınızda, web tarayıcınızda basit Python HTTP sunucusundan sunulan HTML içeriğinin yer aldığı yeni bir sekme açılır. Her şey yolundaysa Londra, İngiltere'yi merkez alan bir harita görürsünüz.

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

4. GeoJSON ile haritayı doldurun

Şimdi mağazalarla ilgili verilere göz atalım. GeoJSON, haritadaki noktalar, çizgiler veya poligonlar gibi basit coğrafi özellikleri temsil eden bir veri biçimidir. Bu özellikler, isteğe bağlı veriler de içerebilir. Bu nedenle GeoJSON, mağazaları temsil etmek için mağazanın adı, çalışma saatleri ve telefon numarası gibi ek verilerden oluşan küçük bir noktadır. Bu bilgiler harita üzerinde kullanıcıları temsil eder. En önemlisi, coğrafi JSON, Google Haritalar'da birinci sınıf destek içerir. Yani bir Google haritasına GeoJSON belgesi gönderebildiğinizde bu doküman haritada uygun şekilde oluşturulur.

  1. stores.json adlı yeni bir dosya oluşturun ve aşağıdaki koda 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 var, ancak bunları incelediğinizde her mağaza için aynı yapıyı tekrar tekrar görüyorsunuz. Her mağaza, koordinatları ve properties anahtarının altında bulunan ek verilerle birlikte bir GeoJSON Point olarak temsil edilir. İlginçtir ki GeoJSON, properties adlı anahtarın altına rastgele adlandırılmış anahtarların dahil edilmesini sağlar. Bu codelab'de bu anahtarlar category, hours, description, name ve phone şeklindedir.

  1. Şimdi app.js dosyasını düzenleyerek stores.js uygulamasındaki GeoJSON'yi haritanıza yükleyin.

uygulama.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 öğesini çağırıp JSON dosyasının adını ileterek GeoJSON'ı haritaya yüklediniz. Ayrıca, bir işaretçi her tıklandığında çalıştırılacak bir işlev tanımladınız. İşlev, işaretçisi tıklanan mağaza için ek verilere erişebilir ve görüntülenen bilgi penceresindeki bilgileri kullanabilir. Bu uygulamayı test etmek için daha önce aynı komutu kullanarak basit Python HTTP sunucusunu çalıştırabilirsiniz.

  1. Cloud Shell'e geri dönün ve aşağıdakileri yazın:
$ python3 -m http.server 8080
  1. Web Önizlemesi 95e419ae763a1d48.png > 8080 bağlantı noktasında önizle'yi tıklayın. Her mağazayla ilgili ayrıntıları görüntülemek için, aşağıdaki örnekte gösterildiği gibi işaretçilerle dolu bir harita görürsünüz. İlerleme!

c4507f7d3ea18439.png

5. Haritayı özelleştirin

Neredeyse bitti. Tüm mağaza işaretçilerinizi ve tıklandığında ek bilgileri gösteren bir haritaya sahipsiniz. Ama görünüşe göre diğer tüm Google haritaları. Ne kadar sıkıcı! Özel bir harita stili, işaretçiler, logolar ve Street View görüntüleriyle renklendirin.

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

uygulama.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);
  });

}

Eklediğiniz öğeler şunlardır:

  • mapStyle değişkeni, haritanın stiline ilişkin tüm bilgileri içerir. (Ayrıca, isterseniz kendi stilinizi de oluşturabilirsiniz.)
  • map.data.setStyle yöntemini kullanarak, GeoJSON'daki her category için farklı olan özel işaretçileri uyguladınız.
  • content değişkenini, logo (mağazanın bulunduğu konum için tekrar category kullanarak) ve Street View resmini içerecek şekilde değiştirdiniz.

Bunu dağıtmadan önce birkaç adımı tamamlamanız gerekir:

  1. app.js içindeki 'YOUR_API_KEY' dizesini daha önce kullandığınız API anahtarıyla değiştirerek (index.html için yapıştırdığınız değerle tırnaklarını değiştirmeden) apiKey değişkeni için doğru değeri belirleyin.
  2. İşaretçiyi ve logo grafiklerini indirmek için Cloud Shell'de aşağıdaki komutları çalıştırın. store-locator dizininde olduğunuzdan emin olun. Çalışıyorsa basit HTTP sunucusunu durdurmak için Control+C politikasını kullanı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, tamamlanan mağaza bulma aracını önizleyin:
$ python3 -m http.server 8080

Önizlemeyi yeniden yüklediğinizde, her harita için özel stil, özel işaretçi resimleri, iyileştirilmiş bilgi penceresi biçimlendirmesi ve Street View resmi içeren bu haritaya benzer bir şey görürsünüz:

3d8d13da126021gg.png

6. Kullanıcı girişini al

Mağaza bulma aracı kullanıcıları, genellikle hangi mağazanın kendilerine en yakın olduğunu veya yolculuklarına başlamayı planladıkları bir adresi öğrenmek ister. Kullanıcının kolayca bir başlangıç adresi girmesine olanak tanımak için Yer Otomatik Tamamlama arama çubuğu ekleyin. Yer Otomatik Tamamlama özelliği, Otomatik Tamamlama özelliğinin diğer Google arama çubuklarındaki işleyiş şekline benzer bir yazma işlevi sağlar ancak tahminler, Google Haritalar Platformu'ndaki Yerlerin tümüdür.

  1. Otomatik tamamlama arama çubuğu ve ilişkili sonuçlar yan paneli için stil eklemek üzere index.html düzenlemeye 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>

Gerektiğinde otomatik tamamlama arama çubuğu ve kaydırma paneli başlangıçta gizlenmiştir.

  1. Şimdi, Otomatik tamamlama widget'ını app.js içindeki initMap işlevinin sonunda, kapanış kıvrıklı ayraçtan hemen önce haritaya ekleyin.

uygulama.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 adresleri döndürecek şekilde kısıtlar (Yer Adları tamamlama özelliği, kuruluş adları ve yönetici konumlarıyla eşleşebilir) ve döndürülen adresleri yalnızca Birleşik Krallık'takilerle sınırlandırır. İsteğe bağlı olan bu spesifikasyonları eklemek, kullanıcının aradığı adresi gösterecek şekilde tahminleri daraltmak için kullanıcının 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ıttaki her Yerle ilgili olarak hangi alanların döndürülmesi gerektiğini belirtir.

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

Şimdi 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öreceksiniz.

5163f34a03910187.png

Şimdi, kullanıcının Otomatik tamamlama widget'ından bir tahmini seçmesi ve bunu mağazalarınıza olan mesafeleri hesaplamak için bir temel olarak kullanması gerekiyor.

  1. Aşağıdaki kodu, az önce yapıştırdığınız koddan sonra app.js öğesindeki initMap öğesinin sonuna ekleyin.

uygulama.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 bir dinleyici ekler. Böylece, kullanıcı önerilerden birini tıkladığında harita seçilen adrese yeniden döner ve mesafe hesaplamalarınız için temel olarak kaynak gösterilir. Mesafe hesaplamalarını bir sonraki adımda uygularsınız.

7. En yakın mağazaları listeleyin

Directions API, Google Haritalar uygulamasında yol tarifi isteme deneyimine benzer şekilde, ikisi arasında bir rota almak için tek bir başlangıç noktası ve tek bir varış noktası girer. Mesafe Matrisi API'si, seyahat süresi ve mesafelere dayalı olarak birden fazla olası kaynak ve birden fazla olası hedef arasındaki optimum eşlemeyi tanımlamak için bu kavramı daha da ileri taşır. Bu durumda, kullanıcının seçilen adrese en yakın mağazayı bulmasına yardımcı olmak için hedefler olarak bir kaynak ve mağaza konumu dizisi sağlarsınız.

  1. app.js hizmetine calculateDistances adında yeni bir işlev ekleyin.

uygulama.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, tek bir kaynak olarak iletilen kaynağı ve bir dizi hedef olarak mağaza konumlarını kullanarak Mesafe Matrisi API'sini çağırır. Ardından, mağazanın kimliğini, insanların okuyabileceği bir dizeyle ifade edilen mesafeyi, sayısal değer olarak metre cinsinden mesafeyi depolayıp bir dizi dizi oluşturur ve diziyi sıralar.

Kullanıcı, en yakından en uzaka doğru sıralanan mağazaların listesini görmeyi bekler. Mağazaların görüntülenme sırasını bildirmek üzere calculateDistances işlevinden döndürülen listeyi kullanarak her mağaza için yan panel bir giriş doldurun.

  1. app.js hizmetine showStoresList adında yeni bir işlev ekleyin.

uygulama.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. Sunucunuzu yeniden başlatın ve aşağıdaki komutu çalıştırarak önizlemenizi yenileyin.
$ python3 -m http.server 8080
  1. Son olarak, Otomatik tamamlama arama çubuğuna bir Birleşik Krallık adresi girin ve önerilerden birini tıklayın.

Haritada söz konusu adres merkeze gelmeli ve seçilen adresten uzaklık sırasına göre mağaza konumları listeleniyorsa bir kenar çubuğu görünmelidir. Aşağıda bir örnek verilmiş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üleyebilirsiniz. Haritanızı etkin Cloud Shell oturumunuzun ötesinde görmek veya haritanızın URL'sini başkalarıyla paylaşabilmek için web sayfanızı barındırmak üzere Cloud Storage'ı kullanın. Cloud Storage, Google altyapısında veri depolama ve depolama için kullanılan çevrimiçi bir dosya depolama web hizmetidir. Hizmet, Google Cloud'un performansını ve ölçeklenebilirliğini gelişmiş güvenlik ve paylaşım özellikleriyle birleştirir. Ayrıca, basit mağaza bulma aracınızı barındırabilmeniz için ücretsiz katman sunar.

Cloud Storage sayesinde dosyalar, bilgisayarınızdaki dizinlere benzeyen paketler halinde 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 gerekebilir. Bu ad, paket adının bir parçası olarak kullanılabilir.

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

gsutil, Cloud Storage ile etkileşimde bulunan araçtır. mb komutu, yaratıcı bir şekilde " yapmak için" anlamına gelir. Kullandığınız komutlar da dahil olmak üzere mevcut tüm komutlar hakkında daha fazla bilgi için gsutil aracı başlıklı makaleye bakın.

Cloud Storage'da barındırılan paketleriniz ve dosyalarınız varsayılan olarak gizlidir. Ancak, mağaza bulma aracınız için, tüm dosyaların internet üzerinden herkes tarafından erişilebilir olmasını sağlamak üzere herkese açık olmasını istersiniz. Her dosyayı yükledikten sonra herkese açık hale getirebilirsiniz ancak bu yorucu olur. 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. yourname-store-locator komutunu paketiniz için seçtiğiniz adla değiştirerek aşağıdaki komutu çalıştırın:
$ gsutil defacl ch -u AllUsers:R gs://yourname-store-locator
  1. Artık, aşağıdaki komutu kullanarak tüm dosyalarınızı mevcut dizinde (ş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 çevrimiçi bir haritaya sahip bir web sayfanız olmalıdır. Bunu görüntülemek için URL, http://storage.googleapis.com/yourname-store-locator/index.html olacaktır. Yine, adınız-mağaza-bulucu bölümünüzün adı daha önce seçtiğiniz paket adıyla değiştirilecektir.

Temizlik

Bu projede oluşturulan tüm kaynakları temizlemenin en kolay yolu, bu eğitimin başında oluşturduğunuz Google Cloud Projesi'ni devre dışı bırakmaktır:

  • Cloud Console'da Ayarlar Sayfası'nı açın
  • 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? Yeni bir sorun için istekte bulunun.

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