Öğretici: Azure Haritalar bulucu oluşturmak için kullanma
Bu öğretici, Azure depolamayı kullanarak basit bir depo bulucu oluşturma sürecinde size Haritalar. Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:
- Azure Harita Denetimi API'sini kullanarak yeni bir web Harita Denetimi oluşturun.
- Bir dosyadan özel verileri yükleme ve haritada görüntüleme.
- Adresi bulmak Haritalar Arama hizmeti sorgu girmek için Azure Haritalar Arama hizmeti'i kullanın.
- Tarayıcıdan kullanıcının konumunu al ve haritada göster.
- Haritada özel semboller oluşturmak için birden çok katmanı birleştirin.
- Küme veri noktaları.
- Haritaya yakınlaştırma denetimleri ekleyin.
Önkoşullar
- 1. Nesil Haritalar (S1) veya 2.Nesil fiyatlandırma katmanında bir Azure depolama hesabı olun.
- Birincil anahtar veya abonelikanahtarı olarak da bilinen birincil abonelik anahtarını alın.
Azure kimlik doğrulaması hakkında daha fazla Haritalar için bkz. Azure'da kimlik doğrulamasını Haritalar.
Bu öğreticide Visual Studio Code kullanır, ancak farklı bir kodlama ortamı kullanabilirsiniz.
Örnek kod
Bu öğreticide Contoso Coffee adlı kurgusal bir şirket için mağaza bulucu oluşturalım. Ayrıca, öğreticide mağaza bulucusu diğer isteğe bağlı işlevlerle genişletme hakkında bilgi edinip size yardımcı olacak bazı ipuçları da vardır.
Canlı mağaza bulucu örneğini burada görüntüabilirsiniz.
Bu öğreticiyi daha kolay takip etmek ve etkileşime etmek için aşağıdaki kaynakları indirmeniz gerekir:
- Basit depo bulucu örneği için tam kaynak kodu
- Depo bulucu veri kümesine içeri aktar için konum verilerini depolama
- Görüntüleri eşleme
Depo bulucu özellikleri
Bu bölümde Contoso Kahve deposu bulucu uygulamasında desteklenen özellikler listelemektedir.
Kullanıcı arabirimi özellikleri
- Logoyu üst bilgide depolama
- Harita kaydırmayı ve yakınlaştırmayı destekler
- Kullanıcının geçerli konumunu aramak için Konumum düğmesi.
- Sayfa düzeni, cihaz ekranı genişliğine göre ayarlanır
- Arama kutusu ve arama düğmesi
İşlevsellik özellikleri
- Arama
keypresskutusuna eklenen bir olay, kullanıcı Enter tuşuna basan bir arama tetikler. - Harita hareket ettiğinde, her konumun haritanın merkezinden uzaklığı hesaplar. Sonuç listesi, haritanın en üstünde en yakın konumları görüntülemek için güncelleştirmeleri içerir.
- Kullanıcı sonuçlar listesinde bir sonuç seçtikten sonra harita, seçilen konumun üzerine ortalar ve konumla ilgili bilgiler açılır pencerede görüntülenir.
- Kullanıcı belirli bir konumu seçerken harita bir açılır pencere tetikler.
- Kullanıcı uzaklaştırıp uzaklaştırıyorsa, konumlar kümelerde gruplandı. Her küme, dairenin içinde sayı bulunan bir daire ile temsil edilen bir kümedir. Kullanıcı yakınlaştırma düzeyini değiştirirken kümeler form ve ayrıdır.
- Bir kümeyi seçmek, haritada iki düzeyi yakınlaştırıp kümenin konumu üzerinde merkezler.
Depo bulucu tasarımı
Aşağıdaki şekilde, depo bulucumuz genel düzeninin bir tel çerçevesini gösterir. Canlı tel çerçeveyi burada görüntüabilirsiniz.
Bu depo bulucus un kullanışlılığını en üst düzeye çıkarmak için, kullanıcının ekran genişliği 700 piksel genişliğinden küçük olduğunda ayarlamalar yapılan duyarlı bir düzen içeririz. Duyarlı bir düzen, mağaza bulucusu mobil cihazda olduğu gibi küçük bir ekranda kullanmayı kolaylaştırır. Küçük ekran düzeninin bir tel çerçevesi şöyledir:
Depo konumu veri kümesi oluşturma
Bu bölümde, haritada görüntülemek istediğiniz depoların veri kümesi oluşturma açıkılmaktadır. Contoso Kahve bulucu için veri kümesi bir çalışma kitabı içinde Excel oluşturulur. Veri kümesi dokuz ülkeye veya bölgeye yayılmış 10.213 Contoso Kahve mağazası konumu içerir: Birleşik Devletler, Kanada, Birleşik Krallık, Fransa, Almanya, İtalya, Hollanda, Norveç ve İspanya. Verilerin nasıl göründüğünün ekran görüntüsü şu şekildedir:
Tüm veri kümelerini görüntülemek için çalışma kitabını Excel indirin.
Verilerin ekran görüntüsüne bakarak aşağıdaki gözlemleri gerçekleştirebilirsiniz:
- Konum bilgileri AddressLine, City, Countryy (şehir), AdminDivision (eyalet/il), PostCode (posta kodu) ve Ülke sütunları kullanılarak depolanır.
- Enlem ve Boylam sütunları her Contoso Kahve konumunun koordinatlarını içerir. Koordinat bilgilerine sahip değilsanız Konum koordinatlarını belirlemek için Azure Haritalar hizmetlerini kullanabilirsiniz.
- Diğer bazı sütunlarda kahve mağazalarıyla ilgili meta veriler bulunur: telefon numarası, Boole sütunları ve mağaza açılış ve kapanış süreleri 24 saat biçimindedir. Boole sütunları, Wi-Fi erişilebilirlik için hazır. Konum verilerinizle daha ilgili meta veriler içeren kendi sütunlarınızı oluşturabilirsiniz.
Not
Azure Haritalar, verileri "EPSG:3857" küresel Mercator projeksiyonu içinde işler, ancak WGS84 datum kullanan "EPSG:4326" içinde verileri okur.
Depo konumu veri kümesi yükleme
Contoso Coffee shop bulucu veri kümesi küçüktür, bu nedenle çalışma Excel sekmeyle ayrılmış bir metin dosyasına dönüştürün. Bu dosya daha sonra uygulama yüklendikten sonra tarayıcı tarafından indirilebilir.
İpucu
Veri kümeniz istemci indirme için çok büyükse veya sık sık güncelleştiriliyorsa, veri kümenizi bir veritabanında depolamayı göz önünde bulundurabilirsiniz. Verileriniz bir veritabanına yüklendikten sonra, veriler için sorguları kabul eden ve ardından sonuçları kullanıcının tarayıcısına gönderen bir web hizmeti oluşturabilirsiniz.
Verileri sekmeyle ayrılmış metin dosyasına dönüştürme
Contoso Coffee shop konum verilerini bir çalışma kitabından Excel düz metin dosyasına dönüştürmek için:
Çalışma kitabını sabit sürücünize kaydedin.
Excel yükleme.
İndirilen çalışma kitabını açın.
Farklı Kaydet’i seçin.
Farklı kaydet türü açılan listesinde Metin (Sekme sınırlandırılmış)(*.txt) öğesini seçin.
Dosyaya ContosoCoffee adını girin.
Metin dosyasını dosyanın Not Defteri aşağıdaki metne benzer:
Projeyi ayarlama
Visual Studio Code açın.
Dosya'ya tıklayın ve ardından Çalışma Alanını Aç... öğesini seçin.
Yeni bir klasör oluşturun ve "ContosoCoffee" olarak ad girin.
Gezginde CONTOSOCOFFEE'yi seçin.
Uygulamanın düzenini, stilini ve mantığını tanımlayan aşağıdaki üç dosya oluşturun:
- index.html
- index.css
- index.js
data adlı bir klasör oluşturun.
Veri ContosoCoffee.txt ekleme.
images adlı başka bir klasör oluşturun.
Henüz indirmedıysanız, bu 10 görüntü indirin.
İndirilen görüntüleri images klasörüne ekleyin.
Çalışma alanı klasörünüz şimdi aşağıdaki ekran görüntüsüne benzer şekilde görünür:
HTML oluşturma
HTML oluşturmak için:
Aşağıdaki
metaetiketleriheadindex.html ekleyin:<meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="IE=Edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">Azure Haritalar web denetimi JavaScript ve CSS dosyalarına başvurular ekleyin:
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" type="text/css"> <script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>Azure Haritalar Services modülüne bir başvuru ekleyin. modül, Azure Haritalar REST hizmetlerini sarmalayan ve javascript 'te kullanmayı kolaylaştıran bir JavaScript kitaplığıdır. Modül, arama işlevselliğini güçetmek için kullanışlıdır.
<script src="https://atlas.microsoft.com/sdk/javascript/service/2/atlas-service.min.js"></script>index.js ve index. css başvurularını ekleyin.
<link rel="stylesheet" href="index.css" type="text/css"> <script src="index.js"></script>Belge gövdesinde bir
headeretiket ekleyin. Etiket içindeheader, logo ve şirket adını ekleyin.<header> <img src="images/Logo.png" /> <span>Contoso Coffee</span> </header>Bir
mainetiket ekleyin ve metin kutusu ve arama düğmesine sahip bir arama bölmesi oluşturun. Ayrıca,divharita, liste paneli ve KONUMUMU GPS için başvurular ekleyin.<main> <div class="searchPanel"> <div> <input id="searchTbx" type="search" placeholder="Find a store" /> <button id="searchBtn" title="Search"></button> </div> </div> <div id="listPanel"></div> <div id="myMap"></div> <button id="myLocationBtn" title="My Location"></button> </main>
Bitirdikten sonra, index.html Bu örnek index.html dosyagibi görünmelidir.
CSS stillerini tanımlama
Sonraki adım CSS stillerini tanımlamaktır. CSS stilleri, uygulama bileşenlerinin nasıl düzenlendiğini ve uygulamanın görünümünü tanımlar.
İndex. css' i açın.
Şu CSS kodunu ekleyin:
Not
@mediaStil, ekran genişliği 700 pikselden küçük olduğunda kullanılacak alternatif stil seçeneklerini tanımlar.html, body { padding: 0; margin: 0; font-family: Gotham, Helvetica, sans-serif; overflow-x: hidden; } header { width: calc(100vw - 10px); height: 30px; padding: 15px 0 20px 20px; font-size: 25px; font-style: italic; font-family: "Comic Sans MS", cursive, sans-serif; line-height: 30px; font-weight: bold; color: white; background-color: #007faa; } header span { vertical-align: middle; } header img { height: 30px; vertical-align: middle; } .searchPanel { position: relative; width: 350px; } .searchPanel div { padding: 20px; } .searchPanel input { width: calc(100% - 50px); font-size: 16px; border: 0; border-bottom: 1px solid #ccc; } #listPanel { position: absolute; top: 135px; left: 0px; width: 350px; height: calc(100vh - 135px); overflow-y: auto; } #myMap { position: absolute; top: 65px; left: 350px; width: calc(100vw - 350px); height: calc(100vh - 65px); } .statusMessage { margin: 10px; } #myLocationBtn, #searchBtn { margin: 0; padding: 0; border: none; border-collapse: collapse; width: 32px; height: 32px; text-align: center; cursor: pointer; line-height: 32px; background-repeat: no-repeat; background-size: 20px; background-position: center center; z-index: 200; } #myLocationBtn { position: absolute; top: 150px; right: 10px; box-shadow: 0px 0px 4px rgba(0,0,0,0.16); background-color: white; background-image: url("images/GpsIcon.png"); } #myLocationBtn:hover { background-image: url("images/GpsIcon-hover.png"); } #searchBtn { background-color: transparent; background-image: url("images/SearchIcon.png"); } #searchBtn:hover { background-image: url("images/SearchIcon-hover.png"); } .listItem { height: 50px; padding: 20px; font-size: 14px; } .listItem:hover { cursor: pointer; background-color: #f1f1f1; } .listItem-title { color: #007faa; font-weight: bold; } .storePopup { min-width: 150px; } .storePopup .popupTitle { border-top-left-radius: 4px; border-top-right-radius: 4px; padding: 8px; height: 30px; background-color: #007faa; color: white; font-weight: bold; } .storePopup .popupSubTitle { font-size: 10px; line-height: 12px; } .storePopup .popupContent { font-size: 11px; line-height: 18px; padding: 8px; } .storePopup img { vertical-align:middle; height: 12px; margin-right: 5px; } /* Adjust the layout of the page when the screen width is fewer than 700 pixels. */ @media screen and (max-width: 700px) { .searchPanel { width: 100vw; } #listPanel { top: 385px; width: 100%; height: calc(100vh - 385px); } #myMap { width: 100vw; height: 250px; top: 135px; left: 0px; } #myLocationBtn { top: 220px; } } .mapCenterIcon { display: block; width: 10px; height: 10px; border-radius: 50%; background: orange; border: 2px solid white; cursor: pointer; box-shadow: 0 0 0 rgba(0, 204, 255, 0.4); animation: pulse 3s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(0, 204, 255, 0.4); } 70% { box-shadow: 0 0 0 50px rgba(0, 204, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(0, 204, 255, 0); } }
Uygulamayı çalıştırın. Üst bilgi, arama kutusu ve arama düğmesini görürsünüz. Ancak, eşleme henüz yüklenmediği için görünür değildir. Bir arama yapmayı denerseniz, hiçbir şey olmaz. Bir sonraki bölümde açıklanan JavaScript mantığını ayarlamız gerekir. Bu mantık, mağaza bulucunun tüm işlevlerine erişir.
JavaScript kodu ekle
Contoso kahve Mağazası Bulucu uygulamasındaki JavaScript kodu aşağıdaki işlemlerin yapılmasını mümkün değildir:
readySayfa yükleme işlemini tamamlayana kadar beklemek için adlı bir olay dinleyicisi ekler. Sayfa yükleme tamamlandığında, olay işleyicisi haritanın yüklenmesini izlemek için daha fazla olay dinleyicisi oluşturur ve arama ve Konumum düğmelerine işlevsellik verir.Kullanıcı arama düğmesini seçtiğinde veya arama kutusuna bir konum yazdığında, sonra ENTER tuşuna bastığında, kullanıcının sorgusuna yönelik belirsiz bir arama başlatılır. Kod, bir ülke/bölge ISO 2 değerleri dizisinde,
countrySetarama sonuçlarını bu ülkelere/bölgelerle sınırlamak için seçeneğine geçer. Ülkeleri/bölgeleri arama yapılacak şekilde sınırlamak, döndürülen sonuçların doğruluğunu artırmaya yardımcı olur.Arama tamamlandıktan sonra, ilk konum sonucu harita kamerasının Merkez odağı olarak kullanılır. Kullanıcı konumumu seçtiğinde, kod, tarayıcıda yerleşik olan HTML5 coğrafi konum API 'sini kullanarak kullanıcının konumunu alır. Konum alındıktan sonra kod, Haritayı kullanıcının konumu üzerine ortalar.
JavaScript eklemek için:
index.js açın.
Ayarları daha kolay güncelleştirilmesini sağlamak için genel seçenekler ekleyin. Harita, açılan pencere, veri kaynağı, simge katmanı ve HTML işaretçisi için değişkenleri tanımlayın. HTML işaretini bir arama alanının merkezini gösterecek şekilde ayarlayın. ve Azure Haritalar arama hizmeti istemcisinin bir örneğini tanımlayın.
//The maximum zoom level to cluster data point data on the map. var maxClusterZoomLevel = 11; //The URL to the store location data. var storeLocationDataUrl = 'data/ContosoCoffee.txt'; //The URL to the icon image. var iconImageUrl = 'images/CoffeeIcon.png'; var map, popup, datasource, iconLayer, centerMarker, searchURL;Aşağıdaki başlatma kodunu ekleyin.
<Your Azure Maps Key>Birincil abonelik anahtarınızla değiştirdiğinizden emin olun.İpucu
Açılır pencereleri kullanırken, tek bir
Popupörnek oluşturmak ve içeriğini ve konumunu güncelleştirerek örneği yeniden kullanmak en iyisidir.PopupKodunuza eklediğiniz her örnek için, sayfaya birden fazla DOM öğesi eklenir. Sayfada daha fazla DOM öğesi varsa, tarayıcıda izlemek için gereken daha fazla şey vardır. Çok fazla öğe varsa tarayıcı yavaş kalabilir.function initialize() { //Initialize a map instance. map = new atlas.Map('myMap', { center: [-90, 40], zoom: 2, //Add your Azure Maps primary subscription key to the map SDK. authOptions: { authType: 'subscriptionKey', subscriptionKey: '<Your Azure Maps Key>' } }); //Create a pop-up window, but leave it closed so we can update it and display it later. popup = new atlas.Popup(); //Use SubscriptionKeyCredential with a subscription key const subscriptionKeyCredential = new atlas.service.SubscriptionKeyCredential(atlas.getSubscriptionKey()); //Use subscriptionKeyCredential to create a pipeline const pipeline = atlas.service.MapsURL.newPipeline(subscriptionKeyCredential, { retryOptions: { maxTries: 4 } // Retry options }); //Create an instance of the SearchURL client. searchURL = new atlas.service.SearchURL(pipeline); //If the user selects the search button, geocode the value the user passed in. document.getElementById('searchBtn').onclick = performSearch; //If the user presses Enter in the search box, perform a search. document.getElementById('searchTbx').onkeyup = function(e) { if (e.keyCode === 13) { performSearch(); } }; //If the user selects the My Location button, use the Geolocation API (Preview) to get the user's location. Center and zoom the map on that location. document.getElementById('myLocationBtn').onclick = setMapToUserLocation; //Wait until the map resources are ready. map.events.add('ready', function() { //Add your post-map load functionality. }); } //Create an array of country/region ISO 2 values to limit searches to. var countrySet = ['US', 'CA', 'GB', 'FR','DE','IT','ES','NL','DK']; function performSearch() { var query = document.getElementById('searchTbx').value; //Perform a fuzzy search on the users query. searchURL.searchFuzzy(atlas.service.Aborter.timeout(3000), query, { //Pass in the array of country/region ISO2 for which we want to limit the search to. countrySet: countrySet }).then(results => { //Parse the response into GeoJSON so that the map can understand. var data = results.geojson.getFeatures(); if (data.features.length > 0) { //Set the camera to the bounds of the results. map.setCamera({ bounds: data.features[0].bbox, padding: 40 }); } else { document.getElementById('listPanel').innerHTML = '<div class="statusMessage">Unable to find the location you searched for.</div>'; } }); } function setMapToUserLocation() { //Request the user's location. navigator.geolocation.getCurrentPosition(function(position) { //Convert the Geolocation API (Preview) position to a longitude and latitude position value that the map can interpret and center the map over it. map.setCamera({ center: [position.coords.longitude, position.coords.latitude], zoom: maxClusterZoomLevel + 1 }); }, function(error) { //If an error occurs when the API tries to access the user's position information, display an error message. switch (error.code) { case error.PERMISSION_DENIED: alert('User denied the request for geolocation.'); break; case error.POSITION_UNAVAILABLE: alert('Position information is unavailable.'); break; case error.TIMEOUT: alert('The request to get user position timed out.'); break; case error.UNKNOWN_ERROR: alert('An unknown error occurred.'); break; } }); } //Initialize the application when the page is loaded. window.onload = initialize;Haritanın
readyolay dinleyicisinde, bir arama alanının merkezini göstermek için bir yakınlaştırma denetimi ve HTML işaretleyicisi ekleyin.//Add a zoom control to the map. map.controls.add(new atlas.control.ZoomControl(), { position: 'top-right' }); //Add an HTML marker to the map to indicate the center to use for searching. centerMarker = new atlas.HtmlMarker({ htmlContent: '<div class="mapCenterIcon"></div>', position: map.getCamera().center }); map.markers.add(centerMarker);Haritanın
readyolay dinleyicisinde bir veri kaynağı ekleyin. Ardından, veri kümesini yükleme ve ayrıştırma çağrısı yapın. Veri kaynağında kümelendirmeyi etkinleştirin. Veri kaynağı gruplarında, çakışan noktaları bir kümede birlikte bulunan kümelendirmelidir. Kullanıcı yakınlaştırdığınızda, kümeler ayrı noktalara ayrılır. Bu davranış daha iyi bir kullanıcı deneyimi sağlar ve performansı geliştirir.//Create a data source, add it to the map, and then enable clustering. datasource = new atlas.source.DataSource(null, { cluster: true, clusterMaxZoom: maxClusterZoomLevel - 1 }); map.sources.add(datasource); //Load all the store data now that the data source is defined. loadStoreData();Veri kümesi haritanın
readyolay dinleyicisine yüklendikten sonra, verileri işlemek için bir katman kümesi tanımlayın. Kabarcık katmanı, kümelenmiş veri noktalarını işler. Sembol katmanı, balon katmanının üzerindeki her bir kümedeki noktaların sayısını işler. İkinci bir sembol katmanı, haritadaki ayrı konumlar için özel bir simge oluşturur.mouseovermouseoutKullanıcı haritada bir kümenin veya simgenin üzerine geldiğinde fare imlecini değiştirmek için kabarcık ve simge katmanlarına olay ekleyin.clickKüme kabarcık katmanına bir olay ekleyin. Buclickolay, haritada iki düzey daha yakınlaştırılır ve Kullanıcı herhangi bir kümeyi seçtiğinde Haritayı bir küme üzerine ortalar.clickSimge katmanına bir olay ekleyin. Buclickolay, Kullanıcı tek bir konum simgesi seçtiğinde bir kafeterin ayrıntılarını gösteren bir açılır pencere görüntüler. Haritanın taşınması tamamlandığında izlemek üzere haritaya bir olay ekleyin. Bu olay tetiklendiğinde, liste panelindeki öğeleri güncelleştirin.//Create a bubble layer to render clustered data points. var clusterBubbleLayer = new atlas.layer.BubbleLayer(datasource, null, { radius: 12, color: '#007faa', strokeColor: 'white', strokeWidth: 2, filter: ['has', 'point_count'] //Only render data points that have a point_count property; clusters have this property. }); //Create a symbol layer to render the count of locations in a cluster. var clusterLabelLayer = new atlas.layer.SymbolLayer(datasource, null, { iconOptions: { image: 'none' //Hide the icon image. }, textOptions: { textField: ['get', 'point_count_abbreviated'], size: 12, font: ['StandardFont-Bold'], offset: [0, 0.4], color: 'white' } }); map.layers.add([clusterBubbleLayer, clusterLabelLayer]); //Load a custom image icon into the map resources. map.imageSprite.add('myCustomIcon', iconImageUrl).then(function() { //Create a layer to render a coffee cup symbol above each bubble for an individual location. iconLayer = new atlas.layer.SymbolLayer(datasource, null, { iconOptions: { //Pass in the ID of the custom icon that was loaded into the map resources. image: 'myCustomIcon', //Optionally, scale the size of the icon. font: ['SegoeUi-Bold'], //Anchor the center of the icon image to the coordinate. anchor: 'center', //Allow the icons to overlap. allowOverlap: true }, filter: ['!', ['has', 'point_count']] //Filter out clustered points from this layer. }); map.layers.add(iconLayer); //When the mouse is over the cluster and icon layers, change the cursor to a pointer. map.events.add('mouseover', [clusterBubbleLayer, iconLayer], function() { map.getCanvasContainer().style.cursor = 'pointer'; }); //When the mouse leaves the item on the cluster and icon layers, change the cursor back to the default (grab). map.events.add('mouseout', [clusterBubbleLayer, iconLayer], function() { map.getCanvasContainer().style.cursor = 'grab'; }); //Add a click event to the cluster layer. When the user selects a cluster, zoom into it by two levels. map.events.add('click', clusterBubbleLayer, function(e) { map.setCamera({ center: e.position, zoom: map.getCamera().zoom + 2 }); }); //Add a click event to the icon layer and show the shape that was selected. map.events.add('click', iconLayer, function(e) { showPopup(e.shapes[0]); }); //Add an event to monitor when the map is finished rendering the map after it has moved. map.events.add('render', function() { //Update the data in the list. updateListItems(); }); });Kahve dükkanı veri kümesi yüklendiğinde, önce indirilmelidir. Sonra, metin dosyası çizgilere bölünmelidir. İlk satır üst bilgi bilgilerini içerir. Kodun izlenmesini kolaylaştırmak için üst bilgiyi bir nesnesine ayrıştırır, bu da daha sonra her bir özelliğin hücre dizinini aramak için kullanabiliriz. İlk satırdan sonra, kalan satırlarda ilerleyin ve bir nokta özelliği oluşturun. Point özelliğini veri kaynağına ekleyin. Son olarak, liste panelini güncelleştirin.
function loadStoreData() { //Download the store location data. fetch(storeLocationDataUrl) .then(response => response.text()) .then(function(text) { //Parse the tab-delimited file data into GeoJSON features. var features = []; //Split the lines of the file. var lines = text.split('\n'); //Grab the header row. var row = lines[0].split('\t'); //Parse the header row and index each column to make the code for parsing each row easier to follow. var header = {}; var numColumns = row.length; for (var i = 0; i < row.length; i++) { header[row[i]] = i; } //Skip the header row and then parse each row into a GeoJSON feature. for (var i = 1; i < lines.length; i++) { row = lines[i].split('\t'); //Ensure that the row has the correct number of columns. if (row.length >= numColumns) { features.push(new atlas.data.Feature(new atlas.data.Point([parseFloat(row[header['Longitude']]), parseFloat(row[header['Latitude']])]), { AddressLine: row[header['AddressLine']], City: row[header['City']], Municipality: row[header['Municipality']], AdminDivision: row[header['AdminDivision']], Country: row[header['Country']], PostCode: row[header['PostCode']], Phone: row[header['Phone']], StoreType: row[header['StoreType']], IsWiFiHotSpot: (row[header['IsWiFiHotSpot']].toLowerCase() === 'true') ? true : false, IsWheelchairAccessible: (row[header['IsWheelchairAccessible']].toLowerCase() === 'true') ? true : false, Opens: parseInt(row[header['Opens']]), Closes: parseInt(row[header['Closes']]) })); } } //Add the features to the data source. datasource.add(new atlas.data.FeatureCollection(features)); //Initially, update the list items. updateListItems(); }); }Liste paneli güncelleştirilirken uzaklık hesaplanır. Bu uzaklık, haritanın merkezinden geçerli harita görünümündeki tüm nokta özelliklerine kadar olur. Özellikler daha sonra uzaklığına göre sıralanır. Her konumu liste panelinde göstermek için HTML oluşturulur.
var listItemTemplate = '<div class="listItem" onclick="itemSelected(\'{id}\')"><div class="listItem-title">{title}</div>{city}<br />Open until {closes}<br />{distance} miles away</div>'; function updateListItems() { //Hide the center marker. centerMarker.setOptions({ visible: false }); //Get the current camera and view information for the map. var camera = map.getCamera(); var listPanel = document.getElementById('listPanel'); //Check to see whether the user is zoomed out a substantial distance. If they are, tell the user to zoom in and to perform a search or select the My Location button. if (camera.zoom < maxClusterZoomLevel) { //Close the pop-up window; clusters might be displayed on the map. popup.close(); listPanel.innerHTML = '<div class="statusMessage">Search for a location, zoom the map, or select the My Location button to see individual locations.</div>'; } else { //Update the location of the centerMarker property. centerMarker.setOptions({ position: camera.center, visible: true }); //List the ten closest locations in the side panel. var html = [], properties; /* Generating HTML for each item that looks like this: <div class="listItem" onclick="itemSelected('id')"> <div class="listItem-title">1 Microsoft Way</div> Redmond, WA 98052<br /> Open until 9:00 PM<br /> 0.7 miles away </div> */ //Get all the shapes that have been rendered in the bubble layer. var data = map.layers.getRenderedShapes(map.getCamera().bounds, [iconLayer]); //Create an index of the distances of each shape. var distances = {}; data.forEach(function (shape) { if (shape instanceof atlas.Shape) { //Calculate the distance from the center of the map to each shape and store in the index. Round to 2 decimals. distances[shape.getId()] = Math.round(atlas.math.getDistanceTo(camera.center, shape.getCoordinates(), 'miles') * 100) / 100; } }); //Sort the data by distance. data.sort(function (x, y) { return distances[x.getId()] - distances[y.getId()]; }); data.forEach(function(shape) { properties = shape.getProperties(); html.push('<div class="listItem" onclick="itemSelected(\'', shape.getId(), '\')"><div class="listItem-title">', properties['AddressLine'], '</div>', //Get a formatted addressLine2 value that consists of City, Municipality, AdminDivision, and PostCode. getAddressLine2(properties), '<br />', //Convert the closing time to a format that is easier to read. getOpenTillTime(properties), '<br />', //Get the distance of the shape. distances[shape.getId()], ' miles away</div>'); }); listPanel.innerHTML = html.join(''); //Scroll to the top of the list panel in case the user has scrolled down. listPanel.scrollTop = 0; } } //This converts a time that's in a 24-hour format to an AM/PM time or noon/midnight string. function getOpenTillTime(properties) { var time = properties['Closes']; var t = time / 100; var sTime; if (time === 1200) { sTime = 'noon'; } else if (time === 0 || time === 2400) { sTime = 'midnight'; } else { sTime = Math.round(t) + ':'; //Get the minutes. t = (t - Math.round(t)) * 100; if (t === 0) { sTime += '00'; } else if (t < 10) { sTime += '0' + t; } else { sTime += Math.round(t); } if (time < 1200) { sTime += ' AM'; } else { sTime += ' PM'; } } return 'Open until ' + sTime; } //Create an addressLine2 string that contains City, Municipality, AdminDivision, and PostCode. function getAddressLine2(properties) { var html = [properties['City']]; if (properties['Municipality']) { html.push(', ', properties['Municipality']); } if (properties['AdminDivision']) { html.push(', ', properties['AdminDivision']); } if (properties['PostCode']) { html.push(' ', properties['PostCode']); } return html.join(''); }Kullanıcı liste panelinde bir öğe seçtiğinde, öğenin ilişkili olduğu şekil veri kaynağından alınır. Şeklin içinde depolanan Özellik bilgilerini temel alan bir açılır pencere oluşturulur. Harita, şeklin üzerine ortalar. Eşleme 700 pikselden daha azsa, harita görünümü, açılır pencere görünür olacak şekilde denkleştirilir.
//When a user selects a result in the side panel, look up the shape by its ID value and display the pop-up window. function itemSelected(id) { //Get the shape from the data source by using its ID. var shape = datasource.getShapeById(id); showPopup(shape); //Center the map over the shape on the map. var center = shape.getCoordinates(); var offset; //If the map is fewer than 700 pixels wide, then the layout is set for small screens. if (map.getCanvas().width < 700) { //When the map is small, offset the center of the map relative to the shape so that there is room for the popup to appear. offset = [0, -80]; } map.setCamera({ center: center, centerOffset: offset }); } function showPopup(shape) { var properties = shape.getProperties(); /* Generating HTML for the pop-up window that looks like this: <div class="storePopup"> <div class="popupTitle"> 3159 Tongass Avenue <div class="popupSubTitle">Ketchikan, AK 99901</div> </div> <div class="popupContent"> Open until 22:00 PM<br/> <img title="Phone Icon" src="images/PhoneIcon.png"> <a href="tel:1-800-XXX-XXXX">1-800-XXX-XXXX</a> <br>Amenities: <img title="Wi-Fi Hotspot" src="images/WiFiIcon.png"> <img title="Wheelchair Accessible" src="images/WheelChair-small.png"> </div> </div> */ //Calculate the distance from the center of the map to the shape in miles, round to 2 decimals. var distance = Math.round(atlas.math.getDistanceTo(map.getCamera().center, shape.getCoordinates(), 'miles') * 100)/100; var html = ['<div class="storePopup">']; html.push('<div class="popupTitle">', properties['AddressLine'], '<div class="popupSubTitle">', getAddressLine2(properties), '</div></div><div class="popupContent">', //Convert the closing time to a format that's easier to read. getOpenTillTime(properties), //Add the distance information. '<br/>', distance, ' miles away', '<br /><img src="images/PhoneIcon.png" title="Phone Icon"/><a href="tel:', properties['Phone'], '">', properties['Phone'], '</a>' ); if (properties['IsWiFiHotSpot'] || properties['IsWheelchairAccessible']) { html.push('<br/>Amenities: '); if (properties['IsWiFiHotSpot']) { html.push('<img src="images/WiFiIcon.png" title="Wi-Fi Hotspot"/>'); } if (properties['IsWheelchairAccessible']) { html.push('<img src="images/WheelChair-small.png" title="Wheelchair Accessible"/>'); } } html.push('</div></div>'); //Update the content and position of the pop-up window for the specified shape information. popup.setOptions({ //Create a table from the properties in the feature. content: html.join(''), position: shape.getCoordinates() }); //Open the pop-up window. popup.open(map); }
Artık tam işlevli bir depolama Konumlayıcı vardır. Bir Web tarayıcısında, mağaza bulucunun index.html dosyasını açın. Kümeler haritada görüntülendiğinde, arama kutusunu kullanarak, bir küme seçerek veya tek tek konumları görmek için haritada yakınlaştırarak bir konum araması yapabilirsiniz ' ı seçin.
Kullanıcı konumumu ilk kez seçtiğinde tarayıcı, kullanıcının konumuna erişmek için izin isteyen bir güvenlik uyarısı görüntüler. Kullanıcı konumunu paylaşmayı kabul ederse, harita kullanıcının konumuna yakınlaşarak yakın kafeterler gösterilir.

Kahve dükterleri bulunan bir alanda yeterince yakından yakınlaştırdığınızda, kümeler tek tek konumlara ayrılır. Harita üzerindeki simgelerden birini seçin veya açılan pencereyi görmek için yan paneldeki bir öğeyi seçin. Açılır pencere, seçili konum için bilgileri gösterir.

Tarayıcı penceresini 700 piksel genişliğinde veya uygulamayı bir mobil cihazda açtığınızda, düzen daha küçük ekranlarda daha uygun olacak şekilde değişir.

bu öğreticide, Azure Haritalar kullanarak temel bir mağaza konumlandırıcısı oluşturmayı öğrendiniz. Bu öğreticide oluşturduğunuz mağaza Bulucu, ihtiyacınız olan tüm işlevlere sahip olabilir. Mağaza bulucusinize özellikler ekleyebilir veya daha özel bir kullanıcı deneyimi için daha gelişmiş özellikler kullanabilirsiniz:
- Arama kutusuna yazarken önerileri etkinleştirin.
- Birden çok dil için destekekleyin.
- Kullanıcının bir rota üzerinde konumları filtrelemesineizin verin.
- Filtre ayarlamaözelliğini ekleyin.
- Sorgu dizesi kullanarak bir ilk arama değeri belirtmek için destek ekleyin. Bu seçeneği mağaza bulucuya eklediğinizde, kullanıcılar daha sonra arama yapabilir ve aramaları paylaşabilir. Ayrıca, aramaları başka bir sayfadan bu sayfaya geçiş yapmak için kolay bir yöntem sağlar.
- Mağaza bulucularınızı web uygulaması Azure App Service dağıtın.
- Verilerinizi bir veritabanında depolar ve yakındaki konumları arayabilirsiniz. Daha fazla bilgi edinmek için uzamsal SQL Server türlerine genel bakış ve En yakın komşu için uzamsal verileri sorgulama'ya bakın.
Kaynak kodunun tamamını burada görüntüebilirsiniz. Canlı örneği görüntüleme ve Yakınlaştırma düzeyleri ve kutucuk kılavuzu kullanarak Azure Haritalar kapsamı ve özellikleri hakkında daha fazla bilgi edinin. İş mantığınıza uygulamak için veri odaklı stil ifadeleri de kullanabilirsiniz.
Kaynakları temizleme
Temizleme gerektiren bir kaynak yoktur.
Sonraki adımlar
Daha fazla kod örneği ve etkileşimli bir kodlama deneyimi için: