+3

Học nhanh Goong Maps - Part 1

Nếu bạn đã đọc bài viết này, thì sẽ nhận ra Goong Maps cung cấp đến 100 javascript front end 😵. Chính vì vậy, việc ngồi đọc hết phần docs là điều vô cùng khó khăn. Để giúp các bạn mới bắt đầu tìm hiểu về Maps API mình đã tổng hợp những kiến thức cốt lõi và thường dùng nhất về Goong Maps API (được ứng dụng trong các use-case).

Ngoài ra, để việc học có thể đi đôi với hành, nhanh chóng làm chủ Goong Maps API mình đã có một bài viết tại đây (mình sẽ viết trong thời gian tới), các bạn có thể kết hợp thực hành để hiểu hơn phần lý thuyết nhé.

Khởi tạo API Key trên Goong Maps

Nếu bạn lần đầu tiên sử dụng Goong Maps hoặc đang cân nhắc sử dụng Google Maps API cho dự án của mình thì, bạn có thể tham khảo bài viết Mình đã biết đến Goong Maps như thế nào?Hướng dẫn chuyển đổi Google Maps API sang Goong Maps API để có thể đưa ra quyết định lựa chọn. Cùng với đó là để được hướng dẫn chi tiết về cách khởi tạo Goong Maps API Key.

Tổng quan về Goong JS API

Tổng quan về Goong JS API bạn có thể chia mọi kiến thức vào 4 nhánh chính đó là:

  • Map: với các Instance (thao tác với Map) như : addControl, addSource, addLayer,...
  • Marker & Control: Bao gồm marker (điểm đánh dấu), các Control như: Navigation, Geolocate,...
  • Events: Sự kiện “lớn”
  • Style specification: Các kiến thức riêng biệt

Map

Object: Map

Trong Goong Maps thì Map là một object quan trọng nhất để hiển thị bản đồ trên website của bạn với các thuộc tính tùy chỉnh. Và đóng vai trò như một container chứa và khởi tạo các Map Control, Map Events,...

Trong Object Map, chúng ta cần quan tâm đến một số thuộc tính thường dùng sau:

Thuộc tính Giải thích
options.container

Giá trị truyền vào: HTML Element hoặc string là id của HTML Element
Đây là thuộc tính quan trọng nhất, xác định phần tử HTML sẽ được Goong GL JS khởi tạo Map.

Lưu ý: thẻ HTML khởi tạo Map không được chứa các thẻ con
options.style

Bạn có thể lựa chọn một trong các style sau:
https://tiles.goong.io/assets/goong_light_v2.json
https://tiles.goong.io/assets/goong_map_web.json
https://tiles.goong.io/assets/goong_map_dark.json
https://tiles.goong.io/assets/navigation_day.json
https://tiles.goong.io/assets/navigation_night.json
Goong Maps cung cấp các style khác nhau thông qua các URL JSON.

Xem thử các style khác nhau trên Map tại đây: https://docs.goong.io/example/setstyle/
options.center

Giá trị truyền vào: [kinh độ, vĩ độ]
Giá trị mặc định: [0, 0]
Đây là thuộc tính giúp bạn xác định điểm trung tâm khi khởi tạo bản đồ.

Lưu ý: Goong Maps sử dụng cặp giá trị [kinh độ, vĩ độ] (có đôi chút trái ngược với một số API về Map khác)
options.zoom

Giá trị truyền vào: Số nguyên
Giá trị mặc định: 0
Thuộc tính này sẽ giúp bạn thiết lập mức độ zoom của bản đồ.

Code demo:

var map = new goongjs.Map({
      container: 'map',
      style: 'https://tiles.goong.io/assets/goong_map_web.json', // stylesheet location
      center: [108.212, 16.068], // starting position [lng, lat]
      zoom: 5 // starting zoom
    });

Instance Members: addControl

Để thêm các control vào Object Map

Cú pháp: addControl(IControl, position*)

Lưu ý về ý nghĩa cách viết giải thích của mình: <tên thuộc tính> (kiểu dữ liệu truyền vào) (ghi chú)

Giải thích

  • IControl: control bạn muốn thêm vào Object map
  • position (string) (tham số không bắt buộc): Nhận giá trị là một string chỉ vị trí mà IControl sẽ hiển thị trên Map. Các giá trị mà position có thể nhận: 'top-left' , 'top-right' , 'bottom-left' , 'bottom-right' - Giá trị mặc định: 'top-right'

Ex: map.addControl(zoom, 'bottom-right');

Instance Members: addSource

Thêm nguồn dữ liệu/tài nguyên vào bản đồ

