diff --git a/.vscode/launch.json b/.vscode/launch.json index 0cf1e84..3c30fad 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "configurations": [ { "name": "Search noname oaza", - "type": "python", + "type": "debugpy", "request": "launch", "module": "jageocoder", "args": [ @@ -17,7 +17,7 @@ }, { "name": "Install dictionary", - "type": "python", + "type": "debugpy", "request": "launch", "module": "jageocoder", "args": [ @@ -28,7 +28,7 @@ }, { "name": "Search all results", - "type": "python", + "type": "debugpy", "request": "launch", "module": "jageocoder", "args": [ @@ -43,7 +43,7 @@ }, { "name": "Python: Reverse test", - "type": "python", + "type": "debugpy", "request": "launch", "module": "jageocoder", "args": [ @@ -57,7 +57,7 @@ }, { "name": "Python: Flask", - "type": "python", + "type": "debugpy", "request": "launch", "module": "flask", "env": { @@ -74,7 +74,7 @@ }, { "name": "Search moved address", - "type": "python", + "type": "debugpy", "request": "launch", "module": "jageocoder", "args": [ @@ -91,7 +91,7 @@ }, { "name": "Python: Current File", - "type": "python", + "type": "debugpy", "request": "launch", "program": "${file}", "console": "integratedTerminal", diff --git a/jageocoder/__init__.py b/jageocoder/__init__.py index d62cdad..2c38cc9 100644 --- a/jageocoder/__init__.py +++ b/jageocoder/__init__.py @@ -19,7 +19,7 @@ >>> jageocoder.searchNode('') """ -__version__ = '2.1.4' # The package version +__version__ = '2.1.5.post1' # The package version __dictionary_version__ = '20230927' # Compatible dictionary version __author__ = 'Takeshi Sagara ' @@ -41,7 +41,7 @@ 'version', 'dictionary_version', 'installed_dictionary_version', - 'instaleld_dictionary_readme', + 'installed_dictionary_readme', ] from jageocoder.module import init, free, is_initialized, \ diff --git a/jageocoder/module.py b/jageocoder/module.py index 0dfaff3..54c8634 100644 --- a/jageocoder/module.py +++ b/jageocoder/module.py @@ -397,9 +397,35 @@ def searchNode(query: str) -> List[Result]: return _tree.searchNode(query) -def reverse(x: float, y: float, level: Optional[int] = None) -> dict: +def reverse( + x: float, + y: float, + level: Optional[int] = None, + as_dict: Optional[bool] = True +) -> list: """ Reverse geocoding. + + Parameters + ---------- + x: float + Longitude of the point. + y: float + Latitude of the point. + level: int, optional + Target node level. + as_dict: bool, default=True + If True, returns candidates as dict objects. + + Returns + ------- + list + + Notes + ----- + - The result list contains up to 3 nodes. + - Each element is a dict type with the following structure: + {"candidate":AddressNode, "dist":float} """ if not is_initialized(): raise JageocoderError("Not initialized. Call 'init()' first.") @@ -407,7 +433,7 @@ def reverse(x: float, y: float, level: Optional[int] = None) -> dict: global _tree idx = Index(tree=_tree) - return idx.nearest(x=x, y=y, level=level) + return idx.nearest(x=x, y=y, level=level, as_dict=as_dict) def create_trie_index() -> None: diff --git a/jageocoder/node.py b/jageocoder/node.py index 8300f09..d5ad10f 100644 --- a/jageocoder/node.py +++ b/jageocoder/node.py @@ -201,6 +201,7 @@ def get_name(self, alt: Optional[str] = ''): def dataset(self): """ Get dataset record. + """ return self.table.datasets.get(id=self.priority) @@ -395,6 +396,7 @@ def children(self) -> List[AddressNode]: ------- List[AddressNode] The list of the child nodes. + """ return self.get_children() diff --git a/jageocoder/result.py b/jageocoder/result.py index 327e33c..de3029a 100644 --- a/jageocoder/result.py +++ b/jageocoder/result.py @@ -24,16 +24,22 @@ class Result(object): It is used only for recursive search. """ - def __init__(self, - node: Optional[AddressNode] = None, - matched: str = '', - nchars: int = 0): + def __init__( + self, + node: Optional[AddressNode] = None, + matched: str = '', + nchars: int = 0 + ): self.node = node self.matched = matched self.nchars = nchars - def set(self, node: AddressNode, - matched: str, nchars: int = 0) -> 'Result': + def set( + self, + node: AddressNode, + matched: str, + nchars: int = 0 + ) -> 'Result': """ Set node and matched string. """ @@ -65,9 +71,20 @@ def get_matched_string(self) -> str: return self.matched def get_matched_nchars(self) -> int: + """ + Get the the number of matched characters. + + Return + ------ + int + Number of characters in the matched substring. + """ return self.nchars - def __getitem__(self, pos) -> Union[AddressNode, str]: + def __getitem__( + self, + pos + ) -> Union[AddressNode, str]: if pos == 0: return self.node elif pos == 1: @@ -77,7 +94,11 @@ def __getitem__(self, pos) -> Union[AddressNode, str]: raise IndexError() - def __setitem__(self, pos, val: Union[AddressNode, str]) -> None: + def __setitem__( + self, + pos, + val: Union[AddressNode, str] + ) -> None: from jageocoder.node import AddressNode if pos == 0 and isinstance(val, AddressNode): self.node = val @@ -89,13 +110,41 @@ def __setitem__(self, pos, val: Union[AddressNode, str]) -> None: raise RuntimeError() def as_dict(self) -> dict: + """ + Convert Result object to dict type for display. + + Return + ------ + dict + A dict object containing the following elements; + + "node" + AddressNode object converted to dict type. + + "matched" + The substring matching the query. + """ return { "node": self.node.as_dict(), "matched": self.matched, - # "nchars": self.nchars } def as_geojson(self) -> dict: + """ + Convert Result to GeoJSON dict type for display. + + Return + ------ + dict + A GeoJSON dict object containing the following elements; + + "type" + Always "Feature". + "geometry" + A point type geometry containing latitude and longitude. + "properties" + Include in "matched" the substring that matched the query, in addition to the attributes of the node. + """ geojson = self.node.as_geojson() geojson['properties']['matched'] = self.matched return geojson diff --git a/jageocoder/rtree.py b/jageocoder/rtree.py index ce27137..6112b49 100644 --- a/jageocoder/rtree.py +++ b/jageocoder/rtree.py @@ -408,7 +408,8 @@ def nearest( self, x: float, y: float, - level: Optional[int] = None + level: Optional[int] = None, + as_dict: Optional[bool] = True, ): """ Search nearest nodes of the target point. @@ -422,10 +423,13 @@ def nearest( level: int, optional The level of the address ndoes to be retrieved as a result. If omitted, search down to the AZA level. + as_dict: bool, default=True + If False is specified, the addressNode object is stored + in the "candidate" field. Returns ------- - [{"candidate":AddressNode, "dist":float}] + [{"candidate":AddressNode or dict, "dist":float}] Returns the results of retrieval up to 3 nodes. """ level = level or AddressLevel.AZA @@ -497,7 +501,7 @@ def nearest( continue results.append({ - "candidate": node.as_dict(), + "candidate": node.as_dict() if as_dict else node, "dist": self.distance(x, y, node.x, node.y) }) registered.add(node.id) diff --git a/poetry.lock b/poetry.lock index 3e41a35..f96620a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1419,4 +1419,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "01dbea0d658b310c685f5ea3cb519803524631219793e4976b51863f9ef3a2cd" +content-hash = "e650a9156cd91fce448cc5d3cedafd0f57c463991885daab52d725da8cfcc0e3" diff --git a/pyproject.toml b/pyproject.toml index bda933d..d69c142 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jageocoder" -version = "2.1.4" +version = "2.1.5.post1" description = "A Japanese-address geocoder for Python." authors = ["Takeshi Sagara "] repository = "https://github.com/t-sagara/jageocoder/" @@ -28,7 +28,7 @@ docopt = "^0.6.2" geographiclib = "^2.0" idna = ">=3.7" jaconv = "^0.3.4" -marisa-trie = "^0.7.8" +marisa-trie = ">=0.7.8" pycapnp = "*" portabletab = ">=0.3.3" rtree = "^1.0.0"