Php 如何找到相邻Maidenhead栅格的定位码?
我正在尝试创建一个围绕单个贴图的贴图,但是我不知道如何计算围绕单个maidenhead网格的9个网格 例如,我有一个locatorPhp 如何找到相邻Maidenhead栅格的定位码?,php,algorithm,gps,Php,Algorithm,Gps,我正在尝试创建一个围绕单个贴图的贴图,但是我不知道如何计算围绕单个maidenhead网格的9个网格 例如,我有一个locatorJO22OI60KE,我根据给定的坐标计算它,我希望其他的(示例中的绿色)九个定位器围绕这个网格 我已经环顾了很多地方,但我看到的实现都集中在从一个纬度和经度获得少女头。我可以计算它的邻居,但一旦你在边缘(也就是说,触摸一个新的子正方形),它就超出了我的能力。克里夫的注释: MLS坐标中的每对字符都是网格中的一个单元,每个后续网格都包含在前一个网格中 每一对在字母
JO22OI60KE
,我根据给定的坐标计算它,我希望其他的(示例中的绿色)九个定位器围绕这个网格
我已经环顾了很多地方,但我看到的实现都集中在从一个纬度和经度获得少女头。我可以计算它的邻居,但一旦你在边缘(也就是说,触摸一个新的子正方形),它就超出了我的能力。克里夫的注释:
- MLS坐标中的每对字符都是网格中的一个单元,每个后续网格都包含在前一个网格中
- 每一对在字母和数字之间交替:18、10、24、
,以获得您想要的精度GOTO 10
- 虽然说明书上说案例很重要,但其实并不重要
(J,O),(2,2),(O,I),(6,0),(K,E)
到(10,15),(2,2),(15,9),(6,0),(11,5)
我采用的方法[包括在下面]是将坐标分解为它们的数字对,然后应用任何变换[由一组偏移量表示],从最低有效到最高,同时保留一个“进位”对
但是,将所有内容相乘到259200 x 259200
[18*10*12*10*12
]网格,进行简单的数学变换,然后使用更多的数学重新格式化回MLS坐标可能会更简单。这也将大大简化lat/lng的转换,因为这只是更简单的数学
生活和学习。某件事情的第一次迭代通常只擅长于教你该如何做。¯\_(ツ)_/“”
代码:
包括,因为链接可能会死亡,这使得答案无效。请检查是否有PRs/更改。也列出在
类坐标{
常量ENC_字段=0;
常数平方=1;
const ENC_SUBSQUARE=2;
常数ENC_MAX=[
self::ENC_字段=>18,
self::ENC_SQUARE=>10,
self::ENC_SUBSQUARE=>24
];
const ENC_CHARS=[
self::ENC_字段=>'abcdefghijklmonpqr',
self::ENC_SQUARE=>“0123456789”,
self::ENC_SUBSQUARE=>“abcdefghijklmonpqrstuvwx”
];
//规范仅涵盖前4对,第4对“扩展子正方形”使用与“正方形”相同的编码
//规范的非标准扩展将作为此类的扩展来实现。
受保护的静态$encode_顺序=[self::ENC_字段,self::ENC_正方形,self::ENC_子正方形,self::ENC_正方形];
受保护的$pairs=[];
受保护的精度;
公共函数构造($pairs){
foreach($pairs作为$pair){
$this->addPair($pair);
}
$this->precision=count($pairs);
}
公共职能转变($offset){
$offset\u count=计数($offset);
$pair\u count=$this->precision;
$encoding\u count=count(静态::$encode\u顺序);
如果($offset\u count>$pair\u count){
抛出新\异常(“偏移数大于坐标对数”);
}
$carry=[0,0];
$new_pairs=[];
//首先处理最小的偏移量,这样我们就不必一直指定完整的数组
//同时也可以有效地处理运载工具
对于($o=1,$c=$pair\u count;$oprecision-$o;
$cur_pair=$this->pairs[$pair_index];
如果($offset_index<0){
$cur_offset=$carry;
}否则{
$cur_offset=$offset[$offset_index];
//套利
$cur_offset=[
$cur_偏移量[0]+$carry[0],
$cur_偏移量[1]+$carry[1]
];
}
$new_lat=$this->rollover($cur_pair->lat+$cur_offset[0],static::ENC_MAX[static::$encode_order[$pair_index]]);
$new_lng=$this->rollover($cur_pair->lng+$cur_offset[1],静态::ENC_MAX[静态::$encode_order[$pair_index]]);
$carry=[$new_lat[1],$new_lng[1];
$new_pair=新对($new_lat[0],$new_lng[0]);
数组\u取消移位($new\u pairs,$new\u pairs);
}
返回新的静态数据($new_pairs);
}
公共函数toString(){
$output='';
对于($i=0;$i精度;$i++){
$output.=$this->encodeAs($this->pairs[$i]->lat,static::$encode_order[$i]);
$output.=$this->encodeAs($this->pairs[$i]->lng,static::$encode_order[$i]);
}
返回$output;
}
公共函数{
返回$this->toString();
}
受保护的功能滚动($value,$base){
如果($value<0){
$result=($value%$base)?$base+($value%$base):0;
$carry=(int)ceil(资产净值/$base)*-1;
}如果($value>=$base),则为else{
$result=$value%$base;
$carry=(int)地板($value/$base);
}否则{
$result=$value;
$carry=0;
}
返回[$result,$carry];
}
受保护的函数addPair(Pair$Pair){
$this->pairs[]=$pair;
}
公共静态函数fromString($input,$pad=true){
$pairs=[];
$raw_pairs=array_map('str_split',str_split($input,2));
对于($i=0,$c=count($raw_pairs);$ilng=$lng;
}
公共函数获取($name){
返回$this->$name;
}
公共函数集($name,$value){
抛出新异常(“不可变”);
}
}
令人震惊的是,这没有一个内置的。你查过一个参考实现吗?你对哪一部分有问题?我到处找了很多,但他们都关注GET
class Coordinate {
const ENC_FIELD = 0;
const ENC_SQUARE = 1;
const ENC_SUBSQUARE = 2;
const ENC_MAX = [
self::ENC_FIELD => 18,
self::ENC_SQUARE => 10,
self::ENC_SUBSQUARE => 24
];
const ENC_CHARS = [
self::ENC_FIELD => 'abcdefghijklmonpqr',
self::ENC_SQUARE => '0123456789',
self::ENC_SUBSQUARE => 'abcdefghijklmonpqrstuvwx'
];
// The spec only covers the first 4 pairs, the 4th pair "extended subsquare" uses the same encoding as "square"
// Non-standard extensions of the spec are to be implemented as extensions of this class.
protected static $encode_order = [ self::ENC_FIELD, self::ENC_SQUARE, self::ENC_SUBSQUARE, self::ENC_SQUARE ];
protected $pairs = [];
protected $precision;
public function __construct($pairs) {
foreach($pairs as $pair) {
$this->addPair($pair);
}
$this->precision = count($pairs);
}
public function transform($offsets) {
$offset_count = count($offsets);
$pair_count = $this->precision;
$encoding_count = count(static::$encode_order);
if( $offset_count > $pair_count ) {
throw new \Exception('Number of offsets greater than the number of coordinate pairs');
}
$carry = [0, 0];
$new_pairs = [];
// process the smallest offset first so that we don't have to specify a full array all the time
// and also so that carries can be efficiently handled
for( $o=1,$c=$pair_count; $o<=$c; $o++ ) {
$offset_index = $offset_count - $o;
$pair_index = $this->precision - $o;
$cur_pair = $this->pairs[$pair_index];
if( $offset_index < 0 ) {
$cur_offset = $carry;
} else {
$cur_offset = $offsets[$offset_index];
// apply carry
$cur_offset = [
$cur_offset[0] + $carry[0],
$cur_offset[1] + $carry[1]
];
}
$new_lat = $this->rollover($cur_pair->lat + $cur_offset[0], static::ENC_MAX[static::$encode_order[$pair_index]]);
$new_lng = $this->rollover($cur_pair->lng + $cur_offset[1], static::ENC_MAX[static::$encode_order[$pair_index]]);
$carry = [ $new_lat[1], $new_lng[1] ];
$new_pair = new Pair( $new_lat[0], $new_lng[0] );
array_unshift($new_pairs, $new_pair);
}
return new static($new_pairs);
}
public function toString() {
$output = '';
for( $i=0; $i<$this->precision; $i++ ) {
$output .= $this->encodeAs($this->pairs[$i]->lat, static::$encode_order[$i]);
$output .= $this->encodeAs($this->pairs[$i]->lng, static::$encode_order[$i]);
}
return $output;
}
public function __toString() {
return $this->toString();
}
protected function rollover($value, $base) {
if( $value < 0 ) {
$result = ($value % $base) ? $base + ($value % $base) : 0;
$carry = (int)ceil(abs($value) / $base) * -1;
} else if( $value >= $base ) {
$result = $value % $base;
$carry = (int)floor($value / $base);
} else {
$result = $value;
$carry = 0;
}
return [ $result, $carry ];
}
protected function addPair(Pair $pair) {
$this->pairs[] = $pair;
}
public static function fromString($input, $pad=true) {
$pairs = [];
$raw_pairs = array_map('str_split', str_split($input, 2));
for( $i=0,$c=count($raw_pairs); $i<$c; $i++ ) {
if( ! isset(static::$encode_order[$i]) ) {
throw new \Exception("No decoding specified for pair index $i");
}
$encoding = static::$encode_order[$i];
$pairs[] = new Pair(
self::decodeAs($raw_pairs[$i][0], $encoding),
self::decodeAs($raw_pairs[$i][1], $encoding)
);
}
if( $pad ) {
for( $c=count(static::$encode_order); $i<$c; $i++ )
$pairs[] = new Pair(0,0);
}
return new static($pairs);
}
public static function decodeAs($str, $encoding) {
$value = strpos(self::ENC_CHARS[$encoding], strtolower($str));
if( $value === false ) {
throw new \Exception("Invalid character $str for encoding $encoding");
}
return $value;
}
public static function encodeAs($int, $encoding) {
return self::ENC_CHARS[$encoding][$int];
}
}
class Pair {
protected $lat, $lng;
public function __construct($lat, $lng) {
$this->lat = $lat;
$this->lng = $lng;
}
public function __get($name) {
return $this->$name;
}
public function __set($name, $value) {
throw new Exception('Immutable');
}
}