0 like 0 dislike
15 views
Hello, dear community!

Actually there is a need to solve a simple problem, but the solution is not in the head.

So, there is a directory online stores, each of which can create a delivery zone with the help Yandex. Cards. The administrator creates a "polygon", coordinates of which are stored in the database. (By the way, while stored in a single field coords but I guess that will have each coordinate of LAT, LNG to store in separate fields)

The user entering directory enters their address and it shows all of the Internet shops offering to it delivery. The coordinates of the addresses are derived from Yandex.Card.

The search gave easy to maintain solutions like this habrahabr.ru/post/127446/ but not quite. You need php and mysql to determine which polygons are the desired coordinates of the address. Maybe someone will come across the idea?
| 15 views

0 like 0 dislike
He asked a question, he seems to have found the answer ) you can Google in the direction of the Spatial Extensions
by
0 like 0 dislike
There is a library GEOS which can be collected as a php extension. In the manuals I understand.
by
0 like 0 dislike
Maybe someone will come across the idea?

The task of the facilities point to a polygon is solved by, for example, the algorithm dressirovki beam.
In General, here:
\rThe problem of the belonging of the point to the polygon
\r
If I understand correctly what you want
by
0 like 0 dislike
In mySQL, there are geographic types, there are corresponding functions for working with them.
However, these functions make mistakes and I had to make the decision on PHP.
\r
This SQL
\r
``/** * Calculates whether Point is in Polygon or not. Uses mySql * @param array \$aPoint * @param array \$aCityBounds * @return boolean */ protected function isPointInCity(array \$aPoint,array &\$aCityBounds) { \$lPointGeomText = 'Point(' . \$aPoint[0] . '' . \$aPoint[1] . ')'; \$lPolyGeomText = "; foreach(\$aCityBounds as &\$lBoundPoint) \$lPolyGeomText .= (empty(\$lPolyGeomText) ? ": ',') . \$lBoundPoint[0] . '' . \$lBoundPoint[1]; // include first point to finish the polygon \$lPolyGeomText = 'Polygon((' . \$lPolyGeomText . ',' . \$aCityBounds[0][0] . '' . \$aCityBounds[0][1] . '))'; \$lQuery = "SELECT MBRIntersects(GeomFromText('" . \$lPolyGeomText . "'),GeomFromText('" . \$lPointGeomText . "'))"; return intval(DbWrapper::dbGetValue(\$lQuery)) > 0 ? true : false; } ``

\r
This without:
\r
``protected function isPointInCityBoundingBox(array \$aPoint, array &\$aCityBoundBox) { return \$aPoint[0] >= \$aCityBoundBox['minx'] && \$aPoint[0] <= \$aCityBoundBox['maxx'] && \$aPoint[1] >= \$aCityBoundBox['miny'] && \$aPoint[1] <= \$aCityBoundBox['maxy']; } /** * Calculate if point is inside polygon, more precisely than mySql now * @param array \$aPoint * @param array \$aCityBounds * @param array \$aCityBoundBox * @return boolean */ protected function isPointInCityNoSql(array \$aPoint, array &\$aCityBounds, array &\$aCityBoundBox) { if(!\$this->isPointInCityBoundingBox(\$aPoint, \$aCityBoundBox)) return false; \$pj = 0; \$pk = 0; \$wrkx = 0; \$yu = 0; \$yl = 0; \$lPointsCount = count(\$aCityBounds); for(\$pj = 0; \$pj < \$lPointsCount; \$pj++) { \$yu = \$aCityBounds[\$pj][1] > \$aCityBounds[(\$pj + 1) % \$lPointsCount][1] ? \$aCityBounds[\$pj][1] : \$aCityBounds[(\$pj + 1) % \$lPointsCount][1]; \$yl = \$aCityBounds[\$pj][1] < \$aCityBounds[(\$pj + 1) % \$lPointsCount][1] ? \$aCityBounds[\$pj][1] : \$aCityBounds[(\$pj + 1) % \$lPointsCount][1]; if(\$aCityBounds[(\$pj + 1) % \$lPointsCount][1] - \$aCityBounds[\$pj][1]) \$wrkx = \$aCityBounds[\$pj][0] + (\$aCityBounds[(\$pj + 1) % \$lPointsCount][0] - \$aCityBounds[\$pj][0]) * (\$aPoint[1] - \$aCityBounds[\$pj][1]) / (\$aCityBounds[(\$pj + 1) % \$lPointsCount][1] - \$aCityBounds[\$pj][1]); else \$wrkx = \$aCityBounds[\$pj][0]; if(\$yu >= \$aPoint[1]) if(\$yl < \$aPoint[1]) { if(\$aPoint[0] > \$wrkx) \$pk++; if(abs(\$aPoint[0] - \$wrkx) < 0.00001) return true; } if((abs(\$aPoint[1] - \$yl) < 0.00001) && (abs(\$yu - \$yl) < 0.00001) && (abs(abs(\$wrkx - \$aCityBounds[\$pj][0]) + abs(\$wrkx - \$aCityBounds[(\$pj + 1) % \$lPointsCount][0]) - abs(\$aCityBounds[\$pj][0] - \$aCityBounds[(\$pj + 1) % \$lPointsCount][0])) < 0.0001)) return true; } return (\$pk % 2) ? true : false; } ``

\r
You can all your decision to shift entirely to mySQL, for each polygon from a big square to calculate the entry address of a user in the polygon.
by
0 like 0 dislike
Here's a look at my solution private your task, namely to all points included in the rectangle. Link. Suddenly the thought of what will appear=)
by

0 like 0 dislike