RRevXMaps API · เอกสาร

ภาพรวม

RRevX Maps API ให้แผนที่ vector, เส้นทางรถยนต์ และค้นหาสถานที่ สำหรับประเทศไทยและลาว ผ่าน REST API ที่ https://api.rrevx.com ข้อมูลอัปเดตทุกเดือน

ความสามารถEndpointนับเป็น
แผนที่ (style)GET /v1/styles/liberty.json1 ครั้งเปิดแผนที่
ภาพแผนที่ (tiles)GET /v1/tiles/{z}/{x}/{y}.pbfไม่คิดเงิน
เส้นทางGET /v1/route/{จุด;จุด;…}1 เส้นทาง
ถนนใกล้จุดGET /v1/nearest/{จุด}1 เส้นทาง
ตารางระยะGET /v1/table/{จุด;จุด;…}ต้นทาง × ปลายทาง
ค้นหาสถานที่GET /v1/geocode1 ค้นหาสถานที่
เติมคำขณะพิมพ์GET /v1/autocomplete1 ต่อ session
สถานที่ใกล้จุดGET /v1/reverse1 ค้นหาสถานที่
ลำดับพิกัด = ลองจิจูด,ละติจูด (lng,lat) ทุกที่ในเส้นทาง พิกัดจุด และ focus / point — แบบเดียวกับ GeoJSON และ MapLibre (กลับกับ Google ที่เป็น lat,lng) · ระยะทางเป็นเมตร เวลาเป็นวินาที · ทุกคำตอบเป็น JSON (UTF-8)

เริ่มใช้ใน 5 นาที

1. สมัคร (ฟรี ไม่ต้องใส่บัตร)

เปิด คอนโซล แล้วล็อกอินด้วยอีเมลหรือ Google — บัญชีใหม่ได้แพ็กฟรีทันที: เปิดแผนที่ 10,000 + เส้นทาง 10,000 + ค้นหาสถานที่ 10,000 ครั้งต่อเดือน

2. สร้างคีย์

กด + สร้างคีย์ → เลือก เว็บ (rx_pub_…) แล้วใส่โดเมนของเว็บ (เช่น example.com, ทดสอบในเครื่องใส่ localhost) หรือ เซิร์ฟเวอร์ (rx_sec_…) สำหรับ backend/แอป · คีย์แสดงครั้งเดียว เก็บไว้ให้ดี

3. แสดงแผนที่ (MapLibre GL JS)

<link href="https://unpkg.com/[email protected]/dist/maplibre-gl.css" rel="stylesheet">
<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
<div id="map" style="height:480px"></div>
<script>
  const KEY = 'rx_pub_คีย์ของคุณ';
  const map = new maplibregl.Map({
    container: 'map',
    style: `https://api.rrevx.com/v1/styles/liberty.json?key=${KEY}`,
    center: [100.5341, 13.7457], // [lng, lat]
    zoom: 13
  });
  map.addControl(new maplibregl.NavigationControl());
</script>

4. วาดเส้นทาง

map.on('load', async () => {
  const from = [100.5341, 13.7457], to = [100.5383, 13.7649]; // สยาม → อนุสาวรีย์ชัยฯ
  const url = `https://api.rrevx.com/v1/route/${from.join(',')};${to.join(',')}?overview=full&geometries=geojson&key=${KEY}`;
  const r = await (await fetch(url)).json();
  if (r.code !== 'Ok') return alert('ไม่มีเส้นทาง: ' + r.code);
  const route = r.routes[0]; // distance (m), duration (s), geometry (GeoJSON)
  map.addSource('route', { type: 'geojson', data: route.geometry });
  map.addLayer({ id: 'route', type: 'line', source: 'route', paint: { 'line-color': '#1D6FA3', 'line-width': 5 } });
  console.log((route.distance / 1000).toFixed(1) + ' กม.', Math.round(route.duration / 60) + ' นาที');
});

5. ช่องค้นหาสถานที่ (เติมคำขณะพิมพ์)

