1

重複の可能性:
PHPでSQLインジェクションを防ぐ方法は?
MySQLデータベースから個別の行を選択します

こんにちは私は、路面の変形(ポットホールやスピードバンプなど)が検出されたときに緯度、経度、住所、重大度を保存する電話ギャップアプリケーションを持っています。

これまでのところ、PHPPDOを介してこれらをデータベースに保存することはまったく問題ではありません。PDOは、報告されている甌穴がすでに10回報告されている場合(15メートルの範囲内のエントリがないかデータベースをチェックする)、報告されない(つまり、データベースに再度挿入される)ように設計されています。また、表面の変形をロードすることも問題ではありません。私はそれを行うためにHaversineの式を使用しています。ここでは、ユーザーの緯度と経度を渡し、特定の距離内の値を取得します。

$stmt = $dbh->prepare("
  SELECT
    lat, lng,
    ( 6378160 * acos( cos( radians(?) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(?) ) + sin( radians(?) ) * sin( radians( lat ) ) ) ) AS distance
  FROM myTable
  HAVING distance > 0 
  ORDER BY distance
  LIMIT 0 , 30
");

私が抱えている問題は、同じ甌穴が10回報告される可能性があるため、同じ甌穴が地図上にチャートを作成するためのアプリケーションに10回報告されることになります。私がする必要があるのは、ユーザーから一定の距離内にある甌穴のリストを取得し(半正矢関数を使用して実行)、このリストから、同じではなく個別の甌穴のみを取得するように甌穴をフィルタリングすることです甌穴は10回返されます。誰かが私がそのようなフィルタリングをどのように行うことができるか考えていますか?PHP / PDOでこれを行う方法を教えてもらえますか、または利用可能な場合は同様のチュートリアルを教えてもらえますか?

簡単に言うと、次のようにする必要があります。データベースに、ポットホールAとポットホールBの近くにいて、ポットホールAのレポートが6つ、ポットホールBのレポートが8つあるとします。半正矢関数を使用することにより、ポットホールAとポットホールBのレポートのすべての値を取得します(つまり、14の結果)。必要なのは、ポットホールAのレポートの中間点とポットホールBのレポートの中間点を取得し(http://www.geomidpoint.com/calculation.htmlを使用)、2つの結果(1つはAと14の結果ではなくB)の1つ。

4

2 に答える 2

1

ポットホールとレポートを分離する必要があります。最初にどのようなくぼみがあるかGROUP BY lat, lngをクエリし、次に で各くぼみについて 1 つのレポートをクエリしますLIMIT 1

$rows = dbh_query("SELECT id FROM ... ");
foreach ($rows as $row)
{
    dbh_query("SELECT ... WHERE id = :id LIMIT 1", array('id' => $row['id']));
}
于 2013-01-02T11:44:58.090 に答える
0

詳しく説明するには2つのオプションがあると思います。残念ながら、どちらもいくつかの複雑さを意味します。

1) 複数の観測を書き込む代わりに、書き込み時に常にそれらをクラスタ化する必要があります。たとえば、10 メートルの空間粒度をサポートする場合、既存の記録から 10 メートル未満の新しい測定値が到着するたびに、新しいくぼみを追加するのではなく、平均値 (緯度、経度、カウンター) を変更します。最も近い既存のレコード。このようにして、例としてポットホール A と B の 2 つのレコードが作成されるので、DISTINCTクエリを使用できます。

2) リクエストごとに、既存のテーブルから 15 メートルの範囲内のすべてのレコードを取得し、道路の斧に沿った確率密度関数を計算するための一時テーブルを作成できます。繰り返しますが、これには、関数で小数精度としてシミュレートできる粒度を選択する必要がありますROUND。たとえば、現在のポイントと既存のレコード間の距離を計算するストアド関数がある場合、次のように記述できます。

INSERT INTO `temppdf` (dist, pothole_id)
SELECT FROM `maintable`
ROUND(distance(@current_lat, @current_lon, maintable.lat, maintable.lon), -1), pothole_id
WHERE distance(@current_lat, @current_lon, maintable.lat, maintable.lon) < 15;

次に、次のように、すべてのポットホールの最大カウンターを使用して行の temppdf をクエリできます。

SELECT pothole, MAX(cnt) as `peak` FROM
(SELECT DISTINCT pothole, COUNT(dist) as cnt FROM `temppdf` GROUP BY pothole, dist) as `subq`
GROUP BY pothole;

カウンターがしきい値よりも大きいポットホールが結果です。

于 2013-01-02T12:38:27.757 に答える