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

项目需求:通过地图坐标和区域坐标点集合 判断当前坐标是否在坐标点集合区域中$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 <[email protected]>
 * 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))

  

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

时间: 2024-08-30 06:25:18

php实现 计算坐标点在某区域的相关文章

for循环/计算坐标

for循环计算坐标 webqq里面有类似桌面的各种图标,是绝对定位的,这样可以拖动改变位置,用浮动的话,没法拖动. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> div{width:50px;height:50px;background:re

QGIS WGS84转其它坐标系并计算坐标

需求: 将带有经度.纬度(WGS84坐标系)坐标的文本(*.txt)转换成指定投影坐标系的shp文件并计算x,y坐标. 环境和工具: WIN10.QGIS2.16.带有经纬度坐标的文本.格式如下图: 1.创建矢量图层 打开QGIS,选择Layer-->Add Layer-->Add Delimited Text Layer 菜单,如下图所示: 2.导入文本坐标 弹出创建图层对话框,选择带有坐标的文本文件,选择自定自定义分割符(Custom delimiters),选择空格(Space),在X

阿里校招:前端线上笔试题--计算鼠标在页面某个区域内的停留时长

校招:阿里前端笔试题收到笔试通知后恶补了几天阿里前端历年笔试题,巧的是这道题今年有同学做过,而且发到了北邮人bbs上(看来临阵磨枪还是有用的),现在贴上当时提交的代码. 水平有限,有错误烦请指点. 题目: <div class='mod-spm'data-spmid='123'> <divclass='child_a'></div> <divclass='child_b'></div> <divclass='child_c'><

php 腾讯 地图 计算 坐标 两点 距离 微信 网页

$r = https_request('http://apis.map.qq.com/ws/geocoder/v1/?address='.$addr['addr'].'&key=F2GBZ-SREWQ-A3K56-GSLK5-ELOHS-PRB2X'); if($r['status'] == 0){ $lng = $r['result']['location']['lng']; $lat = $r['result']['location']['lat']; $r2 = https_request

php 计算坐标点方圆周围多少米的坐标算法

//地球半径 6371千米 const EARTH_ROUNT = 6371; /** * @param $distance 方圆多少千米 默认500米 */ private function _getAround($lng,$lat,$distance=0.5) { $dlng = 2 * asin(sin($distance / (2*self::EARTH_ROUNT) ) / cos(deg2rad($lat)) ); $dlng = rad2deg($dlng); $dlat = $d

[Selenium]计算坐标进行拖拽,重写dragAndDropOffset

//@author jzhang6 public void dragAndDropOffset(WebDriver driver,WebElement dragableEl, WebElement dropableEl, int offsetX, int offsetY){ Actions action = new Actions(driver); action.clickAndHold(dragableEl).build().perform(); action.moveByOffset(off

OpenGL ES总结(三)OpenGL通过计算纹理坐标来显示一张图片

转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/62444395 通过OpenGL来显示一张汽车图片,图片可以看做一个矩形,所以我们先来画一个矩形 OpenGL的基本形状是三角形,一个矩形可以看成由4个三角形构成,如果我们一个一个画,那需要12个顶点,36个坐标,效率不高,所以我们采用另外一种方式--顶点索引与glDrawElements配合使用. 什么是顶点索引呢?顶点索引就是给

高速公路坐标高程计算软件3.3版本发布

---恢复内容开始--- 高速公路坐标高程计算软件说明 高速公路坐标高程计算软件是在多年的施工放样工作中总结出来的一个很有效的程序.它是公路.铁路施工放样的好助手,可以帮你完成以前你用很大的精力和时间完成的计算.它能在工作中给予很大的方便,使你能从繁琐的计算工作中解脱出来,你只要按要求将已知的几个数据输入即可,并大大的提高了计算精确性和准确性.操作简便.实用,适合采用坐标法放样,如具有全站仪和测距仪的测量放线工作,快速准确定位. 高速公路坐标高程计算软件可以帮你完成直线.圆曲线.缓和曲线(完全缓

Android View坐标getLeft, getRight, getTop, getBottom

1  引起疑惑 分析视图invalidate流程的过程中发现view的left, right, top, bottom跟自己理解的不一样,现在想分析一下这几个值具体的含义. 2  理解坐标,位置概念 这里涉及坐标系的概念: 坐标系在二维视图中通过X轴和Y轴两个数字为组合表示某个点的绝对坐标. 例如(30, 100) 通常表示X轴30, Y轴100交叉的一个点 在Android中可以把left相当于X轴值, top相当于Y轴值, 通过这两个值Android系统可以知道视图的绘制起点,在通过Wdit