分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

php实现 计算坐标点在某区域

发布时间:2023-09-06 02:18责任编辑:赖小花关键词:暂无标签
项目需求:通过地图坐标和区域坐标点集合 判断当前坐标是否在坐标点集合区域中
$area[array] 区域坐标点集合数组
$area = array(  // 天通苑店  0 => array(    array(‘x‘=>116.38295, ‘y‘=>40.09416),    array(‘x‘=>116.44037, ‘y‘=>40.095898),    array(‘x‘=>116.448275,‘y‘=>40.083313),    array(‘x‘=>116.448455,‘y‘=>40.050818),    array(‘x‘=>116.448275,‘y‘=>40.038307),    array(‘x‘=>116.441448,‘y‘=>40.038418),    array(‘x‘=>116.436058,‘y‘=>40.038804),    array(‘x‘=>116.417302,‘y‘=>40.039136),    array(‘x‘=>116.414822,‘y‘=>40.039384),    array(‘x‘=>116.412738,‘y‘=>40.039329),    array(‘x‘=>116.407672,‘y‘=>40.039329),    array(‘x‘=>116.388628,‘y‘=>40.085162),    array(‘x‘=>116.383633,‘y‘=>40.084997)  ),  //亚运村  1 => array(    array(‘x‘=>116.358804,‘y‘=>40.028474),    array(‘x‘=>116.41608, ‘y‘=>40.02875),    array(‘x‘=>116.41723, ‘y‘=>40.038915),    array(‘x‘=>116.447988,‘y‘=>40.037921),    array(‘x‘=>116.447844,‘y‘=>40.026761),    array(‘x‘=>116.455821,‘y‘=>40.024164),    array(‘x‘=>116.446281,‘y‘=>39.994736),    array(‘x‘=>116.443532,‘y‘=>39.995372),    array(‘x‘=>116.376267,‘y‘=>39.993493),    array(‘x‘=>116.375908,‘y‘=>40.000015),    array(‘x‘=>116.372027,‘y‘=>39.999904),    array(‘x‘=>116.371452,‘y‘=>40.007366),    array(‘x‘=>116.359451,‘y‘=>40.006758)  ),  //望京店  2 => array(    array(‘x‘=>116.46387, ‘y‘=>40.021125),    array(‘x‘=>116.484495,‘y‘=>40.020462),    array(‘x‘=>116.515684,‘y‘=>39.995151),    array(‘x‘=>116.51519, ‘y‘=>39.976137),    array(‘x‘=>116.491906,‘y‘=>39.972985),    array(‘x‘=>116.476239,‘y‘=>39.977298),    array(‘x‘=>116.467472,‘y‘=>39.96917),    array(‘x‘=>116.443325,‘y‘=>39.984817),    array(‘x‘=>116.449506,‘y‘=>39.993109),    array(‘x‘=>116.446357,‘y‘=>39.994736),    array(‘x‘=>116.456037,‘y‘=>40.024109)  ),);
<?php/** * 验证坐标点是否在某区域内 * @author xiaoliang <1058436713@qq.com> * Class validationMap */class InareaAction extends CommonAction { ???// 一个表示区域的三维数组 ???public $config = null; ???// 包含每个区域的四边形 ???public $rectangles = null; ???// 每个区域(多边形)的所有边 ???public $lines = null; ???// 要判断的点的x, y坐标 ???public $_x = null; ???public $_y = null; ???public function __construct($config){ ???????$this->config = $config; ???????$this->initRectangles(); ???????$this->initLines(); ???} ???/* ???????获取包含每个配送区域的四边形 ???*/ ???public function initRectangles(){ ???????foreach ($this->config as $k => $v) { ???????????$this->rectangles[$k][‘minX‘] = $this->getMinXInEachConfig($k); ???????????$this->rectangles[$k][‘minY‘] = $this->getMinYInEachConfig($k); ???????????$this->rectangles[$k][‘maxX‘] = $this->getMaxXInEachConfig($k); ???????????$this->rectangles[$k][‘maxY‘] = $this->getMaxYInEachConfig($k); ???????} ???} ???/* ???????初始化每个区域(多边形)的边(线段:直线的一部分【限制x或者y坐标范围】) ???????n 个顶点构成的多边形,有 n-1 条边 ???*/ ???public function initLines(){ ???????foreach ($this->config as $k => $v) { ???????????$pointNum = count($v);// 区域的顶点个数 ???????????$lineNum = $pointNum - 1; // 区域的边条数 ???????????for($i=0; $i<$lineNum; $i++){ ???????????????// y=kx+b : k ???????????????if($this->config[$k][$i][‘x‘] - $this->config[$k][$i+1][‘x‘] == 0) $this->lines[$k][$i][‘k‘] = 0; ???????????????else $this->lines[$k][$i][‘k‘] = ???????????????????($this->config[$k][$i][‘y‘] - $this->config[$k][$i+1][‘y‘])/($this->config[$k][$i][‘x‘] - $this->config[$k][$i+1][‘x‘]); ???????????????// y=kx+b : b ???????????????$this->lines[$k][$i][‘b‘] = $this->config[$k][$i+1][‘y‘] - $this->lines[$k][$i][‘k‘] * $this->config[$k][$i+1][‘x‘]; ???????????????$this->lines[$k][$i][‘lx‘] = min($this->config[$k][$i][‘x‘], $this->config[$k][$i+1][‘x‘]); ???????????????$this->lines[$k][$i][‘rx‘] = max($this->config[$k][$i][‘x‘], $this->config[$k][$i+1][‘x‘]); ???????????} ???????????$pointNum-=1; ???????????if($this->config[$k][$pointNum][‘x‘] - $this->config[$k][0][‘x‘] == 0) $this->lines[$k][$pointNum][‘k‘] = 0; ???????????else $this->lines[$k][$pointNum][‘k‘] = ???????????????($this->config[$k][$pointNum][‘y‘] - $this->config[$k][0][‘y‘])/($this->config[$k][$pointNum][‘x‘] - $this->config[$k][0][‘x‘]); ???????????// y=kx+b : b ???????????$this->lines[$k][$pointNum][‘b‘] = $this->config[$k][0][‘y‘] - $this->lines[$k][$pointNum][‘k‘] * $this->config[$k][0][‘x‘]; ???????????$this->lines[$k][$pointNum][‘lx‘] = min($this->config[$k][$pointNum][‘x‘], $this->config[$k][0][‘x‘]); ???????????$this->lines[$k][$pointNum][‘rx‘] = max($this->config[$k][$pointNum][‘x‘], $this->config[$k][0][‘x‘]); ???????} ???} ???/* ???????获取一组坐标中,x坐标最小值 ???*/ ???public function getMinXInEachConfig($index){ ???????$minX = 200; ???????foreach ($this->config[$index] as $k => $v) { ???????????if($v[‘x‘] < $minX){ ???????????????$minX = $v[‘x‘]; ???????????} ???????} ???????return $minX; ???} ???/* ???????获取一组坐标中,y坐标最小值 ???*/ ???public function getMinYInEachConfig($index){ ???????$minY = 200; ???????foreach ($this->config[$index] as $k => $v) { ???????????if($v[‘y‘] < $minY){ ???????????????$minY = $v[‘y‘]; ???????????} ???????} ???????return $minY; ???} ???/* ???????获取一组坐标中,x坐标最大值 ???*/ ???public function getMaxXInEachConfig($index){ ???????$maxX = 0; ???????foreach ($this->config[$index] as $k => $v) { ???????????if($v[‘x‘] > $maxX){ ???????????????$maxX = $v[‘x‘]; ???????????} ???????} ???????return $maxX; ???} ???/* ???????获取一组坐标中,y坐标最大值 ???*/ ???public function getMaxYInEachConfig($index){ ???????$maxY = 0; ???????foreach ($this->config[$index] as $k => $v) { ???????????if($v[‘y‘] > $maxY){ ???????????????$maxY = $v[‘y‘]; ???????????} ???????} ???????return $maxY; ???} ???/* ???????获取 y=y0 与特定区域的所有边的交点,并去除和顶点重复的,再将交点分为左和右两部分 ???*/ ???public function getCrossPointInCertainConfig($index){ ???????$crossPoint = null; ???????foreach ($this->lines[$index] as $k => $v) { ???????????if($v[‘k‘] == 0) return true; ???????????$x0 = ($this->_y - $v[‘b‘]) / $v[‘k‘];// 交点x坐标 ???????????if($x0 == $this->_x) return true;// 点在边上 ???????????if($x0 > $v[‘lx‘] && $x0 < $v[‘rx‘]){ ???????????????if($x0 < $this->_x) $crossPoint[‘left‘][] = $x0; ???????????????if($x0 > $this->_x) $crossPoint[‘right‘][] = $x0; ???????????} ???????} ???????return $crossPoint; ???} ???/* ???????检测一个点,是否在区域内 ???????返回结果: ???????????return === false : 点不在区域内 ???????????return 0, 1, 2, 3 ... 点所在的区域编号(配置文件中的区域编号。) ???*/ ???public function checkPoint($x, $y){ ???????$this->_x = $x; ???????$this->_y = $y; ???????$contain = null; ???????foreach ($this->rectangles as $k => $v) { ???????????if($x > $v[‘maxX‘] || $x < $v[‘minX‘] || $y > $v[‘maxY‘] || $y < $v[‘minY‘]){ ???????????????continue; ???????????}else{ ???????????????$contain = $k; ???????????????break; ???????????} ???????} ???????if($contain === null) return false; ???????$crossPoint = $this->getCrossPointInCertainConfig($contain); ???????if($crossPoint === true) return $contain; ???????if(count($crossPoint[‘left‘])%2 == 1 && count($crossPoint[‘right‘])%2 == 1) return $contain; ???????return false; ???}}

//实例化对象
$area = new Area($area); 
//判断坐标点是否在区域中 如果坐标点在某一区域返回区域编号 否则返回false;
var_dump($area->checkPoint(116.531748,39.944229))

  

php实现 计算坐标点在某区域

原文地址:https://www.cnblogs.com/objects/p/9822385.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved