1. /**
    * 获取边界
    * @return mixed
    * @return false|string
    * @throws \Exception
    */
    public function actionBorder()
    {
    $lock_file = "/tmp/process.lock";
    $lock_file_handle = fopen($lock_file, 'w');
    if ($lock_file_handle === false)
    die("Can not create lock file {$lock_file}\n");
    if (!flock($lock_file_handle, LOCK_EX + LOCK_NB)) {
    die(date("Y-m-d H:i:s") . " Process already exists.\n");
    }
  2.  
  3. $cache = \Yii::$app->cache;
    // $cache->delete('amap_border');
  4.  
  5. $result = $cache->get('amap_border');
    if($result) {
    // return json_encode($result);
    }
  6.  
  7. $gaode_url = 'https://restapi.amap.com/v3/config/district?keywords=110100&subdistrict=0&extensions=all&key=****';
    $curl = new HttpCurl();
    $response_json = $curl->get($gaode_url);
    $response_arr = json_decode($response_json, true);
    $left_lng = 0;
    $up_lat = 0;
    $right_lng = 0;
    $down_lat = 0;
    $lng_lat_arr = [];
    $lng_lat_tmp_arr = [];
    $result_arr_list = [];
    if($response_arr['status'] == 1){
    $lng_lat_str = isset($response_arr['districts'][0]['polyline']) ? $response_arr['districts'][0]['polyline'] : '';
    $lng_lat_tmp_list = explode('|', $lng_lat_str);
    $i = 1;
    foreach ($lng_lat_tmp_list as $k=>$lng_lat_tmp){
    $lng_lat_arr_tmp = explode(';', $lng_lat_tmp);
    foreach ($lng_lat_arr_tmp as $lng_lat_arr_v) {
    // 17152
    if(!($i % 10)) {
    $lng_lat_t_arr = explode(',', $lng_lat_arr_v);
    $result_tmp['lng'] = $lng_lat_t_arr[0];
    $result_tmp['lat'] = $lng_lat_t_arr[1];
    $result_arr_list[$k][] = $result_tmp;
    $lng_lat_arr[$k][] = $lng_lat_t_arr;
    $lng_lat_tmp_arr[] = $lng_lat_t_arr;
    }
    $i++;
    }
    }
    // var_dump(count($lng_lat_tmp_arr));die;
  8.  
  9. $tmp_lng_arr = ArrayHelper::getColumn($lng_lat_tmp_arr, '0');
    $tmp_lat_arr = ArrayHelper::getColumn($lng_lat_tmp_arr, '1');
    $left_lng =min($tmp_lng_arr);
    $up_lat =max($tmp_lat_arr);
    $right_lng =max($tmp_lng_arr);
    $down_lat =min($tmp_lat_arr);
    }
    $boundary_arr = [];
    foreach ($result_arr_list as $result_arr) {
    // 获取6个点
    $boundary_arr = $this->draw_other_lng_lat($left_lng, $up_lat, $result_arr, $right_lng, $down_lat);
    $boundary_arr = array_merge($boundary_arr,$boundary_arr);
    }
  10.  
  11. $result = [
    'code' => 0,
    // 'msg'=>'',
    'data' => $lng_lat_arr,
    'boundary_arr' => $boundary_arr,
    'left_lng'=>$left_lng,
    'up_lat'=>$up_lat,
    'right_lng'=>$right_lng,
    'down_lat'=>$down_lat,
    ];
    $cache->set('amap_border', $result);
    var_dump(count($boundary_arr));die;
  12.  
  13. }
  14.  
  15. public function draw_other_lng_lat($longitude, $latitude, $result_list, $right_lng, $down_lat) {
    $latDistance = 1.0 / 111322 * cos(45*pi() / 180);//每一米代表多少度
    $lonDistance = 1.0 / 111322;
    $radius = 1000;//1000米
    $boundary_arr = [];
    $count_lenth = 1;
    // for (var i_total=0; i_total<count_lenth; i_total+=10) {
    while(1) {
    $count_lenth++;
    $mLongitude_tmp = $longitude + $count_lenth * 1.5 * $radius * $lonDistance;
    $mLatitude_tmp = $latitude - 2 * $count_lenth * $radius * sin(60 * pi() / ) * $latDistance;
    if ($mLongitude_tmp > $right_lng && $mLatitude_tmp < $down_lat) { // 到边界了
    break;
    }
    if($count_lenth > ) break; // 安全值 防止死循环
    }
    for ($i = ; $i <= $count_lenth; $i++) {
    $mLongitude = $longitude + $i * 1.5 * $radius * $lonDistance;
    for ($j = ; $j <= $count_lenth; $j++) {
    $mLatitude = $latitude - 2 * $j * $radius * sin(60 * pi() / ) * $latDistance;
    if ($i % 2 != ) {
    $mLatitude += $radius * sin(60 * pi() / ) * $latDistance;
    }
    if($mLongitude > $right_lng && $mLatitude < $down_lat){
    echo "运行结束-";
    break ;
    }else{
    if($i == $count_lenth){
    $count_lenth = $count_lenth+;
    $i--;
    echo $count_lenth ." \n";
    break;
    }
    }
    $inRing = $this->is_point_in_polygon(['lng'=>$mLongitude,'lat'=>$mLatitude], $result_list); // 是否在多边形内
  16.  
  17. if($inRing == true) {
    $height = $radius * sin(*pi() / ) * $latDistance;
    $lng1 = $mLongitude - $radius / 2 * $lonDistance; $lat1 = $mLatitude + $height;
    $lng2 = $mLongitude + $radius / 2 * $lonDistance; $lat2 = $mLatitude + $height;
    $lng3 = $mLongitude + $radius * $lonDistance; $lat3 = $mLatitude;
    $lng4 = $mLongitude + $radius / 2 * $lonDistance; $lat4 = $mLatitude - $height;
    $lng5 = $mLongitude - $radius / 2 * $lonDistance; $lat5 = $mLatitude - $height;
    $lng6 = $mLongitude - $radius * $lonDistance; $lat6 = $mLatitude;
    $boundary_tmp = [$lng1.','.$lat1,$lng2.','.$lat2,$lng3.','.$lat3,$lng4.','.$lat4,$lng5.','.$lat5,$lng6.','.$lat6];
    $boundary_arr[] = $boundary_tmp;
    }
    }
    // if($break) break;
    }
    // }
    return $boundary_arr;
    }
  18.  
  19. /**
    * 判断一个坐标是否在一个多边形内(由多个坐标围成的)
    * 基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
    * 在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。
    * @param $point 要查询的点
    * @param $pts 要查询的范围
    * @return bool
    */
    public function is_point_in_polygon($point, $pts) {
    $N = count($pts);
    $boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
    $intersectCount = ;//穿越点数
    $precision = 2e-10; //浮点类型计算时候与0比较时候的容差
    $p1 = ;
    $p2 = ;
    $p = $point;
  20.  
  21. $p1 = $pts[];
    for ($i = ; $i <= $N; ++$i) {
    if ($p['lng'] == $p1['lng'] && $p['lat'] == $p1['lat']) {
    return $boundOrVertex;
    }
  22.  
  23. $p2 = $pts[$i % $N];//right vertex
    if ($p['lat'] < min($p1['lat'], $p2['lat']) || $p['lat'] > max($p1['lat'], $p2['lat'])) {//ray is outside of our interests
    $p1 = $p2;
    continue;
    }
  24.  
  25. if ($p['lat'] > min($p1['lat'], $p2['lat']) && $p['lat'] < max($p1['lat'], $p2['lat'])) {//ray is crossing over by the algorithm (common part of)
    if($p['lng'] <= max($p1['lng'], $p2['lng'])){//x is before of ray
    if ($p1['lat'] == $p2['lat'] && $p['lng'] >= min($p1['lng'], $p2['lng'])) {//overlies on a horizontal ray
    return $boundOrVertex;
    }
  26.  
  27. if ($p1['lng'] == $p2['lng']) {//ray is vertical
    if ($p1['lng'] == $p['lng']) {//overlies on a vertical ray
    return $boundOrVertex;
    } else {//before ray
    ++$intersectCount;
    }
    } else {//cross point on the left side
    $xinters = ($p['lat'] - $p1['lat']) * ($p2['lng'] - $p1['lng']) / ($p2['lat'] - $p1['lat']) + $p1['lng'];//cross point of lng
    if (abs($p['lng'] - $xinters) < $precision) {//overlies on a ray
    return $boundOrVertex;
    }
  28.  
  29. if ($p['lng'] < $xinters) {//before ray
    ++$intersectCount;
    }
    }
    }
    } else {//special case when ray is crossing through the vertex
    if ($p['lat'] == $p2['lat'] && $p['lng'] <= $p2['lng']) {//p crossing over p2
    $p3 = $pts[($i+) % $N]; //next vertex
    if ($p['lat'] >= min($p1['lat'], $p3['lat']) && $p['lat'] <= max($p1['lat'], $p3['lat'])) { //p.lat lies between p1.lat & p3.lat
    ++$intersectCount;
    } else {
    $intersectCount += ;
    }
    }
    }
    $p1 = $p2;//next ray left point
    }
  30.  
  31. if ($intersectCount % 2 == ) {//在多边形外
    return false;
    } else { //在多边形内
    return true;
    }
    }

