文件
mashangyoujiu/Application/RiderApi/Controller/MapController.class.php

319 行
11 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace RiderApi\Controller;
/**
* 骑手端地图控制器
*/
class MapController extends BaseController {
/**
* 获取附近地点
*/
public function getNearbyPlaces() {
$lat = floatval($this->getRequestParam('lat', 0));
$lng = floatval($this->getRequestParam('lng', 0));
$radius = intval($this->getRequestParam('radius', 1000)); // 默认1000米
$type = $this->getRequestParam('type', ''); // 地点类型
if (empty($lat) || empty($lng)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '位置信息不能为空'));
}
// 这里可以调用第三方地图API(如高德、百度等)
// 暂时返回模拟数据
$places = array(
array(
'id' => 1,
'name' => '附近餐厅',
'address' => '示例地址1',
'lat' => $lat + 0.001,
'lng' => $lng + 0.001,
'distance' => 100,
'type' => 'restaurant'
),
array(
'id' => 2,
'name' => '附近商店',
'address' => '示例地址2',
'lat' => $lat - 0.001,
'lng' => $lng - 0.001,
'distance' => 200,
'type' => 'shop'
)
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $places
));
}
/**
* 搜索地点
*/
public function searchPlaces() {
$keyword = trim($this->getRequestParam('keyword', ''));
$lat = floatval($this->getRequestParam('lat', 0));
$lng = floatval($this->getRequestParam('lng', 0));
$city = trim($this->getRequestParam('city', ''));
if (empty($keyword)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '搜索关键词不能为空'));
}
// 这里可以调用第三方地图API进行地点搜索
// 暂时返回模拟数据
$places = array(
array(
'id' => 1,
'name' => $keyword . '相关地点1',
'address' => '搜索结果地址1',
'lat' => 39.908823,
'lng' => 116.397470,
'distance' => 500
),
array(
'id' => 2,
'name' => $keyword . '相关地点2',
'address' => '搜索结果地址2',
'lat' => 39.909823,
'lng' => 116.398470,
'distance' => 800
)
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '搜索成功',
'data' => $places
));
}
/**
* 路线规划
*/
public function planRoute() {
$riderId = $this->riderId;
$rider = $this->riderInfo;
// 获取请求参数
$startLat = floatval($this->getRequestParam('start_lat', 0));
$startLng = floatval($this->getRequestParam('start_lng', 0));
$endLat = floatval($this->getRequestParam('end_lat', 0));
$endLng = floatval($this->getRequestParam('end_lng', 0));
$startAddress = trim($this->getRequestParam('start_address', ''));
$endAddress = trim($this->getRequestParam('end_address', ''));
$waypoints = $this->getRequestParam('waypoints', array()); // 途经点
$strategy = $this->getRequestParam('strategy', 'fastest'); // 路线策略:fastest(最快), shortest(最短), avoid_traffic(避开拥堵)
// 参数验证
if (empty($startLat) || empty($startLng) || empty($endLat) || empty($endLng)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '起点和终点坐标不能为空'));
}
// 验证坐标范围
if ($startLat < -90 || $startLat > 90 || $endLat < -90 || $endLat > 90) {
$this->ajaxReturn(array('code' => 0, 'msg' => '纬度范围错误'));
}
if ($startLng < -180 || $startLng > 180 || $endLng < -180 || $endLng > 180) {
$this->ajaxReturn(array('code' => 0, 'msg' => '经度范围错误'));
}
try {
// 调用路线规划服务
$routeResult = $this->calculateRoute($startLat, $startLng, $endLat, $endLng, $waypoints, $strategy);
if (!$routeResult) {
$this->ajaxReturn(array('code' => 0, 'msg' => '路线规划失败'));
}
// 保存路线规划记录
$this->saveRouteRecord($riderId, $startLat, $startLng, $endLat, $endLng, $startAddress, $endAddress, $routeResult);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '路线规划成功',
'data' => $routeResult
));
} catch (\Exception $e) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '路线规划异常:' . $e->getMessage()
));
}
}
/**
* 计算路线
*/
private function calculateRoute($startLat, $startLng, $endLat, $endLng, $waypoints = array(), $strategy = 'fastest') {
// 这里应该调用第三方地图API(如高德、百度等)进行实际的路线规划
// 目前返回模拟数据
// 计算直线距离(简化处理)
$distance = $this->calculateDistance($startLat, $startLng, $endLat, $endLng);
// 模拟路线数据
$route = array(
'distance' => round($distance, 2), // 距离(公里)
'duration' => round($distance / 30 * 60, 0), // 预估时间(分钟,按30km/h计算)
'polyline' => $this->generatePolyline($startLat, $startLng, $endLat, $endLng), // 路线坐标点
'steps' => $this->generateRouteSteps($startLat, $startLng, $endLat, $endLng), // 导航步骤
'strategy' => $strategy,
'traffic_info' => array(
'status' => 'smooth', // 路况:smooth(畅通), slow(缓慢), congested(拥堵)
'delay_time' => 0 // 延误时间(分钟)
)
);
return $route;
}
/**
* 计算两点间距离(公里)
*/
private function calculateDistance($lat1, $lng1, $lat2, $lng2) {
$earthRadius = 6371; // 地球半径(公里)
$lat1Rad = deg2rad($lat1);
$lng1Rad = deg2rad($lng1);
$lat2Rad = deg2rad($lat2);
$lng2Rad = deg2rad($lng2);
$deltaLat = $lat2Rad - $lat1Rad;
$deltaLng = $lng2Rad - $lng1Rad;
$a = sin($deltaLat / 2) * sin($deltaLat / 2) +
cos($lat1Rad) * cos($lat2Rad) *
sin($deltaLng / 2) * sin($deltaLng / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
return $earthRadius * $c;
}
/**
* 生成路线坐标点
*/
private function generatePolyline($startLat, $startLng, $endLat, $endLng) {
// 简化处理,生成几个中间点
$points = array();
$steps = 5;
for ($i = 0; $i <= $steps; $i++) {
$ratio = $i / $steps;
$lat = $startLat + ($endLat - $startLat) * $ratio;
$lng = $startLng + ($endLng - $startLng) * $ratio;
$points[] = array('lat' => $lat, 'lng' => $lng);
}
return $points;
}
/**
* 生成导航步骤
*/
private function generateRouteSteps($startLat, $startLng, $endLat, $endLng) {
return array(
array(
'instruction' => '从起点出发',
'distance' => 0,
'duration' => 0,
'lat' => $startLat,
'lng' => $startLng
),
array(
'instruction' => '直行',
'distance' => $this->calculateDistance($startLat, $startLng, $endLat, $endLng) * 1000,
'duration' => round($this->calculateDistance($startLat, $startLng, $endLat, $endLng) / 30 * 60, 0),
'lat' => $endLat,
'lng' => $endLng
),
array(
'instruction' => '到达目的地',
'distance' => 0,
'duration' => 0,
'lat' => $endLat,
'lng' => $endLng
)
);
}
/**
* 保存路线规划记录
*/
private function saveRouteRecord($riderId, $startLat, $startLng, $endLat, $endLng, $startAddress, $endAddress, $routeResult) {
$routeModel = M('rider_route_record');
$data = array(
'rider_id' => $riderId,
'start_lat' => $startLat,
'start_lng' => $startLng,
'end_lat' => $endLat,
'end_lng' => $endLng,
'start_address' => $startAddress,
'end_address' => $endAddress,
'distance' => $routeResult['distance'],
'duration' => $routeResult['duration'],
'strategy' => $routeResult['strategy'],
'route_data' => json_encode($routeResult),
'create_time' => date('Y-m-d H:i:s')
);
$routeModel->add($data);
}
/**
* 获取缓存信息
*/
public function getCacheInfo() {
$riderId = $this->riderId;
// 获取路线缓存数量
$routeModel = M('rider_route_record');
$routeCount = $routeModel->where(array('rider_id' => $riderId))->count();
$cacheInfo = array(
'route_cache_count' => $routeCount,
'cache_size' => round($routeCount * 0.5, 2) . 'MB', // 估算缓存大小
'last_clear_time' => '2024-01-01 00:00:00' // 最后清理时间
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $cacheInfo
));
}
/**
* 清理缓存
*/
public function clearCache() {
$riderId = $this->riderId;
try {
// 清理路线记录缓存(保留最近30天的记录)
$routeModel = M('rider_route_record');
$thirtyDaysAgo = date('Y-m-d H:i:s', strtotime('-30 days'));
$deletedCount = $routeModel->where(array(
'rider_id' => $riderId,
'create_time' => array('lt', $thirtyDaysAgo)
))->delete();
$this->ajaxReturn(array(
'code' => 1,
'msg' => '缓存清理成功,清理了' . $deletedCount . '条记录'
));
} catch (\Exception $e) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '缓存清理失败:' . $e->getMessage()
));
}
}
}