Files
2026-03-11 15:29:37 +07:00

135 lines
4.1 KiB
PHP
Executable File

<?php
defined('BASEPATH') or exit('No direct script access allowed');
require APPPATH . '/libraries/REST_Controller.php';
class Map extends REST_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper(array('url', 'maps_helper', 'quota_limiter'));
date_default_timezone_set('Asia/Jakarta');
}
public function index_get()
{
$this->response(array(
'message' => 'Map API ready',
), 200);
}
/**
* POST /api/map/directions
* Body: { "origin_lat": 0.0, "origin_lng": 0.0, "dest_lat": 0.0, "dest_lng": 0.0, "mode": "driving" }
*/
public function directions_post()
{
// Simple per-IP quota limiting for map directions.
$hour_limit = (defined('MAPS_LIMIT_PER_HOUR') && MAPS_LIMIT_PER_HOUR !== '') ? (int) MAPS_LIMIT_PER_HOUR : 1000;
$day_limit = (defined('MAPS_LIMIT_PER_DAY') && MAPS_LIMIT_PER_DAY !== '') ? (int) MAPS_LIMIT_PER_DAY : 5000;
$limits = array(
'hour' => $hour_limit,
'day' => $day_limit,
);
$key = 'maps:ip:' . $this->input->ip_address();
if (!quota_limiter_allow($key, $limits)) {
$this->response(array(
'code' => '429',
'message' => 'maps_quota_exceeded',
), 200);
return;
}
$data = json_decode(file_get_contents('php://input'), true);
if (!is_array($data)) {
$this->response(array(
'code' => '400',
'message' => 'invalid_json',
), 200);
return;
}
if (!isset($data['origin_lat'], $data['origin_lng'], $data['dest_lat'], $data['dest_lng'])) {
$this->response(array(
'code' => '400',
'message' => 'missing_coordinates',
), 200);
return;
}
$mode = isset($data['mode']) && is_string($data['mode']) ? $data['mode'] : 'driving';
$result = maps_directions(
(float) $data['origin_lat'],
(float) $data['origin_lng'],
(float) $data['dest_lat'],
(float) $data['dest_lng'],
$mode
);
if ($result === null) {
$this->response(array(
'code' => '500',
'message' => 'maps_error',
), 200);
return;
}
// Proxy Google Directions JSON structure directly so clients can parse as before.
$this->response($result, 200);
}
/**
* POST /api/map/geocode
* Body: { "lat": 0.0, "lng": 0.0 }
*/
public function geocode_post()
{
$hour_limit = (defined('MAPS_LIMIT_PER_HOUR') && MAPS_LIMIT_PER_HOUR !== '') ? (int) MAPS_LIMIT_PER_HOUR : 1000;
$day_limit = (defined('MAPS_LIMIT_PER_DAY') && MAPS_LIMIT_PER_DAY !== '') ? (int) MAPS_LIMIT_PER_DAY : 5000;
$limits = array(
'hour' => $hour_limit,
'day' => $day_limit,
);
$key = 'maps:ip:' . $this->input->ip_address() . ':geocode';
if (!quota_limiter_allow($key, $limits)) {
$this->response(array(
'code' => '429',
'message' => 'maps_quota_exceeded',
), 200);
return;
}
$data = json_decode(file_get_contents('php://input'), true);
if (!is_array($data)) {
$this->response(array(
'code' => '400',
'message' => 'invalid_json',
), 200);
return;
}
if (!isset($data['lat'], $data['lng'])) {
$this->response(array(
'code' => '400',
'message' => 'missing_lat_lng',
), 200);
return;
}
$result = maps_geocode((float) $data['lat'], (float) $data['lng']);
if ($result === null) {
$this->response(array(
'code' => '500',
'message' => 'maps_error',
), 200);
return;
}
// Proxy Google Geocode JSON structure directly.
$this->response($result, 200);
}
}