Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Wyciągnięcie punktów z bazy danych z danego obszaru po kordynatach
Forum PHP.pl > Forum > Przedszkole
brzanek
Witam czy jest możliwość pobrania punktów z bazy danych (mając tylko współrzędne lat i lon) które są w wybranym obszarze np. w powiecie. Mam koordynaty powiatów ale jak wykonać takie zapytanie.
Koordynaty mam w pliku json ale chcę je dodać do bazy danych bo tak chyba będzie najprościej. Jaki powinien być format bazy danych dla takich danych?
Proszę o jakieś wskazówki.
viking
Postgres ma rozszerzenie postgis które daje spore możliwości wyszukiwania rożnych punktów. Mysql nie słyszałem.
brzanek
Mam taką bazę danych z punktami

Druga tabela z koordynatami

Teraz jak wyciągnąć punkty z pierwszej tabeli które mieszczą się w tych koordynatach z drugiej tabeli?
nospor
A ta kolumna KOORDYNATY to co to jest? Zwykla kolumna TEXT?
Jak juz napisano, masz uzyc albo postgis dla PGSQL albo SPATIAL dla mysql - wowczas mozesz dzialac.

edit: od biedy, jesli tych punkow nie masz za duzo, mozesz wszystko liczyc w php. z tego co widze jest pare klas, ktore sprawdzaja czy punkt jest w poligonie czy nie.
brzanek
Niestety punktów jest trochę liczone nawet w tysiącach.
Możesz podać przykłady takich klas?
nospor
No to w takim przypadku, przy paru tysiacach punkow oraz kilkuset powiatach do sprawdzenia to nie ma zadnego sensu robienie tego w php.
Co do klas to wpisze sobie w google: php point inside polygon
i ci wyrzuci
brzanek
Powiatów będzie tylko kilka i nie będzie wszystko sprawdzane na jeden raz tylko wybrany jeden powiat. Fakt punktów może być trochę.
Pyton_000
Przy tylko kilku powiatach wytargałbym to wszystko z bazy i opakował w jakąś klasę z listą pkt a potem wrzucił to w cache np. Redis czy cokolwiek. Potem możesz sobie mielić dane ile Ci się podoba.
brzanek
Mam taki kod
  1. <?php
  2. class pointLocation {
  3. var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices?
  4. function pointLocation() {
  5. }
  6. function pointInPolygon($point, $polygon, $pointOnVertex = true) {
  7. $this->pointOnVertex = $pointOnVertex;
  8. // Transform string coordinates into arrays with x and y values
  9. $point = $this->pointStringToCoordinates($point);
  10. $vertices = array();
  11. foreach ($polygon as $vertex) {
  12. $vertices[] = $this->pointStringToCoordinates($vertex);
  13. }
  14. // Check if the point sits exactly on a vertex
  15. if ($this->pointOnVertex == true and $this->pointOnVertex($point, $vertices) == true) {
  16. return "vertex";
  17. }
  18. // Check if the point is inside the polygon or on the boundary
  19. $intersections = 0;
  20. $vertices_count = count($vertices);
  21.  
  22. for ($i=1; $i < $vertices_count; $i++) {
  23. $vertex1 = $vertices[$i-1];
  24. $vertex2 = $vertices[$i];
  25. if ($vertex1['y'] == $vertex2['y'] and $vertex1['y'] == $point['y'] and $point['x'] > min($vertex1['x'], $vertex2['x']) and $point['x'] < max($vertex1['x'], $vertex2['x'])) { // Check if point is on an horizontal polygon boundary
  26. return "boundary";
  27. }
  28. if ($point['y'] > min($vertex1['y'], $vertex2['y']) and $point['y'] <= max($vertex1['y'], $vertex2['y']) and $point['x'] <= max($vertex1['x'], $vertex2['x']) and $vertex1['y'] != $vertex2['y']) {
  29. $xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];
  30. if ($xinters == $point['x']) { // Check if point is on the polygon boundary (other than horizontal)
  31. return "boundary";
  32. }
  33. if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) {
  34. $intersections++;
  35. }
  36. }
  37. }
  38. // If the number of edges we passed through is odd, then it's in the polygon.
  39. if ($intersections % 2 != 0) {
  40. return "w regionie";
  41. } else {
  42. return "poza";
  43. }
  44. }
  45. function pointOnVertex($point, $vertices) {
  46. foreach($vertices as $vertex) {
  47. if ($point == $vertex) {
  48. return true;
  49. }
  50. }
  51. }
  52. function pointStringToCoordinates($pointString) {
  53. $coordinates = explode(" ", $pointString);
  54. return array("x" => $coordinates[0], "y" => $coordinates[1]);
  55. }
  56. }
  57.  
  58. include('../db.php');
  59. $result = $mysqli->query("SELECT time, lat, lon FROM mybo_strikes_wojewodztwo WHERE `time` LIKE '%2019-09%' AND `lat` BETWEEN 53.323000 AND 53.537000 AND `lon` BETWEEN 14.445000 AND 14.802000");
  60. while ( $row = mysqli_fetch_array($result) ) {
  61. echo "".$row['lon']." ".$row['lat'].", ";
  62. }
  63.  
  64. echo '<br>';
  65.  
  66. $result = $mysqli->query("SELECT * FROM powiaty WHERE `powiat` LIKE 'choszczeński'");
  67. while ( $row = mysqli_fetch_array($result) ) {
  68. //echo "".$row['koordynaty'].", ";
  69. $powiat = $row['koordynaty'];
  70. }
  71. echo $powiat;
  72.  
  73. echo '<br>';
  74.  
  75. $pointLocation = new pointLocation();
  76. //$points = array("50 70","70 40","-20 30","100 10","-10 -10","40 -20","210 -20");
  77. $points = array("15.430256, 53.156151", "14.688979 53.489182", "14.598826 53.462356", "14.614701 53.488319", "14.600575 53.487518", "15.600575 53.487518");
  78. $polygon = array($powiat);
  79. foreach($points as $key => $point) {
  80. echo "point " . ($key+1) . " ($point): " . $pointLocation->pointInPolygon($point, $polygon) . "<br>";
  81. }
  82. ?>


