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

भू दूरी MySQL

हम double . का उपयोग कर रहे हैं latitude स्टोर करने के लिए और longitude . इसके अलावा हम उन सभी मानों को (ट्रिगर द्वारा) पूर्वगणना करते हैं जो केवल एक बिंदु को देखते समय पूर्व-गणना योग्य होते हैं। मेरे पास वर्तमान में उस सूत्र तक पहुंच नहीं है जिसका हम उपयोग कर रहे हैं, इसे बाद में जोड़ेंगे। यह इष्टतम गति/सटीक संतुलन के लिए अनुकूलित है।

परिभाषित क्षेत्र खोजों के लिए (मुझे x किमी के भीतर सभी बिंदु दें) हम अतिरिक्त रूप से lat/lng मान को 1e6 से गुणा करके संग्रहीत करते हैं (1,000,000) इसलिए हम पूर्णांक श्रेणियों की तुलना करके एक वर्ग में सीमित कर सकते हैं जो बिजली की तेजी से उदा.

lat BETWEEN 1290000 AND 2344000
AND
lng BETWEEN 4900000 AND 4910000
AND
distformularesult < 20

संपादित करें:

PHP में वर्तमान स्थान के मानों का सूत्र और पूर्व-परिकलन यहां दिया गया है।

WindowSize वह मान है जिसके साथ आपको खेलना है, यह डिग्री फ़ैक्टर 1e6 है, जिसका उपयोग केंद्र के चारों ओर एक वर्ग में संभावित परिणामों को कम करने के लिए किया जाता है, परिणाम खोजने की गति तेज करता है - यह न भूलें कि यह कम से कम होना चाहिए आपके खोज के दायरे का आकार.

$paramGeoLon = 35.0000 //my center longitude
$paramGeoLat = 12.0000 //my center latitude

$windowSize = 35000;   

$geoLatSinRad = sin( deg2rad( $paramGeoLat ) );
$geoLatCosRad = cos( deg2rad( $paramGeoLat ) );
$geoLonRad    = deg2rad( $paramGeoLon );

$minGeoLatInt = intval( round( ( $paramGeoLat * 1e6 ), 0 ) ) - $windowSize;
$maxGeoLatInt = intval( round( ( $paramGeoLat * 1e6 ), 0 ) ) + $windowSize;
$minGeoLonInt = intval( round( ( $paramGeoLon * 1e6 ), 0 ) ) - $windowSize;
$maxGeoLonInt = intval( round( ( $paramGeoLon * 1e6 ), 0 ) ) + $windowSize;

मेरे केंद्र की एक विशिष्ट श्रेणी के भीतर सभी पंक्तियों को खोजना

SELECT
          `e`.`id`
        , :earthRadius * ACOS ( :paramGeoLatSinRad * `e`.`geoLatSinRad` + :paramGeoLatCosRad * `m`.`geoLatCosRad` * COS( `e`.`geoLonRad` - :paramGeoLonRad ) ) AS `geoDist`

FROM
          `example` `e`
WHERE
        `e`.`geoLatInt` BETWEEN :paramMinGeoLatInt AND :paramMaxGeoLatInt
        AND
        `e`.`geoLonInt` BETWEEN :paramMinGeoLonInt AND :paramMaxGeoLonInt
HAVING `geoDist` < 20
ORDER BY 
        `geoDist`

फॉर्मूलर में काफी अच्छी सटीकता होती है (एक मीटर से नीचे, यह निर्भर करता है कि आप कहां हैं और बिंदु के बीच कितनी दूरी है)

मैंने अपनी डेटाबेस तालिका example . में निम्न मानों का पूर्व-परिकलन किया है

CREATE TABLE `example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `geoLat` double NOT NULL DEFAULT '0',
  `geoLon` double NOT NULL DEFAULT '0',

  # below is precalculated with a trigger
  `geoLatInt` int(11) NOT NULL DEFAULT '0',
  `geoLonInt` int(11) NOT NULL DEFAULT '0',
  `geoLatSinRad` double NOT NULL DEFAULT '0',
  `geoLatCosRad` double NOT NULL DEFAULT '0',
  `geoLonRad` double NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `example_cIdx_geo` (`geoLatInt`,`geoLonInt`,`geoLatSinRad`,`geoLatCosRad`,`geoLonRad`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC

उदाहरण ट्रिगर

DELIMITER $
CREATE TRIGGER 'example_before_insert' BEFORE INSERT ON `example` FOR EACH ROW
BEGIN
    SET NEW.`geoLatInt` := CAST( ROUND( NEW.`geoLat` * 1e6, 0 ) AS SIGNED INTEGER );
    SET NEW.`geoLonInt` := CAST( ROUND( NEW.`geoLon` * 1e6, 0 ) AS SIGNED INTEGER );
    SET NEW.`geoLatSinRad` := SIN( RADIANS( NEW.`geoLat` ) );
    SET NEW.`geoLatCosRad` := COS( RADIANS( NEW.`geoLat` ) );
    SET NEW.`geoLonRad` := RADIANS( NEW.`geoLon` );
END$

CREATE TRIGGER 'example_before_update' BEFORE UPDATE ON `example` FOR EACH ROW
BEGIN
    IF NEW.geoLat <> OLD.geoLat OR NEW.geoLon <> OLD.geoLon
    THEN
        SET NEW.`geoLatInt` := CAST( ROUND( NEW.`geoLat` * 1e6, 0 ) AS SIGNED INTEGER );
        SET NEW.`geoLonInt` := CAST( ROUND( NEW.`geoLon` * 1e6, 0 ) AS SIGNED INTEGER );
        SET NEW.`geoLatSinRad` := SIN( RADIANS( NEW.`geoLat` ) );
        SET NEW.`geoLatCosRad` := COS( RADIANS( NEW.`geoLat` ) );
        SET NEW.`geoLonRad` := RADIANS( NEW.`geoLon` );
    END IF;
END$
DELIMITER ;

प्रशन? नहीं तो मजे करो :)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. पायथन के साथ OSX पर MySQL को लिखने के लिए आसान सेटअप

  2. किसी प्रक्रिया या ट्रिगर के अंदर mysql ईवेंट कैसे बनाएं?

  3. PHP का उपयोग करके एक्सेल या सीएसवी को MySQL डेटा बेस पर कैसे अपलोड करें?

  4. PHP के साथ दो MySQL तालिकाओं में शामिल हों

  5. कैसे तैयार बयान के साथ एक उचित mysqli विस्तार वर्ग बनाने के लिए?