
Khách nhìn hai ghim khá gần nhau rồi nghĩ chuyến giao sẽ nhanh. Giữa chúng có thể là sông, đường phân cách hoặc một khu đất lớn có cổng ở phía bên kia. API chỉ đường tính hành trình theo mạng đường thay vì nối hai điểm bằng đoạn thẳng. Ứng dụng vẫn cần giải thích kết quả và tránh biến thời gian di chuyển ước tính thành lời hẹn chắc chắn.
Bài này xây một mẫu gọi TrackAsia Directions v2 nhỏ, rồi theo phản hồi vào trạng thái ứng dụng, cách hiển thị và kiểm thử. Phạm vi là một hành trình giữa các vị trí đã xác nhận. Phân nhiều đơn cho nhiều xe là bài toán khác, cần luồng tối ưu tuyến riêng.
Bắt đầu bằng yêu cầu hoàn chỉnh, chưa cần ảnh bản đồ
TrackAsia mô tả Directions v2 tại /route/v2/directions/json, nhận origin, destination và khóa API. Chuỗi tọa độ theo vĩ độ,kinh độ; các chế độ được liệt kê gồm driving, motorcycling, walking và truck.[5] Dùng tọa độ rõ ngay từ đầu để thử đúng phần tính đường, chưa trộn với việc hiểu một địa chỉ có thể mơ hồ.
Lưu tệp đầy đủ dưới đây thành directions-demo.html. Mở bằng trình duyệt hiện đại hoặc chạy python3 -m http.server 8080 trong thư mục chứa tệp rồi truy cập http://localhost:8080/directions-demo.html nếu yêu cầu từ tệp cục bộ bị chặn. Mẫu dùng public_key giới hạn cho thử nghiệm theo tài liệu, không phải hạn mức sản xuất.[5]
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>TrackAsia directions</title><style>body{max-width:760px;margin:24px auto;padding:16px;font:17px/1.6 system-ui}input,select,button{font:inherit;max-width:100%;padding:8px}label{display:block;margin:10px 0}pre{white-space:pre-wrap;overflow-wrap:anywhere}</style><h1>Calculate a road journey</h1><p>Limited public test key. Coordinates use latitude,longitude.</p><form id="form"><label>Origin <input id="origin" value="10.761,106.68" required></label><label>Destination <input id="destination" value="10.800,106.75" required></label><label>Mode <select id="mode"><option>driving</option><option>motorcycling</option><option>walking</option><option>truck</option></select></label><button>Calculate</button></form><p id="status" role="status"></p><pre id="output"></pre><script>
let controller,version=0;
function coordinate(text){
const pair=text.split(',').map(x=>Number(x.trim()));
if(pair.length!==2||!pair.every(Number.isFinite)||Math.abs(pair[0])>90||Math.abs(pair[1])>180)throw new Error('Use latitude,longitude');
return pair.join(',');
}
document.querySelector('#form').addEventListener('submit',async event=>{
event.preventDefault();controller?.abort();controller=new AbortController();const current=++version;
const status=document.querySelector('#status'),output=document.querySelector('#output');
output.textContent='';status.textContent='Calculating…';
try{
const url=new URL('https://maps.track-asia.com/route/v2/directions/json');
url.search=new URLSearchParams({origin:coordinate(document.querySelector('#origin').value),destination:coordinate(document.querySelector('#destination').value),mode:document.querySelector('#mode').value,key:'public_key'});
const response=await fetch(url,{signal:controller.signal});
if(!response.ok)throw new Error('HTTP '+response.status);
const data=await response.json();
if(data.status!=='OK'||!data.routes?.length)throw new Error(data.status||'No route');
if(current!==version)return;
const route=data.routes[0],legs=route.legs||[];
if(!legs.length||!legs.every(x=>Number.isFinite(x.distance?.value)&&Number.isFinite(x.duration?.value)))throw new Error('Incomplete route');
const metres=legs.reduce((n,x)=>n+x.distance.value,0),seconds=legs.reduce((n,x)=>n+x.duration.value,0);
output.textContent=JSON.stringify({summary:route.summary,metres,seconds,kilometres:(metres/1000).toFixed(1),minutes:Math.ceil(seconds/60),legs:legs.map(x=>({start:x.start_location,end:x.end_location,metres:x.distance.value,seconds:x.duration.value})),polyline:route.overview_polyline},null,2);
status.textContent='Journey estimate ready. Stop service time is separate.';
}catch(error){if(error.name!=='AbortError'&¤t===version)status.textContent='Route failed: '+error.message;}
});
</script></html>
Bấm Calculate với hai điểm có sẵn, sau đó đổi điểm đến hoặc phương tiện. Kết quả hiện mét, giây, số đổi để hiển thị, các chặng và hình học tổng quan. Mẫu chưa phụ thuộc thư viện bản đồ để người đọc thấy rõ đầu vào đi tới trường phản hồi nào. Một cặp điểm chạy được là kiểm thử chức năng, chưa chứng minh mọi xe và mọi địa điểm đều phù hợp.
Hàm kiểm tra tọa độ chỉ kiểm tra dạng số và miền giá trị toàn cầu. Nó chưa xác nhận điểm nằm trong vùng phục vụ hoặc trên đường tiếp cận dùng được. Bổ sung điều kiện nghiệp vụ đó khi chuyển từ bài thử sang tính năng thật.
Đọc quy ước trước khi dùng lại tọa độ
Đối tượng có tên lat và lng dễ hiểu hơn một cặp số không có nhãn. Directions v2 cần chuỗi vĩ độ,kinh độ.[5] Dịch vụ khác có thể quy định khác; VRP v1 của TrackAsia mô tả mảng kinh độ,vĩ độ.[6] Chuyển đổi ở chỗ gọi dịch vụ thay vì chép nguyên mảng từ một phần tích hợp khác.
Theo tài liệu, Directions cũng nhận chuỗi địa chỉ.[5] Cách đó tiện để thử nhanh. Với đơn giao thật, lấy và xác nhận vị trí trước cho khách hoặc nhân viên cơ hội phát hiện nơi mơ hồ trước khi dùng thời gian đường đi để hẹn giao.
Dùng URLSearchParams cho mọi giá trị, đặc biệt khi thêm địa chỉ và dấu phân cách điểm trung gian. URL nối bằng tay khó kiểm tra và dễ hỏng khi có khoảng trắng, dấu tiếng Việt hoặc dấu câu. Giữ phiên bản endpoint rõ trong mô-đun để lần đổi sau là chủ động.
Mẫu chỉ gọi khi gửi biểu mẫu. Nếu dùng một thư viện giao diện, đừng đặt tính tuyến vào đoạn mã chạy sau mọi lần vẽ lại màn hình. Xác định các đầu vào có ý nghĩa như điểm đi, điểm đến, phương tiện và điểm trung gian; chỉ tính lại khi chúng đổi hoặc người dùng yêu cầu làm mới.
Phản hồi nào đủ để hiển thị một hành trình?
Tài liệu mô tả status, routes, các tuyến có legs, trong đó distance.value theo mét và duration.value theo giây. Từng chặng còn có vị trí, bước chỉ dẫn; tuyến có polyline tổng quan và thông tin trình bày khác.[5] Kiểm tra lần lượt từng lớp trước khi đọc phần tử đầu.
Đầu tiên kiểm tra HTTP, rồi trạng thái ứng dụng và có tuyến hay không, sau cùng xác nhận các trường màn hình thật sự cần. HTTP thành công không có nghĩa được đọc ngay routes[0].legs[0]. Mảng rỗng hoặc đối tượng thiếu trường nên dẫn đến trạng thái giải thích được, không làm cả màn hình dừng vì lỗi chưa xử lý.
Mẫu cộng mọi chặng. Điều này quan trọng khi thêm điểm trung gian: chỉ đọc chặng đầu sẽ làm hành trình nhiều điểm trông ngắn hơn thực tế. Giữ đơn vị gốc trong lưu trữ và tính toán, chỉ đổi km và phút lúc hiển thị. Tránh lấy chuỗi như “11.4km” rồi phân tích ngược thành dữ liệu nghiệp vụ.
Thời gian đường đi chưa phải toàn bộ cuộc hẹn. Giờ tới dự kiến còn phụ thuộc giờ xuất phát, bốc hàng, chờ và phục vụ tại điểm. Nói rõ giả định trong sản phẩm. Không âm thầm thêm một khoảng dự phòng rồi trình bày như đó là cam kết chính xác của nhà cung cấp.
Thử với mã nguồn: Tính hành trình đường bộ
Đổi điểm đi, điểm đến và phương tiện để lấy mét, giây và hành trình trả về.
Ví dụ gọi API dùng public_key giới hạn; ảnh chụp phiên chạy của mã nguồn bên dưới.
Giải nén ZIP, chạy python3 -m http.server 8080 trong thư mục vừa giải nén, rồi mở http://localhost:8080/index-vi.html. README tiếng Việt và tiếng Anh nằm trong ZIP; không cần npm hay bước build.

