How do I draw a mysql polygon circle, and not a square?
The function below creates a polygon square out of 4 points and I assume the last 5th point closed the squar, I need it to have at least 24 points and to make up a circle. Any ideas?
function getRadius($point="POINT(-29.8368 30.9096)", $radius=2)
{
$km = 0.009;
$center = "GeomFromText('$point')";
$radius = $radius*$km;
$bbox = "CONCAT('POLYGON((',
X($center) - $radius, ' ', Y($center) - $radius, ',',
X($center) + $radius, ' ', Y($center) - $radius, ',',
X($center) + $radius, ' ', Y($center) + $radius, ',',
X($center) - $radius, ' ', Y($center) + $radius, ',',
X($center) - $radius, ' ', Y($center) - $radius, '
))')";
$query = $this->db->query("
SELECT id, AsText(latLng) AS latLng, (SQRT(POW( ABS( X(latLng) - X({$center})), 2) + POW( ABS(Y(latLng) - Y({$center})), 2 )))/0.009 AS distance
FROM crime_listing
WHERE Intersects( latLng, GeomFromText($bbox) )
AND SQRT(POW( ABS( X(latLng) - X({$center})), 2) + POW( ABS(Y(latLng) - Y({$center})), 2 )) < $radius
ORDER BY distance
");
if($query->num_rows()>0){
return($query->result());
}else{
return false;
}
}
Below the the js version and this works perfect
var findCirclePolygons = function(point, r)
{
var d2r = Math.PI / 180;
this.circleLatLngs = ne开发者_运维知识库w Array();
numPoints = 24;
var circleLat = r * 0.009; // Convert degrees into km
var circleLng = circleLat / Math.cos(point.lat() * d2r);
for (var i = 0; i < numPoints + 1; i++) {
var theta = Math.PI * (i / (numPoints / 2));
var vertexLat = point.lat() + (circleLat * Math.sin(theta));
var vertexLng = parseFloat(point.lng()) + parseFloat(( circleLng * Math.cos(theta)));
var vertextLatLng = new google.maps.LatLng(vertexLat, vertexLng);
this.circleLatLngs.push(vertextLatLng);
}
// Set options
var options = {
paths: circleLatLngs,
strokeColor: "#0055ff",
strokeOpacity: 1,
strokeWeight: 1,
fillColor: "#0055ff",
fillOpacity: 0.35
};
// Return
return options;
};
You can make a loop (in pseudo code):
for(i=0; i <= 360; i += 360/24)
{
$extra_point = "POINT(". $radius*cos(i)." ". $radius*sin(i) . ")"
}
EDIT
- However, if you just want a bounding box, then using a square is the right way to do it. No need to have a circle looking bounding box. You filter out later with the sorting.
- To measure the distance, no need to use ABS. Squaring does it for you (as an extra, compare to the radius squared instead of computing the square root if you are extreamly picky about performances
- Don't forget to add the spatial index or the performances will be crap
2nd EDIT In somewhat less pseudo-code ;) (It's been ages I didn't work with php).
$lon = 42;
$lat = 2;
$radius = 0.01;
$bbox = "POLYGON((";
for(i=0; i <= 360; i += 360/24)
{
$bbox .= $radius*cos(deg2rad(i)) + $lon." ". $radius*sin(deg2rad(i)) + $lat;
if(i < 360)"
$bbox .= ", "
}
$bbox .= "))"
About the distance thing, you have pow(abs(x),2) == pow(x, 2) for any x. So you can just write (for simplicity):
SQRT(POW( X(latLng) - X({$center}), 2) + POW(Y(latLng) - Y({$center}), 2 )) < $radius
Or even to spare the computation of the square root (in this case it won't change absolutely anything and early optimization is a bad thing, so do as you whish)
POW( X(latLng) - X({$center}), 2) + POW(Y(latLng) - Y({$center}), 2 ) < POW($radius, 2)
精彩评论