<input id="q" placeholder="ค้นหาสถานที่" autocomplete="off"><ul id="list"></ul>
<small>Places © Overture Maps Foundation</small>
<script>
  let session = crypto.randomUUID(), timer;          // 1 session = 1 หน่วย ไม่ว่าพิมพ์กี่ตัว
  q.addEventListener('input', () => {
    clearTimeout(timer);
    timer = setTimeout(async () => {
      const c = map.getCenter();
      const p = new URLSearchParams({ q: q.value, session, focus: `${c.lng},${c.lat}`, key: KEY });
      const { results } = await (await fetch('https://api.rrevx.com/v1/autocomplete?' + p)).json();
      list.innerHTML = '';
      for (const place of results) {
        const li = document.createElement('li');
        li.textContent = `${place.name} · ${place.region?.name ?? ''}`;
        li.onclick = () => { map.flyTo({ center: [place.lng, place.lat], zoom: 16 }); session = crypto.randomUUID(); };
        list.append(li);
      }
    }, 250);                                          // รอผู้ใช้หยุดพิมพ์ 250 มิลลิวินาที
  });
</script>

เสร็จแล้ว — ดูยอดใช้สดได้ในคอนโซล · ทั้งหมดนี้ใช้คีย์เว็บ rx_pub_ ที่ผูกโดเมนได้เลย

คีย์และความปลอดภัย

ชนิดใช้ที่ไหนตรวจอะไร
rx_pub_… เว็บในหน้าเว็บ (JavaScript)ต้องเรียกจากโดเมนที่ตั้งไว้ (ดูจาก header Origin หรือ Referer) · example.com = example.com และ www.example.com · *.example.com = ทุกโดเมนย่อย · localhost · * = ทุกที่ (ไม่แนะนำ)
rx_sec_… เซิร์ฟเวอร์backend, แอปมือถือผ่านเซิร์ฟเวอร์ของคุณ, สคริปต์ห้ามมี header Origin (ถ้าเรียกจากเบราว์เซอร์จะถูกปฏิเสธ secret_key_in_browser)
  • ส่งคีย์เป็น query ?key=… ทุกคำขอ (ยกเว้น fonts/sprites, /v1/health, /v1/status, /v1/plans)
  • ระบบเก็บแค่ค่า hash ของคีย์ · ยกเลิกคีย์ในคอนโซลแล้วหยุดทำงานภายใน 1 นาที · มีได้ 10 คีย์ต่อบัญชี
  • ตั้ง เพดานเงินต่อเดือน ในคอนโซลได้ — ถึงแล้วตอบ 402 budget_reached จนถึงต้นเดือนถัดไป (เดือนตามเวลาไทย)
  • แอปมือถือ: ใช้คีย์ rx_sec_ จากเซิร์ฟเวอร์ของคุณ หรือคีย์เว็บที่ผูกโดเมนแล้วให้แอปส่ง header Referer: https://โดเมนของคุณ/

แผนที่ (style + tiles)

GET/v1/styles/{name}.json?key=1 ครั้งเปิดแผนที่

name = liberty (หรือ default = ตัวเดียวกัน) · คืน MapLibre style ที่ชี้ tiles, fonts และ sprites มาที่ api.rrevx.com และใส่คีย์ของคุณใน URL ของ tiles ให้แล้ว — ส่ง URL นี้ให้ MapLibre ได้เลย · ชื่อบนแผนที่เป็นภาษาท้องถิ่น (ไทย/ลาว) ปรับสี/ซ่อนชั้นข้อมูลได้ด้วย map.setPaintProperty / setLayoutProperty

GET/v1/tiles/{z}/{x}/{y}.pbf?key=ไม่คิดเงิน (fair use)

vector tiles (Mapbox Vector Tile, schema OpenMapTiles) ซูมถึงระดับสูงสุดของข้อมูล (14) — ซูมมากกว่านั้น MapLibre ขยายภาพเอง · ไม่มีข้อมูลตรงนั้น (เช่นทะเล) = 204 · ปกติไม่ต้องเรียกเอง style จัดการให้ · จำกัด 6,000 tiles/นาที/คีย์

