php+mongodb判断坐标是否在指定多边形区域内的实例

MongoDB是一个基于分布式文件存储的数据库,并提供创建基于地理空间的索引的能力,本文将提供使用PHP连接mongodb,判断坐标是否在指定多边形区域内的实例。

1.定义多边形区域

多边形的坐标点如下:

113.314882,23.163055
113.355845,23.167042
113.370289,23.149564
113.356779,23.129758
113.338238,23.13913
113.330979,23.124706
113.313588,23.140858
113.323865,23.158204
113.314882,23.163055

2.在mongodb创建数据库

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use testdb;
 
db.createUser(
   {
     "user" : "root" ,
     "pwd" : "123456" ,
     "roles" :[{ "role" : "readWrite" , "db" : "testdb" }]
   }
);
 
db.auth(
   {
     "user" : "root" ,
     "pwd" : "123456"
   }
);

3.使用php插入多边形数据,并判断坐标是否在区域内

MongoDBPolygons.class.php

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
/**
  * MongoDB 多边形区域类,判断坐标是否在多边形区域内
  * Date:  2016-09-30
  * Author: fdipzone
  * Ver:  1.0
  *
  * Func:
  * public add      创建多边形区域
  * public checkInArea  判断坐标是否在多边形区域内
  * private connect    连接mongodb
  */
class MongoDBPolygons { // class start
 
   // mongo db 连接
   private $_conn = null;
 
   // mongo db
   private $_db = null;
 
   /**
    * 初始化
    * @param String $host  mongodb地址
    * @param String $user  用户名
    * @param String $passwd 密码
    * @param String $db   数据库
    */
   public function __construct( $host , $user , $passwd , $db ){
     $this ->_conn = $this ->connect( $host , $user , $passwd );
     $this ->_db = $db ;
   }
 
   /**
    * 插入多边形数据
    * @param String $collname 表名称
    * @param Array $data   多边形坐标数据
    * @param Array $index  索引
    * @return Int
    */
   public function add( $collname , $data , $index ){
 
     // 创建索引
     $cmd = array (
       'createIndexes' => $collname ,
       'indexes' => array (
         array (
           'name' => 'index' ,
           'key' => $index ,
           'ns' => $this ->_db. '.' . $collname
         )
       )
     );
     $command = new MongoDB\Driver\Command( $cmd );
     $this ->_conn->executeCommand( $this ->_db, $command );
 
     // 插入数据
     $bulk = new MongoDB\Driver\BulkWrite();
     $inserted = 0;
 
     if ( $data ){
       foreach ( $data as $k => $v ){
         $bulk ->insert( $v );
       }
       $result = $this ->_conn->executeBulkWrite( $this ->_db. '.' . $collname , $bulk );
       $inserted = $result ->getInsertedCount();
     }
 
     return $inserted ;
   }
 
   /**
    * 判断是否在多边形区域
    * @param String $collname 表名称
    * @param Decimal $longitude 经度
    * @param Decimal $latitude 纬度
    * @return Array
    */
   public function checkInArea( $collname , $longitude , $latitude ){
     $filter = array (
       'polygons' => array (
           '$geoIntersects' => array (
               '$geometry' => array (
                   'type' => 'Point' ,
                   'coordinates' => array (doubleval( $longitude ), doubleval( $latitude ))
               )
           )
       )
     );
     $options = array ( 'limit' =>1);
     $query = new MongoDB\Driver\Query( $filter , $options );
     $cursor = $this ->_conn->executeQuery( $this ->_db. '.' . $collname , $query );
 
     $result = array ();
     if ( $cursor ){
       foreach ( $cursor as $v ){
         $result [] = $v ;
       }
     }
 
     return $result ? $result [0] : $result ;
   }
 
   /**
    * 连接mongodb
    * @param String $host  数据库地址
    * @param String $user  用户名
    * @param String $passwd 密码
    * @return DBLink
    */
   private function connect( $host , $user , $passwd ){
     $server = 'mongodb://' . $user . ':' . $passwd . '@' . $host ;
     try {
       $conn = new MongoDB\Driver\Manager();
     } catch (MongoDB\Driver\Exception\ConnectionException $e ){
       throw new ErrorException( 'Unable to connect to db server. Error:' . $e ->getMessage(), 31);
     }
     return $conn ;
   }
 
} // class end
?>

demo.php

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
require 'MongoDBPolygons.class.php' ;
 
echo '<strong>php MongoDB 判断坐标是否在多边形区域内演示:</strong><br><br>' ;
 
// 调用mongodb多边形区域类
$oMongoDBPolygons = new MongoDBPolygons( 'localhost' , 'root' , '123456' , 'testdb' );
 
// 索引
$index = array ( 'polygons' => '2dsphere' );
 
// 插入多边形区域数据
$data = array (
       array (
         'polygons' => array (
           'type' => 'Polygon' ,
           'coordinates' => array (
             array (
               array (doubleval(113.314882),doubleval(23.163055)),
               array (doubleval(113.355845),doubleval(23.167042)),
               array (doubleval(113.370289),doubleval(23.149564)),
               array (doubleval(113.356779),doubleval(23.129758)),
               array (doubleval(113.338238),doubleval(23.13913)),
               array (doubleval(113.330979),doubleval(23.124706)),
               array (doubleval(113.313588),doubleval(23.140858)),
               array (doubleval(113.323865),doubleval(23.158204)),
               array (doubleval(113.314882),doubleval(23.163055)),
             )
           )
         ),
       )
     );
 
$inserted = $oMongoDBPolygons ->add( 'geo' , $data , $index );
if ( $inserted ){
   echo '1.成功插入多边形数据<br><br>' ;
}
 
// 判断坐标是否在多边形区域
echo '2.判断广州东站坐标(113.330908, 23.155678)是否在区域内<br>' ;
$result = $oMongoDBPolygons ->checkInArea( 'geo' , 113.330908, 23.155678);
echo '结果:广州东站坐标(113.330908, 23.155678)' .( $result ? '在区域内' : '在区域外' );
echo '<br><br>' ;
 
echo '3.判断宏发大厦坐标(113.33831, 23.137335)是否在区域内<br>' ;
$result = $oMongoDBPolygons ->checkInArea( 'geo' , 113.33831, 23.137335);
echo '结果:宏发大厦坐标(113.33831, 23.137335)' .( $result ? '在区域内' : '在区域外' );
echo '<br><br>' ;
 
?>

输出:
php MongoDB 判断坐标是否在多边形区域内演示:

1.成功插入多边形数据

2.判断广州东站坐标(113.330908, 23.155678)是否在区域内
结果:广州东站坐标(113.330908, 23.155678)在区域内

3.判断宏发大厦坐标(113.33831, 23.137335)是否在区域内
结果:宏发大厦坐标(113.33831, 23.137335)在区域外

广州东站坐标

宏发大厦坐标

以上就是本文的全部内容,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值