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.
Ö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:
- Faturalandırma hesabı oluşturun.
- Bir proje oluşturun.
- Google Haritalar Platformu API'lerini ve SDK'larını etkinleştirin (bir önceki bölümde listelenmiştir).
- 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 seçeneğini tıklayın (temel hazırlığının yapılması ve ortama bağlanması yalnızca birkaç dakika sürer).
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.
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.
- Cloud Shell'in araç çubuğunda, kod düzenleyiciyi yeni bir sekmede açmak için Düzenleyiciyi Başlat'ı tıklayın.
Bu web tabanlı kod düzenleyici, Cloud Shell'de dosyaları kolayca düzenlemenize olanak sağlar.
- Kod düzenleyicide Dosya > Yeni Klasör'ü tıklayarak uygulamanız için yeni bir
store-locator
dizini oluşturun.
- Yeni klasörü
store-locator
olarak adlandırın.
Daha sonra, 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 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.
- 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 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.
- 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.
- Cloud Console araç çubuğundaki Web Önizlemesi'ni tıklayıp 8080 numaralı bağlantı noktasında önizle'yi seçerek bu uygulamada bir web tarayıcısı sekmesi açın.
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.
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.
- Şimdi
app.js
dosyasını düzenleyerekstores.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.
- Cloud Shell'e geri dönün ve aşağıdakileri yazın:
$ python3 -m http.server 8080
- Web Önizlemesi > 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!
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 hercategory
için farklı olan özel işaretçileri uyguladınız.content
değişkenini, logo (mağazanın bulunduğu konum için tekrarcategory
kullanarak) ve Street View resmini içerecek şekilde değiştirdiniz.
Bunu dağıtmadan önce birkaç adımı tamamlamanız gerekir:
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.- İş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çinControl+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
- 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:
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.
- 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.
- Şimdi, Otomatik tamamlama widget'ını
app.js
içindekiinitMap
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.
- 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.
Ş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.
- Aşağıdaki kodu, az önce yapıştırdığınız koddan sonra
app.js
öğesindekiinitMap
öğ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.
app.js
hizmetinecalculateDistances
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.
app.js
hizmetineshowStoresList
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;
}
- Sunucunuzu yeniden başlatın ve aşağıdaki komutu çalıştırarak önizlemenizi yenileyin.
$ python3 -m http.server 8080
- 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:
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.
- 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.
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
- Artık, aşağıdaki komutu kullanarak tüm dosyalarınızı mevcut dizinde (ş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 ç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 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 stilde bir harita ekleme
- GeoJSON biçimindeki haritaya veri katmanı yükleme
- Web sayfasında Street View görüntüsü göstermek için Street View Static API'sini kullanma.
- Sayfaya bir Yerler 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'daki web geliştirme projelerini yönetme ve test etme
- Cloud Storage ile web sitesi barındırma
Daha fazla bilgi
- Code_lab'de New York Subway'i eşleme konusunda Google App Engine'i kullanarak web haritanızı barındırmanın başka bir yolunu öğrenin.
- Yakındaki Bir İşletme Arama hizmeti gibi daha fazla Google Haritalar Platformu codelab'i keşfedin.
- Aşağıdaki soruyu cevaplayarak en çok yararlanacağı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? 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.