地图区域划分转换成数学模型解决问题

计算机与数学是息息相关的,计算机模型中无时无刻不体现数学的理念。例如余弦定理用来求两个文案的相似度。今天我这里解决的问题也与数学有关。实际需求是这样的,在项目当中,需要人工在百度地图中划分配送区域,要求划分出来的区域不能是杂乱无章的,即线段与线段之间不能相穿。当时接到这个需求有点懵逼,如何是好,开完会坐下来,慢慢画图发现划出的图形只要是凹凸多边形即可,突然茅塞顿开,问题迎刃而解,因为规则的凹凸多边形的顶点数与边数相等,根据这段理念简单写了一段验证,结果验证无误。


public function checkMapIsRegularAction(){    $aPoint         = $_POST[‘point‘];    $aPoint         = array(        ‘123.465132,41.870508‘,        ‘123.46082,41.833756‘,        ‘123.510262,41.827951‘,        ‘123.525785,41.879532‘,        ‘123.430349,41.849663‘,        ‘116.404355,39.914444‘,        ‘123.480942,41.830961‘    );

    $aPoint         = array(        ‘116.401696,39.907333‘,        ‘123.46082,41.833756‘,        ‘116.41801,39.917626‘,        ‘116.425052,39.910985‘,        ‘116.414345,39.906004‘    );

    $aFormatPoint   = array();    $aFormatLine    = array();    try {        if ($aPoint) {            foreach ($aPoint as $item) {                list($pointX,$pointY) = explode(‘,‘ ,$item);                $aFormatPoint[] = array(‘x‘ => $pointX, ‘y‘ => $pointY);            }

            $index  = count($aFormatPoint) - 1;            //把顺序坐标转换成线段            foreach ($aFormatPoint as $key=>$point) {                $aFormatLine[][‘start‘] = $point;                if ($index == $key) {                    $aFormatLine[$key][‘end‘]   = $aFormatPoint[0];                } else {                    $aFormatLine[$key][‘end‘]   = $aFormatPoint[$key+1];                }            }        }        $flag = Lib_base::checkIsRegularPolygon($aFormatLine);    }catch (\Exception $e) {        return $e->getMessage();    }}
/** * 检测是不是规则的凹凸多边形(判断标准是顶点数和边数相等) * $aPoint = array(array(‘start‘=>array(‘x‘=>1,‘y‘=>2),‘end‘=>array(‘x‘=>1,‘y‘=>2)),array(‘start‘=>array(‘x‘=>1,‘y‘=>2),‘end‘=>array(‘x‘=>1,‘y‘=>2))) */function checkIsRegularPolygon($aPoint){    $vertexCount    = count($aPoint);

    $aOutPoint      = $aPoint;    $edgeCount      = 0;    array_shift($aPoint);    //两两求交点    foreach ($aOutPoint as $key=>$aLine) {        if (empty($aPoint)) {            continue;        }        foreach ($aPoint as $innerKey => $aInnerLine) {

            $isIntersect = self::checkLineSegIsIntersect($aOutPoint[$key], $aPoint[$innerKey]);            if ($isIntersect) {                $edgeCount += 1;            }        }        array_shift($aPoint);    }

    if ($vertexCount == $edgeCount) {        return true;    }    return false;}

/** * @param $lineSegA * @param $lineSegB * @return bool */function checkLineSegIsIntersect($lineSegA, $lineSegB){    return self::isIntersect($lineSegA[‘start‘],$lineSegA[‘end‘],$lineSegB[‘start‘],$lineSegB[‘end‘]);    //return self::sideIntersectSide($lineSegA[‘start‘],$lineSegA[‘end‘],$lineSegB[‘start‘],$lineSegB[‘end‘]);}

/** * 求叉积 * @param $pointA * @param $pointB * @param $pointC * @return mixed */function  vectorProduct($pointA, $pointB, $pointC){    $AXPoint                = $pointA[‘x‘];    $AYPoint                = $pointA[‘Y‘];    $BXPoint                = $pointB[‘x‘];    $BYPoint                = $pointB[‘y‘];    $CXPoint                = $pointC[‘x‘];    $CYPoint                = $pointC[‘y‘];

    return ($AXPoint - $CXPoint) * ($BYPoint - $CYPoint) - ( $BXPoint - $CXPoint ) * ( $AYPoint - $CYPoint);}

/** * 检测两条线段是否相等 * $pointA, $pointB为一条线段两端点 $pointC,$pointD为另一条线段的两端点 相交返回true, 不相交返回false * @param $pointA * @param $pointB * @param $pointC * @param $pointD * @return bool */function isIntersect($pointA, $pointB, $pointC,$pointD){    $AXPoint                = $pointA[‘x‘];    $AYPoint                = $pointA[‘Y‘];    $BXPoint                = $pointB[‘x‘];    $BYPoint                = $pointB[‘y‘];    $CXPoint                = $pointC[‘x‘];    $CYPoint                = $pointC[‘y‘];    $DXPoint                = $pointD[‘x‘];    $DYPoint                = $pointD[‘y‘];

    if ( max($AXPoint, $BXPoint) < min($CXPoint, $DXPoint) )    {        return false;    }

    if ( max($AYPoint,$BYPoint) < min($CYPoint, $DYPoint) )    {        return false;    }

    if ( max($CXPoint,$DXPoint) < min($AXPoint, $BXPoint) )    {        return false;    }

    if ( max($CYPoint, $DYPoint) < min($AYPoint,$BYPoint) )    {        return false;    }

    if ( (self::vectorProduct($pointC, $pointB, $pointA ) * self::vectorProduct ($pointB,$pointD,$pointA)) < 0 )    {        return false;    }

    if ( (self::vectorProduct($pointA, $pointD, $pointC) * self::vectorProduct($pointD, $pointB, $pointC)) < 0 )    {        return false;    }

    return true;}

后续会按面向对象的方式封装坐标和线段,欢迎点评。

时间: 2024-12-21 18:38:28

地图区域划分转换成数学模型解决问题的相关文章

关于百度地图API批量转换成坐标的方法

下面的代码思路是:从页面获取馆Id数组,将其数组通过ajax提交到服务器,服务器返回馆的ID,馆名,和馆地址: 再循环地址,获取每个地址的坐标,并将馆ID和其坐标对应起来,提交到服务器更新,转换失败的显示到页面上. 只记录了部分js代码~ <script type="text/javascript"> $(function () { $("#Iposition").click(function () { ArrayIdTwo(); }); }); var

使用百度地图将经纬度转换成具体位置

1.申请百度地图的key: AK http://lbsyun.baidu.com/apiconsole/key http://lbsyun.baidu.com/apiconsole/key/create 最早的百度地图是不需要的这些流程的.但现在百度牛逼了.不申请或审核不通过不给用咯,配置请不要吝啬,全部勾选即可 2.找到开发文档 我们使用的的API叫做 [坐标逆转换],也叫[逆/地址解析] http://lbsyun.baidu.com/index.php?title=jspopular/gu

地图坐标点转换成布局坐标点

1 IPoint mapPnt; 2 int xpixels=0,ypixels=0; 3 MapControl.FromMapPoint(mapPnt, ref xpixels, ref ypixels); 4 IPoint pagePnt = PageLayoutControl.ToPagePoint(xpixels, ypixels);

ppt怎么转换成pdf?真正解决问题还得靠它!

ppt怎么转换成pdf?也许你有很多种转换方法,但是它们在遇到批量转换.pdf转ppt或是加密文件的转换时也就不好使了!能够真正解决问题的还得靠它!       因为它拥有最为优秀的转换识别功能,是很多转换工具无法比拟的,即便是图片或扫描版PDF文件也可以轻松转换成Word/Excel/PPT/HTML/IMG,成功的文字.图片.符号.包括排版样式都可以随意在Word文档中进行编辑.唯一的缺点就是:目前该软件提供的是免费试用版.咱先不考虑是试用版还是正式版,先让我们就这试用版来看下它的转换效果究

ArcGIS中利用ArcMap将地理坐标系转换成投影坐标系(从WKID=4326到WKID=102100)

原文:ArcGIS中利用ArcMap将地理坐标系转换成投影坐标系(从WKID=4326到WKID=102100) 对于非地理专业的开发人员,对与这些生涩的概念,我们不一定都要了解,但是我们要理解,凡是以经纬度为单位的都是地理坐标系,因为它归根结底是一个椭球体,只不过各个国家为了反映该国家所在区域地球的真实形状,而采用不同的数学模型对本不是椭球体的地球进行椭球体化.而投影坐标系,是对地理坐标系按照某种方式投影到平面上的,所以可以认为它是一个平面坐标系,单位自然是米或千米. 我们在做开发的时候,尤其

等高线如何转换成西安80坐标系

等高线如何转换成西安80坐标系 BIGEMAP高程数据主要特点: 覆盖全球 (任意范围下载) 精度准确 等高线细腻效果好 高程矢量数据可编辑 支持AutoCAD (DXF.DWG) 支持三维(STL) 支持多格式转换 (kml/kmz/shp/dxf/txt等) 支持投影转换(Xi'an80,Beijing54,WGS84,CGCS2000) 支持公里网格 第一步:需要的工具 1. BIGEMPA地图下载器(全能版已授权)  下载地址:http://download.bigemap.com/bm

Java 内存区域划分 备忘录

最近看了<深入理解虚拟机>的内存分配与管理这部分的内容,这里做一个的总结,以加深我对知识点的理解,如有错误的地方,还望大神们指出,我及时更正:  内存区域划分 首先是下面这幅图: 图 1.0 这幅图是网上download下来的,但是它可以很直观告诉我们Java虚拟机所管理的几个内存区域(包括方法区.堆.虚拟机栈.本地方法栈.程序计数器五个区域),以及线程作用在这些内存区域时的数据访问方式(虚拟机栈.本地方法栈.程序计数器三个区域是线程独有:方法区.堆两个区域是线程间共享): 1.我们首先看看灰

PHP转换成html

PHP转换成html PHP动态网页转换HTML的一个简单办法2006-10-10 14:20 PHP开发工具的优势作为一种简单而高效的Server端嵌入语言,PHP已成为Internet上最流行的一种动态网站制作工具.它不但能够对多种数据库提供良好支持,而且与其它的Server端脚本语言如ASP相比,PHP免费开放源码并且提供跨平台的支持,这使它能够轻易适应当今网络中各种异质的网络环境:可让网页制作人员能够非常快捷.方便地制作出功能强大的动态Web页面. 动态网页的优势随着计算机和互联网技术的

网络安全区域划分&&网络管控粒度思考

2个问题的思考,1.网络安全区域划分的必要性:2.网络管控的粒度在哪里? 第一个问题:网络安全区域划分的必要性 由于资金.网络规模.管理方便等历史原因,网络安全分区总是不那么合理.往往一个区域混杂多种流量,各个流量相互影响,容易由于某个业务遭受攻击连带影响到其他业务.当规模不断扩大时,就像一个隐形炸弹,管理人员光是梳理楚流量都要耗费大量的精力,甚至有时候由于人员变动,没有人分得清楚流量间的关系,给后续的运维带来非常大的成本.一旦发生故障将要耗费大量的时间排错.网络设计宗旨:越简单越好. 近期处理