Tích hợp ô nhập địa chỉ
seo_title: "Tích hợp ô nhập địa chỉ có gợi ý: code mẫu | VIETMAP" description: "Tài liệu này mô tả cách kết hợp Autocomplete v4, Place v4 và Reverse v4 để xây dựng ô nhập địa chỉ có gợi ý:
- Autocomplete v4 gợi ý địa chỉ khi người dùng nhập.
- Place v4 trả toạ độ và các thành phần địa chỉ của gợi ý được chọn.
- Reverse v4 chuyển vị trí ghim trên bản đồ thành địa chỉ.
Các request đi qua server của bạn để bảo vệ services key.
Phía server¶
// Node.js 18+. Chạy ở server, services key không ra tới trình duyệt.
const KEY = process.env.VIETMAP_API_KEY;
const API = "https://maps.vietmap.vn/api";
async function getJson(path, params) {
const q = new URLSearchParams({ apikey: KEY, ...params });
const res = await fetch(`${API}/${path}?${q}`);
if (!res.ok) throw new Error(`${path}: HTTP ${res.status}`);
return res.json();
}
// Gợi ý khi gõ. focus: "lat,lng" của người dùng, nếu có
export async function suggest(text, focus) {
const params = { text, display_type: "5" }; // địa chỉ mới, bản cũ nằm trong data_old
if (focus) params.focus = focus;
const results = await getJson("autocomplete/v4", params);
return results.map((r) => ({ refId: r.ref_id, display: r.display }));
}
// Người dùng chọn một gợi ý: lấy toạ độ và thành phần địa chỉ để lưu vào đơn
export async function resolve(refId) {
const p = await getJson("place/v4", { refid: refId });
return {
display: p.display, lat: p.lat, lng: p.lng,
houseNumber: p.hs_num, street: p.street,
wardId: p.ward_id, ward: p.ward, cityId: p.city_id, city: p.city,
};
}
// Người dùng kéo ghim trên bản đồ: toạ độ -> địa chỉ gần nhất
export async function pinToAddress(lat, lng) {
const [nearest] = await getJson("reverse/v4", { lat, lng, display_type: "1" });
return nearest ? { display: nearest.display, lat: nearest.lat, lng: nearest.lng } : null;
}
import os
import requests
KEY = os.environ["VIETMAP_API_KEY"]
API = "https://maps.vietmap.vn/api"
def get_json(path, params):
resp = requests.get(f"{API}/{path}", params={"apikey": KEY, **params}, timeout=10)
resp.raise_for_status()
return resp.json()
def suggest(text, focus=None):
"""Gợi ý khi gõ. focus: "lat,lng" của người dùng, nếu có."""
# display_type=5: địa chỉ mới, bản cũ nằm trong data_old
results = get_json("autocomplete/v4", {"text": text, "focus": focus, "display_type": 5})
return [{"ref_id": r["ref_id"], "display": r["display"]} for r in results]
def resolve(ref_id):
"""Người dùng chọn một gợi ý: toạ độ và thành phần địa chỉ để lưu vào đơn."""
p = get_json("place/v4", {"refid": ref_id})
keys = ("display", "lat", "lng", "hs_num", "street", "ward_id", "ward", "city_id", "city")
return {k: p[k] for k in keys}
def pin_to_address(lat, lng):
"""Người dùng kéo ghim trên bản đồ: toạ độ -> địa chỉ gần nhất."""
results = get_json("reverse/v4", {"lat": lat, "lng": lng, "display_type": 1})
return results[0] if results else None
Làm ô nhập địa chỉ giao hàng có gợi ý cho trang đặt hàng của tôi, dùng API của VIETMAP.
Server của tôi có ba endpoint, gọi VIETMAP bằng services key:
1. Gợi ý: GET https://maps.vietmap.vn/api/autocomplete/v4 (text, focus, display_type=5) -> danh sách {ref_id, display}
2. Chọn gợi ý: GET https://maps.vietmap.vn/api/place/v4 (refid) -> display, lat, lng, hs_num, street, ward_id, ward, city_id, city
3. Kéo ghim: GET https://maps.vietmap.vn/api/reverse/v4 (lat, lng, display_type=1) -> địa chỉ gần nhất
Phía trình duyệt: chỉ gọi endpoint gợi ý khi đã có ít nhất 2 ký tự và người dùng ngừng gõ 300 ms.
Yêu cầu:
- Đọc API key từ biến môi trường VIETMAP_API_KEY ở server, không gửi key xuống trình duyệt.
- Kiểm tra mã HTTP (401: sai key, 423: hết hạn mức hoặc API chưa bật).
- Đọc tài liệu bên dưới trước. Chỉ dùng tham số và trường dữ liệu có trong tài liệu.
Tài liệu:
- https://maps.vietmap.vn/docs/vi/map-api/use-cases/checkout-address-guide/index.txt
- https://maps.vietmap.vn/docs/vi/map-api/autocomplete-version/autocomplete-v4/index.txt
- https://maps.vietmap.vn/docs/vi/map-api/place-v4/index.txt
- https://maps.vietmap.vn/docs/assets/agents/search-geocoding.txt
Phía trình duyệt: gửi request khi người dùng ngừng gõ¶
Đoạn mã dưới đây gửi request sau khi người dùng ngừng gõ 300 ms, giúp tiết kiệm transaction:
// Trình duyệt: gọi endpoint của server bạn, không gọi thẳng VIETMAP
const input = document.querySelector("#address");
let timer;
input.addEventListener("input", () => {
clearTimeout(timer);
const text = input.value.trim();
if (text.length < 2) return; // Autocomplete cần ít nhất 2 ký tự
timer = setTimeout(async () => {
const res = await fetch(`/address/suggest?text=${encodeURIComponent(text)}`);
showSuggestions(await res.json()); // hàm hiển thị danh sách của bạn
}, 300); // gọi khi người dùng đã ngừng gõ 300 ms
});
Để hiển thị bản đồ có ghim, dùng VietMap GL JS như ở Bắt đầu nhanh, bước 4 với marker kéo thả. Khi thả ghim, gửi toạ độ mới tới endpoint Reverse.
Địa chỉ cũ và mới¶
Autocomplete v4 nhận địa chỉ theo đơn vị hành chính cũ và mới. Đoạn mã ở trên dùng display_type=5: trả địa chỉ mới, kèm bản cũ trong data_old. Các giá trị khác xem ở Autocomplete v4.
Đơn hàng mới nên lưu địa chỉ theo định dạng mới kèm ward_id, city_id và toạ độ. Địa chỉ cũ trong hệ thống chuyển sang định dạng mới bằng API Chuyển đổi địa chỉ.
API liên quan¶
- Geocode v4 — tìm toạ độ cho cả chuỗi địa chỉ trong một lần gọi, ví dụ địa chỉ dán vào từ nơi khác.
- Logistics và giao hàng — phân đơn và tối ưu lộ trình cho đội xe.
- Mã lỗi — xử lý
401,423,429.