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.
Ö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:
- Faturalandırma hesabı oluşturun.
- Proje oluşturun.
- Google Haritalar Platformu API'lerini ve SDK'larını (önceki bölümde listelenmiştir) etkinleştirin.
- 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 tıklayın (ortamın sağlanması ve bağlantının kurulması yalnızca birkaç saniye sürer).
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.
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.
- Yeni bir sekmede kod düzenleyiciyi açmak için Cloud Shell araç çubuğunda Launch Editor 'ı (Düzenleyiciyi Başlat)
tıklayın.
Bu web tabanlı kod düzenleyici, Cloud Shell'deki dosyaları kolayca düzenlemenize olanak tanır.
- Dosya > Yeni Klasör'ü tıklayarak kod düzenleyicide uygulamanız için yeni bir
store-locator
dizini oluşturun.
- Yeni klasörü
store-locator
olarak adlandırın.
Ardından, harita içeren bir web sayfası oluşturursunuz.
store-locator
dizinindeindex.html
adlı bir dosya oluşturun.
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.
- Kod snippet'indeki
YOUR_API_KEY
metnini, bu codelab'de daha önce oluşturduğunuz API anahtarıyla değiştirin. - 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.
- 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.
- 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.
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.
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.
- Ş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.
- Cloud Shell'e dönün ve aşağıdakileri yazın:
$ python3 -m http.server 8080
- Web Önizlemesi
> 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
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 hercategory
için farklı bir işaretçi kullandınız.content
değişkenini, bir logo (GeoJSON'dakicategory
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:
apiKey
değişkeni için doğru değeri ayarlamak üzereapp.js
içindeki'YOUR_API_KEY'
dizesini daha önce kullandığınız API anahtarınızla (tırnak işaretlerini değiştirmedenindex.html
içine yapıştırdığınız anahtarla) değiştirin.- İş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çinControl+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
- 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:
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.
- 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.
- Şimdi,
app.js
içindekiinitMap
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.
- 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.
Ş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.
- Yeni yapıştırdığınız kodun ardından
app.js
içindekiinitMap
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.
app.js
'yacalculateDistances
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.
app.js
'yashowStoresList
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;
}
- Aşağıdaki komutu çalıştırarak sunucunuzu yeniden başlatın ve önizlemenizi yenileyin.
$ python3 -m http.server 8080
- 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:
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.
- 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.
- 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
- Artık aşağıdaki komutla geçerli dizindeki tüm dosyalarınızı (şu anda yalnızca
index.html
veapp.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 Aç'ı tıklayın.
- Proje kimliğini girin ve Kapat'ı tıklayın.
9. Tebrikler
Tebrikler! Bu codelab'i tamamladınız.
Öğrendikleriniz
- Maps JavaScript API ile özel olarak stilize edilmiş bir harita ekleme
- GeoJSON biçiminde bir veri katmanını haritaya yükleme
- Bir web sayfasında Street View görüntüsü göstermek için Street View Static API'yi kullanma.
- Sayfaya Yer Otomatik Tamamlama arama çubuğu eklemek için Yerler Kitaplığı'nı kullanma
- Tek bir API çağrısıyla birden fazla mesafeyi hesaplamak için Mesafe Matrisi hizmetini kullanma
- Tarayıcı tabanlı Cloud Shell komut satırı arayüzünü kullanarak Google Cloud Platform'da web geliştirme projelerini yönetme ve test etme
- Cloud Storage ile web sitesi barındırma
Daha fazla bilgi
- Google App Engine'i kullanarak web haritanızı barındırmanın başka bir yolunu Mapping the NYC Subway (New York Metrosu Haritası) adlı codelab'de öğrenebilirsiniz.
- Yakındaki İşletme Arama Hizmeti Oluşturma gibi diğer Google Haritalar Platformu codelab'lerini keşfedin.
- Aşağıdaki soruyu yanıtlayarak en faydalı bulacağınız içerikleri oluşturmamıza yardımcı olun:
Başka hangi codelab'leri görmek istersiniz?
İ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.