GET/v1/assets/fonts/{fontstack}/{range}.pbf · /v1/assets/sprites/…ไม่ต้องใช้คีย์

ใช้กับ Leaflet

// Leaflet + ปลั๊กอิน @maplibre/maplibre-gl-leaflet
L.maplibreGL({ style: 'https://api.rrevx.com/v1/styles/liberty.json?key=rx_pub_…' }).addTo(map);

แอปมือถือ

MapLibre Native (Android / iOS), Flutter maplibre_gl, React Native @maplibre/maplibre-react-native — ใส่ URL ของ style เดียวกัน

เส้นทาง · route

GET/v1/route/{lng,lat;lng,lat;…}?key=1 เส้นทาง

เส้นทางรถยนต์ 2–25 จุด (จุดแรก = ต้นทาง, จุดสุดท้าย = ปลายทาง, ที่เหลือ = จุดแวะตามลำดับ) · รูปแบบคำขอและคำตอบเหมือน OSRM route service

parameterค่าหมายเหตุ
overviewsimplified (ค่าเริ่ม) · full · falseความละเอียดของเส้นที่คืนมา
geometriespolyline (ค่าเริ่ม) · polyline6 · geojsonวาดบน MapLibre ใช้ geojson ง่ายที่สุด
stepstrue · falseคำแนะนำเลี้ยวทีละจุด (ชื่อถนนเป็นภาษาท้องถิ่น)
alternativestrue · false · ตัวเลขเส้นทางทางเลือก
excludeferry · motorway · tollเช่น exclude=ferry ไม่ข้ามเรือ
annotations, continue_straight, radiuses, bearings, approaches, waypoints, snappingตามเอกสาร OSRM · parameter อื่นนอกจากนี้ = 400 unknown_parameter
curl "https://api.rrevx.com/v1/route/100.5341,13.7457;100.8825,12.9236?overview=simplified&geometries=geojson&exclude=ferry&key=rx_sec_…"
const r = await fetch('https://api.rrevx.com/v1/route/100.5341,13.7457;100.8825,12.9236?overview=false&key=' + KEY).then((x) => x.json());
if (r.code === 'Ok') console.log(r.routes[0].distance, r.routes[0].duration);
import requests
r = requests.get("https://api.rrevx.com/v1/route/100.5341,13.7457;100.8825,12.9236",
                 params={"overview": "false", "key": "rx_sec_…"}, timeout=10).json()
print(r["routes"][0]["distance"], r["routes"][0]["duration"])
{ "code": "Ok",
  "routes": [ { "distance": 144292.6, "duration": 5863.2, "geometry": { "type": "LineString", "coordinates": [[100.5341, 13.7457], …] },
                "legs": [ … ] } ],
  "waypoints": [ { "name": "ถนนพระรามที่ 1", "location": [100.534087, 13.745635], "distance": 7.3 }, … ] }

ไม่มีถนนเชื่อม (เช่น เกาะที่ต้องข้ามเรือเมื่อ exclude=ferry) = {"code":"NoRoute"} HTTP 400 — ไม่นับหน่วย · คำตอบของ OSRM ที่ไม่ใช่ Ok ทุกชนิดไม่นับหน่วย

ถนนใกล้จุด · nearest

GET/v1/nearest/{lng,lat}?key=1 เส้นทาง

ย้ายหมุดไปตรงถนนที่ใกล้ที่สุด (เช่น จุดรับลูกค้า) · number = จำนวนถนน 1–5 · exclude, radiuses, bearings, snapping ตาม OSRM

curl "https://api.rrevx.com/v1/nearest/100.5341,13.7457?number=2&key=rx_sec_…"
const r = await fetch(`https://api.rrevx.com/v1/nearest/${lng},${lat}?key=${KEY}`).then((x) => x.json());
const [roadLng, roadLat] = r.waypoints[0].location;
r = requests.get("https://api.rrevx.com/v1/nearest/100.5341,13.7457", params={"key": "rx_sec_…"}).json()
print(r["waypoints"][0]["name"], r["waypoints"][0]["location"])
{ "code": "Ok", "waypoints": [ { "name": "ถนนพระรามที่ 1", "location": [100.534087, 13.745635], "distance": 7.3, "nodes": [ … ] } ] }