Giữ đường vẽ và con số cùng một yêu cầu
Giao diện nhanh vẫn có thể sai nếu đường thuộc yêu cầu trước còn số km thuộc yêu cầu mới. Mẫu dùng hủy và số phiên bản để phản hồi cũ không ghi đè kết quả mới. Khi ghép bản đồ, cập nhật hình học, tóm tắt, ghim và thông tin yêu cầu như một trạng thái nhất quán.
Polyline tổng quan là biểu diễn đã mã hóa, không phải mảng tọa độ GeoJSON.[5] Cần giải mã bằng cách phù hợp và xem cấu trúc phản hồi thật trước khi chuyển cho thư viện bản đồ. Với polyline của bước trả dưới dạng đối tượng có points, đọc thuộc tính đó thay vì đưa cả đối tượng vào hàm giải mã. Luôn xem cấu trúc nhận được, không mặc định mọi trường hình học đều là chuỗi thuần.
Sau khi giải mã, căn vùng nhìn theo cả tuyến thay vì để máy ảnh ở điểm đầu. Chừa khoảng cho nút điều khiển và thẻ tóm tắt trên điện thoại. Đừng khiến đường trông như biến mất chỉ vì phần lớn hành trình nằm ngoài khung nhìn hiện tại.
Trường html_instructions được mô tả có nội dung HTML.[5] Coi chữ nhà cung cấp trả về là dữ liệu bên ngoài. Nếu chỉ cần danh sách chữ, hiển thị an toàn dưới dạng văn bản. Nếu cần định dạng, áp dụng quy tắc làm sạch rõ thay vì đưa mọi chuỗi thẳng vào innerHTML ở nhiều chỗ.
Điểm trung gian thay đổi điều gì?
Directions mô tả waypoints là tọa độ hoặc địa chỉ trung gian ngăn bằng dấu gạch đứng, cùng tùy chọn alternatives cho các tuyến thay thế.[5] Chúng hữu ích khi hành trình phải qua nơi đã biết hoặc giao diện cần trình bày lựa chọn tuyến. Chúng chưa tự cung cấp quy trình phân việc cho đội xe.
Với thứ tự đã biết như kho, điểm lấy, khách nhận, ứng dụng nên giữ danh sách điểm dự định và gắn chặng với mã nghiệp vụ tương ứng. Đường vẽ không đủ khi điều phối cần giải thích đơn nào nằm ở điểm nào. Phải có ánh xạ rõ giữa dữ liệu vị trí của nhà cung cấp và mã đơn doanh nghiệp.
Không mặc định truyền waypoints sẽ giải được sức chứa, khung giờ nhận hoặc quan hệ lấy–giao. Các điều kiện đó thuộc mô hình tối ưu riêng. Nếu nhu cầu thực là nhiều xe và nhiều công việc, đánh giá API VRP cùng phần mềm bao quanh hoặc TMS, thay vì kéo một yêu cầu Directions thành cả kế hoạch đội xe.[6][7]
Tách phương án đang thử khỏi chỉ dẫn đã phát hành. Điều phối nên xem tuyến thay thế mà không vô tình thay chuyến đang chạy của tài xế. Cơ chế duyệt và gửi thay đổi vẫn là trách nhiệm ứng dụng.
Tên phương tiện chưa phải toàn bộ quy tắc lưu thông
Chọn chế độ phù hợp rồi thử các cặp điểm đại diện. Có truck trong danh sách chưa chứng minh mọi ràng buộc cân nặng, kích thước, giấy phép, giờ cấm hoặc đường vào cơ sở cho xe cụ thể.[5] Nếu những điều đó ảnh hưởng quyết định, hỏi chính xác tham số và hành vi đang được hỗ trợ.
Tương tự, phản hồi có thời gian chưa chứng minh sử dụng giao thông trực tiếp. Xác nhận dữ liệu và điều kiện hiện hành thay vì tự thêm tuyên bố vào sản phẩm. Nếu dùng ước tính để hẹn giao, cần thu thập quan sát hành trình trong điều kiện thực tế đang đánh giá.
Ở điểm khó, đoạn cuối cần được kiểm tra riêng. Tuyến có thể tới gần tòa nhà trong khi cổng nhận ở chỗ khác. Giữ tọa độ cổng đã xác nhận và ghi chú tiếp cận khi cần. Không sửa biểu hiện bằng cách chuyển ghim trên màn hình nhưng vẫn giữ nguyên tọa độ gọi tính đường.
Nếu không có tuyến dùng được, cho bước tiếp theo rõ: xem lại điểm, thử lại sau lỗi tạm thời hoặc chuyển nhân viên. Không vẽ đường thẳng rồi gắn nhãn là tuyến xe dự phòng. Một hình thay thế không được giả làm hành trình đường bộ đã kiểm tra.
Thử lỗi ngay trong cùng màn hình
Nhập chuỗi tọa độ sai để thử kiểm tra cục bộ, sau đó thử mất mạng và lỗi ở mức ứng dụng. Quan sát tuyến trước có còn trên màn hình không. Nếu giữ lại, ghi rõ đó là kết quả cũ; nếu không, người dùng dễ nghĩ đó là hành trình vừa tính.
Chính sách gọi lại cần phân biệt lỗi tạm thời với đầu vào sai. Gửi tọa độ hỏng nhiều lần không sửa được chúng và chỉ tạo yêu cầu thừa. Nút thử lại nên giữ nội dung đã nhập; chỉ tự động gọi lại có giới hạn khi thiết kế vận hành thực sự cần.
Trên điện thoại, thử cả địa chỉ dài, tên đường dài và thông báo lỗi. Khối mã và kết quả cần xuống dòng, nhưng giao diện sản phẩm nên ưu tiên tóm tắt hữu ích thay vì buộc khách đọc JSON. Giữ vùng chạm đủ dùng và trạng thái yêu cầu hiện tại dễ thấy.
Lập tập tuyến gồm trung tâm, ngoại thành, qua sông, kho và cổng khó. Nhờ người vận hành xem tính hợp lý và khả năng tiếp cận, rồi đối chiếu thời gian ước tính với quan sát trong điều kiện đang xét. Không công bố độ chính xác hay tỷ lệ tiết kiệm chung từ một màn thử nhỏ.
Chốt gì trước khi mở lưu lượng thật?
Thay khóa công khai giới hạn bằng tích hợp tài khoản phù hợp, xác nhận giới hạn khóa và điều kiện thương mại. Khóa trong trình duyệt có thể được người dùng xem. Nếu máy chủ trung gian gọi dịch vụ, giữ bí mật ở đó và đặt thời gian chờ, nhật ký cùng quyền truy cập rõ ràng.
Nhật ký cần mã yêu cầu, thời gian, trạng thái và vừa đủ ngữ cảnh để chẩn đoán. Tránh lưu hàng loạt địa chỉ cá nhân. Có phương tiện và phiên bản đầu vào giúp hỗ trợ phân biệt tuyến không phù hợp với phản hồi cũ bị vẽ lại hoặc người dùng đã chọn chế độ khác.
Dự báo lượt gọi theo sự kiện thật: gửi hành trình, đổi đầu vào có ý nghĩa và thử lại. Xác nhận đơn vị tính phí và quyền dùng dữ liệu với TrackAsia. Chờ ngừng gõ hoặc tránh gọi theo mỗi lần vẽ lại là thiết kế tốt, chưa thay thế việc hiểu thỏa thuận đang áp dụng.
Bước tiếp theo là ghép phản hồi vào bản đồ và hồ sơ đơn, vẫn giữ các trạng thái rõ như mẫu. Bắt đầu từ điểm đã xác nhận, kiểm tra phản hồi, phát hành kết quả nhất quán và thể hiện điều chưa chắc khi không có tuyến dùng được. Nhờ vậy, người đọc có thể hành động theo chỉ đường mà không nhầm một phép tính hành trình với cả hệ thống dẫn đường hay điều phối.