Skip to content

Commit

Permalink
PolygonField and spatial near queries removed.
Browse files Browse the repository at this point in the history
  • Loading branch information
coady committed Nov 8, 2017
1 parent 96e886d commit ff08799
Show file tree
Hide file tree
Showing 4 changed files with 3 additions and 50 deletions.
8 changes: 1 addition & 7 deletions docs/engine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ engine
* `IndexSearcher`_, `MultiSearcher`_, `IndexWriter`_, `Indexer`_
* `Document`_, `Field`_, `NestedField`_, `NumericField`_, `DateTimeField`_
* `Query`_
* `PointField`_, `PolygonField`_
* `PointField`_


analyzers
Expand Down Expand Up @@ -239,9 +239,3 @@ PointField
.. autoclass:: PointField
:show-inheritance:
:members:

PolygonField
^^^^^^^^^^^^^
.. autoclass:: PolygonField
:show-inheritance:
:members:
2 changes: 1 addition & 1 deletion lupyne/engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .queries import Query
from .documents import Document, Field, NestedField, NumericField, DateTimeField
from .indexers import IndexSearcher, MultiSearcher, IndexWriter, Indexer
from .spatial import PointField, PolygonField
from .spatial import PointField

version = tuple(map(int, lucene.VERSION.split('.')))
assert version >= (6,), version
31 changes: 0 additions & 31 deletions lupyne/engine/spatial.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,6 @@ def distance(self, point):
"""Return euclidean distance between tile and point in meters."""
return sum(max(0, l - m, m - u) ** 2 for m, l, u in zip(point, *self.points)) ** 0.5

def walk(self, other):
"""Generate all tiles between corners."""
assert len(self) == len(other)
(left, right), (bottom, top) = map(sorted, zip(self.coords, other.coords))
for x, y in itertools.product(range(left, right + 1), range(bottom, top + 1)):
yield type(self)(x, y, len(self))


class PointField(NumericField):
"""Geospatial points, which create a tiered index of tiles.
Expand Down Expand Up @@ -123,14 +116,6 @@ def ranges(self, tiles):
stop = tile + step
yield self.range(start, stop)

def prefix(self, tile):
"""Return range query which is equivalent to the prefix of the tile."""
return next(self.ranges([tile]))

def near(self, lng, lat, precision=None):
"""Return prefix query for point at given precision."""
return self.prefix(self.tile(lng, lat)[:precision])

def within(self, lng, lat, distance, limit=4):
"""Return range queries for any tiles which could be within distance of given point.
Expand All @@ -143,22 +128,6 @@ def within(self, lng, lat, distance, limit=4):
return Query.any(*self.ranges(tiles))


class PolygonField(PointField):
"""PointField which implicitly supports polygons (technically linear rings of points).
Differs from points in that all necessary tiles are included to match the points' boundary.
As with PointField, the tiered tiles are a search optimization, not a distance calculator.
"""
def items(self, *polygons):
"""Generate all covered tiles from polygons."""
tiles = set()
for points in polygons:
lngs, lats = zip(*points)
lower, upper = self.tile(min(lngs), min(lats)), self.tile(max(lngs), max(lats))
tiles.update(lower.walk(upper))
return NumericField.items(self, *map(int, tiles))


class Distances(object):
def __init__(self, lng, lat, lngs, lats):
self.point = Point(lng, lat)
Expand Down
12 changes: 1 addition & 11 deletions tests/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,28 +385,18 @@ def test_spatial(indexer, zipcodes):
for name in ('longitude', 'latitude'):
indexer.set(name, engine.NumericField, stored=True, docValuesType='numeric')
field = indexer.set('tile', engine.PointField, precision=15, stored=True)
points = []
for doc in zipcodes:
if doc['state'] == 'CA':
point = doc['longitude'], doc['latitude']
indexer.add(doc, tile=[point])
if doc['city'] == 'Los Angeles':
points.append(point)
assert len(list(engine.PolygonField('', precision=15).items(points))) > len(points)
indexer.commit()
city, zipcode, tile = 'Beverly Hills', '90210', '023012311120332'
hit, = indexer.search('zipcode:' + zipcode)
assert hit['tile'] == int(tile, 4) and hit['city'] == city
hit, = indexer.search(field.prefix(tile))
hit, = indexer.search(*field.ranges([tile]))
assert hit['zipcode'] == zipcode and hit['city'] == city
x, y = (float(hit[l]) for l in ['longitude', 'latitude'])
assert engine.spatial.Tile(2, 9, 4) == tile[:4]
hits = indexer.search(field.near(x, y))
cities = {hit['city'] for hit in hits}
assert {city} == cities
hits = indexer.search(field.near(x, y, precision=10))
cities = {hit['city'] for hit in hits}
assert city in cities and len(cities) > 10
query = field.within(x, y, 10 ** 4)
assert len(list(query)) == 3
distances = indexer.distances(x, y, 'longitude', 'latitude')
Expand Down

0 comments on commit ff08799

Please sign in to comment.