From fe4f7b23c6f9809a54a677f95f0f688ab415a2c7 Mon Sep 17 00:00:00 2001 From: tsuga <2888173+tsuga@users.noreply.github.com> Date: Mon, 31 May 2021 17:07:43 +0900 Subject: [PATCH 1/5] add unofficial level 7, 8, 9, 10 supports --- jismesh/utils/_scalar.py | 211 ++++++++++++++++++++++++++++++++++++++- jismesh/utils/_vector.py | 120 ++++++++++++++++++++-- 2 files changed, 322 insertions(+), 9 deletions(-) diff --git a/jismesh/utils/_scalar.py b/jismesh/utils/_scalar.py index 0ec6094..e6ddb13 100644 --- a/jismesh/utils/_scalar.py +++ b/jismesh/utils/_scalar.py @@ -37,6 +37,14 @@ _unit_lon_lv5 = _functools.lru_cache(1)(lambda: _unit_lon_lv4()/2) _unit_lat_lv6 = _functools.lru_cache(1)(lambda: _unit_lat_lv5()/2) _unit_lon_lv6 = _functools.lru_cache(1)(lambda: _unit_lon_lv5()/2) +_unit_lat_lv7 = _functools.lru_cache(1)(lambda: _unit_lat_lv6()/2) +_unit_lon_lv7 = _functools.lru_cache(1)(lambda: _unit_lon_lv6()/2) +_unit_lat_lv8 = _functools.lru_cache(1)(lambda: _unit_lat_lv7()/2) +_unit_lon_lv8 = _functools.lru_cache(1)(lambda: _unit_lon_lv7()/2) +_unit_lat_lv9 = _functools.lru_cache(1)(lambda: _unit_lat_lv8()/2) +_unit_lon_lv9 = _functools.lru_cache(1)(lambda: _unit_lon_lv8()/2) +_unit_lat_lv10 = _functools.lru_cache(1)(lambda: _unit_lat_lv9()/2) +_unit_lon_lv10 = _functools.lru_cache(1)(lambda: _unit_lon_lv9()/2) _dict_unit_lat_lon = { 1 : (_unit_lat_lv1, _unit_lon_lv1), @@ -52,7 +60,11 @@ 3 : (_unit_lat_lv3, _unit_lon_lv3), 4 : (_unit_lat_lv4, _unit_lon_lv4), 5 : (_unit_lat_lv5, _unit_lon_lv5), - 6 : (_unit_lat_lv6, _unit_lon_lv6) + 6 : (_unit_lat_lv6, _unit_lon_lv6), + 7 : (_unit_lat_lv7, _unit_lon_lv7), + 8 : (_unit_lat_lv8, _unit_lon_lv8), + 9 : (_unit_lat_lv9, _unit_lon_lv9), + 10 : (_unit_lat_lv10, _unit_lon_lv10) } def unit_lat(level): @@ -82,6 +94,10 @@ def to_meshcode(lat, lon, level, astype): 4次(500m四方):4 5次(250m四方):5 6次(125m四方):6 + 7次(62.5m四方):7 + 8次(31.25m四方):8 + 9次(15.625m四方):9 + 10次(7.8125四方):10 Return: 指定次の地域メッシュコード @@ -124,6 +140,14 @@ def to_meshcode(lat, lon, level, astype): rem_lon_lv5 = lambda lon: rem_lon_lv4(lon) % _unit_lon_lv5() rem_lat_lv6 = lambda lat: rem_lat_lv5(lat) % _unit_lat_lv6() rem_lon_lv6 = lambda lon: rem_lon_lv5(lon) % _unit_lon_lv6() + rem_lat_lv7 = lambda lat: rem_lat_lv6(lat) % _unit_lat_lv7() + rem_lon_lv7 = lambda lon: rem_lon_lv6(lon) % _unit_lon_lv7() + rem_lat_lv8 = lambda lat: rem_lat_lv7(lat) % _unit_lat_lv8() + rem_lon_lv8 = lambda lon: rem_lon_lv7(lon) % _unit_lon_lv8() + rem_lat_lv9 = lambda lat: rem_lat_lv8(lat) % _unit_lat_lv9() + rem_lon_lv9 = lambda lon: rem_lon_lv8(lon) % _unit_lon_lv9() + rem_lat_lv10 = lambda lat: rem_lat_lv9(lat) % _unit_lat_lv10() + rem_lon_lv10 = lambda lon: rem_lon_lv9(lon) % _unit_lon_lv10() def meshcode_lv1(lat, lon): ab = int(rem_lat_lv0(lat) / _unit_lat_lv1()) @@ -193,6 +217,22 @@ def meshcode_lv6(lat, lon): k = int(rem_lat_lv5(lat) / _unit_lat_lv6())*2 + int(rem_lon_lv5(lon) / _unit_lon_lv6()) + 1 return meshcode_lv5(lat, lon) + str(k) + def meshcode_lv7(lat, lon): + k = int(rem_lat_lv6(lat) / _unit_lat_lv7())*2 + int(rem_lon_lv6(lon) / _unit_lon_lv7()) + 1 + return meshcode_lv6(lat, lon) + str(k) + + def meshcode_lv8(lat, lon): + k = int(rem_lat_lv7(lat) / _unit_lat_lv8())*2 + int(rem_lon_lv7(lon) / _unit_lon_lv8()) + 1 + return meshcode_lv7(lat, lon) + str(k) + + def meshcode_lv9(lat, lon): + k = int(rem_lat_lv8(lat) / _unit_lat_lv9())*2 + int(rem_lon_lv8(lon) / _unit_lon_lv9()) + 1 + return meshcode_lv8(lat, lon) + str(k) + + def meshcode_lv10(lat, lon): + k = int(rem_lat_lv9(lat) / _unit_lat_lv10())*2 + int(rem_lon_lv9(lon) / _unit_lon_lv10()) + 1 + return meshcode_lv9(lat, lon) + str(k) + if level == 1: return astype(meshcode_lv1(lat, lon)) @@ -235,6 +275,18 @@ def meshcode_lv6(lat, lon): if level == 6: return astype(meshcode_lv6(lat, lon)) + if level == 7: + return astype(meshcode_lv7(lat, lon)) + + if level == 8: + return astype(meshcode_lv8(lat, lon)) + + if level == 9: + return astype(meshcode_lv9(lat, lon)) + + if level == 10: + return astype(meshcode_lv10(lat, lon)) + raise ValueError("the level is unsupported.") def to_meshlevel(meshcode): @@ -258,6 +310,10 @@ def to_meshlevel(meshcode): 4次(500m四方):4 5次(250m四方):5 6次(125m四方):6 + 7次(62.5m四方):7 + 8次(31.25m四方):8 + 9次(15.625m四方):9 + 10次(7.8125四方):10 """ meshcode = str(meshcode) length = len(meshcode) @@ -307,6 +363,22 @@ def to_meshlevel(meshcode): if meshcode[10:11] in ['1','2','3','4']: return 6 + if length == 12: + if meshcode[11:12] in ['1','2','3','4']: + return 7 + + if length == 13: + if meshcode[12:13] in ['1','2','3','4']: + return 8 + + if length == 14: + if meshcode[13:14] in ['1','2','3','4']: + return 9 + + if length == 15: + if meshcode[14:15] in ['1','2','3','4']: + return 10 + return -1 def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): @@ -326,6 +398,10 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): 4次(500m四方):4 5次(250m四方):5 6次(125m四方):6 + 7次(62.5m四方):7 + 8次(31.25m四方):8 + 9次(15.625m四方):9 + 10次(7.8125四方):10 Args: meshcode: 指定次の地域メッシュコード @@ -429,6 +505,31 @@ def mesh_cord(func_higher_cord, func_unit_cord, func_multiplier): lon_multiplier_lv6 = _functools.partial( lambda meshcode: int(bin(int(meshcode[10:11])-1)[2:].zfill(2)[1:2]), meshcode=meshcode) + lat_multiplier_lv7 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[11:12])-1)[2:].zfill(2)[0:1]), meshcode=meshcode) + + lon_multiplier_lv7 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[11:12])-1)[2:].zfill(2)[1:2]), meshcode=meshcode) + + lat_multiplier_lv8 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[12:13])-1)[2:].zfill(2)[0:1]), meshcode=meshcode) + + lon_multiplier_lv8 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[12:13])-1)[2:].zfill(2)[1:2]), meshcode=meshcode) + + lat_multiplier_lv9 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[13:14])-1)[2:].zfill(2)[0:1]), meshcode=meshcode) + + lon_multiplier_lv9 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[13:14])-1)[2:].zfill(2)[1:2]), meshcode=meshcode) + + lat_multiplier_lv10 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[14:15])-1)[2:].zfill(2)[0:1]), meshcode=meshcode) + + lon_multiplier_lv10 = _functools.partial( + lambda meshcode: int(bin(int(meshcode[14:15])-1)[2:].zfill(2)[1:2]), meshcode=meshcode) + + mesh_lv1_default_lat = _functools.partial( mesh_cord, func_higher_cord=lambda: 0, @@ -597,6 +698,54 @@ def mesh_cord(func_higher_cord, func_unit_cord, func_multiplier): func_unit_cord=_unit_lon_lv6, func_multiplier=lon_multiplier_lv6) + mesh_lv7_default_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv6_default_lat, + func_unit_cord=_unit_lat_lv7, + func_multiplier=lat_multiplier_lv7) + + mesh_lv7_default_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv6_default_lon, + func_unit_cord=_unit_lon_lv7, + func_multiplier=lon_multiplier_lv7) + + mesh_lv8_default_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv7_default_lat, + func_unit_cord=_unit_lat_lv8, + func_multiplier=lat_multiplier_lv8) + + mesh_lv8_default_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv7_default_lon, + func_unit_cord=_unit_lon_lv8, + func_multiplier=lon_multiplier_lv8) + + mesh_lv9_default_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv8_default_lat, + func_unit_cord=_unit_lat_lv9, + func_multiplier=lat_multiplier_lv9) + + mesh_lv9_default_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv8_default_lon, + func_unit_cord=_unit_lon_lv9, + func_multiplier=lon_multiplier_lv9) + + mesh_lv10_default_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv9_default_lat, + func_unit_cord=_unit_lat_lv10, + func_multiplier=lat_multiplier_lv10) + + mesh_lv10_default_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv9_default_lon, + func_unit_cord=_unit_lon_lv10, + func_multiplier=lon_multiplier_lv10) + mesh_lv1_lat = _functools.partial( mesh_cord, func_higher_cord=mesh_lv1_default_lat, @@ -765,6 +914,54 @@ def mesh_cord(func_higher_cord, func_unit_cord, func_multiplier): func_unit_cord=_unit_lon_lv6, func_multiplier=lon_multiplier_lv) + mesh_lv7_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv7_default_lat, + func_unit_cord=_unit_lat_lv7, + func_multiplier=lat_multiplier_lv) + + mesh_lv7_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv7_default_lon, + func_unit_cord=_unit_lon_lv7, + func_multiplier=lon_multiplier_lv) + + mesh_lv8_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv8_default_lat, + func_unit_cord=_unit_lat_lv8, + func_multiplier=lat_multiplier_lv) + + mesh_lv8_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv8_default_lon, + func_unit_cord=_unit_lon_lv8, + func_multiplier=lon_multiplier_lv) + + mesh_lv9_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv9_default_lat, + func_unit_cord=_unit_lat_lv9, + func_multiplier=lat_multiplier_lv) + + mesh_lv9_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv9_default_lon, + func_unit_cord=_unit_lon_lv9, + func_multiplier=lon_multiplier_lv) + + mesh_lv10_lat = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv10_default_lat, + func_unit_cord=_unit_lat_lv10, + func_multiplier=lat_multiplier_lv) + + mesh_lv10_lon = _functools.partial( + mesh_cord, + func_higher_cord=mesh_lv10_default_lon, + func_unit_cord=_unit_lon_lv10, + func_multiplier=lon_multiplier_lv) + level = to_meshlevel(meshcode) if level == 1: @@ -809,6 +1006,18 @@ def mesh_cord(func_higher_cord, func_unit_cord, func_multiplier): if level == 6: return mesh_lv6_lat(), mesh_lv6_lon() + if level == 7: + return mesh_lv7_lat(), mesh_lv7_lon() + + if level == 8: + return mesh_lv8_lat(), mesh_lv8_lon() + + if level == 9: + return mesh_lv9_lat(), mesh_lv9_lon() + + if level == 10: + return mesh_lv10_lat(), mesh_lv10_lon() + raise ValueError("the level is unsupported.") def _make_envelope(lat_s, lon_w, lat_n, lon_e, to_level, astype): diff --git a/jismesh/utils/_vector.py b/jismesh/utils/_vector.py index 534e585..cc07989 100644 --- a/jismesh/utils/_vector.py +++ b/jismesh/utils/_vector.py @@ -44,8 +44,16 @@ def _slice(t, start, stop): _unit_lon_lv5 = _functools.lru_cache(1)(lambda: _unit_lon_lv4()/2) _unit_lat_lv6 = _functools.lru_cache(1)(lambda: _unit_lat_lv5()/2) _unit_lon_lv6 = _functools.lru_cache(1)(lambda: _unit_lon_lv5()/2) +_unit_lat_lv7 = _functools.lru_cache(1)(lambda: _unit_lat_lv6()/2) +_unit_lon_lv7 = _functools.lru_cache(1)(lambda: _unit_lon_lv6()/2) +_unit_lat_lv8 = _functools.lru_cache(1)(lambda: _unit_lat_lv7()/2) +_unit_lon_lv8 = _functools.lru_cache(1)(lambda: _unit_lon_lv7()/2) +_unit_lat_lv9 = _functools.lru_cache(1)(lambda: _unit_lat_lv8()/2) +_unit_lon_lv9 = _functools.lru_cache(1)(lambda: _unit_lon_lv8()/2) +_unit_lat_lv10 = _functools.lru_cache(1)(lambda: _unit_lat_lv9()/2) +_unit_lon_lv10 = _functools.lru_cache(1)(lambda: _unit_lon_lv9()/2) -_supported_levels = [1, 40000, 20000, 16000, 2, 8000, 5000, 4000, 2500, 2000, 3, 4, 5, 6] +_supported_levels = [1, 40000, 20000, 16000, 2, 8000, 5000, 4000, 2500, 2000, 3, 4, 5, 6, 7, 8, 9, 10] def unit_lat(level): level = _np.atleast_1d(level).astype(_np.int64) @@ -68,6 +76,10 @@ def unit_lat(level): lat[level==4] = _unit_lat_lv4() lat[level==5] = _unit_lat_lv5() lat[level==6] = _unit_lat_lv6() + lat[level==7] = _unit_lat_lv7() + lat[level==8] = _unit_lat_lv8() + lat[level==9] = _unit_lat_lv9() + lat[level==10] = _unit_lat_lv10() if lat.size == 1: lat = _np.asscalar(lat) @@ -95,6 +107,10 @@ def unit_lon(level): lon[level==4] = _unit_lon_lv4() lon[level==5] = _unit_lon_lv5() lon[level==6] = _unit_lon_lv6() + lon[level==7] = _unit_lon_lv7() + lon[level==8] = _unit_lon_lv8() + lon[level==9] = _unit_lon_lv9() + lon[level==10] = _unit_lon_lv10() if lon.size == 1: lon = _np.asscalar(lon) @@ -122,6 +138,10 @@ def to_meshcode(lat, lon, level, astype): 4次(500m四方):4 5次(250m四方):5 6次(125m四方):6 + 7次(62.5m四方):7 + 8次(31.25m四方):8 + 9次(15.625m四方):9 + 10次(7.8125四方):10 astype: 戻り値メッシュコードの型 Return: 指定次の地域メッシュコード @@ -158,6 +178,14 @@ def to_meshcode(lat, lon, level, astype): rem_lon_lv5 = lambda lon: rem_lon_lv4(lon) % _unit_lon_lv5() rem_lat_lv6 = lambda lat: rem_lat_lv5(lat) % _unit_lat_lv6() rem_lon_lv6 = lambda lon: rem_lon_lv5(lon) % _unit_lon_lv6() + rem_lat_lv7 = lambda lat: rem_lat_lv6(lat) % _unit_lat_lv7() + rem_lon_lv7 = lambda lon: rem_lon_lv6(lon) % _unit_lon_lv7() + rem_lat_lv8 = lambda lat: rem_lat_lv7(lat) % _unit_lat_lv8() + rem_lon_lv8 = lambda lon: rem_lon_lv7(lon) % _unit_lon_lv8() + rem_lat_lv9 = lambda lat: rem_lat_lv8(lat) % _unit_lat_lv9() + rem_lon_lv9 = lambda lon: rem_lon_lv8(lon) % _unit_lon_lv9() + rem_lat_lv10 = lambda lat: rem_lat_lv9(lat) % _unit_lat_lv10() + rem_lon_lv10 = lambda lon: rem_lon_lv9(lon) % _unit_lon_lv10() def meshcode_lv1(lat, lon): ab = (rem_lat_lv0(lat) // _unit_lat_lv1()) @@ -227,6 +255,22 @@ def meshcode_lv6(lat, lon): k = (rem_lat_lv5(lat) // _unit_lat_lv6())*2 + (rem_lon_lv5(lon) // _unit_lon_lv6()) + 1 return meshcode_lv5(lat, lon)*10 + k + def meshcode_lv7(lat, lon): + l = (rem_lat_lv6(lat) // _unit_lat_lv7())*2 + (rem_lon_lv6(lon) // _unit_lon_lv7()) + 1 + return meshcode_lv6(lat, lon)*10 + l + + def meshcode_lv8(lat, lon): + m = (rem_lat_lv7(lat) // _unit_lat_lv8())*2 + (rem_lon_lv7(lon) // _unit_lon_lv8()) + 1 + return meshcode_lv7(lat, lon)*10 + m + + def meshcode_lv9(lat, lon): + n = (rem_lat_lv8(lat) // _unit_lat_lv9())*2 + (rem_lon_lv8(lon) // _unit_lon_lv9()) + 1 + return meshcode_lv8(lat, lon)*10 + n + + def meshcode_lv10(lat, lon): + o = (rem_lat_lv9(lat) // _unit_lat_lv10())*2 + (rem_lon_lv9(lon) // _unit_lon_lv10()) + 1 + return meshcode_lv9(lat, lon)*10 + o + lat = _np.atleast_1d(lat).astype(_np.float64) lon = _np.atleast_1d(lon).astype(_np.float64) level = _np.atleast_1d(level).astype(_np.int64) @@ -284,6 +328,18 @@ def meshcode_lv6(lat, lon): if _np.any(_np.isin(level, 6)): meshcode += meshcode_lv6(lat, lon) * (level == 6) + + if _np.any(_np.isin(level, 7)): + meshcode += meshcode_lv7(lat, lon) * (level == 7) + + if _np.any(_np.isin(level, 8)): + meshcode += meshcode_lv8(lat, lon) * (level == 8) + + if _np.any(_np.isin(level, 9)): + meshcode += meshcode_lv9(lat, lon) * (level == 9) + + if _np.any(_np.isin(level, 10)): + meshcode += meshcode_lv10(lat, lon) * (level == 10) meshcode = meshcode.astype(_np.int64) meshcode = meshcode.astype(astype) @@ -314,6 +370,10 @@ def to_meshlevel(meshcode): 4次(500m四方):4 5次(250m四方):5 6次(125m四方):6 + 7次(62.5m四方):7 + 8次(31.25m四方):8 + 9次(15.625m四方):9 + 10次(7.8125四方):10 """ meshcode = _np.array(meshcode).astype(_np.int64) level = _np.full(meshcode.shape, _np.int64(-1)) @@ -328,6 +388,10 @@ def to_meshlevel(meshcode): i = _slice(meshcode, 8, 9) j = _slice(meshcode, 9, 10) k = _slice(meshcode, 10, 11) + l = _slice(meshcode, 11, 12) + m = _slice(meshcode, 12, 13) + n = _slice(meshcode, 13, 14) + o = _slice(meshcode, 14, 15) level[(num_digits==4)] = 1 level[(num_digits==5)] = 40000 @@ -343,6 +407,10 @@ def to_meshlevel(meshcode): level[(num_digits==9) & (i == 7)] = 4000 level[(num_digits==10) & (_np.isin(j, [1,2,3,4]))] = 5 level[(num_digits==11) & (_np.isin(k, [1,2,3,4]))] = 6 + level[(num_digits==12) & (_np.isin(k, [1,2,3,4]))] = 7 + level[(num_digits==13) & (_np.isin(k, [1,2,3,4]))] = 8 + level[(num_digits==14) & (_np.isin(k, [1,2,3,4]))] = 9 + level[(num_digits==15) & (_np.isin(k, [1,2,3,4]))] = 10 if level.size == 1: level = _np.asscalar(level) @@ -366,6 +434,10 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): 4次(500m四方):4 5次(250m四方):5 6次(125m四方):6 + 7次(62.5m四方):7 + 8次(31.25m四方):8 + 9次(15.625m四方):9 + 10次(7.8125四方):10 Args: meshcode: 指定次の地域メッシュコード @@ -387,6 +459,10 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): i = _slice(meshcode, 8, 9) j = _slice(meshcode, 9, 10) k = _slice(meshcode, 10, 11) + l = _slice(meshcode, 11, 12) + m = _slice(meshcode, 12, 13) + n = _slice(meshcode, 13, 14) + o = _slice(meshcode, 14, 15) level = to_meshlevel(meshcode) @@ -404,10 +480,14 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): target_lv4 = level == 4 target_lv5 = level == 5 target_lv6 = level == 6 + target_lv7 = level == 7 + target_lv8 = level == 8 + target_lv9 = level == 9 + target_lv10 = level == 10 # level 1 # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':1}, '5339'), - targets = target_lv1 | target_40000 | target_20000 | target_16000 | target_8000 | target_4000 | target_lv2 | target_5000 | target_2500 | target_2000 | target_lv3 | target_lv4 | target_lv5 | target_lv6 + targets = target_lv1 | target_40000 | target_20000 | target_16000 | target_8000 | target_4000 | target_lv2 | target_5000 | target_2500 | target_2000 | target_lv3 | target_lv4 | target_lv5 | target_lv6 | target_lv7 | target_lv8 | target_lv9| target_lv10 lat = (ab * _unit_lat_lv1()) * targets lon = (cd * _unit_lon_lv1() + 100) * targets @@ -443,7 +523,7 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): # level 2 # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':2}, '533935'), - targets = target_lv2 | target_5000 | target_2500 | target_2000 | target_lv3 | target_lv4 | target_lv5 | target_lv6 + targets = target_lv2 | target_5000 | target_2500 | target_2000 | target_lv3 | target_lv4 | target_lv5 | target_lv6 | target_lv7 | target_lv8 | target_lv9 | target_lv10 lat += (e * _unit_lat_lv2()) * targets lon += (f * _unit_lon_lv2()) * targets @@ -467,29 +547,53 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): # level 3 # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':3}, '53393599'), - targets = target_lv3 | target_lv4 | target_lv5 | target_lv6 + targets = target_lv3 | target_lv4 | target_lv5 | target_lv6 | target_lv7 | target_lv8 | target_lv9 | target_lv10 lat += (g * _unit_lat_lv3()) * targets lon += (h * _unit_lon_lv3()) * targets # level 4 # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':4}, '533935992'), - targets = target_lv4 | target_lv5 | target_lv6 + targets = target_lv4 | target_lv5 | target_lv6 | target_lv7 | target_lv8 | target_lv9 | target_lv10 lat += ((i//3 == 1) * _unit_lat_lv4()) * targets lon += ((i%2 == 0) * _unit_lon_lv4()) * targets # level 5 # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':5}, '5339359921'), - targets = target_lv5 | target_lv6 + targets = target_lv5 | target_lv6 | target_lv7 | target_lv8 | target_lv9 | target_lv10 lat += ((j//3 == 1) * _unit_lat_lv5()) * targets lon += ((j%2 == 0) * _unit_lon_lv5()) * targets # level 6 # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':6}, '53393599212'), - targets = target_lv6 + targets = target_lv6 | target_lv7 | target_lv8 | target_lv9 | target_lv10 lat += ((k//3 == 1) * _unit_lat_lv6()) * targets lon += ((k%2 == 0) * _unit_lon_lv6()) * targets - # メッシュ内座業 + # level 7 + # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':7}, '533935992121'), + targets = target_lv7 | target_lv8 | target_lv9 | target_lv10 + lat += ((k//3 == 1) * _unit_lat_lv7()) * targets + lon += ((k%2 == 0) * _unit_lon_lv7()) * targets + + # level 8 + # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':8}, '5339359921211'), + targets = target_lv8 | target_lv9 | target_lv10 + lat += ((k//3 == 1) * _unit_lat_lv8()) * targets + lon += ((k%2 == 0) * _unit_lon_lv8()) * targets + + # level 9 + # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':9}, '53393599212113'), + targets = target_lv9 | target_lv10 + lat += ((k//3 == 1) * _unit_lat_lv9()) * targets + lon += ((k%2 == 0) * _unit_lon_lv9()) * targets + + # level 10 + # ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':10}, '533935992121134'), + targets = target_lv10 + lat += ((k//3 == 1) * _unit_lat_lv10()) * targets + lon += ((k%2 == 0) * _unit_lon_lv10()) * targets + + # メッシュ内産業 lat += unit_lat(level)*lat_multiplier lon += unit_lon(level)*lon_multiplier From 1ac846dac93c463baf08972cfd6f8574d28dfcd6 Mon Sep 17 00:00:00 2001 From: tsuga <2888173+tsuga@users.noreply.github.com> Date: Mon, 31 May 2021 17:05:48 +0900 Subject: [PATCH 2/5] add tests --- tests/test_to_meshcode.py | 8 ++++++++ tests/test_to_meshlevel.py | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/tests/test_to_meshcode.py b/tests/test_to_meshcode.py index f86250b..a43fd01 100644 --- a/tests/test_to_meshcode.py +++ b/tests/test_to_meshcode.py @@ -29,6 +29,10 @@ def _data_scalar(): ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':4}, '533935992'), ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':5}, '5339359921'), ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':6}, '53393599212'), + ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':7}, '533935992121'), + ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':8}, '5339359921211'), + ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':9}, '53393599212113'), + ({'lat':_lat_tokyo_tower, 'lon':_lon_tokyo_tower, 'level':10}, '533935992121134'), ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':1}, '5235'), ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':40000}, '52352'), ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':20000}, '5235245'), @@ -43,6 +47,10 @@ def _data_scalar(): ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':4}, '523536804'), ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':5}, '5235368041'), ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':6}, '52353680412'), + ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':7}, '523536804122'), + ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':8}, '5235368041222'), + ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':9}, '52353680412222'), + ({'lat':_lat_kyoto_tower, 'lon':_lon_kyoto_tower, 'level':10}, '523536804122224'), ] def _data_vector(num_elements=10): diff --git a/tests/test_to_meshlevel.py b/tests/test_to_meshlevel.py index 4540770..79bef98 100644 --- a/tests/test_to_meshlevel.py +++ b/tests/test_to_meshlevel.py @@ -19,6 +19,10 @@ def _data_scalar(): ({'meshcode': 533935992}, 4), ({'meshcode': 5339359921}, 5), ({'meshcode': 53393599212}, 6), + ({'meshcode': 533935992121}, 7), + ({'meshcode': 5339359921211}, 8), + ({'meshcode': 53393599212113}, 9), + ({'meshcode': 533935992121134}, 10), ({'meshcode': 5235}, 1), ({'meshcode': 52352}, 40000), ({'meshcode': 5235245}, 20000), @@ -33,6 +37,10 @@ def _data_scalar(): ({'meshcode': 523536804}, 4), ({'meshcode': 5235368041}, 5), ({'meshcode': 52353680412}, 6), + ({'meshcode': 523536804122}, 7), + ({'meshcode': 5235368041222}, 8), + ({'meshcode': 52353680412222}, 9), + ({'meshcode': 523536804122224}, 10), ({'meshcode': 5}, -1), ] From c6328ac44c9e4437e541d337538a3ee209f1358d Mon Sep 17 00:00:00 2001 From: tsuga <2888173+tsuga@users.noreply.github.com> Date: Mon, 31 May 2021 17:06:25 +0900 Subject: [PATCH 3/5] add warnings for non-standard levels --- jismesh/utils/__init__.py | 36 +++++++++++++++++++++++++++++++----- jismesh/utils/_scalar.py | 5 +++++ jismesh/utils/_vector.py | 4 ++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/jismesh/utils/__init__.py b/jismesh/utils/__init__.py index ffcb25d..4a906b1 100644 --- a/jismesh/utils/__init__.py +++ b/jismesh/utils/__init__.py @@ -1,10 +1,15 @@ from __future__ import absolute_import import numpy as _np +import warnings from . import _vector from . import _scalar +class JismeshNonstandardWarning(Warning): + pass + def unit_lat(level): + warn_if_nonstandard(level) if _np.isscalar(level): unit_lat = _scalar.unit_lat else: @@ -13,6 +18,7 @@ def unit_lat(level): return unit_lat(level) def unit_lon(level): + warn_if_nonstandard(level) if _np.isscalar(level): unit_lon = _scalar.unit_lon else: @@ -21,7 +27,7 @@ def unit_lon(level): return unit_lon(level) def to_meshcode(lat, lon, level, astype=_np.int64): - + warn_if_nonstandard(level) if _np.isscalar(lat) and _np.isscalar(lon) and _np.isscalar(level): to_meshcode = _scalar.to_meshcode else: @@ -35,20 +41,27 @@ def to_meshlevel(meshcode): else: to_meshlevel = _vector.to_meshlevel - return to_meshlevel(meshcode) + meshlevel = to_meshlevel(meshcode) + warn_if_nonstandard(meshlevel) + return meshlevel def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): if _np.isscalar(meshcode) and _np.isscalar(lat_multiplier) and _np.isscalar(lon_multiplier): to_meshpoint = _scalar.to_meshpoint else: to_meshpoint = _vector.to_meshpoint - + + to_meshlevel(meshcode) # for JismeshNonstandardWarning + return to_meshpoint(meshcode, lat_multiplier, lon_multiplier) def to_envelope(meshcode_sw, meshcode_ne): assert _np.isscalar(meshcode_sw) assert _np.isscalar(meshcode_sw) assert type(meshcode_sw) == type(meshcode_ne) + + to_meshlevel(meshcode_sw) # for JismeshNonstandardWarning + to_meshlevel(meshcode_ne) # for JismeshNonstandardWarning to_envelope = _scalar.to_envelope @@ -57,8 +70,21 @@ def to_envelope(meshcode_sw, meshcode_ne): def to_intersects(meshcode, to_level): assert _np.isscalar(meshcode) assert _np.isscalar(to_level) - + + warn_if_nonstandard(to_level) + to_intersects = _scalar.to_intersects return to_intersects(meshcode, to_level) - \ No newline at end of file + +def is_nonstandard(level): + if _np.isscalar(level): + is_nonstandard = _scalar.is_nonstandard + else: + is_nonstandard = _vector.is_nonstandard + + return is_nonstandard(level) + +def warn_if_nonstandard(level): + if is_nonstandard(level): + warnings.warn("Levels 7, 8, 9, and 10 are not standard levels.", JismeshNonstandardWarning, stacklevel=3) \ No newline at end of file diff --git a/jismesh/utils/_scalar.py b/jismesh/utils/_scalar.py index e6ddb13..491a6b7 100644 --- a/jismesh/utils/_scalar.py +++ b/jismesh/utils/_scalar.py @@ -67,6 +67,8 @@ 10 : (_unit_lat_lv10, _unit_lon_lv10) } +_nonstandard_levels = [7, 8, 9, 10] + def unit_lat(level): return _dict_unit_lat_lon[level][0]() @@ -1059,3 +1061,6 @@ def to_intersects(meshcode, to_level): from_lat_n, from_lon_e = to_meshpoint(meshcode, 1, 1) return _make_envelope(from_lat_s, from_lon_w, from_lat_n, from_lon_e, to_level, type(meshcode)) + +def is_nonstandard(level): + return level in _nonstandard_levels \ No newline at end of file diff --git a/jismesh/utils/_vector.py b/jismesh/utils/_vector.py index cc07989..9051b42 100644 --- a/jismesh/utils/_vector.py +++ b/jismesh/utils/_vector.py @@ -54,6 +54,7 @@ def _slice(t, start, stop): _unit_lon_lv10 = _functools.lru_cache(1)(lambda: _unit_lon_lv9()/2) _supported_levels = [1, 40000, 20000, 16000, 2, 8000, 5000, 4000, 2500, 2000, 3, 4, 5, 6, 7, 8, 9, 10] +_nonstandard_levels = [7, 8, 9, 10] def unit_lat(level): level = _np.atleast_1d(level).astype(_np.int64) @@ -598,3 +599,6 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): lon += unit_lon(level)*lon_multiplier return lat, lon + +def is_nonstandard(level): + return _np.any(_np.isin(level, _nonstandard_levels)) \ No newline at end of file From 16b48e1e74fac4e470b7cf42558d2afd399cf3a6 Mon Sep 17 00:00:00 2001 From: tsuga <2888173+tsuga@users.noreply.github.com> Date: Mon, 31 May 2021 17:09:45 +0900 Subject: [PATCH 4/5] update docs --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da03845..a26ef11 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # jismesh -地域メッシュコードに関するユーティリティです。 +地域メッシュコード [JISX0410:2002](https://www.jisc.go.jp/app/jis/general/GnrJISNumberNameSearchList?show&jisStdNo=X0410) に関するユーティリティです。 ## 対応地域メッシュコード - 1次(標準地域メッシュ 80km四方): 1 @@ -17,7 +17,16 @@ - 4次(分割地域メッシュ 500m四方): 4 - 5次(分割地域メッシュ 250m四方): 5 - 6次(分割地域メッシュ 125m四方): 6 +- 7次(62.5m四方)*: 7 +- 8次(31.25m四方)*: 8 +- 9次(15.625m四方)*: 9 +- 10次(7.8125m四方)*: 10 + +\* 7次以降は [JISX0410:2002](https://www.jisc.go.jp/app/jis/general/GnrJISNumberNameSearchList?show&jisStdNo=X0410) の規定外ですが、実務上のニーズに応えるため本ユーティリティでは取り扱い可能としています。 +それらの次数を使用した場合は、`JismeshNonstandardWarning`の警告が表示されます。 + + ## インストール ```bash pip install jismesh From a885ae4783f6b73fa2ff326a53a3c9b6e02c6bec Mon Sep 17 00:00:00 2001 From: tsuga <2888173+tsuga@users.noreply.github.com> Date: Mon, 31 May 2021 17:25:52 +0900 Subject: [PATCH 5/5] fix typo --- jismesh/utils/_vector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jismesh/utils/_vector.py b/jismesh/utils/_vector.py index 9051b42..3330182 100644 --- a/jismesh/utils/_vector.py +++ b/jismesh/utils/_vector.py @@ -594,7 +594,7 @@ def to_meshpoint(meshcode, lat_multiplier, lon_multiplier): lat += ((k//3 == 1) * _unit_lat_lv10()) * targets lon += ((k%2 == 0) * _unit_lon_lv10()) * targets - # メッシュ内産業 + # メッシュ内座標 lat += unit_lat(level)*lat_multiplier lon += unit_lon(level)*lon_multiplier