滴滴热力图-php版(后面有js版本)的更多相关文章

  1. libnode 0.4.0 发布,C++ 语言版的 Node.js

    libnode 0.4.0 支持 Windows ,提升了性能,libuv 更新到 0.10.17 版本,libj 更新到 0.8.2 版本. libnode 是 C++ 语言版的 Node.js,和 ...

  2. Atitit js版本es5 es6新特性

    Atitit js版本es5 es6新特性 Es5( es5 其实就是adobe action script的标准化)1 es6新特性1 Es5( es5 其实就是adobe action scrip ...

  3. 微信支付.NET版开发总结(JS API),好多坑,适当精简

    前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下.接下来,按照开发步骤,细数一下,我遇到的那些坑. [坑1]官方邮件中下载的demo只有PHP版本,其他版本没有给链接.可能让人误以为只有 ...

  4. [Effective JavaScript笔记]第1条:了解使用的js版本

    1997年 正式成为国际标准,官方名称为ECMAScript. 1999年 定稿第3版ECMAScript标准(简称ES3),最广泛的js版本. 2009年 发布第5版即ES5,引入了一些新特性,标准 ...

  5. 微信支付.NET版开发总结(JS API),好多坑,适当精简。

    前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下.接下来,按照开发步骤,细数一下,我遇到的那些坑. [坑1]官方邮件中下载的demo只有PHP版本,其他版本没有给链接.可能让人误以为只有 ...

  6. Mac下nvm管理node.js版本问题

    本篇文章主要是针对已经安装了node.js和nvm管理工具小伙伴遇到的问题. 管理工具有两个,一个是nvm,还有一个是nnvm的好处就是可以管理多个node版本,而且可以切换想要的版本,可以安装一个稳 ...

  7. 利用n 升级工具升级Node.js版本及在mac环境下的坑

    一.利用n 升级Node.js 最近在用NPM安装一个nodejs工具时发现,我的nodejs的版本有些旧了.这不是大问题,只要升级就可以了,当然,重新从nodejs.org最新版本是一种方法,但我想 ...

  8. 使用nvm管理node.js版本以及更换npm淘宝镜像源

    目录 1,前言 2,安装nvm 3,nvm的使用 4,错误处理 5,修改npm默认镜像源 6,win10下cnpm报错 1,前言 注意:此教程仅限Windows,Mac可能不适用 在我们的日常开发中可 ...

  9. JS版本网站资源状态检测

    Title:JS版本网站资源状态检测  --2012-08-28 14:08 前几天需要一个网站状态检测的东东,后面写了个蹩脚的JS版本,里面用到了以前没用过的东西,在这里记下来,其实批处理加curl ...

随机推荐

  1. 2017福建省赛 L Tic-Tac-Toe 模拟

    Kim likes to play Tic-Tac-Toe. Given a current state, and now Kim is going to take his next move. Pl ...

  2. HDU-1532 网络流裸题

    HDU-1532 题意简单的来说就是从1点到n点,最大的流量是多少. 代码: #include<bits/stdc++.h> using namespace std; #define Fo ...

  3. 牛客网暑期ACM多校训练营(第三场) A PACM Team 01背包 记录路径

    链接:https://www.nowcoder.com/acm/contest/141/A来源:牛客网 Eddy was a contestant participating in ACM ICPC ...

  4. CodeForces 311 B Cats Transport 斜率优化DP

    题目传送门 题意:现在有n座山峰,现在 i-1 与 i 座山峰有 di长的路,现在有m个宠物, 分别在hi座山峰,第ti秒之后可以被带走,现在有p个人,每个人会从1号山峰走到n号山峰,速度1m/s.现 ...

  5. codeforces 811 C. Vladik and Memorable Trip(dp)

    题目链接:http://codeforces.com/contest/811/problem/C 题意:给你n个数,现在让你选一些区间出来,对于每个区间中的每一种数,全部都要出现在这个区间. 每个区间 ...

  6. yzoj P2043 & 洛谷 P1282 多米诺骨牌 题解

    题意 类似于就是背包. 解析 代码 跟解析有点不一样v[i]价值,w[i]重量,s背包容积,背包转移即可. #include<bits/stdc++.h> using namespace ...

  7. Codeforces Round #582 (Div. 3)

    题目链接:https://codeforces.com/contest/1213 A: 题意:给定数的位置,位置为整数,每个数可以向左或右移动一格或者两格,移动一格花费一个硬币,两格不花费硬币,问所有 ...

  8. JPA案例

    ORM 什么是ORM: 对象关系映射(Object Relational Mapping,简称ORM)是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的. ORM思想 主要 ...

  9. 【Offer】[54] 【二叉搜索树的第k小节点】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 给定一棵二叉搜索树,请找出其中第k小的节点.例如,在下图的二叉搜索树里,按节点数值大小顺序,第三小节点的值是4.  牛客网刷题地址 思 ...

  10. JAVA父类的静态方法能否被子类重写?

    静态: 在编译时所分配的内存会一直存在(不会被回收),直到程序退出内存才会释放这个空间,在实例化之前这个方法就已经存在于内存,跟类的对象没什么关系.子类中如果定义了相同名称的静态方法,并不会重写,而应 ...