月度归档:2016年03月

git小型团队,协作使用约定

#git分支约定

master = 正式版本
develop = 开发版本

#git定型版本tag

当每个develop版本合并至master分支以后,打git tag 1.1.2版本标签,便于版本细节变化操作的跟踪.

#bug相关

当正式版本产生bug的时候,可能需要修改代码,为了后期便于维护,请根据以下约定进行操作.

#本地场景操作->确认至本地master版本

git checkout master

#更新本地分支

git pull origin master

#创建本地bug分支版本

git branch bug#1.1.2

#修复以后的操作

git checkout master
``

#合并分支

git merge bug#1.1.2


#写入日记

git commit -m “日记,写入本地合并的操作相关信息”


#打标签

git tag -a 1.1.2 -m “Release version 1.1.2”


#详解 git tag命令

-a 1.1.2 是增加名为1.1.2的标签
-m 后面跟着的是标签的注释


#提交标签到远程服务器上

git push origin master
git push origin –tags
–tags参数表示提交所有tag至服务器端,普通的git push origin master操作不会推送标签到服务器端。


#删除标签的命令

git tag -d  1.1.2


#删除远端服务器的标签

git push origin :refs/tags/1.1.2
“`

php geohash附近算法和使用类

原理google

 

实现类

<?php

class Geohash {

    private $bitss = array(16, 8, 4, 2, 1);
    private $neighbors = array();
    private $borders = array();

    private $coding = "0123456789bcdefghjkmnpqrstuvwxyz";
    private $codingMap = array();

    /**
     * 实例化数据
     * Geohash constructor.
     */
    public function __construct()
    {
        $this->neighbors['right']['even'] = 'bc01fg45238967deuvhjyznpkmstqrwx';
        $this->neighbors['left']['even'] = '238967debc01fg45kmstqrwxuvhjyznp';
        $this->neighbors['top']['even'] = 'p0r21436x8zb9dcf5h7kjnmqesgutwvy';
        $this->neighbors['bottom']['even'] = '14365h7k9dcfesgujnmqp0r2twvyx8zb';

        $this->borders['right']['even'] = 'bcfguvyz';
        $this->borders['left']['even'] = '0145hjnp';
        $this->borders['top']['even'] = 'prxz';
        $this->borders['bottom']['even'] = '028b';

        $this->neighbors['bottom']['odd'] = $this->neighbors['left']['even'];
        $this->neighbors['top']['odd'] = $this->neighbors['right']['even'];
        $this->neighbors['left']['odd'] = $this->neighbors['bottom']['even'];
        $this->neighbors['right']['odd'] = $this->neighbors['top']['even'];

        $this->borders['bottom']['odd'] = $this->borders['left']['even'];
        $this->borders['top']['odd'] = $this->borders['right']['even'];
        $this->borders['left']['odd'] = $this->borders['bottom']['even'];
        $this->borders['right']['odd'] = $this->borders['top']['even'];

        //build map from encoding char to 0 padded bitfield
        for($i=0; $i<32; $i++)
        {
            $this->codingMap[substr($this->coding, $i, 1)] = str_pad(decbin($i), 5, "0", STR_PAD_LEFT);
        }

    }

    /**
     * 解密
     * @param 纬度,经度 lat,long in it
     */
    public function decode($hash)
    {

        //decode hash into binary string
        $binary = "";
        $hl = strlen($hash);
        for ($i=0; $i<$hl; $i++) {

            $binary .= $this->codingMap[substr($hash, $i, 1)];
        }

        //split the binary into lat and log binary strings
        $bl = strlen($binary);
        $blat = "";
        $blong = "";
        for ($i=0; $i<$bl; $i++) {

            if ($i%2)
                $blat=$blat.substr($binary, $i, 1);
            else
                $blong=$blong.substr($binary, $i, 1);

        }

        //now concert to decimal
        $lat = $this->binDecode($blat, -90, 90);
        $long = $this->binDecode($blong, -180, 180);

        //figure out how precise the bit count makes this calculation
        $latErr = $this->calcError(strlen($blat), -90, 90);
        $longErr = $this->calcError(strlen($blong), -180, 180);

        //how many decimal places should we use? There's a little art to
        //this to ensure I get the same roundings as geohash.org
        $latPlaces = max(1, -round(log10($latErr))) - 1;
        $longPlaces = max(1, -round(log10($longErr))) - 1;

        //round it
        $lat = round($lat, $latPlaces);
        $long = round($long, $longPlaces);

        return array($lat, $long);
    }


    private function calculateAdjacent($srcHash, $dir) {

        $srcHash = strtolower($srcHash);
        $lastChr = $srcHash[strlen($srcHash) - 1];
        $type = (strlen($srcHash) % 2) ? 'odd' : 'even';
        $base = substr($srcHash, 0, strlen($srcHash) - 1);

        if (strpos($this->borders[$dir][$type], $lastChr) !== false) {

            $base = $this->calculateAdjacent($base, $dir);
        }

        return $base . $this->coding[strpos($this->neighbors[$dir][$type], $lastChr)];
    }


    /**
     * 获取相对区域的8个位置
     * @param $srcHash
     * @return mixed
     */
    public function neighbors($srcHash)
    {

        $geohashPrefix = substr($srcHash, 0, strlen($srcHash) - 1);

        $neighbors['top'] = $this->calculateAdjacent($srcHash, 'top');
        $neighbors['bottom'] = $this->calculateAdjacent($srcHash, 'bottom');
        $neighbors['right'] = $this->calculateAdjacent($srcHash, 'right');
        $neighbors['left'] = $this->calculateAdjacent($srcHash, 'left');

        $neighbors['topleft'] = $this->calculateAdjacent($neighbors['left'], 'top');
        $neighbors['topright'] = $this->calculateAdjacent($neighbors['right'], 'top');
        $neighbors['bottomright'] = $this->calculateAdjacent($neighbors['right'], 'bottom');
        $neighbors['bottomleft'] = $this->calculateAdjacent($neighbors['left'], 'bottom');

        return $neighbors;
    }

    /**
     * 经纬度加密
     * @param $lat 纬度
     * @param $long 经度
     * @return string
     */
    public function encode($lat, $long)
    {

        //how many bits does latitude need?
        $plat = $this->precision($lat);
        $latbits = 1;
        $err = 45;
        while($err > $plat) {

            $latbits++;
            $err /= 2;
        }

        //how many bits does longitude need?
        $plong = $this->precision($long);
        $longbits = 1;
        $err = 90;
        while($err > $plong) {

            $longbits++;
            $err /= 2;
        }

        //bit counts need to be equal
        $bits = max($latbits, $longbits);

        //as the hash create bits in groups of 5, lets not
        //waste any bits - lets bulk it up to a multiple of 5
        //and favour the longitude for any odd bits
        $longbits = $bits;
        $latbits = $bits;
        $addlong = 1;
        while (($longbits + $latbits) % 5 != 0) {

            $longbits += $addlong;
            $latbits += !$addlong;
            $addlong = !$addlong;
        }


        //encode each as binary string
        $blat = $this->binEncode($lat, -90, 90, $latbits);
        $blong = $this->binEncode($long, -180, 180, $longbits);

        //merge lat and long together
        $binary = "";
        $uselong = 1;
        while (strlen($blat) + strlen($blong)) {

            if ($uselong) {

                $binary = $binary.substr($blong, 0, 1);
                $blong = substr($blong, 1);

            } else {

                $binary = $binary.substr($blat, 0, 1);
                $blat = substr($blat, 1);
            }

            $uselong = !$uselong;
        }

        //convert binary string to hash
        $hash = "";
        for ($i=0; $i<strlen($binary); $i+=5) {

            $n = bindec(substr($binary, $i, 5));
            $hash = $hash.$this->coding[$n];
        }

        return $hash;
    }

    /**
     * What's the maximum error for $bits bits covering a range $min to $max
     */
    private function calcError($bits, $min, $max)
    {

        $err = ($max - $min) / 2;
        while ($bits--)
            $err /= 2;
        return $err;
    }

    /*
    * returns precision of number
    * precision of 42 is 0.5
    * precision of 42.4 is 0.05
    * precision of 42.41 is 0.005 etc
    *
    * Author: Bruce Chen (weibo: @一个开发者)
    */
    private function precision($number)
    {

        $precision = 0;
        $pt = strpos($number,'.');
        if ($pt !== false) {

            $precision = -(strlen($number) - $pt - 1);
        }

        return pow(10, $precision) / 2;
    }


    /**
     * create binary encoding of number as detailed in http://en.wikipedia.org/wiki/Geohash#Example
     * removing the tail recursion is left an exercise for the reader
     *
     * Author: Bruce Chen (weibo: @一个开发者)
     */
    private function binEncode($number, $min, $max, $bitcount)
    {

        if ($bitcount == 0)
        {
            return '';
        }

        #echo "$bitcount: $min $max<br>";

        //this is our mid point - we will produce a bit to say
        //whether $number is above or below this mid point
        $mid = ($min + $max) / 2;
        if ($number > $mid)
            return "1" . $this->binEncode($number, $mid, $max, $bitcount - 1);
        else
            return "0" . $this->binEncode($number, $min, $mid, $bitcount - 1);
    }


    /**
     * decodes binary encoding of number as detailed in http://en.wikipedia.org/wiki/Geohash#Example
     * removing the tail recursion is left an exercise for the reader
     * Author: Bruce Chen (weibo: @一个开发者)
     */
    private function binDecode($binary, $min, $max)
    {

        $mid = ($min + $max) / 2;

        if (strlen($binary) == 0)
        {
            return $mid;
        }

        $bit = substr($binary, 0, 1);
        $binary = substr($binary, 1);

        if ($bit == 1)
        {
            return $this->binDecode($binary, $mid, $max);
        }
        else
        {
            return $this->binDecode($binary, $min, $mid);
        }
    }

}

使用方式

$geo = new Geohash();
$latitude = '120.33.22.3';
$longitude = '310.23.132';
//获取gao算法加密字符串
$geohashVal = $geo->encode($latitude,$longitude);

//把$geohashVal插入数据表即可

 #查询附近的人
 $geo = new Geohash();
 $geohash = $geo->encode($latitude,$longitude);
 //切割长度是位置的距离线 
 $prefix = substr($geohash, 0, 6);
 $so = array_values($geo->neighbors($prefix));
 
 //$so是一个索引二维数组,相对8个位置角度,具体可打印测试

非常角度的方式使用咯