Sử dụng Map API cho website của bạn – LeafletJS

Sử dụng Map API cho website của bạn – LeafletJS

Chào các bạn,

Dạo gần đây, nhu cầu dùng map của người dùng là rất nhiều, Map sửa dụng và xuất hiện ở khắp mọi nơi, từ web đến mobile,…

Về dịch vụ cung cấp & API thì mạnh nhất là Google Maps, không ai dám xưng nhì. Nhưng gần đây google đã update lại policy & pricing => giá thành rất là cao.

Vậy nên, đối với các nhu cầu cơ bản nhất định, ta có thể tìm một bên thứ ba khác để hỗ trợ ta vụ này. Không dùng hết APIs của Google Maps mà dùng nó thì khá là tốn $$$ =))
có dịch vụ sử dụng leafletJS ra đời vì việc đó, bao gồm:

  • Free to use
  • Open license
  • Cập nhập cũng rất ổn, không thua gì nhiều so với Google Maps.

Hiện nay cũng có khá nhiều website đang sử dụng và Việt Nam cũng có nữa đó các bạn 😀

Tuy nhiên, để implement Map lên website, ta cần phải dùng thông qua một library(thư viện) có tên là LeafletJS.
Sau đây mình sẽ hướng dẫn cho các bạn nhé.

Thực hiện cấu hình map

1/ Tải library/thư viện LeafletJS

Truy cập vào đây để tải về nhé bạn hoặc dùng CDN của LeafletJS free:

https://leafletjs.com/download.html

Mình thì sẽ sử dụng CDN cho nhanh và tiện nhé 😀

2/ Import Library và Init Map đơn giản

Mình import css/js này:

 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
 <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>

Sau đó tạo ra một cái container và set ID cho nó nhé:

<body>
  <div id="map"></div>
</body>

Nhớ là cái container của id map nó phải có height cụ thể (px, %, ...):

<style>
  #map{
	width:100%;
	height:100%;
  }
</style>

Rồi các bạn viết với một đoạn JS như sau:

var map = L.map('map').setView([21.02014554822514, 105.784259312448], 13);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

Map sẽ hiện ra như sau:
map

Các bạn có thể xem demo: XEM DEMO

3/ Thêm Marker và click vào Marker hiện Popup

Ta chỉ cần dùng hàm marker như sau tạo xong nhớ add vào map:

L.marker([lat, lng], objOptions).addTo(map);

Với objOptions các bạn có thể xem chi tiết ở đây: Link detail
Tạo 1 marker cơ bản và gán vào map:

L.marker([10.7743, 106.6669]).addTo(map);

Test code thì các bạn được như sau:

123

Các bạn có thể xem demo: XEM DEMO

Như các bạn đã biết thì marker chúng ta chả biết được gì nhiều các thông tin của vị trí đó, phải zoom to nhất có khi mới rõ chỗ. Vậy nên Map nào nó cũng có cái Popup đi kèm.

Ta phải nói là Marker và Popup là đôi bạn thân 😀 đơn giản hình dung là vậy.

Tạo popup thì như sau:

L.popup(objOption, layer);

Với cái marker mặc định đó ta tạo popup và gán cho nó như sau:

var marker = L.marker([21.02014554822514, 105.784259312448]).addTo(map);
var inforWindown = L.popup({ closeOnClick: false})
  .setLatLng(marker.getLatLng())
  .setContent('"<b>Hello Everyone</b> <br> Hello World!!!!"');
  marker.bindPopup(inforWindown);
  inforWindown.openOn(map);

Kết quả khi click vào marker:

clickmarker

Nếu các bạn muốn marker hiển thị liền với popup chúng ta sử dụng hai hàm này tuy vào từng trường hợp:

marker.openPopup();
inforWindown.openOn(map);

Các bạn có thể xem demo: XEM DEMO

Các bạn muốn sử dụng tooltip khi di chuột vào marker thì cách bạn sử dụng như sau:

marker.bindTooltip("Tooltip !!!");

Khi bạn di chuột đến marker thì tooltip "Tooltip !!!" sẽ hiện ra 😀.

4/ Styling cho Popup

Thêm một chút style để hiện hình bên trái và một số text bên phải:

.popup-content {
  width: 300px;
}
		
.popup-content .left {
  float:left;
  width: 40%;
}
.popup-content .left img {
  width:100%;
  height:100px;
  margin: -11px 0 -15px -20px;
  border-radius:12px;
}

.popup-content .right {
  float:left;
  width: 60%;
}

.clearfix {
  clear:both;
}

Sau đó thêm đoạn code js hoặc chỉnh sửa code js trước đó bạn biết như sau:

