This repository has been archived by the owner on Jul 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
geometry_utils.php
92 lines (77 loc) · 2.25 KB
/
geometry_utils.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
function get_length($points) {
$distance = 0;
for($i = 0; $i+1 < count($points); $i++)
{
$pos1 = $points[$i];
$pos2 = $points[$i+1];
$distance += get_distance($pos1, $pos2);
}
return $distance;
}
function get_center($points) {
$length = get_length($points);
$halfDistance = $length / 2;
if($halfDistance == 0) return $points[0];
$distance = 0;
for($i = 0; $i+1 < count($points); $i++)
{
$pos1 = $points[$i];
$pos2 = $points[$i+1];
$segmentDistance = get_distance($pos1, $pos2);
$distance += $segmentDistance;
if($distance > $halfDistance)
{
$ratio = ($distance - $halfDistance) / $segmentDistance;
$lat = $pos2[1] - $ratio * ($pos2[1] - $pos1[1]);
$lon = $pos2[0] - $ratio * ($pos2[0] - $pos1[0]);
return array($lon, $lat);
}
}
return null;
}
/**
* @return distance between two points in meters
*/
function get_distance($pos1, $pos2) {
return 6371000 * distance(
deg2rad($pos1[1]), deg2rad($pos1[0]),
deg2rad($pos2[1]), deg2rad($pos2[0])
);
}
// https://en.wikipedia.org/wiki/Great-circle_navigation#cite_note-2
function distance($φ1, $λ1, $φ2, $λ2) {
$Δλ = $λ2 - $λ1;
$y = sqrt(pow(cos($φ2)*sin($Δλ), 2) + pow(cos($φ1)*sin($φ2) - sin($φ1)*cos($φ2)*cos($Δλ), 2));
$x = sin($φ1)*sin($φ2) + cos($φ1)*cos($φ2)*cos($Δλ);
return atan2($y, $x);
}
function parse_lineString_points($str) {
$str = trim($str);
if(strpos($str, "LINESTRING") !== 0) return FALSE;
$str = trim(substr($str, strlen("LINESTRING")));
if(substr($str, -1) != ')' || substr($str, 0, 1) != '(') return FALSE;
$str = substr($str, 1, -1);
$coords = parse_coordinates($str);
if($coords === FALSE || count($coords) < 2) return FALSE;
return $coords;
}
function parse_coordinates($str) {
$coord_strings = explode(',', $str);
$coords = array();
foreach ($coord_strings as $coord_string) {
$coord = parse_coordinate($coord_string);
if($coord === FALSE) return FALSE;
$coords[] = $coord;
}
return $coords;
}
function parse_coordinate($str) {
$floats = explode(' ', trim($str));
if(count($floats) < 2) return FALSE;
$x = $floats[0];
$y = $floats[1];
if (!is_numeric($x) || !is_numeric($y)) return FALSE;
return array(floatval($x), floatval($y));
}
?>