Cú pháp: addSource(id, source)

  • id (string): Mã id được đặt cho nguồn dữ liệu/tài nguyên mà bạn sẽ thêm vào
  • source (Object): Nguồn dữ liệu/tài nguyên bạn thêm vào có thể ở dạng một object hoặc một URL.

Code demo:

map.addSource('my-data', {
  type: 'vector',
  url: 'mapbox://myusername.tilesetid'
});

Instance Members: addLayer

Thêm vào map một Layer để thiết lập style cho source

Cú pháp: addLayer(layer, beforeId)

  • layer ((Object | CustomLayerInterface)): Style của layer được thêm vào.
  • beforeId (string) (tham số không bắt buộc): Được sử dụng để phân lớp layer (lớp nào ở trên và lớp nào ở dưới)

Code demo:

// Add a circle layer with a vector source.
map.addLayer({
  id: 'points-of-interest',
  source: {
    type: 'vector',
    url: 'mapbox://mapbox.mapbox-streets-v8'
  },
  'source-layer': 'poi_label',
  type: 'circle',
  paint: {
    // Mapbox Style Specification paint properties
  },
  layout: {
    // Mapbox Style Specification layout properties
  }
});

Instance Members: getSource

Trả về nguồn có ID được chỉ định theo kiểu của bản đồ.

Instance Members: queryRenderedFeatures

Trả về một mảng các đối tượng GeoJSON Feature objects đại diện cho các đối tượng có thể nhìn thấy thỏa mãn các tham số truy vấn

Cú pháp: queryRenderedFeatures(geometry, options)

  • geometry((PointLike | Array <PointLike>)): Thiết lập hình dạng cho vùng truy vấn: Một điểm đơn lẻ hoặc cặp điểm theo hướng [tây nam, đông bắc] mô tả một không gian giới hạn. Nếu bạn bỏ qua tham số này (tức là gọi queryRenderedFeatures không có đối số hoặc chỉ có đối số tùy chọn) thi sẽ tương đương với việc chọn một không gian toàn bản đồ
  • options(Object?): Có các giá trị sau:
Thuộc tính Giải thích
options.layers

Giá trị truyền vào: Array<string>
Một mảng các style layer IDs để truy vấn kiểm tra. (Chỉ các tính năng trong các lớp này sẽ được trả về)

Nếu bỏ qua tham số này, tất cả các lớp sẽ được kiểm tra.
options.filter

Giá trị truyền vào: Array
Giới hạn kết quả tìm được từ mỗi truy vấn
options.validateboolean

Giá trị mặc định: true
Kiểm tra xem [options.filter] có tuân theo Mapbox GL Style Specification hay không.

Để tối ưu hóa hiệu xuất bạn có thể tắt chức năng này. Hãy sử dụng nó khi thực sự cần thiết.

Instance Members: getCanvas

Trả về cho map thuộc tính <canvas>

Bạn có thể đọc thêm về HTMLCanvasElement

Controls

NavigationControl

NavigationControl là một control giúp map của bạn có thêm chức năng zoom và một la bàn định hướng bản đồ.

Các thuộc tính thường dùng trong Navigation Control là:

Thuộc tính Giải thích
options.showCompass

Giá trị truyền vào: Boolean
Giá trị mặc định: true
Nếu giá trị truyền vào là true, nút la bàn sẽ hiển thị
options.showZoom

Giá trị truyền vào: Boolean
Giá trị mặc định: true
Nếu giá trị truyền vào là true, chức năng zoom với 2 nút phóng to và thu nhỏ sẽ được hiển thị

GeolocateControl

GeolocateControl cung cấp một nút sử dụng API định vị địa lý của trình duyệt để xác định vị trí của người dùng trên bản đồ.

Lưu ý: GeolocateControl chỉ hiển thị trên các trình duyệt hỗ trợ định vị vị trí địa lý và trang web phải được truy cập với giao thức HTTPS.

Thuộc tính Giải thích
options.positionOptions

Giá trị mặc định: {enableHighAccuracy:false,timeout:6000}
API định vị vị trí PositionOptions
options.trackUserLocation

Giá trị mặc định: false
Nếu nhận giá trị false. Goong sẽ xác định vị trí của người dùng một lần duy nhất

Nếu nhận giá trị true Thông tin về vị trí địa lý của người dùng sẽ được cập nhật liên tục với 3 chế độ thiết lập

* active - khung hình bản đồ tự động dịch chuyển khi vị trí của người dùng thay đổi, giữ cho điểm đánh dấu vị trí người dùng luôn ở trung tâm.
* passive - Chỉ có điểm đánh dấu vị trí người dùng di chuyển, còn khung hình bản đồ giữ nguyên.
disabled
options.showUserLocation

