diff --git a/mongiris/mongiris.py b/mongiris/mongiris.py index 3d2eed17953dbb1e55eaaeff98cc6b6e5a718aa5..256ae5fc0fadad82bfcce7e242d0576cf3917518 100755 --- a/mongiris/mongiris.py +++ b/mongiris/mongiris.py @@ -144,12 +144,11 @@ class Mongiris: Find all documents from given collection and which contain totally the given geometry Cannot be used to find the IRIS containing a point (geometry must be a polygon) :param collection: the collection to search in - :param geometry: a geojson geometry ("Polygon" or "MultiPolygon", NO "Point") + :param geometry: a geojson geometry ("Polygon", "$box" or "MultiPolygon", NO "Point") :param json_projection: a json document indicating the fields that appear in the results :return: a cursor (set of documents) """ - cursor = self.find_documents(collection, {"geometry": {"$geoWithin": { - "$geometry": geometry}}}, json_projection) + cursor = self.find_documents(collection, {"geometry": {"$geoWithin": {"$geometry": geometry}}}, json_projection) doc_json = Mongiris.bson_to_json(cursor) return doc_json @@ -188,6 +187,32 @@ class Mongiris: """ return {"type": "Point", "coordinates": coordinates} + @staticmethod + def convert_geojson_box_to_polygon(lng1, lat1, lng2, lat2): + """ + Builds a dictionary with GeoJSON syntax for a polygon using two coordinates (points south-west and north-east). + This method builds the polygon by adding 2 missing points (north-west and south-east) and adds the starting + point (south-west) to end the loop. + The MongoDB $box operator is not supported with 2d-spherical indexes. + :param lng1 longitude of the first point (south-west) of the box + :param lat1 latitude of the first point (south-west) of the box + :param lng2 longitude of the second point (north-east) of the box + :param lat2 latitude of the second point (north-east) of the box + :return: a dictionary with GeoJSON syntax for a Box + """ + coordinates = [[[lng1, lat1], [lng1, lat2], [lng2, lat2], [lng2, lat1], [lng1, lat1]]] + return Mongiris.get_geojson_polygon(coordinates) + + @staticmethod + def get_geojson_polygon(coordinates): + """ + Builds a dictionary with GeoJSON syntax for a polygon using the given coordinates. + CAREFUL: polygons must be closed ! (first coordinate must be identical to last coordinate) + :param coordinates: the coordinates (long, lat) as a list of list, e.g. [[[4.8, 45.7], [4.9, 47.8]]] + :return: a dictionary with GeoJSON syntax for a Polygon + """ + return {"type": "Polygon", "coordinates": coordinates} + def point_in_which_iris(self, coordinates, json_projection=None): """ Find the document (IRIS) containing the given coordinates. Uses near() since geo_within() requires a Polygon. diff --git a/mongiris/tests/mongoiris_tests.py b/mongiris/tests/mongoiris_tests.py index eec059d7b66b068381b98f17082771a6e0576b33..d977588e8815b18eacd9c4886a35ac76b985154e 100644 --- a/mongiris/tests/mongoiris_tests.py +++ b/mongiris/tests/mongoiris_tests.py @@ -28,6 +28,18 @@ class TestCase(unittest.TestCase): assert(iris is not None), 'Function find_one_document(..., "593500203") should return one document, not None' self.db.logger.info(iris) + def test_op_geo_within(self): + self.db.logger.info("Finding all IRIS in area [[2.3530807599035124, 50.865983520113346], [2.607984899697411, 50.98885556985259]]") + long1 = 2.3530807599035124 + lat1 = 50.865983520113346 + long2 = 2.607984899697411 + lat2 = 50.98885556985259 + polygon = self.db.convert_geojson_box_to_polygon(long1, lat1, long2, lat2) + cursor = self.db.geo_within(self.db.iris_collection, polygon) + for doc in cursor: + self.db.logger.info(str(doc["_id"]) + "\t" + doc["properties"]["NOM_IRIS"] + "\t" + doc["properties"]["CODE_IRIS"]) + assert(len(cursor) == 12), "Method test_op_geo_within() should find 12 iris, not " + str(len(cursor)) + def test_op_near(self): random_iris = self.db.get_random_document(self.db.iris_collection) point_random_iris = random.choice(random_iris["geometry"]["coordinates"][0]) # get a random coordinate diff --git a/setup.cfg b/setup.cfg index 9b2985974d2a94a49c528aa9b71e5890e177cd5c..9190b662da8cbedd95b5db25c5a2fbf881687aa8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ [metadata] name = mongiris -version = 0.19 +version = 0.2 description = This package is an interface for querying INSEE IRIS stored as documents in MongoDB. Requires loading the IRIS files into MongoDB prior to using this package. author = Fabien Duchateau author_email = fabien.duchateau@univ-lyon1.fr diff --git a/setup.py b/setup.py index 39c246a98683a1830c9d3670c6b7c57e4ff60cf9..2e7943341f0b3c150836be8495c0ce96fccae143 100644 --- a/setup.py +++ b/setup.py @@ -1,20 +1,24 @@ +#!/usr/bin/env python +# mongiris setup.py (uses setup.cfg) + # python3 -m setup bdist_wheel sdist # python3 -m pip install -e mongiris/ # python3 -m pip install git+https://fduchate@gitlab.liris.cnrs.fr/fduchate/mongiris.git#egg=mongiris -#!/usr/bin/env python -# mongiris setup.py (uses setup.cfg) -import os -import sys from setuptools import setup +import shutil + + +def delete_dir(directories): # delete directories (ignore errors such as read-only files) + for directory in directories: + shutil.rmtree(directory, ignore_errors=True) + -if sys.argv[-1] == "publish": - os.system("python setup.py bdist_wheel upload --sign") - sys.exit() +# delete build/config directories because egg-info only updates config files for new versions +delete_dir(['./mongiris.egg-info/', './build/', './dist/']) readme = open("README.md").read() -#history = open("HISTORY.rst").read().replace(".. :changelog:", "") setup(long_description=readme) # + "\n\n" + history)