首页 > 技术文档 > 技术文档 > php下的mongodb地理位置搜寻

php下的mongodb地理位置搜寻

时间:2016-7-1 已查看2491次

LBS,存储每个地点的经纬度坐标,搜寻附近的地点,建立地理位置索引可提高查询效率。

mongodb地理位置索引,2d和2dsphere,对应平面和球面。


1.创建lbs集合存放地点坐标



use lbs;


db.lbs.insert(

    {

        loc:{

            type: "Point",

            coordinates: [113.332264, 23.156206]

        },

        name: "广州东站"

    }

)


db.lbs.insert(

    {

        loc:{

            type: "Point",

            coordinates: [113.330611, 23.147234]

        },

        name: "林和西"

    }

)


db.lbs.insert(

    {

        loc:{

            type: "Point",

            coordinates: [113.328095, 23.165376]

        },

        name: "天平架"

    }

)

创建地理位置索引


db.lbs.ensureIndex(

    {

        loc: "2dsphere"

    }

)


3.查询附近的坐标

当前位置为:时代广场,

坐标:113.323568, 23.146436


搜寻附近一公里内的点,由近到远排序

db.lbs.find(

    {

        loc: {

            $near:{

                $geometry:{

                    type: "Point",

                    coordinates: [113.323568, 23.146436]

                },

                $maxDistance: 1000

            }

        }

    }

)


搜寻结果:

{ "_id" : ObjectId("556a651996f1ac2add8928fa"), "loc" : { "type" : "Point", "coordinates" : [ 113.330611, 23.147234 ] }, "name" : "林和西" }


php代码如下:


<?php

// 连接mongodb

function conn($dbhost, $dbname, $dbuser, $dbpasswd){

    $server = 'mongodb://'.$dbuser.':'.$dbpasswd.'@'.$dbhost.'/'.$dbname;

    try{

        $conn = new MongoClient($server);

        $db = $conn->selectDB($dbname);

    } catch (MongoException $e){

        throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);

    }

    return $db;

}


// 插入坐标到mongodb

function add($dbconn, $tablename, $longitude, $latitude, $name){

    $index = array('loc'=>'2dsphere');

    $data = array(

            'loc' => array(

                    'type' => 'Point',

                    'coordinates' => array(doubleval($longitude), doubleval($latitude))

            ),

            'name' => $name

    );

    $coll = $dbconn->selectCollection($tablename);

    $coll->ensureIndex($index);

    $result = $coll->insert($data, array('w' => true));

    return (isset($result['ok']) && !empty($result['ok'])) ? true : false;

}


// 搜寻附近的坐标

function query($dbconn, $tablename, $longitude, $latitude, $maxdistance, $limit=10){

    $param = array(

        'loc' => array(

            '$nearSphere' => array(

                '$geometry' => array(

                    'type' => 'Point',

                    'coordinates' => array(doubleval($longitude), doubleval($latitude)), 

                ),

                '$maxDistance' => $maxdistance*1000

            )

        )

    );


    $coll = $dbconn->selectCollection($tablename);

    $cursor = $coll->find($param);

    $cursor = $cursor->limit($limit);

    

    $result = array();

    foreach($cursor as $v){

        $result[] = $v;

    }  


    return $result;

}


$db = conn('localhost','lbs','root','123456');


// 随机插入100条坐标纪录

for($i=0; $i<100; $i++){

    $longitude = '113.3'.mt_rand(10000, 99999);

    $latitude = '23.15'.mt_rand(1000, 9999);

    $name = 'name'.mt_rand(10000,99999);

    add($db, 'lbs', $longitude, $latitude, $name);

}


// 搜寻一公里内的点

$longitude = 113.323568;

$latitude = 23.146436;

$maxdistance = 1;

$result = query($db, 'lbs', $longitude, $latitude, $maxdistance);

print_r($result);

?>


演示php代码,首先需要在mongodb的lbs中创建用户和执行auth。方法如下:


use lbs;

db.createUser(

    {

        "user":"root",

        "pwd":"123456",

        "roles":[]

    }

)


db.auth(

    {

        "user":"root",

        "pwd":"123456"

    }

)




查询命令 距离单位 说明

$near 官方文档上关于这一点是错的

$nearSphere 弧度  

$center  

$centerSphere 弧度  

$polygon  

$geoNear 度或弧度 指定参数spherical为true则为弧度,否则为度

如果坐标以GeoJSON格式,则单位都为米。


当然如果你的操作比较复杂,或者希望知道更加详细的对照关系,也可以参考官方的这个更详细的对比表格:http://docs.mongodb.org/manual/reference/operator/query-geospatial/


上一篇:mongdb的lbs位置查询的php语法 下一篇:HTML DOM 事件