更新完整的OpenLocationCode的8邻域代码

本文针对上篇博客中OpenLocationCode(OLC)编码在多次进位时遇到的问题进行修复,采用递归思想,详细阐述了如何计算不同编码长度(2, 4, 6, 8, 10, 11, 12位)的邻域编码,包括当编码长度为11和12位时,OLC编码规则变化的情况。" 124712092,13063121,Linux shell详解:命令、脚本与技巧,"['Linux', 'bash']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题

上篇博客传送门实现了求OLC邻域编码部分代码,最后多次进位时出现问题,本篇博客旨在解决这一问题。

递归的思想:

  1. 首先计算出编码长度为2时,每个编码的邻域;

  2. 求编码为4的时候,就是前两位的邻域+后面两位的邻域(如果最后一位(经度的最后一位或者纬度的最后一位)不是边界的话,直接计算后两位的邻域,否则计算后两位和前两位的邻域);

  3. 求编码长度为6的时候,前4位的邻域+后两位;

  4. 同样,求编码长度为8、10一样的思路;

  5. 求编码长度为11时,由于OLC编码方式发生了改变,因此是求前10位+最后一位(不分经纬);

  6. 求编码长度位12时,是求前11位+最后一位。

二、代码

/*
* OLC 8邻域的第二个版本,解决多次进位的问题
*
* 2019-12-03
* 来桂兵
* */
public class OpenLocationCodeNearCodeV2 {

    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 )
     */
    public static String getTop(String code) {

        String latCode = getLatCode(code);   //纬度code
        String lonCode = getLonCode(code);   //经度code
        String newCode = new String();

        //编码长度为2时
        if (code.length() == 2) {
            String newlatCode = new String();               //初始化一个新字符串用来保存新纬度值

            if (latCode.equals("C")) {      //边界是 “C”, 就变成 ”2“
                newlatCode = "2";
            } else {                                 //最后一位不是“C”
                newlatCode = BASE18.charAt(BASE18.indexOf(latCode) + 1) + "";  // 否则 取 下一位索引对应的字符(为了保证它是String,而不是char)
            }

            //重新组合
            newCode = getMerge(newlatCode, lonCode);
        }

        //编码长度为4时
        else if (code.length() == 4) {
            String FirstTwoChr = code.substring(0, 2);   //前两位
            String lastlatChr = latCode.substring(1);   //最后一位纬度Code
            String lastlonChr = lonCode.substring(1);   //最后一位经度Code

            if (lastlatChr.equals("X")) {                 //最后一位是X
                FirstTwoChr = getTop(FirstTwoChr);
                lastlatChr = "2" + "";
                lastlonChr = lastlonChr;

                newCode = FirstTwoChr + lastlatChr + lastlonChr;
            } else {                                       //最后一位不是X
                FirstTwoChr = FirstTwoChr;
                lastlatChr = BASE20.charAt(BASE20.indexOf(lastlatChr) + 1) + "";
                lastlonChr = lastlonChr;

                newCode = FirstTwoChr + lastlatChr + lastlonChr;
            }
        }

        //编码 6位
        else if(code.length() == 6){
            String FirstFourChr = code.substring(0, 4);   //前四位
            String lastlatChr = latCode.substring(2);   //最后一位纬度Code
            String lastlonChr = lonCode.substring(2);   //最后一位经度Code

            if (lastlatChr.equals("X")) {                 //最后一位是X
                FirstFourChr = getTop(FirstFourChr);
                lastlatChr = "2" + "";
                lastlonChr = lastlonChr;

                newCode = FirstFourChr + lastlatChr + lastlonChr;
            } else {                                       //最后一位不是X
                FirstFourChr = FirstFourChr;
                lastlatChr = BASE20.charAt(BASE20.indexOf(lastlatChr) + 1) + "";
                lastlonChr = lastlonChr;

                newCode = FirstFourChr + lastlatChr + lastlonChr;
            }

        }

        //编码 8位
        else if(code.length() == 8){
            String FirstSixChr = code.substring(0, 6);   //前六位
            String lastlatChr = latCode.substring(3);   //最后一位纬度Code
            String lastlonChr = lonCode.substring(3);   //最后一位经度Code

            if (lastlatChr.equals("X")) {                 //最后一位是X
                FirstSixChr = getTop(FirstSixChr);
                lastlatChr = "2" + "";
                lastlonChr = lastlonChr;

                newCode = FirstSixChr + "+" + lastlatChr + lastlonChr;
            } else {                                       //最后一位不是X
                FirstSixChr = FirstSixChr;
                lastlatChr = BAS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值