Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

PHP/MySQL में भू-खोज (दूरी) (प्रदर्शन)

अपनी SQL क्वेरी के WHERE क्लॉज में पंक्तियों के एक सबसेट का चयन करने के लिए एक बाउंडिंग बॉक्स की गणना करें, ताकि आप केवल अपनी तालिका में संपूर्ण 200k रिकॉर्ड के बजाय पंक्तियों के उस सबसेट पर महंगी दूरी की गणना निष्पादित कर रहे हों। इस विधि का वर्णन इस चल प्रकार पर लेख में किया गया है। (PHP कोड उदाहरणों के साथ)। फिर आप वास्तविक दूरी की गणना करने के लिए उस सबसेट के विरुद्ध अपनी क्वेरी में Haversine गणना शामिल कर सकते हैं, और उस बिंदु पर HAVING क्लॉज में कारक शामिल कर सकते हैं।

यह बाउंडिंग बॉक्स है जो आपके प्रदर्शन में मदद करता है, क्योंकि इसका मतलब है कि आप केवल अपने डेटा के एक छोटे से सबसेट पर महंगी दूरी की गणना कर रहे हैं। यह प्रभावी रूप से वही तरीका है जो पैट्रिक ने सुझाया है, लेकिन मूवेबल टाइप लिंक में विधि की व्यापक व्याख्या है, साथ ही PHP कोड भी है जिसका उपयोग आप बाउंडिंग बॉक्स और अपनी SQL क्वेरी बनाने के लिए कर सकते हैं।

संपादित करें

अगर आपको नहीं लगता कि हैवरसाइन काफी सटीक है, तो विंसेंटी फॉर्मूला भी है।

//  Vincenty formula to calculate great circle distance between 2 locations expressed as Lat/Long in KM

function VincentyDistance($lat1,$lat2,$lon1,$lon2){
    $a = 6378137 - 21 * sin($lat1);
    $b = 6356752.3142;
    $f = 1/298.257223563;

    $p1_lat = $lat1/57.29577951;
    $p2_lat = $lat2/57.29577951;
    $p1_lon = $lon1/57.29577951;
    $p2_lon = $lon2/57.29577951;

    $L = $p2_lon - $p1_lon;

    $U1 = atan((1-$f) * tan($p1_lat));
    $U2 = atan((1-$f) * tan($p2_lat));

    $sinU1 = sin($U1);
    $cosU1 = cos($U1);
    $sinU2 = sin($U2);
    $cosU2 = cos($U2);

    $lambda = $L;
    $lambdaP = 2*M_PI;
    $iterLimit = 20;

    while(abs($lambda-$lambdaP) > 1e-12 && $iterLimit>0) {
        $sinLambda = sin($lambda);
        $cosLambda = cos($lambda);
        $sinSigma = sqrt(($cosU2*$sinLambda) * ($cosU2*$sinLambda) + ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda) * ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda));

        //if ($sinSigma==0){return 0;}  // co-incident points
        $cosSigma = $sinU1*$sinU2 + $cosU1*$cosU2*$cosLambda;
        $sigma = atan2($sinSigma, $cosSigma);
        $alpha = asin($cosU1 * $cosU2 * $sinLambda / $sinSigma);
        $cosSqAlpha = cos($alpha) * cos($alpha);
        $cos2SigmaM = $cosSigma - 2*$sinU1*$sinU2/$cosSqAlpha;
        $C = $f/16*$cosSqAlpha*(4+$f*(4-3*$cosSqAlpha));
        $lambdaP = $lambda;
        $lambda = $L + (1-$C) * $f * sin($alpha) * ($sigma + $C*$sinSigma*($cos2SigmaM+$C*$cosSigma*(-1+2*$cos2SigmaM*$cos2SigmaM)));
    }

    $uSq = $cosSqAlpha*($a*$a-$b*$b)/($b*$b);
    $A = 1 + $uSq/16384*(4096+$uSq*(-768+$uSq*(320-175*$uSq)));
    $B = $uSq/1024 * (256+$uSq*(-128+$uSq*(74-47*$uSq)));

    $deltaSigma = $B*$sinSigma*($cos2SigmaM+$B/4*($cosSigma*(-1+2*$cos2SigmaM*$cos2SigmaM)- $B/6*$cos2SigmaM*(-3+4*$sinSigma*$sinSigma)*(-3+4*$cos2SigmaM*$cos2SigmaM)));

    $s = $b*$A*($sigma-$deltaSigma);
    return $s/1000;
}


echo VincentyDistance($lat1,$lat2,$lon1,$lon2);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ClassCastException:java.math.BigInteger को java.lang पर नहीं डाला जा सकता। MySQL से कनेक्ट होने पर लांग

  2. क्या मैसकल एक कॉलम को विभाजित कर सकता है?

  3. मैं PHP का उपयोग करके mysql डेटाबेस में .sql फ़ाइल कैसे आयात करूं?

  4. MySQL में LEFT () फ़ंक्शन कैसे काम करता है

  5. केस या IF ELSEIF के साथ MySQL चयन कथन? सुनिश्चित नहीं है कि परिणाम कैसे प्राप्त करें