php地理位置附近演算法
① PHP演算法:如何判斷一個已知坐標點存在於一個多邊形內
如果沒有辦法就用內角和辦法算出來,把每一個角的角度算出來,注意回算的時候必須按答照一個方向計算,比如第一個角算的時候是順時針那麼後面的角都按照順時針算,光算出角度你還是無法判讀你算的是內角還是外角的,再根據內角和公式加一下就知道了,最後判斷一下離未知坐標點最近的角就知道它在外面還是裡面了
比如坐標點x 最後算出來離x最近點為a,相鄰點為bc,那麼比較xb+xc和ab+ac的長度就能算出來了
這種純數字計算對php來說很快
② php根據經緯度獲取地理位置
//高德地圖
gaode_get_addr_by_latlng(lat+','+lon,function(a,b){
txt.set('value', b.formatted_address);
});
function gaode_get_addr_by_latlng(latlng, cbfunc) {
var arr = (''+latlng).split(',');
latlng = arr[1] + ',' + arr[0]; // gaode 是 lon 在前 lat 在後
var url = 'http://restapi.amap.com/v3/geocode/regeo?location='+encodeURIComponent(latlng)+'&radius=1000&extensions=all&key='+hc_gaode_key;
hc_xhr(hc_gc_proxy(url), false, function(data){
// json 數據
//alert(data.regeocode.formatted_address);
if( data && 'object' == typeof(data.regeocode) ) {
// 返回的數據中有 pois 周邊名稱? 也有 formated_address, 等
if( 'function' == typeof(cbfunc) ) {
var loc = [];
if( data.regeocode.addressComponent && data.regeocode.addressComponent.streetNumber && data.regeocode.addressComponent.streetNumber.location ) {
loc = (data.regeocode.addressComponent.streetNumber.location + '').split(',');
}
cbfunc.call(null, false,
{
location: { // TODO: 糾偏此數據
type: 'google',
lat: loc[1],
lng: loc[0]
},
formatted_address: data.regeocode.formatted_address, //『詳細地址描述』
business: data.regeocode.business, // '周圍商圈'
addressComponent: {
city: data.regeocode.addressComponent.city, //』城市名稱』,
district: data.regeocode.addressComponent.district, //『區縣名稱』,
province: data.regeocode.addressComponent.province, //』省份名稱』,
street: data.regeocode.addressComponent.township, //『街道名稱』,
streetNumber: data.regeocode.addressComponent.streetNumber.street // '門牌號碼'
},
cityCode: data.regeocode.cityCode, // '城市代碼'
pois: data.regeocode.pois // 周邊
});
}
} else {
if( 'function' == typeof(cbfunc) )
cbfunc.call(null, 'data format error!');
}
}, function(err){
if( 'function' == typeof(cbfunc) )
cbfunc.call(null, err);
});
}
③ php怎麼做附近的人功能
1、用戶登錄或用戶在線後,對用戶進行定位,html5提供了地理定位的API,或用其他介面,獲取回每個用戶的定位(一般返答回的是經緯度)。
2、得到用戶經緯度後,根據圓周的演算法,以你本人為中心,向外擴展具體的多少范圍。其他用戶的經緯度要是在這個范圍內,這些個用戶就是你的附近的人,然後根據每個用戶經緯度,將標記顯示在地圖上。
根據我自己的邏輯思路來的。
④ php相對地址與絕對地址問題。
相對地址:
如果在a/b/c.php這個文件中,要讀取1/2.php,看看你a與1是否在同一個目錄,內如果是,那麼訪問就可以在容c.php中寫
include_once('../../../1/2.php');//我習慣用include_once,"../"表示上一級目錄,你有幾個目錄就上幾層,具體你可以根據你的目錄位置來調整。
絕對路徑:
在c.php中寫
include_once($_SERVER["DOCUMENT_ROOT"].'/1/2.php');
⑤ php怎麼根據經緯度獲取地理位置
這種功能,只能調用第三方的介面了,網路地圖就有這個介面addressComponents,逆地址解析,參考方法如下:
<GeocoderSearchResponse>
<status>OK</status>
<result>
<location>
<lat>38.990998</lat>
<lng>103.645966</lng>
</location>
<formatted_address>甘肅省武威市民勤縣</formatted_address>
<business/>
<addressComponent>
<streetNumber/>
<street/>
<district>民勤縣</district>
<city>武威市</city>
<province>甘肅省</province>
</addressComponent>
<cityCode>118</cityCode>
</result>
</GeocoderSearchResponse>
⑥ php如何實現通過ip獲取地理位置
加If-Modified-Since頭
xmlhttp多次調來用時它卻總源是顯示緩存頁面, 嘗試在 php 或 asp 中加入相應的http頭明確不要緩存, 也沒什麼效果!!
現在終於找到一個辦法啦,就是在 xmlhttp.open 之後發送一個If-Modified-Since頭即可, 代碼如下
xmlhttp.setRequestHeader('If-Modified-Since', '0');
⑦ php現在有哪些常用的演算法
<?
//--------------------
// 基本數據結構演算法
//--------------------
//二分查找(數組里查找某個元素)
function bin_sch($array, $low, $high, $k){
if ( $low <= $high){
$mid = intval(($low+$high)/2 );
if ($array[$mid] == $k){
return $mid;
}elseif ( $k < $array[$mid]){
return bin_sch($array, $low, $mid-1, $k);
}else{
return bin_sch($array, $mid+ 1, $high, $k);
}
}
return -1;
}
//順序查找(數組里查找某個元素)
function seq_sch($array, $n, $k){
$array[$n] = $k;
for($i=0; $i<$n; $i++){
if( $array[$i]==$k){
break;
}
}
if ($i<$n){
return $i;
}else{
return -1;
}
}
//線性表的刪除(數組中實現)
function delete_array_element($array , $i)
{
$len = count($array);
for ($j= $i; $j<$len; $j ++){
$array[$j] = $array [$j+1];
}
array_pop ($array);
return $array ;
}
//冒泡排序(數組排序)
function bubble_sort( $array)
{
$count = count( $array);
if ($count <= 0 ) return false;
for($i=0 ; $i<$count; $i ++){
for($j=$count-1 ; $j>$i; $j--){
if ($array[$j] < $array [$j-1]){
$tmp = $array[$j];
$array[$j] = $array[ $j-1];
$array [$j-1] = $tmp;
}
}
}
return $array;
}
//快速排序(數組排序)
function quick_sort($array ) {
if (count($array) <= 1) return $array;
$key = $array [0];
$left_arr = array();
$right_arr = array();
for ($i= 1; $i<count($array ); $i++){
if ($array[ $i] <= $key)
$left_arr [] = $array[$i];
else
$right_arr[] = $array[$i ];
}
$left_arr = quick_sort($left_arr );
$right_arr = quick_sort( $right_arr);
return array_merge($left_arr , array($key), $right_arr);
}
//------------------------
// PHP內置字元串函數實現
//------------------------
//字元串長度
function strlen ($str)
{
if ($str == '' ) return 0;
$count = 0;
while (1){
if ( $str[$count] != NULL){
$count++;
continue;
}else{
break;
}
}
return $count;
}
//截取子串
function substr($str, $start, $length=NULL)
{
if ($str== '' || $start>strlen($str )) return;
if (($length!=NULL) && ( $start>0) && ($length> strlen($str)-$start)) return;
if (( $length!=NULL) && ($start< 0) && ($length>strlen($str )+$start)) return;
if ($length == NULL) $length = (strlen($str ) - $start);
if ($start < 0){
for ($i=(strlen( $str)+$start); $i<(strlen ($str)+$start+$length ); $i++) {
$substr .= $str[$i];
}
}
if ($length > 0){
for ($i= $start; $i<($start+$length ); $i++) {
$substr .= $str[$i];
}
}
if ( $length < 0){
for ($i =$start; $i<(strlen( $str)+$length); $i++) {
$substr .= $str[$i ];
}
}
return $substr;
}
//字元串翻轉
function strrev($str)
{
if ($str == '') return 0 ;
for ($i=(strlen($str)- 1); $i>=0; $i --){
$rev_str .= $str[$i ];
}
return $rev_str;
}
//字元串比較
function strcmp($s1, $s2)
{
if (strlen($s1) < strlen($s2)) return -1 ;
if (strlen($s1) > strlen( $s2)) return 1;
for ($i =0; $i<strlen($s1 ); $i++){
if ($s1[ $i] == $s2[$i]){
continue;
}else{
return false;
}
}
return 0;
}
//查找字元串
function strstr($str, $substr)
{
$m = strlen($str);
$n = strlen($substr );
if ($m < $n) return false ;
for ($i=0; $i <=($m-$n+1); $i ++){
$sub = substr( $str, $i, $n);
if ( strcmp($sub, $substr) == 0) return $i;
}
return false ;
}
//字元串替換
function str_replace($substr , $newsubstr, $str)
{
$m = strlen($str);
$n = strlen($substr );
$x = strlen($newsubstr );
if (strchr($str, $substr ) == false) return false;
for ( $i=0; $i<=($m- $n+1); $i++){
$i = strchr($str, $substr);
$str = str_delete ($str, $i, $n);
$str = str_insert($str, $i, $newstr);
}
return $str ;
}
//--------------------
// 自實現字元串處理函數
//--------------------
//插入一段字元串
function str_insert($str, $i , $substr)
{
for($j=0 ; $j<$i; $j ++){
$startstr .= $str[$j ];
}
for ($j=$i; $j <strlen($str); $j ++){
$laststr .= $str[$j ];
}
$str = ($startstr . $substr . $laststr);
return $str ;
}
//刪除一段字元串
function str_delete($str , $i, $j)
{
for ( $c=0; $c<$i; $c++){
$startstr .= $str [$c];
}
for ($c=( $i+$j); $c<strlen ($str); $c++){
$laststr .= $str[$c];
}
$str = ($startstr . $laststr );
return $str;
}
//復制字元串
function strcpy($s1, $s2 )
{
if (strlen($s1)==NULL || !isset( $s2)) return;
for ($i=0 ; $i<strlen($s1); $i++){
$s2[] = $s1 [$i];
}
return $s2;
}
//連接字元串
function strcat($s1 , $s2)
{
if (!isset($s1) || !isset( $s2)) return;
$newstr = $s1 ;
for($i=0; $i <count($s); $i ++){
$newstr .= $st[$i ];
}
return $newsstr;
}
//簡單編碼函數(與php_decode函數對應)
function php_encode($str)
{
if ( $str=='' && strlen( $str)>128) return false;
for( $i=0; $i<strlen ($str); $i++){
$c = ord($str[$i ]);
if ($c>31 && $c <107) $c += 20 ;
if ($c>106 && $c <127) $c -= 75 ;
$word = chr($c );
$s .= $word;
}
return $s;
}
//簡單解碼函數(與php_encode函數對應)
function php_decode($str)
{
if ( $str=='' && strlen($str )>128) return false;
for( $i=0; $i<strlen ($str); $i++){
$c = ord($word);
if ( $c>106 && $c<127 ) $c = $c-20;
if ($c>31 && $c< 107) $c = $c+75 ;
$word = chr( $c);
$s .= $word ;
}
return $s;
}
//簡單加密函數(與php_decrypt函數對應)
function php_encrypt($str)
{
$encrypt_key = '';
$decrypt_key = '';
if ( strlen($str) == 0) return false;
for ($i=0; $i<strlen($str); $i ++){
for ($j=0; $j <strlen($encrypt_key); $j ++){
if ($str[$i] == $encrypt_key [$j]){
$enstr .= $decrypt_key[$j];
break;
}
}
}
return $enstr;
}
//簡單解密函數(與php_encrypt函數對應)
function php_decrypt($str)
{
$encrypt_key = '';
$decrypt_key = '';
if ( strlen($str) == 0) return false;
for ($i=0; $i<strlen($str); $i ++){
for ($j=0; $j <strlen($decrypt_key); $j ++){
if ($str[$i] == $decrypt_key [$j]){
$enstr .= $encrypt_key[$j];
break;
}
}
}
return $enstr;
}
?>
⑧ php獲取了ip地址,用php怎麼獲取ip的地理位置請大蝦賜教!
通過純真QQip地址庫文件查詢IP地理位置
2009-02-26 14:11
一、下載純真IP地址庫文件QQWry.Dat (網上有很多,並且可以定期升級)
二、創建類文件 IPLocation.php ,將下面代碼直接拷貝到php文件中
<?php
/**
* IP 地理位置查詢類
*
* @author 馬秉堯
* @version 1.5
* @right 2005 CoolCode.CN
*/
class IpLocation
{
/**
* QQWry.Dat文件指針(使用以前珊瑚蟲QQ的IP)
*
* @var resource
*/
var $fp;
/**
* 第一條IP記錄的偏移地址
*
* @var int
*/
var $firstip;
/**
* 最後一條IP記錄的偏移地址
*
* @var int
*/
var $lastip;
/**
* IP記錄的總條數(不包含版本信息記錄)
*
* @var int
*/
var $totalip;
/**
* 返回讀取的長整型數
*
* @access private
* @return int
*/
function getlong()
{
//將讀取的little-endian編碼的4個位元組轉化為長整型數
$result = unpack('Vlong', fread($this->fp, 4));
return $result['long'];
}
/**
* 返回讀取的3個位元組的長整型數
*
* @access private
* @return int
*/
function getlong3()
{
//將讀取的little-endian編碼的3個位元組轉化為長整型數
$result = unpack('Vlong', fread($this->fp, 3).chr(0));
return $result['long'];
}
/**
* 返回壓縮後可進行比較的IP地址
*
* @access private
* @param string $ip
* @return string
*/
function packip($ip)
{
// 將IP地址轉化為長整型數,如果在PHP5中,IP地址錯誤,則返回False,
// 這時intval將Flase轉化為整數-1,之後壓縮成big-endian編碼的字元串
return pack('N', intval(ip2long($ip)));//intaval 獲取變數的整數值
}
/**
* 返回讀取的字元串
*
* @access private
* @param string $data
* @return string
*/
function getstring($data = "")
{
$char = fread($this->fp, 1);
while (ord($char) > 0)
{ // 字元串按照C格式保存,以\0結束 ord()得到字元的ASCII碼
$data .= $char; // 將讀取的字元連接到給定字元串之後
$char = fread($this->fp, 1);
}
return $data;
}
/**
* 返回地區信息
*
* @access private
* @return string
*/
function getarea()
{
$byte = fread($this->fp, 1); // 標志位元組
switch (ord($byte)) {
case 0: // 沒有區域信息
$area = "";
break;
case 1:
case 2: // 標志位元組為1或2,表示區域信息被重定向
fseek($this->fp, $this->getlong3());
$area = $this->getstring();
break;
default: // 否則,表示區域信息沒有被重定向
$area = $this->getstring($byte);
break;
}
return $area;
}
/**
* 根據所給 IP 地址或域名返回所在地區信息
*
* @access public
* @param string $ip
* @return array
*/
function getlocation($ip)
{
if (!$this->fp) return null; // 如果數據文件沒有被正確打開,則直接返回空
$location['ip'] = gethostbyname($ip); // 將輸入的域名轉化為IP地址
$ip = $this->packip($location['ip']); // 將輸入的IP地址轉化為可比較的IP地址
// 不合法的IP地址會被轉化為255.255.255.255
// 對分搜索
$l = 0; // 搜索的下邊界
$u = $this->totalip; // 搜索的上邊界
$findip = $this->lastip; // 如果沒有找到就返回最後一條IP記錄(QQWry.Dat的版本信息)
while ($l <= $u)
{ // 當上邊界小於下邊界時,查找失敗
$i = floor(($l + $u) / 2); // 計算近似中間記錄
fseek($this->fp, $this->firstip + $i * 7);
$beginip = strrev(fread($this->fp, 4)); // 獲取中間記錄的開始IP地址
// strrev函數在這里的作用是將little-endian的壓縮IP地址轉化為big-endian的格式
// 以便用於比較,後面相同。
if ($ip < $beginip)
{ // 用戶的IP小於中間記錄的開始IP地址時
$u = $i - 1; // 將搜索的上邊界修改為中間記錄減一
}
else
{
fseek($this->fp, $this->getlong3());
$endip = strrev(fread($this->fp, 4)); // 獲取中間記錄的結束IP地址
if ($ip > $endip)
{ // 用戶的IP大於中間記錄的結束IP地址時
$l = $i + 1; // 將搜索的下邊界修改為中間記錄加一
}
else
{ // 用戶的IP在中間記錄的IP范圍內時
$findip = $this->firstip + $i * 7;
break; // 則表示找到結果,退出循環
}
}
}
//獲取查找到的IP地理位置信息
fseek($this->fp, $findip);
$location['beginip'] = long2ip($this->getlong()); // 用戶IP所在范圍的開始地址
$offset = $this->getlong3();
fseek($this->fp, $offset);
$location['endip'] = long2ip($this->getlong()); // 用戶IP所在范圍的結束地址
$byte = fread($this->fp, 1); // 標志位元組
switch (ord($byte))
{
case 1: // 標志位元組為1,表示國家和區域信息都被同時重定向
$countryOffset = $this->getlong3(); // 重定向地址
fseek($this->fp, $countryOffset);
$byte = fread($this->fp, 1); // 標志位元組
switch (ord($byte))
{
case 2: // 標志位元組為2,表示國家信息又被重定向
fseek($this->fp, $this->getlong3());
$location['country'] = $this->getstring();
fseek($this->fp, $countryOffset + 4);
$location['area'] = $this->getarea();
break;
default: // 否則,表示國家信息沒有被重定向
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
break;
case 2: // 標志位元組為2,表示國家信息被重定向
fseek($this->fp, $this->getlong3());
$location['country'] = $this->getstring();
fseek($this->fp, $offset + 8);
$location['area'] = $this->getarea();
break;
default: // 否則,表示國家信息沒有被重定向
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
if ($location['country'] == " CZ88.NET")
{ // CZ88.NET表示沒有有效信息
$location['country'] = "未知";
}
if ($location['area'] == " CZ88.NET")
{
$location['area'] = "";
}
return $location;
}
/**
* 構造函數,打開 QQWry.Dat 文件並初始化類中的信息
*
* @param string $filename
* @return IpLocation
*/
function IpLocation($filename = "QQWry.Dat")
{
if (($this->fp = @fopen($filename, 'rb')) !== false)
{
$this->firstip = $this->getlong();
$this->lastip = $this->getlong();
$this->totalip = ($this->lastip - $this->firstip) / 7;
//注冊析構函數,使其在程序執行結束時執行
register_shutdown_function(array(&$this, '_IpLocation'));
}
}
/**
* 析構函數,用於在頁面執行結束後自動關閉打開的文件。
*
*/
function _IpLocation()
{
fclose($this->fp);
}
}
?>
三、程序部分
require_once("includes/IPLocation.php") ; //這里引用剛創建的類文件
$ipLocation = new IpLocation("includes/QQWry.Dat") ; //這里引用ip地址庫
$ips = $ipLocation->getlocation($userIP) ; //$ips 就是所得到的物理地址,$userIP是傳入的IP ,例如(202.106.12.23)
來源:http://hi..com/yang_bd/blog/item/7b44f830b8764e1eebc4afd1.html
下面是一個實例,獲取IP並且檢索出該IP地理位置
<?
//獲取IP
error_reporting (E_ERROR | E_WARNING | E_PARSE);
if($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"])
{
$ip = $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"];
}
elseif($HTTP_SERVER_VARS["HTTP_CLIENT_IP"])
{
$ip = $HTTP_SERVER_VARS["HTTP_CLIENT_IP"];
}
elseif ($HTTP_SERVER_VARS["REMOTE_ADDR"])
{
$ip = $HTTP_SERVER_VARS["REMOTE_ADDR"];
}
elseif (getenv("HTTP_X_FORWARDED_FOR"))
{
$ip = getenv("HTTP_X_FORWARDED_FOR");
}
elseif (getenv("HTTP_CLIENT_IP"))
{
$ip = getenv("HTTP_CLIENT_IP");
}
elseif (getenv("REMOTE_ADDR"))
{
$ip = getenv("REMOTE_ADDR");
}
else
{
$ip = "Unknown";
}
require_once("includes/IPLocation.php") ; //這里引用剛創建的類文件
$ipLocation = new IpLocation("includes/QQWry.Dat") ; //這里引用ip地址庫
$ips = $ipLocation->getlocation($ip) ; //$ips 就是所得到的物理地址
var_mp($ips);
?>
效果如下(我使用本地測試):
array(5) { ["ip"]=> string(9) "127.0.0.1" ["beginip"]=> string(9) "127.0.0.1" ["endip"]=> string(9) "127.0.0.1" ["country"]=> string(8) "本機地址" ["area"]=> string(0) "" }
⑨ 微信開發,php獲取用戶地理位置,求php解析xml並輸出經緯度的方法
<?php
$doc=newDOMDocument();
$doc->load("test.xml");
$latitude=$doc->getElementsByTagName("Latitude")->item(0)->nodeValue;
$longitude=$doc->getElementsByTagName("Longitude")->item(0)->nodeValue;
$precision=$doc->getElementsByTagName("Precision")->item(0)->nodeValue;
echo"Latitude:".$latitude."<br>";
echo"Longitude:".$longitude."<br>";
echo"Precision:".$precision."<br>";
?>