Skip to content

Commit

Permalink
cropping geojson (features) (#23)
Browse files Browse the repository at this point in the history
* update manylinux

* update

* update headers

* init cropping

* not ready

* bbox filtering

* crop geojson

* nice

* update headers

* add crop

* not ready

* export bbox

* update version

---------

Co-authored-by: TANG ZHIXIONG <[email protected]>
  • Loading branch information
district10 and zhixiong-tang authored Jul 2, 2023
1 parent ed0fd3e commit 9205a44
Show file tree
Hide file tree
Showing 9 changed files with 466 additions and 12 deletions.
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ docs_serve:
mkdocs serve -a 0.0.0.0:8088

DOCKER_TAG_WINDOWS ?= ghcr.io/cubao/build-env-windows-x64:v0.0.1
DOCKER_TAG_LINUX ?= ghcr.io/cubao/build-env-manylinux2014-x64:v0.0.1
DOCKER_TAG_LINUX ?= ghcr.io/cubao/build-env-manylinux2014-x64:v0.0.4
DOCKER_TAG_MACOS ?= ghcr.io/cubao/build-env-macos-arm64:v0.0.1

test_in_win:
Expand All @@ -95,6 +95,15 @@ test_in_mac:
test_in_linux:
docker run --rm -w `pwd` -v `pwd`:`pwd` -v `pwd`/build/linux:`pwd`/build -it $(DOCKER_TAG_LINUX) bash

DEV_CONTAINER_NAME ?= $(USER)_$(subst /,_,$(PROJECT_NAME)____$(PROJECT_SOURCE_DIR))
DEV_CONTAINER_IMAG ?= $(DOCKER_TAG_LINUX)
test_in_dev_container:
docker ps | grep $(DEV_CONTAINER_NAME) \
&& docker exec -it $(DEV_CONTAINER_NAME) bash \
|| docker run --rm --name $(DEV_CONTAINER_NAME) \
--network host --security-opt seccomp=unconfined \
-v `pwd`:`pwd` -w `pwd` -it $(DEV_CONTAINER_IMAG) bash

PYTHON ?= python3
python_install:
$(PYTHON) setup.py install --force
Expand Down Expand Up @@ -155,7 +164,7 @@ python_build_py310:
PYTHON=python conda run --no-capture-output -n py310 make python_build
python_build_all: python_build_py36 python_build_py37 python_build_py38 python_build_py39 python_build_py310
python_build_all_in_linux:
docker run --rm -w `pwd` -v `pwd`:`pwd` -v `pwd`/build/win:`pwd`/build -it $(DOCKER_TAG_LINUX) make python_build_all
docker run --rm -w `pwd` -v `pwd`:`pwd` -v `pwd`/build/linux:`pwd`/build -it $(DOCKER_TAG_LINUX) make python_build_all
make repair_wheels && rm -rf dist/*.whl && mv wheelhouse/*.whl dist && rm -rf wheelhouse
python_build_all_in_macos: python_build_py38 python_build_py39 python_build_py310
python_build_all_in_windows: python_build_all
Expand Down
4 changes: 4 additions & 0 deletions docs/about/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ To upgrade `pybind11-geobuf` to the latest version, use pip:
pip install -U pybind11-geobuf
```

## Version 0.1.6 (2023-07-02)

* Crop geojson features by polygon (alpha release)

## Version 0.1.5 (2023-06-02)

* Add `round_non_geojson` to `normalize_json`
Expand Down
2 changes: 1 addition & 1 deletion headers
Submodule headers updated 75 files
+6 −0 README.md
+5 −0 include/README.md
+13 −7 include/cubao/cheap_ruler.hpp
+6 −0 include/cubao/crs_transform.hpp
+6 −0 include/cubao/densify_polyline.hpp
+367 −30 include/cubao/fast_crossing.hpp
+26 −22 include/cubao/flatbush.h
+312 −0 include/cubao/kd_quiver.hpp
+199 −0 include/cubao/nanoflann_kdtree.hpp
+85 −0 include/cubao/polyline_in_polygon.hpp
+68 −24 include/cubao/polyline_ruler.hpp
+79 −0 include/cubao/pybind11_cheap_ruler.hpp
+84 −2 include/cubao/pybind11_fast_crossing.hpp
+3 −2 include/cubao/pybind11_flatbush.hpp
+73 −0 include/cubao/pybind11_nanoflann_kdtree.hpp
+1 −1 include/cubao/pybind11_polyline_ruler.hpp
+283 −0 include/cubao/pybind11_quiver.hpp
+433 −0 include/cubao/quiver.hpp
+112 −0 include/jni/advanced_ownership.hpp
+147 −0 include/jni/array.hpp
+41 −0 include/jni/arraylike.hpp
+159 −0 include/jni/boxing.hpp
+137 −0 include/jni/class.hpp
+15 −0 include/jni/constructor.hpp
+125 −0 include/jni/errors.hpp
+27 −0 include/jni/field.hpp
+684 −0 include/jni/functions.hpp
+26 −0 include/jni/jni.hpp
+12 −0 include/jni/make.hpp
+31 −0 include/jni/method.hpp
+381 −0 include/jni/native_method.hpp
+24 −0 include/jni/npe.hpp
+153 −0 include/jni/object.hpp
+225 −0 include/jni/ownership.hpp
+27 −0 include/jni/static_field.hpp
+31 −0 include/jni/static_method.hpp
+35 −0 include/jni/string.hpp
+21 −0 include/jni/string_conversion.hpp
+131 −0 include/jni/tagging.hpp
+34 −0 include/jni/traits.hpp
+89 −0 include/jni/type_signature.hpp
+147 −0 include/jni/typed_methods.hpp
+97 −0 include/jni/types.hpp
+220 −0 include/jni/unique.hpp
+40 −0 include/jni/weak_reference.hpp
+152 −0 include/jni/wrapping.hpp
+220 −0 include/kdbush.hpp
+396 −0 include/mapbox/geometry/wagyu/active_bound_list.hpp
+277 −0 include/mapbox/geometry/wagyu/almost_equal.hpp
+99 −0 include/mapbox/geometry/wagyu/bound.hpp
+28 −0 include/mapbox/geometry/wagyu/bubble_sort.hpp
+183 −0 include/mapbox/geometry/wagyu/build_edges.hpp
+26 −0 include/mapbox/geometry/wagyu/build_local_minima_list.hpp
+68 −0 include/mapbox/geometry/wagyu/build_result.hpp
+50 −0 include/mapbox/geometry/wagyu/config.hpp
+120 −0 include/mapbox/geometry/wagyu/edge.hpp
+50 −0 include/mapbox/geometry/wagyu/interrupt.hpp
+70 −0 include/mapbox/geometry/wagyu/intersect.hpp
+365 −0 include/mapbox/geometry/wagyu/intersect_util.hpp
+117 −0 include/mapbox/geometry/wagyu/local_minimum.hpp
+314 −0 include/mapbox/geometry/wagyu/local_minimum_util.hpp
+110 −0 include/mapbox/geometry/wagyu/point.hpp
+256 −0 include/mapbox/geometry/wagyu/process_horizontal.hpp
+123 −0 include/mapbox/geometry/wagyu/process_maxima.hpp
+139 −0 include/mapbox/geometry/wagyu/quick_clip.hpp
+633 −0 include/mapbox/geometry/wagyu/ring.hpp
+836 −0 include/mapbox/geometry/wagyu/ring_util.hpp
+45 −0 include/mapbox/geometry/wagyu/scanbeam.hpp
+191 −0 include/mapbox/geometry/wagyu/snap_rounding.hpp
+1,347 −0 include/mapbox/geometry/wagyu/topology_correction.hpp
+98 −0 include/mapbox/geometry/wagyu/util.hpp
+64 −0 include/mapbox/geometry/wagyu/vatti.hpp
+145 −0 include/mapbox/geometry/wagyu/wagyu.hpp
+178 −0 include/mapbox/polylabel.hpp
+446 −0 include/mapbox/supercluster.hpp
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ site_description: A compact binary encoding for geographic data, with python bin
site_author: district10

repo_url: https://github.com/cubao/pybind11-geobuf
edit_uri: blob/master/docs/
edit_uri: blob/dev/docs/

theme: readthedocs
nav:
Expand Down
135 changes: 135 additions & 0 deletions pybind11_geobuf/crop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import os
from typing import List, Optional, Tuple, Union # noqa

import numpy as np
from _pybind11_geobuf import geojson, tf
from loguru import logger


def bbox2polygon(bbox: np.ndarray):
lon0, lat0, lon1, lat1 = bbox
return np.array(
[
[lon0, lat0, 0.0],
[lon1, lat0, 0.0],
[lon1, lat1, 0.0],
[lon0, lat1, 0.0],
[lon0, lat0, 0.0],
]
)


def crop_by_feature_id(
input_path: str,
output_path: str,
*,
feature_id: str,
buffer: Union[float, Tuple[float, float]] = 100.0,
clipping_mode: str = "longest",
max_z_offset: float = None,
) -> bool:
if not feature_id:
logger.info(
f"invalid feature id: {feature_id} (type: {type(feature_id)})"
) # noqa
return False
g = geojson.GeoJSON().load(input_path)
if not g.is_feature_collection():
logger.warning(f"{input_path} is not valid GeoJSON FeatureCollection")
return False

fc = g.as_feature_collection()
bbox = None
height = None
for f in fc:
props = f.properties()
if "id" not in props:
continue
fid = props["id"]()
if fid == feature_id:
bbox = f.bbox()
if max_z_offset is not None:
height = f.bbox(with_z=True)[2::3].mean()
if bbox is None:
logger.error(f"not any feature matched by id: {feature_id}")
return False

dlon, dlat = 1.0 / tf.cheap_ruler_k(bbox[1::2].mean())[:2]
if isinstance(buffer, (int, float, np.generic)):
dlon *= buffer
dlat *= buffer
else:
dlon *= buffer[0]
dlat *= buffer[1]
bbox += [-dlon, -dlat, dlon, dlat]
logger.info(f"bbox: {bbox}")

polygon = bbox2polygon(bbox)
if height is not None:
polygon[:, 2] = height
logger.info(f"polygon:\n{polygon}")

logger.info(f"writing to {output_path} ...")
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
cropped = g.crop(
polygon,
clipping_mode=clipping_mode,
max_z_offset=max_z_offset,
)
return cropped.to_rapidjson().sort_keys().dump(output_path, indent=True)


def crop_by_grid(
input_path: str,
output_dir: str,
*,
anchor_lla: Union[str, List[float]] = None,
grid_size: Union[float, Tuple[float, float]] = 1000.0,
):
os.makedirs(os.path.abspath(output_dir), exist_ok=True)


def crop_by_center(
input_path: str,
output_dir: str,
*,
anchor_lla: Union[str, List[float]] = None,
size: Union[float, Tuple[float, float]] = 1000.0,
):
os.makedirs(os.path.abspath(output_dir), exist_ok=True)


def crop_by_bbox(
input_path: str,
output_path: str,
*,
bbox: Union[str, List[float]],
z_center: float = None,
z_max_offset: float = None,
):
logger.info(f"wrote to {output_path}")


def crop_by_polygon(
input_path: str,
output_path: str,
*,
polygon: Union[str, np.ndarray],
z_max_offset: float = None,
):
pass


if __name__ == "__main__":
import fire

fire.core.Display = lambda lines, out: print(*lines, file=out)
fire.Fire(
{
"by_feature_id": crop_by_feature_id,
"by_grid": crop_by_grid,
"by_center": crop_by_center,
"by_bbox": crop_by_bbox,
"by_polygon": crop_by_polygon,
}
)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def build_extension(self, ext):
# logic and declaration, and simpler if you include description/version in a file.
setup(
name="pybind11_geobuf",
version="0.1.5",
version="0.1.6",
author="tzx",
author_email="[email protected]",
url="https://geobuf-cpp.readthedocs.io",
Expand Down
Loading

0 comments on commit 9205a44

Please sign in to comment.