W tym miejscu
  1. $points = array("15.430256, 53.156151", "14.688979 53.489182", "14.598826 53.462356", "14.614701 53.488319", "14.600575 53.487518", "15.600575 53.487518");

są przykładowe dane
a w tym $polygon = array($powiat); powinny być dane z bazy danych ale nie ma.
Jak można dodać zmienną $powiat która jest pobierana z bd mysql do tablicy array.
W bazie danych pod koordynaty mam takie wartości "15.301023 52.952381", "15.306165 52.965328", "15.307717 52.972298", "15.307131 52.982159", "15.301071 52.991863"
Pyton_000
$powiaty to już jest tablica. A ty powinieneś wywołać to tak:

pointInPolygon($point, $powiat['koordynaty'])
brzanek
Mówisz o tym?
pointInPolygon($point, $polygon)
Zamieniłem to ale nadal nic
pointInPolygon($point, $powiat['koordynaty'])
trueblue
Zmienna $powiat jest nadpisywana w pętli.

Tam nie jest potrzebna pętla. Zakładam, że wybierasz jeden rekord, gdzie w kolumnie jest ten JSON, tak?

Przeparsuj ten JSON do tablicy, sklej każde dwa elementy w string, a każdy taki string wrzucaj do tablicy.
ohm
W sumie robiłem coś podobnego, tyle że można powiedzieć bez bazy danych. Używałem do tego https://github.com/phayes/geoPHP i wydajnosciowo smigalo dobrze. Jeśli masz mozliwosc instalacji dodatkow, to sprawdz dokumentacje czy bedzie ci to odpowiadało.
brzanek
Coś namieszałem to nie ma prawa działać
  1. $result = $mysqli->query("SELECT * FROM powiaty WHERE `powiat` LIKE 'choszczeński'");
  2. while ( $row = mysqli_fetch_array($result) ) {
  3. $powiat = $row['koordynaty'];
  4. }
  5. echo $powiat;
  6.  
  7. echo '<br>';
  8.  
  9. $pointLocation = new pointLocation();
  10. //$points = array("50 70","70 40","-20 30","100 10","-10 -10","40 -20","210 -20");
  11. $points = array("15.430256, 53.156151", "14.688979 53.489182", "14.598826 53.462356", "14.614701 53.488319", "14.600575 53.487518", "15.600575 53.487518");
  12.  
  13. $polygon = array($powiat);
  14. // The last point's coordinates must be the same as the first one's, to "close the loop"
  15. foreach($points as $key => $point) {
  16. echo "point " . ($key+1) . " ($point): " . $pointLocation->pointInPolygon($point, $powiat['koordynaty']) . "<br>";
  17. }
trueblue
W zmiennej $powiat nie ma indeksu koordynaty.

Pisałem Ci wyżej jak masz zbudować tablicę.
0=>"x1 y1", 1=>"x2 y2" itd.

Gdybyś się pokusił o zmianę kodu, to mógłbyś tak nie robić, bo i tak metoda pointStringToCoordinates rozbija ponownie taki string na dwie odrębne wartości.
Pyton_000
Cytat(trueblue @ 31.12.2019, 18:05:16 ) *
W zmiennej $powiat nie ma indeksu koordynaty.