ตารางระยะ · table

GET/v1/table/{lng,lat;lng,lat;…}?key=ต้นทาง × ปลายทาง

เวลา (และระยะ) ระหว่างหลายจุดพร้อมกัน สูงสุด 25 จุด — เช่นหาคนขับที่ถึงลูกค้าเร็วสุด · sources / destinations = เลขลำดับจุดคั่นด้วย ; (ไม่ใส่ = ทุกจุด) · annotations=duration,distance · คิด จำนวนต้นทาง × จำนวนปลายทาง หน่วย (ราคาต่อช่องเท่ากับเส้นทาง)

# คนขับ 3 คน (จุด 0–2) → ลูกค้า 1 คน (จุด 3) = 3 × 1 = 3 หน่วย
curl "https://api.rrevx.com/v1/table/100.53,13.74;100.56,13.75;100.50,13.73;100.5341,13.7457?sources=0;1;2&destinations=3&annotations=duration,distance&key=rx_sec_…"
const pts = [...drivers, customer].map((p) => p.join(',')).join(';');
const src = drivers.map((_, i) => i).join(';');
const r = await fetch(`https://api.rrevx.com/v1/table/${pts}?sources=${src}&destinations=${drivers.length}&key=${KEY}`).then((x) => x.json());
const best = r.durations.map((row, i) => [i, row[0]]).sort((a, b) => a[1] - b[1])[0]; // [คนขับ, วินาที]
pts = ";".join(f"{lng},{lat}" for lng, lat in drivers + [customer])
r = requests.get(f"https://api.rrevx.com/v1/table/{pts}",
                 params={"sources": ";".join(map(str, range(len(drivers)))), "destinations": str(len(drivers)), "key": "rx_sec_…"}).json()
print(r["durations"])  # [[วินาที], …] ต่อคนขับ
{ "code": "Ok", "durations": [[412.5], [655.1], [301.8]], "distances": [[3120.4], [5402.9], [2290.0]], "sources": [ … ], "destinations": [ … ] }

ค้นหาสถานที่ · geocode

GET/v1/geocode?q=…&key=1 ค้นหาสถานที่

ค้นชื่อสถานที่ในไทยและลาว (ห้าง โรงพยาบาล โรงเรียน สถานี สนามบิน โรงแรม ร้าน ที่พัก คอนโด ฯลฯ ~7 แสนแห่ง) ด้วยภาษาไทย ลาว หรืออังกฤษ · ไม่สนช่องว่าง ตัวพิมพ์ วรรณยุกต์ · เข้าใจตัวย่อ รพ. รร. ม. สน. ซ. ถ. BTS/MRT/รถไฟฟ้า (= สถานี) และ ท่าอากาศยาน = สนามบิน

parameterค่าหมายเหตุ
q *ข้อความ ≤ 200 ตัวเหลือไม่ถึง 2 ตัวอักษรหลังตัดช่องว่าง/เครื่องหมาย = คืนผลว่าง ไม่นับหน่วย
focuslng,latตำแหน่งผู้ใช้หรือกลางแผนที่ → ที่ใกล้ขึ้นก่อน และผลมี distance_m
countryTH · LA · TH,LA (ค่าเริ่ม)
limit1–10 (ค่าเริ่ม 5)
langth (ค่าเริ่ม) · en · loภาษาของ name และชื่อจังหวัด (ไม่มีภาษานั้น = ชื่อหลัก)

ลำดับผล: ชื่อตรงทั้งคำ → ขึ้นต้นด้วยคำค้น → มีคำค้นอยู่ในชื่อ (→ มีทุกคำแต่ไม่ติดกัน) · ในแต่ละขั้น: สถานที่สำคัญที่คัดไว้ก่อน → ใกล้ focus ก่อน → สถานที่ที่ข้อมูลน่าเชื่อถือกว่าก่อน