Giá trị mặc định: true
Nếu giá trị là true, một dấu chấm sẽ được hiển thị trên bản đồ tại vị trí của người dùng.

Code demo:

var getLocal = new goongjs.GeolocateControl(
      {
        positionOptions: {
          enableHighAccuracy:false,
          timeout:6000
        },
        trackUserLocation: false,
        showUserLocation: true
      })

Events

Evented: On

Evented này có tác dụng lắng nghe sự kiện được chỉ định.

Cú pháp 1: on(type, listener)

  • type (string) Kiểu event của Map hoặc Controls được lắng nghe. Nhận một trong các giá trị sau: 'mousedown' , 'mouseup' , 'click' , 'dblclick' , 'mousemove' , 'mouseenter' , 'mouseleave' , 'mouseover' , 'mouseout' , 'contextmenu' , 'touchstart' , 'touchend' , 'touchcancel'
  • listener (Function) Hàm sẽ thực thi khi kiểu event của Map hoặc Controls xảy ra.

Cú pháp 2: on(type, layerID, listener)

Ở cú pháp 2 này có thêm tham số layerID. Điều này có nghĩa chỉ thực thi khi sự kiện diễn ra trên layer có ID được truyền vào tham số layerID..

Map event: load

Được kích hoạt ngay lập tức sau khi tất cả các tài nguyên cần thiết đã được load và hiển thị bản đồ lần đầu hoàn tất.

STYLE SPECIFICATION

Sources

Để xác định cụ thể nguồn dữ liệu hoặc tài nguyên sử dụng, bạn cần sử dụng thuộc tính type

Giới thiệu về GeoJSON

Dành cho những bạn chưa thao tác với dữ liệu trên bản đồ thì GeoJSON là một dạng cấu trúc dữ liệu địa lý, dựa trên JavaScript Object Notation (JSON). Nó thể hiện chức năng địa lý, thuộc tính và dữ liệu hình học. GeoJSON sử dụng hệ tọa độ địa lý World Geodetic System 1984 (WGS84) và đơn vị độ thập phân.

Về cấu trúc sẽ gồm 3 thuộc tính chính, đó là type, geometry, properties. Trong đó:

  • type: kiểu dữ liệu của file GeoJSON này. Gồm các loại sau:
    • Feature: Chỉ 1 đối tượng địa lý.
    • FeatureCollection: Tập hợp nhiều đối tượng địa lý.
  • geometry: toạ độ của đối tượng. Gồm các loại sau:
    • Point: Một điểm. Thường được dùng việc hiển thị marker.
    • LineString: Một đường thẳng.
    • MultiLineString: Tập hợp nhiều đường thẳng.
    • Polygon: Một đa giác.
    • MultiPolygon: Tập hợp nhiều đa giác.
    • GeometryCollection: Tập hợp nhiều loại hình học khác nhau.
  • properties: danh sách thuộc tính của đối tượng.

image.png

geojson trong Goong Maps

Để bắt đầu sử dụng geojson, bạn hãy đặt giá trị cho thuộc tính type như sau:

type: 'geojson'

Tiếp theo là dữ liệu geojson cần phải được đặt trong thuộc tính data. Giá trị mà thuộc tính này nhận có thể là một URL hoặc một object dạng GeoJSON.

"geojson-marker": {
    "type": "geojson",
    "data": {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [-77.0323, 38.9131]
        },
        "properties": {
            "title": "Mapbox DC",
            "marker-symbol": "monument"
        }
    }
}

Layers

Các thuộc tính của layers như sau:

Thuộc tính Giải thích
id

Giá trị bắt buộc - Nhận định dạng string
ID được gán cho layer
type

Giá trị bắt buộc - Nhận định dạng string
Là một trong các kiểu layer sau: "fill", "line", "symbol", "circle", "heatmap", "fill-extrusion", "raster", "hillshade", "background".
source

Bắt buộc đối với mọi layer. Ngoại trừ layer kiểu background
ID source được sử dụng cho layer
filter

Giá trị tùy chọn - Nhận một expression.
Một biểu thức xác định các điều kiện lọc trên Sources. (Để hiểu hơn hãy đọc Expression ở mục dưới)
paint

Giá trị tùy chọn - Nhận định dạng paint
Thuộc tính có tác dụng vẽ layer lên map
layout Tại đây có một số thuộc tính quen thuộc:
'text-field': '{point_count_abbreviated}',
'text-font': ['Roboto Regular'],
'text-size': 12

