jageocoder 2.2.0__tar.gz → 2.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jageocoder-2.2.0 → jageocoder-2.2.1}/PKG-INFO +4 -1
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/__init__.py +1 -1
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/__main__.py +5 -1
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/aza_master.py +0 -1
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/dbm/base_table.py +3 -4
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/module.py +12 -7
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/node.py +2 -2
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/remote.py +1 -1
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/rtree.py +44 -24
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/strlib.py +1 -1
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/trie.py +0 -1
- {jageocoder-2.2.0 → jageocoder-2.2.1}/pyproject.toml +5 -2
- {jageocoder-2.2.0 → jageocoder-2.2.1}/LICENSE +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/README.md +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/address.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/dataset.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/dbm/__init__.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/dbm/abstract_table.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/dbm/base_index.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/dbm/exceptions.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/dbm/types.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/exceptions.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/itaiji.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/itaiji_dic.json +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/local.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/result.py +0 -0
- {jageocoder-2.2.0 → jageocoder-2.2.1}/jageocoder/tree.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: jageocoder
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: A Japanese-address geocoder for Python.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: geocoder,Japanese address
|
|
@@ -17,6 +17,7 @@ Provides-Extra: doc
|
|
|
17
17
|
Provides-Extra: test
|
|
18
18
|
Requires-Dist: deprecated (>=1.2.13)
|
|
19
19
|
Requires-Dist: docopt-ng
|
|
20
|
+
Requires-Dist: flake8 ; extra == "dev"
|
|
20
21
|
Requires-Dist: geographiclib (>=2.0)
|
|
21
22
|
Requires-Dist: jaconv (>=0.3.9)
|
|
22
23
|
Requires-Dist: marisa-trie (>=1.3.1)
|
|
@@ -24,6 +25,8 @@ Requires-Dist: pytest (>=8.4.1) ; extra == "test"
|
|
|
24
25
|
Requires-Dist: requests
|
|
25
26
|
Requires-Dist: rtree (>=1.0.0)
|
|
26
27
|
Requires-Dist: sphinx-rtd-theme (>=1.2.0) ; extra == "doc"
|
|
28
|
+
Requires-Dist: tox (>=4.0.0) ; extra == "dev"
|
|
29
|
+
Requires-Dist: tox-uv ; extra == "dev"
|
|
27
30
|
Requires-Dist: tqdm (>=4.0.0)
|
|
28
31
|
Requires-Dist: twine (>=5.1.1) ; extra == "dev"
|
|
29
32
|
Project-URL: Documentation, https://jageocoder.readthedocs.io/ja/latest/
|
|
@@ -17,7 +17,7 @@ running the following steps.
|
|
|
17
17
|
>>> import jageocoder
|
|
18
18
|
>>> jageocoder.init()
|
|
19
19
|
>>> jageocoder.searchNode('新宿区西新宿2-8-1')
|
|
20
|
-
[{"node": {"id": ..., "name": "8番", "name_index": "8.番", "x": 139.6..., "y": 35.6..., "level": 7, "priority": 3, "note": "", "parent_id": ..., "sibling_id": ...}, "matched": "新宿区西新宿2-8-"}]
|
|
20
|
+
[{"node": {"id": ..., "name": "8番", "name_index": "8.番", "x": 139.6..., "y": 35.6..., "level": 7, "priority": 3, "note": "", "parent_id": ..., "sibling_id": ...}, "matched": "新宿区西新宿2-8-"}] # noqa: E501
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
from importlib.metadata import version
|
|
@@ -127,7 +127,11 @@ def main():
|
|
|
127
127
|
|
|
128
128
|
elif args['reverse']:
|
|
129
129
|
from jageocoder.address import AddressLevel
|
|
130
|
-
jageocoder.init(
|
|
130
|
+
jageocoder.init(
|
|
131
|
+
db_dir=args['--db-dir'],
|
|
132
|
+
mode='r',
|
|
133
|
+
debug=args['--debug'],
|
|
134
|
+
url=args['--url'])
|
|
131
135
|
print(json.dumps(
|
|
132
136
|
jageocoder.reverse(
|
|
133
137
|
x=float(args['<longitude>']),
|
|
@@ -397,7 +397,7 @@ class BaseTable(object):
|
|
|
397
397
|
|
|
398
398
|
# Create empty table
|
|
399
399
|
cur = self.get_conn().cursor()
|
|
400
|
-
cur.execute(
|
|
400
|
+
cur.execute("DROP TABLE IF EXISTS records")
|
|
401
401
|
cur.execute(self._get_create_table_statement())
|
|
402
402
|
self.commit()
|
|
403
403
|
|
|
@@ -493,7 +493,6 @@ class BaseTable(object):
|
|
|
493
493
|
if from_pos < 0 or to_pos > self.count_records():
|
|
494
494
|
raise ValueError("Out of range.")
|
|
495
495
|
|
|
496
|
-
limits = to_pos - from_pos
|
|
497
496
|
conn = self.get_conn()
|
|
498
497
|
conn.row_factory = sqlite3.Row
|
|
499
498
|
cur = conn.cursor()
|
|
@@ -762,7 +761,7 @@ class BaseTable(object):
|
|
|
762
761
|
raise ValueError(f"Field '{k}' is not in this table.")
|
|
763
762
|
elif k == self.pos_field:
|
|
764
763
|
raise ValueError(
|
|
765
|
-
|
|
764
|
+
"The value of the pos field can not modified.")
|
|
766
765
|
|
|
767
766
|
fields.append(k)
|
|
768
767
|
if isinstance(self.schema[k], (dict, list)):
|
|
@@ -830,7 +829,7 @@ class BaseTable(object):
|
|
|
830
829
|
raise ValueError(f"Field '{k}' is not in this table.")
|
|
831
830
|
elif k == pos_field:
|
|
832
831
|
raise ValueError(
|
|
833
|
-
|
|
832
|
+
"The value of the pos field can not modified.")
|
|
834
833
|
|
|
835
834
|
cols.append(k)
|
|
836
835
|
if isinstance(self.schema[k], (dict, list)):
|
|
@@ -4,15 +4,14 @@ import shutil
|
|
|
4
4
|
from typing import Any, Dict, List, Optional, Union
|
|
5
5
|
import urllib.request
|
|
6
6
|
from urllib.error import URLError
|
|
7
|
+
import zipfile
|
|
7
8
|
|
|
8
9
|
import jageocoder
|
|
9
|
-
from .dataset import Dataset
|
|
10
10
|
from .exceptions import JageocoderError
|
|
11
11
|
from .local import LocalTree
|
|
12
12
|
from .tree import AddressTree, get_db_dir
|
|
13
13
|
from .remote import RemoteTree
|
|
14
14
|
from .result import Result
|
|
15
|
-
from .rtree import Index
|
|
16
15
|
|
|
17
16
|
_tree: Optional[AddressTree] = None # The default AddressTree
|
|
18
17
|
logger = logging.getLogger(__name__)
|
|
@@ -193,7 +192,6 @@ def get_module_tree() -> AddressTree:
|
|
|
193
192
|
AddressTree
|
|
194
193
|
The singleton object.
|
|
195
194
|
"""
|
|
196
|
-
global _tree
|
|
197
195
|
if _tree is None:
|
|
198
196
|
raise JageocoderError("Tree is not initialized")
|
|
199
197
|
|
|
@@ -268,10 +266,17 @@ def install_dictionary(
|
|
|
268
266
|
# Unzip the archive
|
|
269
267
|
os.makedirs(db_dir, exist_ok=True)
|
|
270
268
|
shutil.rmtree(db_dir)
|
|
271
|
-
shutil.unpack_archive(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
)
|
|
269
|
+
# shutil.unpack_archive(
|
|
270
|
+
# filename=str(path),
|
|
271
|
+
# extract_dir=str(db_dir),
|
|
272
|
+
# )
|
|
273
|
+
with zipfile.ZipFile(path, "r") as zipf:
|
|
274
|
+
zipinfo_list = zipf.infolist()
|
|
275
|
+
n = len(zipinfo_list)
|
|
276
|
+
for index, zipinfo in enumerate(zipinfo_list):
|
|
277
|
+
logger.info(f"[{index+1}/{n}] Extractiong '{zipinfo.filename}'")
|
|
278
|
+
zipf.extract(zipinfo, db_dir)
|
|
279
|
+
|
|
275
280
|
for readme_fname in ("README.txt", "README.md",):
|
|
276
281
|
readme_path = os.path.join(db_dir, readme_fname)
|
|
277
282
|
if os.path.exists(readme_path):
|
|
@@ -122,7 +122,7 @@ class AddressNodeTable(AbstractTable):
|
|
|
122
122
|
notes = []
|
|
123
123
|
for attr in re.split(r'(?<!\\)/', note):
|
|
124
124
|
try:
|
|
125
|
-
k, v = re.split(r'(?<!\\):', attr, 1)
|
|
125
|
+
k, v = re.split(r'(?<!\\):', attr, maxsplit=1)
|
|
126
126
|
except ValueError:
|
|
127
127
|
k, v = '', attr
|
|
128
128
|
|
|
@@ -539,7 +539,7 @@ class AddressNode(object):
|
|
|
539
539
|
notes = []
|
|
540
540
|
for attr in re.split(r'(?<!\\)/', self.note):
|
|
541
541
|
try:
|
|
542
|
-
k, v = re.split(r'(?<!\\):', attr, 1)
|
|
542
|
+
k, v = re.split(r'(?<!\\):', attr, maxsplit=1)
|
|
543
543
|
except ValueError:
|
|
544
544
|
k, v = '', attr
|
|
545
545
|
|
|
@@ -356,10 +356,25 @@ class Index(object):
|
|
|
356
356
|
index.Rtree
|
|
357
357
|
Created rtree index.
|
|
358
358
|
"""
|
|
359
|
-
import time
|
|
360
359
|
file_idx = index.Rtree(str(treepath)) # Filename must be passed as str
|
|
361
360
|
node_table: AddressNodeTable = self._tree.address_nodes
|
|
362
361
|
|
|
362
|
+
def _insert_node_to_rtree(
|
|
363
|
+
id: int,
|
|
364
|
+
coordinates: Tuple[float, float, float, float],
|
|
365
|
+
) -> None:
|
|
366
|
+
file_idx.insert(
|
|
367
|
+
id=id,
|
|
368
|
+
coordinates=coordinates,
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
def _get_limit_bdr(cx: float, cy: float, radius: float) -> Tuple[float, float, float, float]:
|
|
372
|
+
# cx, cy を中心とし、半径 radius (m)の円を内包する BDR の (x0, y0, x1, y1) を返す
|
|
373
|
+
import math
|
|
374
|
+
delta_lat = radius / 111320.0
|
|
375
|
+
delta_lon = radius / (111320.0 * math.cos(math.radians(cy)))
|
|
376
|
+
return (cx - delta_lon, cy - delta_lat, cx + delta_lon, cy + delta_lat)
|
|
377
|
+
|
|
363
378
|
max_id = AddressNode.ROOT_NODE_ID + node_table.count_records()
|
|
364
379
|
registered_coordinates = set()
|
|
365
380
|
|
|
@@ -367,47 +382,49 @@ class Index(object):
|
|
|
367
382
|
id = AddressNode.ROOT_NODE_ID
|
|
368
383
|
with tqdm(total=max_id, mininterval=0.5, ascii=True) as pbar:
|
|
369
384
|
mode = ""
|
|
385
|
+
bdr = None
|
|
386
|
+
first_block_node = None
|
|
387
|
+
parent_node = None
|
|
370
388
|
sibling_id = AddressNode.ROOT_NODE_ID
|
|
371
389
|
for node in node_table.get_nodes_by_id(
|
|
372
390
|
AddressNode.ROOT_NODE_ID, max_id):
|
|
373
391
|
id = node.id
|
|
374
392
|
pbar.update(1)
|
|
375
393
|
|
|
376
|
-
if mode == "block":
|
|
394
|
+
if mode == "block" and parent_node is not None:
|
|
377
395
|
if id < sibling_id:
|
|
378
396
|
if node.has_valid_coordinate_values():
|
|
379
|
-
if bdr is None:
|
|
397
|
+
if bdr is None or first_block_node is None:
|
|
380
398
|
bdr = (node.x, node.y, node.x, node.y)
|
|
399
|
+
first_block_node = node
|
|
400
|
+
bdr_limit = _get_limit_bdr(
|
|
401
|
+
node.x, node.y, 500.0)
|
|
381
402
|
else:
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
403
|
+
if node.x < bdr_limit[0] or node.y < bdr_limit[1] \
|
|
404
|
+
or node.x > bdr_limit[2] or node.y > bdr_limit[3]:
|
|
405
|
+
# The node is too far from the first node.
|
|
406
|
+
pass
|
|
407
|
+
else:
|
|
408
|
+
bdr = (
|
|
409
|
+
min(node.x, bdr[0]),
|
|
410
|
+
min(node.y, bdr[1]),
|
|
411
|
+
max(node.x, bdr[2]),
|
|
412
|
+
max(node.y, bdr[3]),
|
|
413
|
+
)
|
|
388
414
|
|
|
389
415
|
if id == sibling_id - 1:
|
|
390
416
|
mode = ""
|
|
391
417
|
if bdr:
|
|
392
|
-
|
|
418
|
+
_insert_node_to_rtree(
|
|
393
419
|
id=parent_node.id,
|
|
394
420
|
coordinates=bdr,
|
|
395
421
|
)
|
|
396
|
-
else:
|
|
397
|
-
# All child nodes have invalid coordinate values
|
|
398
|
-
key = (parent_node.x, parent_node.y)
|
|
399
|
-
if parent_node.has_valid_coordinate_values() and \
|
|
400
|
-
key not in registered_coordinates:
|
|
401
|
-
file_idx.insert(
|
|
402
|
-
id=parent_node.id,
|
|
403
|
-
coordinates=(node.x, node.y,
|
|
404
|
-
node.x, node.y),
|
|
405
|
-
)
|
|
406
|
-
registered_coordinates.add(key)
|
|
407
422
|
|
|
408
423
|
if id >= sibling_id:
|
|
409
|
-
|
|
410
|
-
|
|
424
|
+
raise RTreeError((
|
|
425
|
+
f"データファイルが異常です。"
|
|
426
|
+
f"The child node ({id}) of the parent_node ({parent_node.id}) "
|
|
427
|
+
f"exceeded the sibling_id:{sibling_id}."))
|
|
411
428
|
|
|
412
429
|
continue
|
|
413
430
|
|
|
@@ -425,7 +442,7 @@ class Index(object):
|
|
|
425
442
|
if key in registered_coordinates:
|
|
426
443
|
continue
|
|
427
444
|
|
|
428
|
-
|
|
445
|
+
_insert_node_to_rtree(
|
|
429
446
|
id=id,
|
|
430
447
|
coordinates=(node.x, node.y, node.x, node.y),
|
|
431
448
|
)
|
|
@@ -441,8 +458,11 @@ class Index(object):
|
|
|
441
458
|
|
|
442
459
|
if node.has_valid_coordinate_values():
|
|
443
460
|
bdr = (node.x, node.y, node.x, node.y)
|
|
461
|
+
first_block_node = node
|
|
462
|
+
bdr_limit = _get_limit_bdr(node.x, node.y, 500.0)
|
|
444
463
|
else:
|
|
445
464
|
bdr = None
|
|
465
|
+
first_block_node = None
|
|
446
466
|
|
|
447
467
|
continue
|
|
448
468
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "jageocoder"
|
|
3
|
-
version = "2.2.
|
|
3
|
+
version = "2.2.1"
|
|
4
4
|
description = "A Japanese-address geocoder for Python."
|
|
5
5
|
authors = [{name = "Takeshi Sagara", email = "sagara@info-proto.com"}]
|
|
6
6
|
readme = "README.md"
|
|
@@ -28,7 +28,10 @@ dependencies = [
|
|
|
28
28
|
|
|
29
29
|
[project.optional-dependencies]
|
|
30
30
|
dev = [
|
|
31
|
-
"
|
|
31
|
+
"flake8",
|
|
32
|
+
"twine >=5.1.1",
|
|
33
|
+
"tox >=4.0.0",
|
|
34
|
+
"tox-uv"
|
|
32
35
|
]
|
|
33
36
|
doc = [
|
|
34
37
|
"sphinx-rtd-theme >=1.2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|