curl "https://api.rrevx.com/v1/geocode?q=รพ.รามาธิบดี&focus=100.5341,13.7457&limit=3&key=rx_sec_…"
const p = new URLSearchParams({ q: 'Siam Paragon', lang: 'en', key: KEY });
const { results, attribution } = await fetch('https://api.rrevx.com/v1/geocode?' + p).then((x) => x.json());
r = requests.get("https://api.rrevx.com/v1/geocode",
                 params={"q": "ตลาดเช้า", "country": "LA", "lang": "lo", "key": "rx_sec_…"}, timeout=10).json()
for p in r["results"]:
    print(p["name"], p["lat"], p["lng"], p["region"]["name"])
{ "results": [
    { "id": "0671b5b1-38ce-4a4b-986f-c2b52751e5b2",   // Overture GERS id (ส่วนใหญ่คงเดิมเมื่อข้อมูลอัปเดต)
      "name": "สยามพารากอน", "name_en": "Siam Paragon",  // name_en / name_lo มีเมื่อมีชื่อภาษานั้นและต่างจาก name
      "alt": ["Paragon Department Store"],             // ชื่ออื่น
      "category": "shopping_mall", "group": "shopping",
      "lat": 13.74678, "lng": 100.53495, "country": "TH",
      "region": { "code": "TH-10", "name": "กรุงเทพมหานคร" },
      "distance_m": 152 }                              // เมื่อส่ง focus
  ],
  "attribution": "Places © Overture Maps Foundation (Meta, Microsoft, Foursquare, AllThePlaces)" }

group: transport · lodging · shopping · health · education · government · landmark · work · leisure · bank · food · residential · category = หมวดละเอียดของ Overture (เช่น hospital, train_station, coffee_shop) · ไม่พบ = results: [] (นับหน่วย)

เติมคำขณะพิมพ์ · autocomplete

GET/v1/autocomplete?q=…&session=…&key=1 ต่อ session

parameter และคำตอบเหมือน geocode แต่เร็วและเหมาะกับการเรียกทุกครั้งที่ผู้ใช้พิมพ์ (ค้นด้วยคำที่พิมพ์ไม่ครบได้ เช่น สยามพา) · เพิ่ม session

  • session = ข้อความ 8–64 ตัว (A–Z a–z 0–9 - _) เช่น crypto.randomUUID() — สร้างใหม่ทุกครั้งที่ผู้ใช้เริ่มค้นหา และสร้างใหม่หลังเลือกผลลัพธ์
  • คำขอทั้งหมดที่ใช้ session เดียวกันภายใน 3 นาที นับจากคำขอแรก = 1 หน่วย · เกิน 3 นาที = นับ session ใหม่
  • ไม่ส่ง session = นับทุกคำขอ · พิมพ์ไม่ถึง 2 ตัวอักษร = ผลว่าง ไม่นับ
  • แนะนำ: รอผู้ใช้หยุดพิมพ์ ~250 มิลลิวินาทีก่อนส่ง (debounce) และยกเลิกคำขอเก่า
curl "https://api.rrevx.com/v1/autocomplete?q=สยามพา&session=3f1c2a9e-5b7d-4c11-9a0e-2d6b8f4e7a10&focus=100.5341,13.7457&key=rx_sec_…"
let session = crypto.randomUUID(), ctrl;
async function suggest(text) {
  ctrl?.abort(); ctrl = new AbortController();
  const p = new URLSearchParams({ q: text, session, key: KEY });
  return (await fetch('https://api.rrevx.com/v1/autocomplete?' + p, { signal: ctrl.signal }).then((x) => x.json())).results;
}
function picked(place) { session = crypto.randomUUID(); /* … */ }
import uuid
session = str(uuid.uuid4())
for text in ["สย", "สยาม", "สยามพารา"]:   # 3 คำขอ = 1 หน่วย
    r = requests.get("https://api.rrevx.com/v1/autocomplete", params={"q": text, "session": session, "key": "rx_sec_…"}).json()

สถานที่ใกล้จุด · reverse

GET/v1/reverse?point=lng,lat&key=1 ค้นหาสถานที่