Circle

Khi vẽ hình tròn trên map, bạn cần quan tâm đến một số thuộc tính của hình tròn như sau:

Thuộc tính Giải thích
circle-color

Giá trị tùy chọn - Nhận vào một mã màu
Giá trị mặc định: "#000000"

Hỗ trợ sử dụng trong expression loại: feature-stateinterpolate
Đổ màu cho hình tròn
circle-radius

Giá trị tùy chọn - Nhận vào một số nguyên (lớn hơn hoặc bằng 0)
Giá trị mặc định: 5
Đơn vị: px
Bán kính hình tròn
circle-stroke-width

Giá trị tùy chọn - Nhận vào một số nguyên (lớn hơn hoặc bằng 0)
Giá trị mặc định: 0
Đơn vị: px
Thiết lập độ dày cho đường viền hình tròn
circle-stroke-color

Giá trị tùy chọn - Nhận vào một mã màu
Giá trị mặc định: "#000000"
Thiết lập màu cho đường viền hình tròn

Expression

Cú pháp:[expression_name, argument_0, argument_1, ...]

  • Expression_name là một trong các giá trị sau: get, has, id, geometry-type, properties, step, feature-state
  • argument_0, argument_1, …: là các đối số

Lưu ý: feature-state chỉ hoạt động trong tham số paint của Layers

get

Trả về giá trị của một thuộc tính trong các đối tượng được cung cấp thông qua các đối số. Trả về null nếu không tìm thấy thuộc tính trong các đối số.

['get', 'point_count']

has

Kiểm tra có tồn tại một thuộc tính trong các đối tượng được cung cấp thông qua các đối số.

['has', 'point_count']

step

Tạo ra một chuỗi các input và output rời rạc

["step",
    input: number,
    stop_output_0: OutputType,
    stop_input_1: number, stop_output_1: OutputType,
    stop_input_n: number, stop_output_n: OutputType, ...
]: OutputType
  • input có thể là bất cứ một biểu thức numeric nào.

Mình sẽ lấy một ví dụ giúp các bạn hiểu dễ hơn: Giả sử, mình có một bộ dữ liệu về số lượng nhà hàng theo từng tỉnh thành. Và mình muốn hiển thị một hình tròn kèm theo số tổng số nhà hàng tại mỗi tỉnh đó.

Để trực quan hơn mình muốn các tỉnh có số lượng nhà hàng theo nhóm ít, nhiều, cực nhiều sẽ có màu sắc khác nhau. Chẳng hạn:

  • Hiển thị màu xanh với những tỉnh có số lượng nhà hàng ít hơn 100
  • Hiển thị màu vàng với những tỉnh có số lượng nhà hàng từ 100 -> 750
  • Hiển thị màu đỏ với những tỉnh có số lượng nhà hàng trên 750

Lúc này step sẽ có tác dụng và code sẽ trông như sau

'circle-color': [
            'step',
            ['get', 'point_count'], //input
            '#51bbd6', 
            100,  '#f1f075', 
            750,  '#f28cb1'
          ],

Toán tử !

Toán tử logic. Trả về true nếu nhận vào giá trị false và ngược lại.

Cluster

Để có thể gom các markers hoặc điểm thành một cụm bạn có thể tạo một cluster với Goong Maps. Nó sẽ trông giống như sau:

image.png

Để có thể thiết lập được chế độ cluster bạn phải có một Source dạng GeoJSon. Khi thiết lập geojson bạn cần thêm một số thuộc tính sau:

Thuộc tính Giải thích
cluster

Giá trị truyền vào: Boolean
Giá trị mặc định: false
Nếu giá trị truyền vào là true, cluster sẽ được kích hoạt.

Đặc biệt lưu ý: Khi này, GL-JS sẽ tự động thêm một thuộc tính là: point_count vào source data của bạn
clusterMaxZoom

Giá trị truyền vào: Số nguyên
Độ zoom tối đa tới một điểm trong cluster
clusterRadius

Giá trị truyền vào: Số nguyên
Giá trị mặc định: 50
Bán kính của cluster khi hiển thị các điểm

Code demo:

map.addSource('earthquakes', {
        type: 'geojson',
        // Point to GeoJSON data. This example visualizes all M1.0+ earthquakes
        // from 12/22/15 to 1/21/16 as logged by USGS' Earthquake hazards program.
        data: 'https://docs.goong.io/assets/earthquakes.geojson',
        cluster: true,
        clusterMaxZoom: 14, // Max zoom to cluster points on
        clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
      });

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.