Ah faktycznie. Więc powinno zostać samo $powiat (zaćmiło mi że tam już jest wybierana kolumna)
brzanek
Niestety tak nie działa
  1. <?php
  2. class pointLocation {
  3. var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices?
  4. function pointLocation() {
  5. }
  6. function pointInPolygon($point, $polygon, $pointOnVertex = true) {
  7. $this->pointOnVertex = $pointOnVertex;
  8. // Transform string coordinates into arrays with x and y values
  9. $point = $this->pointStringToCoordinates($point);
  10. $vertices = array();
  11. foreach ($polygon as $vertex) {
  12. $vertices[] = $this->pointStringToCoordinates($vertex);
  13. }
  14. // Check if the point sits exactly on a vertex
  15. if ($this->pointOnVertex == true and $this->pointOnVertex($point, $vertices) == true) {
  16. return "vertex";
  17. }
  18. // Check if the point is inside the polygon or on the boundary
  19. $intersections = 0;
  20. $vertices_count = count($vertices);
  21.  
  22. for ($i=1; $i < $vertices_count; $i++) {
  23. $vertex1 = $vertices[$i-1];
  24. $vertex2 = $vertices[$i];
  25. if ($vertex1['y'] == $vertex2['y'] and $vertex1['y'] == $point['y'] and $point['x'] > min($vertex1['x'], $vertex2['x']) and $point['x'] < max($vertex1['x'], $vertex2['x'])) { // Check if point is on an horizontal polygon boundary
  26. return "boundary";
  27. }
  28. if ($point['y'] > min($vertex1['y'], $vertex2['y']) and $point['y'] <= max($vertex1['y'], $vertex2['y']) and $point['x'] <= max($vertex1['x'], $vertex2['x']) and $vertex1['y'] != $vertex2['y']) {
  29. $xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];
  30. if ($xinters == $point['x']) { // Check if point is on the polygon boundary (other than horizontal)
  31. return "boundary";
  32. }
  33. if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) {
  34. $intersections++;
  35. }
  36. }
  37. }
  38. // If the number of edges we passed through is odd, then it's in the polygon.
  39. if ($intersections % 2 != 0) {
  40. return "w regionie";
  41. } else {
  42. return "poza";
  43. }
  44. }
  45. function pointOnVertex($point, $vertices) {
  46. foreach($vertices as $vertex) {
  47. if ($point == $vertex) {
  48. return true;
  49. }
  50. }
  51. }
  52. function pointStringToCoordinates($pointString) {
  53. $coordinates = explode(" ", $pointString);
  54. return array("x" => $coordinates[0], "y" => $coordinates[1]);
  55. }
  56. }
  57.  
  58. include('../db.php');
  59. $result = $mysqli->query("SELECT time, lat, lon FROM mybo_strikes_wojewodztwo WHERE `time` LIKE '%2019-09%' AND `lat` BETWEEN 53.323000 AND 53.537000 AND `lon` BETWEEN 14.445000 AND 14.802000");
  60. while ( $row = mysqli_fetch_array($result) ) {
  61. echo "".$row['lon']." ".$row['lat'].", ";
  62. }
  63.  
  64. echo '<br>';
  65.  
  66. $result = $mysqli->query("SELECT * FROM powiaty WHERE `powiat` LIKE 'choszczeński'");
  67. while ( $row = mysqli_fetch_array($result) ) {
  68. $powiat = $row['koordynaty'];
  69. }
  70. //echo $powiat;
  71.  
  72. echo '<br>';
  73.  
  74. $pointLocation = new pointLocation();
  75. $points = array("15.430256, 53.156151", "14.688979 53.489182", "14.598826 53.462356", "14.614701 53.488319", "14.600575 53.487518", "15.600575 53.487518");
  76.  
  77. $polygon = array($powiat);
  78. // The last point's coordinates must be the same as the first one's, to "close the loop"
  79. foreach($points as $key => $point) {
  80. echo "point " . ($key+1) . " ($point): " . $pointLocation->pointInPolygon($point, $polygon) . "<br>";
  81. }
  82. ?>


Zamiana tego
pointInPolygon($point, $polygon)
na to
pointInPolygon($point, $powiat)
Też nie działa
nospor
Cytat
W bazie danych pod koordynaty mam takie wartości "15.301023 52.952381", "15.306165 52.965328", "15.307717 52.972298", "15.307131 52.982159", "15.301071 52.991863"

Ze screenu pare postow wyzej widac, ze jednak masz tam dane w zupelnie innym formacie. Po co wprowadzasz ludzi w blad?

No i tyle lat naforum, i patrzac po historii twoich postow - tyle lat z tym samym skryptem, a ty nadal nie potrafisz wlaczyc wyswietlania wszystkich bledow czy tez zajrzec do logow aplikacji, mimo ze wielokrotnie ciebie o to prosilem i inni pewnie tez. Po co w ogole przychodzisz na forum jak wiekszosc uwag w latuje jednym uchem a drugim od razu wylatuje?
brzanek
Chyba nie rozumiecie mojego problemu.
Chodzi mi o coś takiego:
https://assemblysys.com/php-point-in-polygon-algorithm/
Z tym, że współrzędne punktów pobierane są z bazy danych.
$polygon dane pobierane z bazy danych albo z pliku txt.
nospor
Kazdy tutaj rozumie o co tobie chodzi. To ty poki co stwarzasz problemy:
1) Nie wylaczysz wyswietlania bledow jak nie raz byles proszony
2) Raz podajesz ze baza ma dane w postaci X, innym razem podajesz ze ma w formacie Y - wprowadzasz ludzi w blad przez to
3) Generalnei nie stosujesz sie do tego co i ludzie pisza

A na koniec zwalasz wine, ze nikt ciebie nie rozumie.... smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.