สถานที่ในระยะ 500 ม. เรียงจากใกล้สุด (มี distance_m) และจังหวัด/แขวงที่จุดนั้นอยู่ — เช่นแสดง "ใกล้ สยามพารากอน, กรุงเทพมหานคร" ตอนปักหมุด · limit 1–10 · lang · country

curl "https://api.rrevx.com/v1/reverse?point=100.5349,13.7465&limit=3&key=rx_sec_…"
map.on('click', async (e) => {
  const p = new URLSearchParams({ point: `${e.lngLat.lng},${e.lngLat.lat}`, limit: 1, key: KEY });
  const r = await fetch('https://api.rrevx.com/v1/reverse?' + p).then((x) => x.json());
  console.log(r.results[0]?.name ?? 'ไม่มีสถานที่ใกล้ ๆ', r.region?.name);
});
r = requests.get("https://api.rrevx.com/v1/reverse", params={"point": "102.6186,17.9706", "lang": "en", "key": "rx_sec_…"}).json()
print([p["name"] for p in r["results"]], r["region"])
{ "results": [ { "id": "…", "name": "สยามพารากอน", …, "distance_m": 42 }, … ],
  "region": { "code": "TH-10", "name": "กรุงเทพมหานคร" },   // null = ไกลจากทุกสถานที่ (เช่น กลางทะเล)
  "attribution": "Places © Overture Maps Foundation (Meta, Microsoft, Foursquare, AllThePlaces)" }

health · status · plans

GET/v1/healthไม่ต้องใช้คีย์

{"ok": true, "data": "thailand-laos-YYYYMMDD"} = ชุดข้อมูลแผนที่ที่ใช้อยู่

GET/v1/statusไม่ต้องใช้คีย์

ผลตรวจระบบทุก 5 นาที: สถานะ, uptime 24 ชม. / 30 วัน / 90 วัน, เวลาตอบ p50 และรายวัน 90 วัน ต่อบริการ (maps, tiles, routing, places) — หน้าเว็บ rrevx.com/maps/status

GET/v1/plansไม่ต้องใช้คีย์

ราคาปัจจุบัน (บาท รวม VAT), ส่วนฟรีต่อเดือน และแพ็กทั้งหมด

การนับหน่วยและราคา

หน่วยนับเมื่อฟรี / เดือนเกินแล้ว (รวม VAT)
เปิดแผนที่โหลด style ด้วยคีย์ 1 ครั้ง (tiles ไม่นับ)10,000฿0.11 / ครั้ง
เส้นทางroute 1 ครั้ง · nearest 1 ครั้ง · table ต้นทาง × ปลายทาง10,000฿0.08 / หน่วย
ค้นหาสถานที่geocode 1 ครั้ง · reverse 1 ครั้ง · autocomplete 1 session10,000ประกาศเร็ว ๆ นี้
  • เดือนนับตามเวลาไทย เริ่มใหม่วันที่ 1 · ดูยอดสดในคอนโซล
  • ไม่นับ: คำขอที่ผิด (4xx), เส้นทางที่หาไม่ได้ (NoRoute ฯลฯ), ระบบของเราขัดข้อง (5xx), autocomplete ที่สั้นกว่า 2 ตัวอักษร
  • แพ็กฟรีหยุดเมื่อครบส่วนฟรี (402 free_quota_used) ไม่มีบิลเพิ่ม · แพ็กที่จ่ายเงินใช้ต่อได้และคิดส่วนเกินในรอบบิลถัดไป · แพ็ก 100,000 ใช้รวมได้ทั้งแผนที่ เส้นทาง และค้นหาสถานที่ · ราคาแพ็ก

ขีดจำกัด

อะไรขีดจำกัด
คำขอ API (style, เส้นทาง, ค้นหาสถานที่)1,200 / นาที / คีย์ (ต่อศูนย์ข้อมูลของ Cloudflare) → 429
tiles6,000 / นาที / คีย์
จุดใน route / table2–25 จุด · nearest number ≤ 5
ค้นหาสถานที่q ≤ 200 ตัวอักษร · limit ≤ 10 · reverse รัศมี 500 ม.
คีย์10 คีย์ใช้งานอยู่ต่อบัญชี · โดเมนไม่เกิน 20 รายการต่อคีย์