var markerCoord = [21.02014554822514, 105.784259312448]; // Toạ độ marker
var popupOption = {
  className: "popup-content",
  closeOnClick: false
};
 var popupContent = `
 <div class='left'>
     <img src='https://cellphones.com.vn/sforum/wp-content/uploads/2018/11/2-8.png' />
 </div>
 <div class='right'>
     <p>"<strong>Hello Everyone!</strong> <br> Welcome to my map!!!!"</p>
 </div>
 <div class='clearfix'></div>`;

var marker = L.marker(markerCoord).addTo(map);
var inforWindown = L.popup(popupOption)
.setLatLng(marker.getLatLng())
.setContent(popupContent);
marker.bindPopup(inforWindown);
inforWindown.openOn(map);

Map hiển thị lên với kết quả như sau:

2
=> Các bạn muốn style như nào tùy vào các bạn nhé 😀

Các bạn có thể xem demo: XEM DEMO

5/ marker ClusterGroup

Hướng dẫn này chỉ cho bạn cách sử dụng các cụm điểm đánh dấu để hiển thị một số lượng lớn các điểm đánh dấu trên bản đồ.
Bạn có thể sử dụng thư viện MarkerClusterer kết hợp với API JavaScript của LefletJs để kết hợp các điểm đánh dấu gần nhau thành các cụm và đơn giản hóa việc hiển thị các điểm đánh dấu trên bản đồ.

Mình sẽ lấy ví dụ như sau:

3

  • Như các bạn đã nhìn thấy thì các marker nhiều sẽ làm cho chúng ta loạn mắt khó nhìn
    chính điều đó chúng ta cần gộp chúng lại thành những điểm và có các con số thống kê cụ thể.
    Ví dụ như hình dưới đây:

4
Để thực hiện được điều đó chúng ta làm như sau:

Các bạn cần import thêm CDN css/js sau:

<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.Default.css" />
<script src="https://unpkg.com/leaflet.markercluster@1.3.0/dist/leaflet.markercluster.js"></script>

Trong phần Js các bạn cần phải lấy được một tập hợp các điểm location trên bản đồ map:
mình sẽ lấy một tập hợp các điểm như sau:

var addressPoints = [
  [21.047185530868, 105.81806964398888, "2"],
  [21.033718372066183, 105.78636096825407, "3"],
  [21.013641375127147, 105.80241319457676, "3A"],
  [21.014539867700403, 105.82049271225165, "1"],
  [21.00705521078788, 105.71594231528208, "5"],
  [21.044343688606382, 105.88183605852102, "7"],
  [21.14227137692819, 105.83794347615343, "537"],
  [20.943522034828668, 106.07520510176208, "454"],
  [20.91188071724392, 105.81905456552911, "176"],
  [20.9185426025085, 105.97357693077404, "178"],
  [12.879135146877635, 108.23404103956851, "190"],
  [11.324853651908152, 107.14849588123124, "156"],
  [19.51955232468305, 104.57671548473961, "210"],
  [18.79304129044341, 105.7292465323276, "212"],
  [18.78844747720122, 105.32325888711638, "146"],
  [18.87035164726613, 105.50926916281077, "125"],
  [19.851682548825583, 105.74253544479204, "174"],
  [19.76444044325432, 105.89610964250022, "129"]
];

Đến đây các bạn đã làm được 60% rồi. Tiếp đến chúng ta cần viết một đoạn code để tổng hợp chúng thành một group hoặc một vùng nào đó. Dưới đây là một ví dụ code với tập hợp các điểm trên.

var markers = L.markerClusterGroup();

for (var i = 0; i < addressPoints.length; i++) {
  var a = addressPoints[i];
  var title = a[2];
  var marker = L.marker(new L.LatLng(a[0], a[1]), {
    title: title
  });
  marker.bindPopup(title);
  markers.addLayer(marker);
}

map.addLayer(markers);

=> Kết quả chúng ta đạt được đó là:

5-1

Các bạn có thể xem demo: XEM DEMO

6/ Kết luận:

Với một số thông tin cơ bản như trên, sau bài viết này thì các bạn đã có thể sử dụng LeafletJS Map một cách cơ bản gồm:

  • Init map trên website
  • Tạo marker
  • Tạo popup, tooltip cho marker
  • Custom styling cho Popup
  • CLusterMarker group

Và một cái lưu ý nữa khi mà các bạn sử dụng để thay đổi kích thước bản đồ của map cho màn hình mobile thì các bạn cần thêm hàm này hay đoạn code này để sử lý được việc đó.

 if (map) {
   map.invalidateSize();
 } else {
   map = new L.map('map', obtion)
 }

Các bạn check xem map đã được khởi tạo chưa:

  • Nếu có thì chúng ta resize map bằng hàm: invalidateSize()
  • Ngược lại thì chúng ta khởi tạo một map mới.
Thank you for reading!. Hẹn Gặp lại các bạn vào các bài tiếp theo!!