一、首先说一下思路
1、通过观察OLC(这里有介绍pluscode)的编码方式这里是演示页面,可以发现求某个编码的4邻域时只需要相应的纬度值或经度值进行字符进位借位运算即可。
2、举个栗子:编码为"8P",拆分为纬度的编码值"8"和经度的编码值"P",编码"8P"的上邻域就是纬度+1经度不变"9P",下邻域就是纬度-1经度不变"7P"。
3、计算左右邻域同理:左邻域就是纬度值不变经度值-1"8M",右邻域就是纬度值不变经度值+1"8Q"。
4、当计算8邻域的时候就是 编码左邻域的上下邻域 + 右邻域的上下邻域(也可以编码上邻域的左右邻域 + 下邻域的左右邻域)
二、8邻域的代码
public class OpenLocationCodeNearCode {
/*
* OLC的8邻域编码
* input:olcCode
* output:olc的8邻域
* 当前版本支持2、4、6、8、10、11、12位编码(全部层级的编码)
* Bug是只能有一次进位,已想出办法,正在解决。
*
* 2019-12-02
* 来桂兵
* */
public static String BASE20 = "23456789CFGHJMPQRVWX"; //2位以上编码
public static String BASE18 = "23456789CFGHJMPQRV"; //2位编码
/*
*从Code中获取纬度的编码值(code的奇数位)
*/
public static String getLatCode(String code){
code = code.replace("+","");
String latCode = new String();
for(int i = 0; i < code.length(); i += 2){
latCode += code.charAt(i);
}
return latCode;
}
/*
*从code中获取经度的编码值(code的偶数位)
*/
public static String getLonCode(String code){
code = code.replace("+","");
String lonCode = new String();
for(int i = 1; i < code.length(); i += 2){
lonCode += code.charAt(i);
}
return lonCode;
}
/*
* 组合经纬度为Code(交叉合并经纬度的Code值)
*/
public static String getMerge(String a, String b) {
// 将字符串转换为字符数组
char[] aArray = a.toCharArray();
char[] bArray = b.toCharArray();
// 定义一个字符缓冲流
StringBuffer stringBuffer = new StringBuffer();
// 循环字符数组将两个字符数组中的元素进行交换位置
for (int i = 0; i < aArray.length; i++) {
// 将第一个字符数组添加的字符缓冲区
stringBuffer.append(aArray[i]);
// 如果i<bArray.length将bArray添加到字符串缓冲区
if (i < bArray.length) {
stringBuffer.append(bArray[i]);
}
}
// 返回交叉后的结果
return stringBuffer.toString();
}
/*
*计算 上邻域 (纬度 + 1 )
* 目前边界值的判断还不完善,如8P22X2-->YES; 8PX2X2-->NO
*/
public static String getTop(String code){
String latCode = getLatCode(code); //纬度code
String lonCode = getLonCode(code); //经度code
//编码长度为2时
if(code.length() == 2){
String newlatCode = ""; //初始化一个新字符串用来保存新纬度值
if(latCode.equals("C")){ //边界是 “C”, 就变成 ”2“
newlatCode = "2";
}
else{ //最后一位不是“C”
newlatCode = BASE18.charAt(BASE18.indexOf(latCode) + 1) + ""; // 否则 取 下一位索引对应的字符(为了保证它是String,而不是char)
}
//重新组合
String newCode = getMerge(newlatCode,lonCode);
return newCode;
}
//编码长度为11时
else if(code.replace("+","").length() == 11){
String newTenCode = code.replace("+","").substring(0,10);
String lastchr = code.replace("+","").substring(10);
//solution 1:
// if(lastchr.equals("R")){
// newTenCode = getTop(newTenCode);
// lastchr = "2";
// }
// else if(lastchr.equals("V")){
// newTenCode