Skip to content

Commit 2fbb6e8

Browse files
authored
fix windows build; add cli interface (#8)
* test on Windows * add url * fix username hostname * fix * fix * use dummy version_h * fix windows build * fix CI * windows * add cli interface * add cli interface * normalize with precision * fix * rename geojson to json * normalize geobuf * fix * fix
1 parent 21b30a5 commit 2fbb6e8

File tree

14 files changed

+196
-25
lines changed

14 files changed

+196
-25
lines changed

.github/workflows/wheels.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
strategy:
3737
fail-fast: false
3838
matrix:
39-
os: [ubuntu-latest, macos-latest]
39+
os: [ubuntu-latest, windows-latest, macos-latest]
4040

4141
steps:
4242
- uses: actions/checkout@v3
@@ -57,7 +57,7 @@ jobs:
5757
CIBW_ARCHS_MACOS: x86_64 arm64
5858
CIBW_BEFORE_BUILD: pip install numpy fire --prefer-binary
5959
# https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip
60-
CIBW_SKIP: pp* *i686 *musllinux* *win*
60+
CIBW_SKIP: pp* *i686 *musllinux*
6161
CIBW_TEST_SKIP: "*macosx* *win* *aarch64"
6262

6363
- name: Verify clean directory

.pre-commit-config.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ repos:
3232
- id: mixed-line-ending
3333
- id: requirements-txt-fixer
3434
- id: trailing-whitespace
35-
- id: end-of-file-fixer
3635

3736
# Black, the code formatter, natively supports pre-commit
3837
- repo: https://github.com/psf/black

CMakeLists.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ include(${CUBAO_INCLUDE}/utils.cmake)
88
activate_common_configuration()
99
auto_build_type_and_compile_flags()
1010
configure_output_directories()
11+
12+
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
13+
set(CUBAO_USE_DUMMY_VERSION_H "True")
14+
endif()
1115
configure_version_h()
1216

1317
# MISC
@@ -83,9 +87,9 @@ add_custom_target(test_all COMMAND make -C .. test_all)
8387
set(PYBIND11_CPP_STANDARD -std=c++17)
8488
add_subdirectory(pybind11)
8589
pybind11_add_module(
86-
pybind11_geobuf
90+
_pybind11_geobuf
8791
src/main.cpp
8892
src/pybind11_rapidjson.cpp
8993
src/pybind11_geojson.cpp)
90-
target_link_libraries(pybind11_geobuf PRIVATE ${PROJECT_NAME})
91-
target_compile_definitions(pybind11_geobuf PRIVATE VERSION_INFO=${PYBIND11_GEOBUF_VERSION_INFO})
94+
target_link_libraries(_pybind11_geobuf PRIVATE ${PROJECT_NAME})
95+
target_compile_definitions(_pybind11_geobuf PRIVATE VERSION_INFO=${PYBIND11_GEOBUF_VERSION_INFO})

Makefile

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
PROJECT_SOURCE_DIR ?= $(abspath ./)
2+
PROJECT_NAME ?= $(shell basename $(PROJECT_SOURCE_DIR))
23
BUILD_DIR ?= $(PROJECT_SOURCE_DIR)/build
34
INSTALL_DIR ?= $(BUILD_DIR)/install
45
NUM_JOB ?= 8
@@ -102,8 +103,16 @@ python_build:
102103
python_sdist:
103104
$(PYTHON) setup.py sdist
104105
# tar -tvf dist/geobuf-*.tar.gz
105-
python_test:
106-
# TODO
106+
python_test: pytest
107+
108+
cli_test:
109+
python3 -m pybind11_geobuf
110+
python3 -m pybind11_geobuf --help
111+
python3 -m pybind11_geobuf json2geobuf data/sample1.json build/sample1.pbf
112+
python3 -m pybind11_geobuf geobuf2json build/sample1.pbf build/sample1.json --indent=True --sort_keys=True
113+
python3 -m pybind11_geobuf pbf_decode build/sample1.pbf build/sample1.pbf.txt
114+
python3 -m pybind11_geobuf normalize_json data/sample1.json build/sample1.normalized.json
115+
python3 -m pybind11_geobuf normalize_json data/sample1.json build/sample1.normalized.precision2.json --precision=2
107116

108117
# conda create -y -n py36 python=3.6
109118
# conda create -y -n py37 python=3.7
@@ -139,8 +148,8 @@ upload_wheels:
139148
twine upload dist/*.whl -r $(pypi_remote)
140149

141150
tar.gz:
142-
tar -cvz --exclude .git -f ../geobuf.tar.gz .
143-
ls -alh ../geobuf.tar.gz
151+
tar -cvz --exclude .git -f ../$(PROJECT_NAME).tar.gz .
152+
ls -alh ../$(PROJECT_NAME).tar.gz
144153

145154
# https://stackoverflow.com/a/25817631
146155
echo-% : ; @echo -n $($*)

docs/about/release-notes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ To upgrade `pybind11-geobuf` to the latest version, use pip:
1010
pip install -U pybind11-geobuf
1111
```
1212

13+
## Version 0.0.5 (2023-03-08)
14+
15+
* Add windows version
16+
* Add cli interface
17+
1318
## Version 0.0.4 (2023-03-04)
1419

1520
* Use GitHub workflow to release to pypi

docs/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
mkdocs>=1.3.0
2-
mkdocs-include-markdown-plugin
1+
mkdocs==1.4.2
2+
mkdocs-include-markdown-plugin==4.0.3

mkdocs.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
site_name: pybind11-geobuf
22
site_url: https://pybind11-geobuf.readthedocs.io
3-
site_description: A compact binary encoding for geographic data, with python binding.
3+
site_description: A compact binary encoding for geographic data, with python binding.
44
site_author: district10
55

66
repo_url: https://github.com/cubao/pybind11-geobuf
77
edit_uri: blob/master/docs/
88

99
theme: readthedocs
1010
nav:
11-
- Home: index.md
12-
- About:
13-
- Release Notes: about/release-notes.md
14-
- License: about/license.md
11+
- Home: index.md
12+
- About:
13+
- Release Notes: about/release-notes.md
14+
- License: about/license.md
1515

1616
plugins:
1717
- include-markdown
1818

19-
copyright: Copyright &copy; 2023 <a href="https://github.com/cubao">cubao team</a>.
19+
copyright: Copyright &copy; 2023 <a href="https://cubao.readthedocs.io">cubao team</a>.

pybind11_geobuf/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from _pybind11_geobuf import * # noqa
2+
from _pybind11_geobuf import __version__ # noqa

pybind11_geobuf/__main__.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import os
2+
3+
from loguru import logger
4+
5+
from pybind11_geobuf import rapidjson # noqa
6+
from pybind11_geobuf import Decoder, Encoder # noqa
7+
from pybind11_geobuf import normalize_json as normalize_json_impl # noqa
8+
from pybind11_geobuf import pbf_decode as pbf_decode_impl # noqa
9+
10+
11+
def __filesize(path: str) -> int:
12+
return os.stat(path).st_size
13+
14+
15+
def geobuf2json(
16+
input_path: str,
17+
output_path: str,
18+
*,
19+
indent: bool = False,
20+
sort_keys: bool = False,
21+
):
22+
logger.info(
23+
f"geobuf decoding {input_path} ({__filesize(input_path):,} bytes)..."
24+
) # noqa
25+
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
26+
decoder = Decoder()
27+
assert decoder.decode(
28+
geobuf=input_path,
29+
geojson=output_path,
30+
indent=indent,
31+
sort_keys=sort_keys,
32+
), f"failed at decoding geojson, input:{input_path}, output:{output_path}"
33+
logger.info(f"wrote to {output_path} ({__filesize(output_path):,} bytes)")
34+
35+
36+
def json2geobuf(
37+
input_path: str,
38+
output_path: str,
39+
*,
40+
precision: int = 8,
41+
):
42+
logger.info(
43+
f"geobuf encoding {input_path} ({__filesize(input_path):,} bytes)..."
44+
) # noqa
45+
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
46+
encoder = Encoder(max_precision=int(10**precision))
47+
assert encoder.encode(
48+
geojson=input_path,
49+
geobuf=output_path,
50+
), f"failed at encoding geojson, input:{input_path}, output:{output_path}"
51+
logger.info(f"wrote to {output_path} ({__filesize(output_path):,} bytes)")
52+
53+
54+
def normalize_geobuf(
55+
input_path: str,
56+
output_path: str = None,
57+
*,
58+
sort_keys: bool = True,
59+
precision: int = -1,
60+
):
61+
logger.info(
62+
f"normalize_geobuf {input_path} ({__filesize(input_path):,} bytes)"
63+
) # noqa
64+
with open(input_path, "rb") as f:
65+
encoded = f.read()
66+
decoder = Decoder()
67+
json = decoder.decode_to_rapidjson(encoded, sort_keys=sort_keys)
68+
if precision < 0:
69+
precision = decoder.precision()
70+
logger.info(f"auto precision from geobuf: {precision}")
71+
else:
72+
logger.info(f"user precision: {precision}")
73+
encoder = Encoder(max_precision=int(10**precision))
74+
encoded = encoder.encode(json)
75+
logger.info(f"encoded #bytes: {len(encoded):,}")
76+
output_path = output_path or input_path
77+
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
78+
with open(output_path, "wb") as f:
79+
f.write(encoded)
80+
logger.info(f"wrote to {output_path} ({__filesize(output_path):,} bytes)")
81+
82+
83+
def normalize_json(
84+
input_path: str,
85+
output_path: str = None,
86+
*,
87+
indent: bool = True,
88+
sort_keys: bool = True,
89+
precision: int = -1,
90+
):
91+
logger.info(
92+
f"normalize_json {input_path} ({__filesize(input_path):,} bytes)"
93+
) # noqa
94+
output_path = output_path or input_path
95+
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
96+
if precision > 0:
97+
logger.info(
98+
f"convert to geobuf (precision: {precision}), then back to geojson"
99+
) # noqa
100+
encoder = Encoder(max_precision=int(10**precision))
101+
geojson = rapidjson().load(input_path)
102+
assert geojson.IsObject(), f"invalid geojson: {input_path}"
103+
encoded = encoder.encode(geojson)
104+
logger.info(f"geobuf #bytes: {len(encoded):,}")
105+
decoder = Decoder()
106+
text = decoder.decode(encoded, indent=indent, sort_keys=sort_keys)
107+
logger.info(f"geojson #bytes: {len(text):,}")
108+
with open(output_path, "w", encoding="utf8") as f:
109+
f.write(text)
110+
else:
111+
assert normalize_json_impl(
112+
input_path,
113+
output_path,
114+
indent=indent,
115+
sort_keys=sort_keys,
116+
), f"failed to normalize json to {output_path}"
117+
logger.info(f"wrote to {output_path} ({__filesize(output_path):,} bytes)")
118+
119+
120+
def pbf_decode(path: str, output_path: str = None, *, indent: str = ""):
121+
with open(path, "rb") as f:
122+
data = f.read()
123+
decoded = pbf_decode_impl(data, indent=indent)
124+
if output_path:
125+
os.makedirs(
126+
os.path.dirname(os.path.abspath(output_path)), exist_ok=True
127+
) # noqa
128+
with open(output_path, "w", encoding="utf8") as f:
129+
f.write(decoded)
130+
logger.info(f"wrote to {output_path}")
131+
else:
132+
print(decoded)
133+
134+
135+
if __name__ == "__main__":
136+
import fire
137+
138+
fire.core.Display = lambda lines, out: print(*lines, file=out)
139+
fire.Fire(
140+
{
141+
"geobuf2json": geobuf2json,
142+
"json2geobuf": json2geobuf,
143+
"normalize_geobuf": normalize_geobuf,
144+
"normalize_json": normalize_json,
145+
"pbf_decode": pbf_decode,
146+
}
147+
)

0 commit comments

Comments
 (0)