滴滴热力图-php版(后面有js版本)
/**
* 获取边界
* @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");
} $cache = \Yii::$app->cache;
// $cache->delete('amap_border'); $result = $cache->get('amap_border');
if($result) {
// return json_encode($result);
} $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; $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);
} $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; } 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); // 是否在多边形内 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;
} /**
* 判断一个坐标是否在一个多边形内(由多个坐标围成的)
* 基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
* 在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。
* @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; $p1 = $pts[];
for ($i = ; $i <= $N; ++$i) {
if ($p['lng'] == $p1['lng'] && $p['lat'] == $p1['lat']) {
return $boundOrVertex;
} $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;
} 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;
} 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;
} 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
} if ($intersectCount % 2 == ) {//在多边形外
return false;
} else { //在多边形内
return true;
}
}
滴滴热力图-php版(后面有js版本)的更多相关文章
- libnode 0.4.0 发布,C++ 语言版的 Node.js
libnode 0.4.0 支持 Windows ,提升了性能,libuv 更新到 0.10.17 版本,libj 更新到 0.8.2 版本. libnode 是 C++ 语言版的 Node.js,和 ...
- Atitit js版本es5 es6新特性
Atitit js版本es5 es6新特性 Es5( es5 其实就是adobe action script的标准化)1 es6新特性1 Es5( es5 其实就是adobe action scrip ...
- 微信支付.NET版开发总结(JS API),好多坑,适当精简
前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下.接下来,按照开发步骤,细数一下,我遇到的那些坑. [坑1]官方邮件中下载的demo只有PHP版本,其他版本没有给链接.可能让人误以为只有 ...
- [Effective JavaScript笔记]第1条:了解使用的js版本
1997年 正式成为国际标准,官方名称为ECMAScript. 1999年 定稿第3版ECMAScript标准(简称ES3),最广泛的js版本. 2009年 发布第5版即ES5,引入了一些新特性,标准 ...
- 微信支付.NET版开发总结(JS API),好多坑,适当精简。
前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下.接下来,按照开发步骤,细数一下,我遇到的那些坑. [坑1]官方邮件中下载的demo只有PHP版本,其他版本没有给链接.可能让人误以为只有 ...
- Mac下nvm管理node.js版本问题
本篇文章主要是针对已经安装了node.js和nvm管理工具小伙伴遇到的问题. 管理工具有两个,一个是nvm,还有一个是nnvm的好处就是可以管理多个node版本,而且可以切换想要的版本,可以安装一个稳 ...
- 利用n 升级工具升级Node.js版本及在mac环境下的坑
一.利用n 升级Node.js 最近在用NPM安装一个nodejs工具时发现,我的nodejs的版本有些旧了.这不是大问题,只要升级就可以了,当然,重新从nodejs.org最新版本是一种方法,但我想 ...
- 使用nvm管理node.js版本以及更换npm淘宝镜像源
目录 1,前言 2,安装nvm 3,nvm的使用 4,错误处理 5,修改npm默认镜像源 6,win10下cnpm报错 1,前言 注意:此教程仅限Windows,Mac可能不适用 在我们的日常开发中可 ...
- JS版本网站资源状态检测
Title:JS版本网站资源状态检测 --2012-08-28 14:08 前几天需要一个网站状态检测的东东,后面写了个蹩脚的JS版本,里面用到了以前没用过的东西,在这里记下来,其实批处理加curl ...
随机推荐
- POJ 3268 Silver Cow Party 单向最短路
Silver Cow Party Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 22864 Accepted: 1044 ...
- vscode代码段设置console.log,转换大小写,目录别名
https://blog.csdn.net/gyz718/article/details/71513075 vscode代码段设置console.log https://blog.csdn.net/u ...
- 063 Python必备库-从人机交互到艺术设计
目录 一.概述 二.Python库之图形用户界面 2.1 PyQt5 2.2 wxPython 2.3 PyGObject 三.Python库之游戏开发 3.1 PyGame 3.2 Panda3D ...
- 反射,Expression Tree,IL Emit 属性操作对比
.net的反射(Reflection) 是.Net中获取运行时类型信息的一种方法,通过反射编码的方式可以获得 程序集,模块,类型,元数据等信息. 反射的优点在于微软提供的API调用简单,使用方便: 表 ...
- 关于纯xmlhttprequest请求服务器数据
今天我们的web技术已经相当的完善, 各种前端框架如jquery或者再深一点的工具APIcloud 的使用极大的方便了我们的开发工作. 今天我要分享一个纯javascript的方式来解决请求服务器数据 ...
- 遇到XML-GB2312网页编码的处理方法
报的错误:encoding error : input conversion failed due to input error, bytes I/O error : encoder error 1 ...
- elasticsearch Discovery 发现模块学习
发现模块和集群的形成 目标 发现节点 Master选举 组成集群,在Master信息发生变化时及时更新. 故障检测 细分为几个子模块 Discovery发现模块 Discover是在集群Master节 ...
- Android服务之混合方式开启服务
引言 前面介绍过了Android服务的两种开启方式:Start方式可以让服务在后台运行:bind方式能够调用到服务中的方法. 在实际的开发工作中,有很多需求是:既要在后台能够长期运行,又要在服务中操作 ...
- el-table合并行并自定义某一列或几列
在el-table的官方组件中并没有看到具体的合并行或者列及自定义表格内容,于是就自己写了一个效果如下所示. 这种对左侧内容要求比较高,要求行合并,并要自定义一些内容.下面说一下具体方法及代码写法. ...
- wait()与notify()
一,前言 简单画了一下线程的流程图,只是一个大概.如图所示,线程有多种状态,那么不同状态之间是如何切换的,下面主要总结关于wait()和notify()的使用. 二,wait() wait ...