ต้องการมากกว่านี้ ติดต่อทีมงาน

รหัส error

error ทุกตัวตอบเป็น {"error": "รหัส", "message": "คำอธิบาย"} พร้อม HTTP status ด้านล่าง · ยกเว้น route/nearest/table ที่ OSRM ปฏิเสธ จะได้คำตอบของ OSRM ตรง ๆ ({"code": "NoRoute", …})

HTTPerrorความหมาย / ทำอย่างไร
400unknown_parameterมี parameter ที่ไม่รองรับ (ชื่ออยู่ใน message)
400parameter_too_longค่า parameter ยาวเกิน 2,000 ตัว
400bad_coordinatesพิกัดใน path ต้องเป็น lng,lat;lng,lat (ทศนิยม ≤ 8 ตำแหน่ง)
400too_many_coordinatesroute/table 2–25 จุด · nearest 1 จุด
400number_max_5nearest number เกิน 5
400bad_sources · bad_destinationstable: เลขลำดับจุดไม่ถูกต้อง
400bad_tileเลข z/x/y ของ tile ไม่ถูกต้อง
400q_required · q_too_longgeocode/autocomplete: ไม่มี q / ยาวเกิน 200
400point_required · bad_point · bad_focusพิกัด point / focus ต้องเป็น lng,lat
400bad_country · bad_limit · bad_lang · bad_sessionค่า country (TH, LA) / limit (1–10) / lang (th, en, lo) / session (8–64 ตัว) ไม่ถูกต้อง
400NoRoute · NoSegment · InvalidValue …คำตอบของ OSRM: ไม่มีถนนเชื่อม / จุดไกลจากถนน / ค่าไม่ถูกต้อง — ไม่นับหน่วย
401key_missingไม่ได้ส่ง ?key=
401key_invalidคีย์ผิด ถูกยกเลิก หรือบัญชีถูกระงับ
402free_quota_usedแพ็กฟรีใช้ครบส่วนฟรีของเดือนแล้ว → สมัครแพ็กในคอนโซล หรือรอวันที่ 1
402budget_reachedถึงเพดานเงินต่อเดือนที่ตั้งไว้ → เพิ่มเพดานในคอนโซล
403origin_not_allowedคีย์เว็บถูกเรียกจากโดเมนที่ไม่ได้ตั้งไว้ → เพิ่มโดเมนในคอนโซล
403origin_missingคีย์เว็บถูกเรียกโดยไม่มี Origin/Referer (เช่นจากเซิร์ฟเวอร์) → ใช้คีย์ลับ
403secret_key_in_browserคีย์ลับถูกใช้ในเบราว์เซอร์ → ยกเลิกคีย์นั้นแล้วใช้คีย์เว็บ
404not_found · style_not_foundไม่มี endpoint / style นี้
405method_not_allowedAPI ลูกค้าใช้ GET เท่านั้น
429too_many_requestsเกินขีดจำกัดต่อนาที → รอแล้วลองใหม่ (ถอยเวลาแบบทวีคูณ)
500server_errorข้อผิดพลาดของเรา (ไม่นับหน่วย) → ลองใหม่
502style_unavailable · asset_unavailableต้นทางแผนที่ไม่ตอบชั่วคราว (ไม่นับหน่วย) → ลองใหม่
503routing_unavailableเครื่องคำนวณเส้นทางไม่ตอบ (ไม่นับหน่วย) → ลองใหม่ · ดู สถานะระบบ
503places_unavailableฐานข้อมูลสถานที่ไม่ตอบ (ไม่นับหน่วย) → ลองใหม่

ย้ายจาก Google Maps JavaScript API

แผนที่ใช้ MapLibre GL JS (โอเพนซอร์ส ฟรี) แทน google.maps · เส้นทาง/ค้นหาสถานที่เป็น REST API เรียกด้วย fetch

