php 電子圍欄算法
最近公司有圍欄的需求,要求車輛進(jìn)入設(shè)置好的圍欄中時報警,反之亦然。
這個函數(shù)解決了判斷一個坐標(biāo)在指定的幾個坐標(biāo)圍成的圍欄中。
這個圍欄可以是任意形狀,任意大小,任意區(qū)域。不依賴任何第三方。純函數(shù)。
/*** @name 圍欄算法,判斷一個坐標(biāo),是否在圍欄里面.如:['113.664673,34.810146','113.681667,34.796896','113.69231,34.794711','113.702009,34.809159']* @author zlx3323* @param array $fences 圍欄,是一組坐標(biāo)數(shù)組 如:113.674458,34.804719* @param string $point 要判斷的坐標(biāo)* @return bool?*/public?function?getDistance($macid,$longitude2,?$latitude2)?{$userid = DB::name('merchant_shop_commodity')->where('macid',$macid)->value('userid');$isfence = Gps::name('gps_realtime')->where('macid',$macid)->value('isfence');$fence = Gps::name('gps_police_setting')->where('userid',$userid)->value('fence');??????//判斷是否圍欄通知if($fence){$point = $longitude2.','.$latitude2;$fences = DB::name('gps_fencelist')->where('macid',$macid)->where('is_round',0)->field('lat_lng,status')->select();if($fences){foreach($fences as $k=>$vs){$newsfences = json_decode($vs['lat_lng'],true);$nvert = count($newsfences[0]);$vertx = [];$verty = [];list($testy, $testx) = explode(',', $point);$yes = 0;foreach ($newsfences as $r=>$vo) {foreach($vo as $k=>$vv){list($lng, $lat) = explode(',', $vv);$vertx[] = $lng;$verty[] = $lat;}$i = $j = $c = 0;for ($i = 0, $j = $nvert - 1; $i < $nvert; $j = $i++) {if (( ($verty[$i] > $testy) != ($verty[$j] > $testy) ) &&($testx < ($vertx[$j] - $vertx[$i]) * ($testy - $verty[$i]) / ($verty[$j] - $verty[$i]) + $vertx[$i]))$c = !$c;}unset($verty);unset($vertx);//判斷是否在圍欄中if($c){$yes = 1;}}if($yes ==1){return $yes;}}}}}
圓形圍欄算法:
//計算圓形圍欄距離public function getroundDistance($macid='',$longitude2='', $latitude2='',$unit=1, $decimal=2){$userid = DB::name('merchant_shop_commodity')->where('macid',$macid)->value('userid');$isfence = Gps::name('gps_realtime')->where('macid',$macid)->value('isfence');$fence = Gps::name('gps_police_setting')->where('userid',$userid)->value('fence');//判斷是否圍欄通知if($fence){$fences = DB::name('gps_fencelist')->where('macid',$macid)->where('is_round',1)->field('lat_lng,radius,status')->select();if($fences){foreach($fences as $k=>$vo){$lat_lng = explode(',', $vo['lat_lng']);$fences[$k]['lat'] = $lat_lng[1];$fences[$k]['lng'] = $lat_lng[0];}$yes = 0;foreach($fences as $k=>$vo){$longitude1 = $vo['lng'];$latitude1 = $vo['lat'];if($longitude1 && $latitude1){$EARTH_RADIUS = 6370.996; // 地球半徑系數(shù)$PI = 3.1415926;$radLat1 = $latitude1 * $PI / 180.0;$radLat2 = $latitude2 * $PI / 180.0;$radLng1 = $longitude1 * $PI / 180.0;$radLng2 = $longitude2 * $PI /180.0;$a = $radLat1 - $radLat2;$b = $radLng1 - $radLng2;$distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));$distance = $distance * $EARTH_RADIUS * 1000;if($unit==2){$distance = $distance / 1000;}$result = round($distance, $decimal);//判斷是否在圍欄中,radius為半徑??????????????????????????if($result?$vo['radius']){$yes = 1;}if($yes == 1){return $yes;}}}}}}
數(shù)據(jù)庫字段示例:

評論
圖片
表情
