今日,在项目中用到了全国行政区域码的一些操作,现将常用的一些操作api列举如下
标准行政区域区域码为12位数字,这12位数字可分解为 2-2-2-3-3 五部分,每部分分别为 省 市 县/辖区 镇/区 村/街道办 级别行政码
例如,61-01-13-004-203 表示 陕西省-西安市-雁塔区-电子城街道办事处-徐家庄村委会,13-05-21-102-207 表示 河北省-邢台市-邢台县-祝村镇-相家屯村
首先对区域码进行修正,将区域码按照 2 2 2 3 3 结构进行分隔,再进行其他操作
JAVA版
区域码修正
首先对区域码进行修正
/**
* 修正区域码为12位
*
* 不足12位的补0
* 超出12位的,截取前12位
*/
private static String revise(String divisionCode) {
if (null == divisionCode || divisionCode.isEmpty()) {
return "000000000000";
}
int len = divisionCode.length();
if (len < 12) { // 不足12位的,后边补0
return divisionCode + String.format("%1$0" + (12 - len) + "d", 0);
}
if (len > 12) { // 超出12位的,截取前12位
return divisionCode.substring(0, 12);
}
return divisionCode;
}
区域码分隔
再将区域码按照 2 2 2 3 3 结构进行分隔,这里不对全0的部分进行保留,如 110117000000将仅返回 {11, 01, 11, 170} /**
* 将区域码按照 2 2 2 3 3 进行区域分割
*/
public static String[] split(String divisionCode) {
String code = revise(divisionCode);
/*code = code.replaceAll("0*$", "");*/
List<String> splits = new LinkedList<String>();
String regionCode = null;
int pos = 0;
for (int digit : digits) {
regionCode = code.substring(pos, (pos += digit));
if (!regionCode.matches("^0*$")) {
splits.add(regionCode);
} else { // 已经到达最后了,这一部分区域码全部都是0了
break;
}
}
return splits.toArray(new String[splits.size()]);
}
有了以上两个函数,便可实现各种区域码处理函数
区域码比较
比较两个区域码的层级关系 /**
* 区域码比较
*/
public static Level regionLevelCompare(String origin, String compared) {
if (null == origin) {
return Level.LOW;
}
if (null == compared) {
return Level.HIGH;
}
/* 按区域 2 2 2 3 3 进行分割 */
String[] origins = split(origin);
String[] compareds = split(compared);
int origLen = origins.length;
int compLen = compareds.length;
int index = 0;
while (index < origLen && index < compLen) {
String orig = origins[index];
String comp = compareds[index++];
/* ****** 此级别相同 ****** */
/* */
if (orig.equalsIgnoreCase(comp)) {
continue;
}
/* ******************** */
/* ****** 此级别不相同 ****** */
/* */
/*boolean isOrigEnd = (index == origLen);
boolean isCompEnd = (index == compLen);
if (isOrigEnd && isCompEnd) { // 都最后一级 11-10-23-000-000 11-10-24-000-000
return Level.SAME;
}*/
return Level.UNRELATED;
// 11-10-23-000-000 11-10-24-000-000
// 11-10-23-000-000 11-10-24-569-000
// 11-10-23-596-000 11-10-24-569-000
/* ********************* */
}
boolean isOrigEnd = (index == origLen);
boolean isCompEnd = (index == compLen);
if (isOrigEnd && isCompEnd) { // 都最后一级 11-10-23-000-000 11-10-23-000-000
return Level.SAME;
} else if (isOrigEnd) { // 11-10-23-000-000 11-10-23-156-000
return Level.HIGH;
} else {
return Level.LOW; // 11-10-23-156-000 11-10-23-000-000
}
}
获取区域码行政级别
获取区域码所在的行政级别
/**
* 获取区域码所代表级别
*/
public static RegionLevel getRegionLevel(String region) {
try {
Assert.hasLength(region, "Cannot Get Null region level");
} catch (IllegalArgumentException e) {
LOGGER.warn("illegal param", e);
return null;
}
String[] regions = split(region);
int index = regions.length;
if (index > 0 && index <= RegionLevel.values().length) {
return RegionLevel.values()[index - 1];
}
return null;
}
获取指定级别区域码
根据给定的区域码,获取其上指定级别的区域码,如获取110101001001市级区域码,则为110100000000
/**
* 获取指定级别的区域码
*/
public static String getRegionByLevel(String region, RegionLevel regionLevel) {
Assert.hasLength(region, "Cannot Get Region by NULL");
Assert.notNull(regionLevel, "Cannot Get Region by Null Level");
String division = revise(region);
int len = 0;
for (int i = 0; i <= regionLevel.ordinal(); i++) {
len += digits[i];
}
division = division.substring(0, len); // 只取有效位
division = revise(division); // 对区域码进行修正
return division;
}
完整代码
完整代码如下
package com.manerfan;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.util.Assert;
/**
* <p>比较区域级别
*
* @author ManerFan 2015年01月12日
*/
public class RegionLevelUtil {
private static final Logger LOGGER = Logger.getLogger(RegionLevelUtil.class);
private static final int[] digits = { 2, 2, 2, 3, 3 };
/**
* 区域码比较
*/
public static Level regionLevelCompare(String origin, String compared) {
if (null == origin) {
return Level.LOW;
}
if (null == compared) {
return Level.HIGH;
}
/* 按区域 2 2 2 3 3 进行分割 */
String[] origins = split(origin);
String[] compareds = split(compared);
int origLen = origins.length;
int compLen = compareds.length;
int index = 0;
while (index < origLen && index < compLen) {
String orig = origins[index];
String comp = compareds[index++];
/* ****** 此级别相同 ****** */
/* */
if (orig.equalsIgnoreCase(comp)) {
continue;
}
/* ******************** */
/* ****** 此级别不相同 ****** */
/* */
/*boolean isOrigEnd = (index == origLen);
boolean isCompEnd = (index == compLen);
if (isOrigEnd && isCompEnd) { // 都最后一级 11-10-23-000-000 11-10-24-000-000
return Level.SAME;
}*/
return Level.UNRELATED;
// 11-10-23-000-000 11-10-24-000-000
// 11-10-23-000-000 11-10-24-569-000
// 11-10-23-596-000 11-10-24-569-000
/* ********************* */
}
boolean isOrigEnd = (index == origLen);
boolean isCompEnd = (index == compLen);
if (isOrigEnd && isCompEnd) { // 都最后一级 11-10-23-000-000 11-10-23-000-000
return Level.SAME;
} else if (isOrigEnd) { // 11-10-23-000-000 11-10-23-156-000
return Level.HIGH;
} else {
return Level.LOW; // 11-10-23-156-000 11-10-23-000-000
}
}
/**
* 将区域码按照 2 2 2 3 3 进行区域分割
*/
public static String[] split(String divisionCode) {
String code = revise(divisionCode);
/*code = code.replaceAll("0*$", "");*/
List<String> splits = new LinkedList<String>();
String regionCode = null;
int pos = 0;
for (int digit : digits) {
regionCode = code.substring(pos, (pos += digit));
if (!regionCode.matches("^0*$")) {
splits.add(regionCode);
} else { // 已经到达最后了,这一部分区域码全部都是0了
break;
}
}
return splits.toArray(new String[splits.size()]);
}
/**
* 修正区域码为12位
*
* 不足12位的补0
* 超出12位的,截取前12位
*/
private static String revise(String divisionCode) {
if (null == divisionCode || divisionCode.isEmpty()) {
return "000000000000";
}
int len = divisionCode.length();
if (len < 12) { // 不足12位的,后边补0
return divisionCode + String.format("%1$0" + (12 - len) + "d", 0);
}
if (len > 12) { // 超出12位的,截取前12位
return divisionCode.substring(0, 12);
}
return divisionCode;
}
/**
* 获取指定级别的区域码
*/
public static String getRegionByLevel(String region, RegionLevel regionLevel) {
Assert.hasLength(region, "Cannot Get Region by NULL");
Assert.notNull(regionLevel, "Cannot Get Region by Null Level");
String division = revise(region);
int len = 0;
for (int i = 0; i <= regionLevel.ordinal(); i++) {
len += digits[i];
}
division = division.substring(0, len); // 只取有效位
division = revise(division); // 对区域码进行修正
return division;
}
/**
* 获取区域码所代表级别
*/
public static RegionLevel getRegionLevel(String region) {
try {
Assert.hasLength(region, "Cannot Get Null region level");
} catch (IllegalArgumentException e) {
LOGGER.warn("illegal param", e);
return null;
}
String[] regions = split(region);
int index = regions.length;
if (index > 0 && index <= RegionLevel.values().length) {
return RegionLevel.values()[index - 1];
}
return null;
}
public static enum Level {
HIGH, /* 高级别 */
SAME, /* 同级别 */
LOW, /* 低级别 */
UNRELATED, /* 不相关 */
}
public static enum RegionLevel {
PROVINCE, /*省*/
CITY, /* 市 */
COUNTY, /* 县 */
TOWN, /* 镇 */
VILLAGE, /* 村 */
}
}
JS版
有时候,不只是在后台JAVA代码中使用,前台JavaScript代码同样可能用到
实现过程完全一致,这里不再分步解释,直接上代码
/**
* (c) Copyright 2015 ManerFan. All Rights Reserved. 2015-01-12
*/
/**
* 区域码相关操作
* 将java相关功能移植到javascript
*/
!(function () {
RegionLevelUtil = {
_instance: null,
instance: function () {
if (!this._instance) {
this._instance = {
/**
* 区域码分布
*/
digits: [2, 2, 2, 3, 3],
/**
* 全零正则
*/
zero: new RegExp("^0*$", "i"),
/**
* 级别比较
*/
Level: {
HIGH: 0, /* 高级别 */
SAME: 1, /* 同级别 */
LOW: 2, /* 低级别 */
UNRELATED: 3 /* 不相关 */
},
/**
* 区域级别
*/
RegionLevel: {
PROVINCE: 0, /*省*/
CITY: 1, /* 市 */
COUNTY: 2, /* 县 */
TOWN: 3, /* 镇 */
VILLAGE: 4 /* 村 */
},
/**
* 获取特定级别
* @param region 原区域码
* @param regionLevel 区域级别
* @returns {String} 特定级别区域码
*/
getRegionByLevel: function getRegionByLevel(region, regionLevel) {
if (typeof(region) == "undefined" || null == region) {
return null;
}
if (typeof(regionLevel) == "undefined" || null == regionLevel) {
return null;
}
var division = RegionLevelUtil._instance.revise(region);
var len = 0;
for (var i = 0; i <= regionLevel && i < 5; i++) {
len += RegionLevelUtil._instance.digits[i];
}
/* 只取有效位 */
division = division.substr(0, len);
/* 补齐12位 */
division = RegionLevelUtil._instance.revise(division);
return division;
},
/**
* 获取区域级别
* @param region
* @returns {RegionLevel}
*/
getRegionLevel: function getRegionLevel(region) {
if (typeof(region) == "undefined" || null == region || region.length < 1) {
return null;
}
regions = RegionLevelUtil._instance.split(region);
var index = regions.length - 1;
for (var level in RegionLevelUtil._instance.RegionLevel) {
if (index == RegionLevelUtil._instance.RegionLevel[level]) {
return level;
}
}
return null;
},
/**
* 区域比较
* @param origin
* @param compared
* @returns {Level}
*/
regionLevelCompare: function regionLevelCompare(origin, compared) {
if (typeof(origin) == "undefined" || null == origin) {
return RegionLevelUtil._instance.Level.LOW;
}
if (typeof(origin) == "undefined" || null == compared) {
return RegionLevelUtil._instance.Level.HIGH;
}
/* 按区域 2 2 2 3 3 进行分割 */
var origins = RegionLevelUtil._instance.split(origin);
var compareds = RegionLevelUtil._instance.split(compared);
var origLen = origins.length;
var compLen = compareds.length;
var index = 0;
while (index < origLen && index < compLen) {
var orig = origins[index];
var comp = compareds[index++];
/* ****** 此级别相同 ****** */
/* */
if (orig == comp) {
continue;
}
/* ******************** */
/* ****** 此级别不相同 ****** */
/* */
/*boolean isOrigEnd = (index == origLen);
boolean isCompEnd = (index == compLen);
if (isOrigEnd && isCompEnd) { // 都最后一级 11-10-23-000-000 11-10-24-000-000
return Level.SAME;
}*/
return RegionLevelUtil._instance.Level.UNRELATED;
/* ********************* */
}
var isOrigEnd = (index == origLen);
var isCompEnd = (index == compLen);
if (isOrigEnd && isCompEnd) { // 都最后一级 11-10-23-000-000 11-10-23-000-000
return RegionLevelUtil._instance.Level.SAME;
} else if (isOrigEnd) { // 11-10-23-000-000 11-10-23-156-000
return RegionLevelUtil._instance.Level.HIGH;
} else {
return RegionLevelUtil._instance.Level.LOW; // 11-10-23-156-000 11-10-23-000-000
}
},
/**
* 将区域码进行分隔
* @param divisionCode
* @returns {Array}
*/
split: function split(divisionCode) {
var code = RegionLevelUtil._instance.revise(divisionCode);
var splits = [];
var regionCode = null;
var pos = 0;
$(RegionLevelUtil._instance.digits).each(function (index, num) {
regionCode = code.substring(pos, (pos += num));
if (!RegionLevelUtil._instance.zero.test(regionCode)) {
splits.push(regionCode);
} else { // 已经到达最后了,这一部分区域码全部都是0了
return false;
}
});
return splits;
},
/**
* 修正区域码为12位
* @param divisionCode
* @returns {String}
*/
revise: function revise(divisionCode) {
var all = "000000000000";
if (typeof(divisionCode) == "undefined" || null == divisionCode || divisionCode.length < 1) {
return all;
}
var len = divisionCode.length;
if (len < 12) { // 不足12位的,后边补0
return divisionCode + all.substr(0, 12 - len);
}
if (len > 12) { // 超出12位的,截取前12位
return divisionCode.substr(0, 12);
}
return divisionCode;
}
}
}
return this._instance;
}
}
})();
使用方法如下
var util = RegionLevelUtil.instance();
util.revise("1020");
util.split("110101001001");
util.regionLevelCompare("110101001001", "110101001000");
util.regionLevelCompare("110101001000", "110101001001");
util.regionLevelCompare("110101001001", "110101001001");
util.regionLevelCompare("110101001001", "110101002001");
util.getRegionLevel("110101001000"));
util.getRegionByLevel("110101001001", util.RegionLevel.CITY);
util.getRegionByLevel("110101001001", util.RegionLevel.PROVINCE);