|
@@ -651,8 +651,10 @@ class Route_ViewTableAjax extends RouteBase {
|
|
|
$points = Geometry::objectFromText($result_points, 'Wgs84ToPuwg2000')->points();
|
|
$points = Geometry::objectFromText($result_points, 'Wgs84ToPuwg2000')->points();
|
|
|
$lines = Geometry::pointsToLines($points);
|
|
$lines = Geometry::pointsToLines($points);
|
|
|
|
|
|
|
|
- $i = 1;
|
|
|
|
|
- $array = [['i' => $i++, 'x' => $points[0]->x, 'y' => $points[0]->y, 'desc' => 'Punkt']];
|
|
|
|
|
|
|
+ // Dodanie początkowego punktu pierwszej linii do tabeli wszystkcih punktów
|
|
|
|
|
+ $_points = [['point' => $points[0], 'type' => ['p']]];
|
|
|
|
|
+
|
|
|
|
|
+ // Szukanie kolzji dla każdej linii prostej
|
|
|
foreach ($lines as $line) {
|
|
foreach ($lines as $line) {
|
|
|
$polygon_asText = Geometry::lineToRectangle($line, $nearDistance)->asText('Puwg2000ToWgs84');
|
|
$polygon_asText = Geometry::lineToRectangle($line, $nearDistance)->asText('Puwg2000ToWgs84');
|
|
|
$query_nears = "select st_astext(`the_geom`) as `the_geom` from `rurociagi_obce_wsg84` where st_intersects(st_geomfromtext('{$polygon_asText}'), `the_geom`)";
|
|
$query_nears = "select st_astext(`the_geom`) as `the_geom` from `rurociagi_obce_wsg84` where st_intersects(st_geomfromtext('{$polygon_asText}'), `the_geom`)";
|
|
@@ -666,71 +668,152 @@ class Route_ViewTableAjax extends RouteBase {
|
|
|
return Geometry::distance($line, $near) <= $nearDistance;
|
|
return Geometry::distance($line, $near) <= $nearDistance;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- $ki = 1;
|
|
|
|
|
- $lastNear = null;
|
|
|
|
|
- $nearsOnLine = [];
|
|
|
|
|
|
|
+ // Szukanie odcinków kolizyjnych
|
|
|
|
|
+ $crossPoints = [];
|
|
|
|
|
+ $_nearsOnLine = [];
|
|
|
foreach ($nears as $near) {
|
|
foreach ($nears as $near) {
|
|
|
- if ($crossPoints = Geometry::crossPoint($line, $near)) {
|
|
|
|
|
- switch (count($crossPoints)) {
|
|
|
|
|
|
|
+ if ($_crossPoints = Geometry::crossPoint($line, $near)) {
|
|
|
|
|
+ switch (count($_crossPoints)) {
|
|
|
case 1:
|
|
case 1:
|
|
|
- $array[] = ['i' => ($i - 1) . '.k' . $ki++, 'x' => $crossPoints[0]->x, 'y' => $crossPoints[0]->y, 'desc' => 'Kolizja (X)'];
|
|
|
|
|
|
|
+ // Znaleziono kolizję przecinającą linię
|
|
|
|
|
+ $crossPoints[] = ['point' => $_crossPoints[0], 'type' => ['x']];
|
|
|
break;
|
|
break;
|
|
|
case 2:
|
|
case 2:
|
|
|
- $array[] = ['i' => ($i - 1) . '.k' . $ki . 'a', 'x' => $crossPoint->x, 'y' => $crossPoint->y, 'desc' => 'Kolizja (I) start'];
|
|
|
|
|
- $array[] = ['i' => ($i - 1) . '.k' . $ki++ . 'b', 'x' => $crossPoint->x, 'y' => $crossPoint->y, 'desc' => 'Kolizja (I) stop'];
|
|
|
|
|
|
|
+ // Znaleziono kolizję idealnie nałożoną na linię
|
|
|
|
|
+ $_nearsOnLine[] = Geometry::line($_crossPoints[0], $_crossPoints[1]);
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
throw new Exception(__CLASS__ . "::" . __FUNCTION__ . ' - unknown error');
|
|
throw new Exception(__CLASS__ . "::" . __FUNCTION__ . ' - unknown error');
|
|
|
}
|
|
}
|
|
|
- } else $crossPoints = [];
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- $nearOnLine = Geometry::line(Geometry::closedPointOnLine($near->a, $line), Geometry::closedPointOnLine($near->b, $line));
|
|
|
|
|
|
|
+ // Analiza pobliskich kolizji
|
|
|
|
|
+ $a = Geometry::closedPointOnLine($near->a, $line);
|
|
|
|
|
+ $b = Geometry::closedPointOnLine($near->b, $line);
|
|
|
|
|
+ if (Geometry::distance($a, $line->a) < Geometry::distance($b, $line->a)) $nearOnLine = Geometry::line($a, $b);
|
|
|
|
|
+ else $nearOnLine = Geometry::line($b, $a);
|
|
|
|
|
|
|
|
|
|
+ // Weryfikacja czy pobliska kolizja nie jest jednocześnie kolizją przecinajacą i czy nie jest za krótka (<1m) - wtedy ją usuwamy
|
|
|
|
|
+ $add = true;
|
|
|
if ($nearOnLine->length() < 1) {
|
|
if ($nearOnLine->length() < 1) {
|
|
|
- $break = false;
|
|
|
|
|
foreach ($crossPoints as $crossPoint) {
|
|
foreach ($crossPoints as $crossPoint) {
|
|
|
- if (Geometry::distance($crossPoint, $nearOnLine) == 0) {
|
|
|
|
|
- $break = true;
|
|
|
|
|
|
|
+ if (Geometry::distance($crossPoint['point'], $nearOnLine) == 0) {
|
|
|
|
|
+ $add = false;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if ($break) continue;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+ if ($add) $_nearsOnLine[] = $nearOnLine;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Przesortowanie wszystkich kolizji linowych
|
|
|
|
|
+ usort($_nearsOnLine, function ($A, $B) use ($line) {
|
|
|
|
|
+ if (Geometry::samePoint($A->a, $B->a)) return 0;
|
|
|
|
|
+ if (Geometry::distance($A, $line->a) < Geometry::distance($B, $line->a)) return -1;
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
|
|
+ // Scalenie wszystkich kolizji jeżeli odstęp między nimi jest krótszy niz 1m
|
|
|
|
|
+ $lastNearOnLine = null;
|
|
|
|
|
+ $nearsOnLine = [];
|
|
|
|
|
+ foreach ($_nearsOnLine as $nearOnLine) {
|
|
|
if ($lastNearOnLine) {
|
|
if ($lastNearOnLine) {
|
|
|
- if (Geometry::distance($lastNearOnLine->b, $nearOnLine->a) < 1) $lastNearOnLine->b = $nearOnLine->b;
|
|
|
|
|
- else $nearsOnLine[] = $lastNearOnLine;
|
|
|
|
|
|
|
+ if (Geometry::distance($nearOnLine, $lastNearOnLine) < 1) {
|
|
|
|
|
+ $nearOnLine->a = $lastNearOnLine->a;
|
|
|
|
|
+ if (Geometry::distance($nearOnLine->b, $line->a) < Geometry::distance($lastNearOnLine->b, $line->a)) $nearOnLine->b = $lastNearOnLine->b;
|
|
|
|
|
+ } else $nearsOnLine[] = $lastNearOnLine;
|
|
|
}
|
|
}
|
|
|
$lastNearOnLine = $nearOnLine;
|
|
$lastNearOnLine = $nearOnLine;
|
|
|
}
|
|
}
|
|
|
if ($lastNearOnLine) $nearsOnLine[] = $lastNearOnLine;
|
|
if ($lastNearOnLine) $nearsOnLine[] = $lastNearOnLine;
|
|
|
|
|
|
|
|
|
|
+ // Nałożenie kolizji liniowych na punkty kolizyjne
|
|
|
foreach ($nearsOnLine as $nearOnLine) {
|
|
foreach ($nearsOnLine as $nearOnLine) {
|
|
|
- $array[] = ['i' => ($i - 1) . '.k' . $ki . 'a', 'x' => $nearOnLine->a->x, 'y' => $nearOnLine->a->y, 'desc' => 'Kolizja (II) start'];
|
|
|
|
|
- $array[] = ['i' => ($i - 1) . '.k' . $ki++ . 'b', 'x' => $nearOnLine->b->x, 'y' => $nearOnLine->b->y, 'desc' => 'Kolizja (II) stop'];
|
|
|
|
|
|
|
+ $crossPoints[] = ['point' => $nearOnLine->a, 'type' => ['iistart']];
|
|
|
|
|
+ $crossPoints[] = ['point' => $nearOnLine->b, 'type' => ['iistop']];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Podzielenie linii prostej na krótsze odcinki, jezeli jest zbyt długa (>$minDistance)
|
|
|
if (($distance = $line->length()) > $minDistance) {
|
|
if (($distance = $line->length()) > $minDistance) {
|
|
|
$parts = ceil($distance / $minDistance);
|
|
$parts = ceil($distance / $minDistance);
|
|
|
$deltaX = ($line->b->x - $line->a->x) / $parts;
|
|
$deltaX = ($line->b->x - $line->a->x) / $parts;
|
|
|
$deltaY = ($line->b->y - $line->a->y) / $parts;
|
|
$deltaY = ($line->b->y - $line->a->y) / $parts;
|
|
|
for ($j = 1; $j < $parts; $j++) {
|
|
for ($j = 1; $j < $parts; $j++) {
|
|
|
- $array[] = ['i' => ($i - 1) . "." . $j, 'x' => ($line->a->x + $j * $deltaX), 'y' => ($line->a->y + $j * $deltaY), 'desc' => 'Pośredni'];
|
|
|
|
|
|
|
+ $_point = Geometry::point($line->a->x + $j * $deltaX, $line->a->y + $j * $deltaY);
|
|
|
|
|
+ $collision = false;
|
|
|
|
|
+ foreach ($nearsOnLine as $nearOnLine) {
|
|
|
|
|
+ if (Geometry::distance($nearOnLine, $_point) == 0) {
|
|
|
|
|
+ $collision = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $type = ['m'];
|
|
|
|
|
+ if ($collision) $type[] = 'ii';
|
|
|
|
|
+ $crossPoints[] = ['point' => Geometry::point($line->a->x + $j * $deltaX, $line->a->y + $j * $deltaY), 'type' => $type];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $array[] = ['i' => $i, 'x' => $line->b->x, 'y' => $line->b->y, 'desc' => 'Punkt'];
|
|
|
|
|
- $i++;
|
|
|
|
|
|
|
+ // Przesortowanie wszystkich punktów na linii
|
|
|
|
|
+ usort($crossPoints, function ($a, $b) use ($line) {
|
|
|
|
|
+ if (Geometry::samePoint($a['point'], $b['point'])) return 0;
|
|
|
|
|
+ if (Geometry::distance($a['point'], $line->a) < Geometry::distance($b['point'], $line->a)) return -1;
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Dodanie wszystkich punktów kolizyjnych i pośrednich do tabeli wszystkich punktów
|
|
|
|
|
+ foreach ($crossPoints as $crossPoint) $_points[] = ['point' => $crossPoint['point'], 'type' => $crossPoint['type']];
|
|
|
|
|
+
|
|
|
|
|
+ // Dodanie końcowego punktu linii do tabeli wszystkich punktów
|
|
|
|
|
+ $_points[] = ['point' => $line->b, 'type' => ['p']];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Połączenie kilku takich samych punktów w jeden punkt (np. punkt początku linii oraz punkt początku kolizji - gdy wypadają w tym samym miejscu)
|
|
|
|
|
+ $points = [];
|
|
|
|
|
+ $lastPoint = null;
|
|
|
|
|
+ $desc = [];
|
|
|
|
|
+ foreach ($_points as $point) {
|
|
|
|
|
+ if ($lastPoint) {
|
|
|
|
|
+ if (Geometry::samePoint($point['point'], $lastPoint['point'])) $point['type'] = array_merge($lastPoint['type'], $point['type']);
|
|
|
|
|
+ else $points[] = $lastPoint;
|
|
|
|
|
+ }
|
|
|
|
|
+ $lastPoint = $point;
|
|
|
}
|
|
}
|
|
|
|
|
+ if ($lastPoint) $points[] = $lastPoint;
|
|
|
|
|
+
|
|
|
|
|
+ // Funkcja generująca czytelny opis rodzaju punktu
|
|
|
|
|
+ $typeToDesc = function($type) {
|
|
|
|
|
+ if (in_array('iistart', $type) && in_array('iistop', $type)) {
|
|
|
|
|
+ $type = array_diff($type, ['iistart', 'iistop']);
|
|
|
|
|
+ $type[] = 'ii';
|
|
|
|
|
+ }
|
|
|
|
|
+ usort($type, function($a, $b) {
|
|
|
|
|
+ if ($a == 'p' || $a == 'm') return -1;
|
|
|
|
|
+ if ($b == 'p' || $b == 'm') return 1;
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ });
|
|
|
|
|
+ return implode('|', array_map(function($_type) {
|
|
|
|
|
+ $types = [
|
|
|
|
|
+ 'p' => 'Punkt',
|
|
|
|
|
+ 'm' => 'Posredni',
|
|
|
|
|
+ 'x' => 'Kolizja (X)',
|
|
|
|
|
+ 'ii' => 'Kolizja (II)',
|
|
|
|
|
+ 'iistart' => 'Kolizja (II) start',
|
|
|
|
|
+ 'iistop' => 'Kolizja (II) stop'
|
|
|
|
|
+ ];
|
|
|
|
|
+ if (!in_array($_type, $types)) return $types[$_type];
|
|
|
|
|
+ throw new Exception("Nieznany typ punktu - {$_type} (" . __CLASS__ . '::' . __FUNCTION__ . ')');
|
|
|
|
|
+ }, $type));
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- $csv = implode("\n", array_map(function ($item) {
|
|
|
|
|
|
|
+ // Generowanie pliku CSV
|
|
|
|
|
+ $csv = implode("\n", array_map(function ($point, $i) use ($typeToDesc) {
|
|
|
try {
|
|
try {
|
|
|
- $z = EpsgConversion::GetZByPuwg2000($item['x'], $item['y']);
|
|
|
|
|
|
|
+ $z = EpsgConversion::GetZByPuwg2000($point['point']->x, $point['point']->y);
|
|
|
} catch (Exception $e) {
|
|
} catch (Exception $e) {
|
|
|
$z = 0;
|
|
$z = 0;
|
|
|
}
|
|
}
|
|
|
- return $item['i'] . "," . round($item['y'], 3) . "," . round($item['x'], 3) . "," . round($z, 3) . "," . $item['desc'];
|
|
|
|
|
- }, $array));
|
|
|
|
|
|
|
+ return $i . "," . round($point['point']->y, 3) . "," . round($point['point']->x, 3) . "," . round($z, 3) . "," . $typeToDesc($point['type']);
|
|
|
|
|
+ }, $points, range(1, count($points))));
|
|
|
|
|
|
|
|
// echo "<pre>{$csv}</pre>";
|
|
// echo "<pre>{$csv}</pre>";
|
|
|
Response::sendCsv($csv, "{$table}.{$id}");
|
|
Response::sendCsv($csv, "{$table}.{$id}");
|