findmydevice 히스토리 전체 지점 사용
This commit is contained in:
-130
@@ -428,137 +428,7 @@ if ($historySets) {
|
||||
});
|
||||
}
|
||||
|
||||
function pathDistanceM(array $a, array $b): float
|
||||
{
|
||||
$earth = 6371000;
|
||||
$lat1 = deg2rad((float)$a['lat']);
|
||||
$lat2 = deg2rad((float)$b['lat']);
|
||||
$dLat = $lat2 - $lat1;
|
||||
$dLng = deg2rad((float)$b['lng'] - (float)$a['lng']);
|
||||
$h = sin($dLat / 2) ** 2 + cos($lat1) * cos($lat2) * sin($dLng / 2) ** 2;
|
||||
return 2 * $earth * asin(min(1, sqrt($h)));
|
||||
}
|
||||
|
||||
function pointLineDistanceM(array $point, array $start, array $end): float
|
||||
{
|
||||
$latScale = 111320;
|
||||
$lngScale = 111320 * cos(deg2rad((float)$point['lat']));
|
||||
$px = (float)$point['lng'] * $lngScale;
|
||||
$py = (float)$point['lat'] * $latScale;
|
||||
$sx = (float)$start['lng'] * $lngScale;
|
||||
$sy = (float)$start['lat'] * $latScale;
|
||||
$ex = (float)$end['lng'] * $lngScale;
|
||||
$ey = (float)$end['lat'] * $latScale;
|
||||
$dx = $ex - $sx;
|
||||
$dy = $ey - $sy;
|
||||
|
||||
if ($dx == 0.0 && $dy == 0.0) {
|
||||
return sqrt(($px - $sx) ** 2 + ($py - $sy) ** 2);
|
||||
}
|
||||
|
||||
$t = max(0, min(1, (($px - $sx) * $dx + ($py - $sy) * $dy) / ($dx ** 2 + $dy ** 2)));
|
||||
$cx = $sx + $t * $dx;
|
||||
$cy = $sy + $t * $dy;
|
||||
|
||||
return sqrt(($px - $cx) ** 2 + ($py - $cy) ** 2);
|
||||
}
|
||||
|
||||
function douglasPeucker(array $points, float $epsilon): array
|
||||
{
|
||||
$count = count($points);
|
||||
if ($count <= 2) {
|
||||
return $points;
|
||||
}
|
||||
|
||||
$maxDistance = 0.0;
|
||||
$index = 0;
|
||||
$last = $count - 1;
|
||||
for ($i = 1; $i < $last; $i++) {
|
||||
$distance = pointLineDistanceM($points[$i], $points[0], $points[$last]);
|
||||
if ($distance > $maxDistance) {
|
||||
$index = $i;
|
||||
$maxDistance = $distance;
|
||||
}
|
||||
}
|
||||
|
||||
if ($maxDistance > $epsilon) {
|
||||
$left = douglasPeucker(array_slice($points, 0, $index + 1), $epsilon);
|
||||
$right = douglasPeucker(array_slice($points, $index), $epsilon);
|
||||
return array_merge(array_slice($left, 0, -1), $right);
|
||||
}
|
||||
|
||||
return [$points[0], $points[$last]];
|
||||
}
|
||||
|
||||
function smoothPath(array $path): array
|
||||
{
|
||||
$count = count($path);
|
||||
if ($count < 5) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$smoothed = [];
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if ($i === 0 || $i === $count - 1) {
|
||||
$smoothed[] = $path[$i];
|
||||
continue;
|
||||
}
|
||||
|
||||
$prev = $path[$i - 1];
|
||||
$cur = $path[$i];
|
||||
$next = $path[$i + 1];
|
||||
$smoothed[] = [
|
||||
'lat' => ((float)$prev['lat'] + ((float)$cur['lat'] * 2) + (float)$next['lat']) / 4,
|
||||
'lng' => ((float)$prev['lng'] + ((float)$cur['lng'] * 2) + (float)$next['lng']) / 4,
|
||||
'time' => $cur['time'],
|
||||
'accuracy' => $cur['accuracy'] ?? null,
|
||||
'source' => $cur['source'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
return $smoothed;
|
||||
}
|
||||
|
||||
function renderPath(array $path, int $renderLimit = 1200): array
|
||||
{
|
||||
$count = count($path);
|
||||
if ($count <= 2) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$filtered = [];
|
||||
$last = null;
|
||||
foreach ($path as $point) {
|
||||
if ($last === null || pathDistanceM($last, $point) >= 8) {
|
||||
$filtered[] = $point;
|
||||
$last = $point;
|
||||
}
|
||||
}
|
||||
if (count($filtered) < 2) {
|
||||
$filtered = [$path[0], $path[$count - 1]];
|
||||
}
|
||||
|
||||
$epsilon = 6.0;
|
||||
$render = $filtered;
|
||||
do {
|
||||
$render = douglasPeucker($filtered, $epsilon);
|
||||
$epsilon *= 1.45;
|
||||
} while (count($render) > $renderLimit && $epsilon < 500);
|
||||
|
||||
if (count($render) > $renderLimit) {
|
||||
$sampled = [];
|
||||
$lastIndex = count($render) - 1;
|
||||
for ($i = 0; $i < $renderLimit; $i++) {
|
||||
$sampled[] = $render[(int)round($i * $lastIndex / max(1, $renderLimit - 1))];
|
||||
}
|
||||
$render = $sampled;
|
||||
}
|
||||
|
||||
return smoothPath($render);
|
||||
}
|
||||
|
||||
$historyRawCount = count($path);
|
||||
$path = renderPath($path);
|
||||
|
||||
$lang = $_GET['lang'] ?? 'en';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user