Как проверить размещается ли точка координат в указанной области на mysql
Возникла проблема в написании SQL запроса, нужна найти записи которые входят в зону с координатами, на php написать данный код не составило труда и он работает, но вот перевести на SQL мешает один фактор, координаты в колонке искомой точки хранятся в таком виде "46.4854932,30.2069585"
$x = 46.4854932;
$y = 30.2069585;
if (empty($model->zone_coordinates) === false) {
$zoneCoordinateNormalize = json_decode($model->zone_coordinates, true);
$inside = false;
for ($i = 0, $j = count($zoneCoordinateNormalize) - 1; $i < count($zoneCoordinateNormalize); $j = $i++) {
$xi = $zoneCoordinateNormalize[$i]['lat'];
$yi = $zoneCoordinateNormalize[$i]['lng'];
$xj = $zoneCoordinateNormalize[$j]['lat'];
$yj = $zoneCoordinateNormalize[$j]['lng'];
$intersect = (($yi > $y) != ($yj > $y)) && ($x < ($xj - $xi) * ($y - $yi) / ($yj - $yi) + $xi);
if ($intersect === true) {
$inside = !$inside;
}
}
}
По факту сама зона будет одна и мне нужно только привести данный (($yi > $y) != ($yj > $y)) && ($x < ($xj - $xi) * ($y - $yi) / ($yj - $yi) кусок в SQL, мне б узнать как можно с колонки при поисках в SQL получать значения после и перед комой, чтобы получить значения X и Y, если кто-то с чём-то подобным сталкивался, буду рад любой помощи.
Ответы (2 шт):
С текущей структурой - вам остаётся только скриптом перебирать ВСЕ записи, выполнить $coords = explode(',', $координата); и проверять скриптом.
А по хорошему - хранить x и y в отдельных столбиках
Сделал решения, оказалось все просто, координаты отсоединил функцией mysql SUBSTRING_INDEX, а все остальное как на php:
if (empty($model->zone_coordinates) === false) {
$zoneCoordinateNormalize = json_decode($model->zone_coordinates, true);
$coordinatesQueryPieces = [];
for ($i = 0, $j = count($zoneCoordinateNormalize) - 1; $i < count($zoneCoordinateNormalize); $j = $i++) {
$xi = $zoneCoordinateNormalize[$i]['lat'];
$yi = $zoneCoordinateNormalize[$i]['lng'];
$xj = $zoneCoordinateNormalize[$j]['lat'];
$yj = $zoneCoordinateNormalize[$j]['lng'];
// Формула проверки вхожденния точки в вказаную зону ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi) и тогокое количиство вхождений должно быть не чотним
$coordinatesQueryPieces[] = "
IF(
(
(({$yi} > SUBSTRING_INDEX({{%object}}.coordinates, ',', -1)) != ({$yj} > SUBSTRING_INDEX({{%object}}.coordinates, ',', -1)))
AND (SUBSTRING_INDEX({{%object}}.coordinates, ',', 1) < ({$xj} - {$xi}) * (SUBSTRING_INDEX({{%object}}.coordinates, ',', -1) - {$yi}) / ({$yj} - {$yi}) + {$xi})
)
!= 0,
1,
0
)
";
}
if (empty($coordinatesQueryPieces) === false) {
$coordinatesQueryAsString = implode(' + ', $coordinatesQueryPieces);
$query->andWhere("(CASE ($coordinatesQueryAsString) % 2 WHEN 0 THEN 0 ELSE 1 END)");
}
}