จุดที่พลาดบ่อย: Google ใช้ {lat, lng} แต่ MapLibre และ RRevX ใช้ [lng, lat] · ระดับซูม MapLibre น้อยกว่า Google ประมาณ 1 ที่ภาพเท่ากัน (Google zoom 15 ≈ MapLibre 14)
Google MapsRRevX + MapLibre
new google.maps.Map(el, {center, zoom})new maplibregl.Map({container: el, style: 'https://api.rrevx.com/v1/styles/liberty.json?key=…', center: [lng, lat], zoom})
new google.maps.Marker({position, map})new maplibregl.Marker().setLngLat([lng, lat]).addTo(map)
new google.maps.InfoWindow({content})new maplibregl.Popup().setHTML(html) → marker.setPopup(popup)
map.panTo / setZoom / fitBoundsmap.panTo / setZoom / fitBounds([[w, s], [e, n]])
map.addListener('click', e => e.latLng)map.on('click', e => e.lngLat)
google.maps.Polyline / Polygon / Datamap.addSource(id, {type: 'geojson', data}) + map.addLayer({type: 'line' | 'fill' | 'circle', …})
DirectionsService.route() + DirectionsRendererGET /v1/route/…?geometries=geojson + ชั้น line (ตัวอย่างข้อ 4)
DistanceMatrixServiceGET /v1/table/…
Geocoder.geocode({address})GET /v1/geocode?q=
Geocoder.geocode({location})GET /v1/reverse?point=lng,lat
places.Autocomplete / AutocompleteSessionTokenGET /v1/autocomplete?q=&session= + รายการของคุณเอง (ตัวอย่างข้อ 5)
MarkerClustererGeoJSON source cluster: true (มีในตัว MapLibre)
Street View, ภาพดาวเทียม, ข้อมูลจราจรสดยังไม่มี

ก่อน → หลัง

// ก่อน (Google)
const map = new google.maps.Map(document.getElementById('map'), { center: { lat: 13.7457, lng: 100.5341 }, zoom: 15 });
new google.maps.Marker({ position: { lat: 13.7457, lng: 100.5341 }, map, title: 'สยาม' });

// หลัง (RRevX + MapLibre)
const map = new maplibregl.Map({ container: 'map', style: 'https://api.rrevx.com/v1/styles/liberty.json?key=rx_pub_…', center: [100.5341, 13.7457], zoom: 14 });
new maplibregl.Marker().setLngLat([100.5341, 13.7457]).setPopup(new maplibregl.Popup().setText('สยาม')).addTo(map);

อยากให้เราช่วยย้ายทั้งระบบ คุยกับทีมงาน

เครดิตที่ต้องแสดง

ข้อมูลมาจากโครงการเปิด ซึ่งกำหนดให้แสดงที่มา — การใช้ API นี้ถือว่ายอมรับเงื่อนไขเหล่านี้ด้วย (ดู ข้อตกลงการใช้งาน)

ใช้อะไรต้องแสดงที่ไหน
แผนที่ (style/tiles)© OpenMapTiles © OpenStreetMap contributorsมุมแผนที่ — MapLibre แสดงให้เองจาก style (อย่าซ่อน AttributionControl)
เส้นทาง / ตารางระยะ / nearest© OpenStreetMap contributorsบนแผนที่ที่แสดงเส้นทาง หรือหน้าที่แสดงผล
ค้นหาสถานที่ (geocode / autocomplete / reverse)Places © Overture Maps Foundation (Meta, Microsoft, Foursquare, AllThePlaces) (ค่า attribution ในคำตอบ)ใต้รายการผลค้นหา หรือหน้าเครดิต/เกี่ยวกับของแอป

สัญญาอนุญาต: OpenStreetMap = ODbL 1.0 · Overture Maps places = CDLA-Permissive-2.0 / Apache-2.0 / CC0 (ตามแหล่ง) · ห้ามดาวน์โหลดผลลัพธ์จำนวนมากไปเก็บไว้ใช้แทนบริการ (ดูข้อตกลงการใช้งาน)