diff --git a/src/main/java/haya4/tools/jpmesh/Jpmesh.java b/src/main/java/haya4/tools/jpmesh/Jpmesh.java index 65d35d1..7359a70 100644 --- a/src/main/java/haya4/tools/jpmesh/Jpmesh.java +++ b/src/main/java/haya4/tools/jpmesh/Jpmesh.java @@ -1,6 +1,7 @@ package haya4.tools.jpmesh; import java.awt.geom.Rectangle2D; +import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; @@ -8,76 +9,73 @@ public class Jpmesh { + /** + * 指定された位置の地域メッシュコードを取得する。 + * @param lon 緯度、緯度の有効桁数は小数点以下7桁 + * @param lat 経度、経度の有効桁数は小数点以下6桁 + * @param level 取得するメッシュコードのレベル[1,2,3] + * @return + */ public static String getMesh(double lon, double lat, int level) { - double lon1 = lon - 100.0d; - double lat1 = lat * 3.0d / 2.0d; - if (level >= 1) { - String x1 = get2(lon1); - String y1 = get2(lat1); - - if (level >= 2) { - double lon2 = lon1 - Double.parseDouble(x1); - lon2 = lon2 * 10; - String x2 = get1(lon2); - - double lat2 = lat1 - Double.parseDouble(y1); - lat2 = lat2 * 10; - String y2 = get1(lat2); - - if (level >= 3) { - double lon3 = lon2 - Double.parseDouble(x2); - lon3 = lon3 * 10; - String x3 = get1(lon3); - - double lat3 = lat2 - Double.parseDouble(y2); - lat3 = lat3 * 10; - String y3 = get1(lat3); - - if (level >= 4) { - double lon4 = lon3 - Double.parseDouble(x3); - lon4 = lon4 * 10; - String x4 = get1(lon4); - - double lat4 = lat3 - Double.parseDouble(y3); - lat4 = lat4 * 10; - String y4 = get1(lat4); - - // 4次メッシュ - return (y1 + x1 + y2 + x2 + y3 + x3 + y4 + x4); - } - else { - // 3次メッシュ - return (y1 + x1 + y2 + x2 + y3 + x3); - } - } - else { - // 2次メッシュ - return (y1 + x1 + y2 + x2); - } - } - else { - // 1次メッシュ - return (y1 + x1); - } + if (level < 1) { + return null; } - return null; + + // 1次メッシュ + BigDecimal lat0 = BigDecimal.valueOf(lat); + BigDecimal lat1 = lat0.multiply(BigDecimal.valueOf(3)).divide(BigDecimal.valueOf(2)); + lat1 = lat1.setScale(6, BigDecimal.ROUND_HALF_UP); + String y1 = get2(lat1); + + BigDecimal lon1 = BigDecimal.valueOf(lon).subtract(BigDecimal.valueOf(100)); + lon1 = lon1.setScale(7, BigDecimal.ROUND_HALF_UP); + String x1 = get2(lon1); + + if (level < 2) { + return (y1 + x1); + } + + // 2次メッシュ + BigDecimal lat2 = lat1.subtract(BigDecimal.valueOf(Integer.parseInt(y1))); + lat2 = lat2.multiply(BigDecimal.valueOf(8)); + String y2 = get1(lat2); + + BigDecimal lon2 = lon1.subtract(BigDecimal.valueOf(Double.parseDouble(x1))); + lon2 = lon2.multiply(BigDecimal.valueOf(8)); + String x2 = get1(lon2); + + if (level < 3) { + return (y1 + x1 + y2 + x2); + } + + // 3次メッシュ + BigDecimal lat3 = lat2.subtract(BigDecimal.valueOf(Double.parseDouble(y2))); + lat3 = lat3.multiply(BigDecimal.valueOf(10)); + String y3 = get1(lat3); + + BigDecimal lon3 = lon2.subtract(BigDecimal.valueOf(Double.parseDouble(x2))); + lon3 = lon3.multiply(BigDecimal.valueOf(10)); + String x3 = get1(lon3); + + return (y1 + x1 + y2 + x2 + y3 + x3); } - private static String get2(double d) { + private static String get2(BigDecimal d) { DecimalFormat s2 = new DecimalFormat("##"); s2.setRoundingMode(RoundingMode.DOWN); return s2.format(d); } - private static String get1(double d) { + private static String get1(BigDecimal d) { DecimalFormat s1 = new DecimalFormat("#"); s1.setRoundingMode(RoundingMode.DOWN); return s1.format(d); } /** - * 地域メッシュコードの位置(南西角)を取得する - * @param str 地域メッシュコード(1~4次コード) + * 地域メッシュコードの位置(南西角)を取得する。 + * ただし、緯度の有効桁数は小数点以下7桁、経度の有効桁数は小数点以下6桁まで。 + * @param str 地域メッシュコード(1~3次コード) * @return 地域メッシュコードの南西角位置。変換できなかった場合にはNULL。 */ public static DirectPosition2D getPosition(String str) { @@ -87,7 +85,7 @@ if (str.length() >= 4) { double lat1 = Double.parseDouble(str.substring(0, 2)); double lon1 = Double.parseDouble(str.substring(2, 4)); - double lat = lat1 / 1.5 * 3600; + double lat = lat1 * (2d / 3d) * 3600; double lon = (lon1 + 100) * 3600; if (str.length() >= 6) { @@ -104,13 +102,6 @@ lon = lon + (lon3 * 45); } - if (str.length() >= 10) { - double lat4 = Double.parseDouble(str.substring(8, 9)); - double lon4 = Double.parseDouble(str.substring(9, 10)); - lat = lat + (lat4 * 3); - lon = lon + (lon4 * 4.5d); - } - return new DirectPosition2D((lon / 3600), (lat / 3600)); } } @@ -123,7 +114,8 @@ /** * 地域メッシュコードの位置(中央)を取得する - * @param str 地域メッシュコード(1~4次コード) + * ただし、緯度の有効桁数は小数点以下7桁、経度の有効桁数は小数点以下6桁まで。 + * @param str 地域メッシュコード(1~3次コード) * @return 地域メッシュコードの中央位置。変換できなかった場合にはNULL。 */ public static DirectPosition2D getCenterPosition(String str) { @@ -131,11 +123,7 @@ if (ret != null) { double lat = (ret.getY()); double lon = (ret.getX()); - if (str.length() >= 10) { - lat = (lat + (7.5d / 3600.0d)); - lon = (lon + (11.25d / 3600.0d)); - } - else if (str.length() >= 8) { + if (str.length() >= 8) { lat = (lat + (15.0d / 3600.0d)); lon = (lon + (22.5d / 3600.0d)); } @@ -154,6 +142,7 @@ /** * 地域メッシュコードの矩形領域を取得する + * ただし、緯度の有効桁数は小数点以下7桁、経度の有効桁数は小数点以下6桁まで。 * @param str 地域メッシュコード(3次コード) * @return 地域メッシュコードの矩形領域。変換できなかった場合にはNULL。 */ @@ -164,11 +153,7 @@ double lon = ret.getX(); double lat2 = 0; double lon2 = 0; - if (str.length() >= 10) { - lat2 = 15d / 3600.0d; - lon2 = 22.5d / 3600.0d; - } - else if (str.length() >= 8) { + if (str.length() >= 8) { lat2 = 30.0d / 3600.0d; lon2 = 45.0d / 3600.0d; } diff --git a/src/test/java/haya4/tools/jpmesh/JpmeshTest.java b/src/test/java/haya4/tools/jpmesh/JpmeshTest.java index 325a3d9..8ccc91c 100755 --- a/src/test/java/haya4/tools/jpmesh/JpmeshTest.java +++ b/src/test/java/haya4/tools/jpmesh/JpmeshTest.java @@ -20,8 +20,15 @@ DirectPosition2D ret = Jpmesh.getPosition(null); assertNull(ret); - ret = Jpmesh.getPosition("53394526 "); - assertNull(ret); + ret = Jpmesh.getPosition("5339"); + assertNotNull(ret); + assertEquals(35.333333d, ret.getY(), 0.000001d); + assertEquals(139.000000d, ret.getX(), 0.000001d); + + ret = Jpmesh.getPosition("533945"); + assertNotNull(ret); + assertEquals(35.666666d, ret.getY(), 0.000001d); + assertEquals(139.625000d, ret.getX(), 0.000001d); ret = Jpmesh.getPosition("53394526"); assertNotNull(ret); @@ -33,15 +40,8 @@ assertEquals(35.683333d, ret.getY(), 0.000001d); assertEquals(139.7d, ret.getX(), 0.000001d); - ret = Jpmesh.getPosition("533945"); - assertNotNull(ret); - assertEquals(35.666666d, ret.getY(), 0.000001d); - assertEquals(139.625000d, ret.getX(), 0.000001d); - - ret = Jpmesh.getPosition("5339"); - assertNotNull(ret); - assertEquals(35.333333d, ret.getY(), 0.000001d); - assertEquals(139.000000d, ret.getX(), 0.000001d); + ret = Jpmesh.getPosition("53394526 "); + assertNull(ret); } @Test