Rend visualizes spatial data and offers plugins for operations like searching in circles, nearest k neighbors. Rend provides the cardinal which visualizes in the 2d space the points and the gui tools which provide the interface needed to change/configure spatial indexes and search them.
Along with rend there is a script generate.py
used for point generation.
The following command:
python generate.py points.dat 1000 -2000 2000
Creates 1000 random points ranging from -2000,-2000 to 2000,2000 and saves them in points.dat
.
Points also include a UUID which can be any kind of information the point represents.
Run the HTTP server like this:
python rend.py -p 8888 -i Rtree -d points.dat
Flag explanation:
- -p defines the port the app is running
- -i defines the index you are using. Options are [Quad-Tree, Rtree] without any external index.
- -d defines the data file you are using.
By visiting the http://127.0.0.1:8888/nearest/x=100/y=100/k=100
we get the following json response:
{'metrics': {'time': 0.0005013942718505859}, 'data': [(100, 93, '6babe218-7ad8-4072-9740-2bdb189ff30c'), ...]}
The url format is like this
/action_name/param1=value1/param2=value2/param3=value3
Where action name is the name of the index's method and the params are the names of the method's arguments.
Create a demo plugin inside the plugins folder demo.py
Then you need to create an index class with the following
methods: add_points
.
We create the PARAMETERS
class variable which is essential a dictionary.
- The
visual
value represents as a boolean if the data you have should be displayed using rend's cardinal. - The
elements
value tells the rend gui that this plugin needs two variables namedParam1
andParam2
and that they should be visualized through theLabelEditFloat
andLabelEditString
. - The
data
value is a bunch of placeholder values and that's where the user values are stored.
Components included are
- LabelEditFloat
- LabelEditString
- PointEdit
Let's say our class has two methods we want to expose to the user
intersection
and nearest
. From the ACTIONS
class variable we can do that.
We name each action and we define in the action
field the name of the method we are going to expose.
Like the PARAMETERS
class variable we create an elements
field and a data
field.
Notice that PointEdit
has its value separated by comma because we are defining multidimensional variables.
Also the elements are named after the method's parameters, in order to match them.
Example of our demo index should be like this.
class DemoIndex:
PARAMETERS = {
"visual": True,
"elements": {
"Param1": "LabelEditFloat",
"Param2": "LabelEditString"
},
"data": {
"Param1": 1000,
"Param2": "hey"
},
}
ACTIONS = {
"Point Intersection": {
"action": "intersection",
"elements": {
"x,y": "PointEdit",
"r": "LabelEditFloat"
},
"data": {}
},
"Nearest K": {
"action": "nearest",
"elements": {
"x,y": "PointEdit",
"k": "LabelEditFloat"
},
"data": {}
}
}
def add_points(self, points):
pass
def intersection(self, x, y, r):
return []
def nearest(self, x, y, k):
return []
Finally you have to load it in the config.py
. Add the following lines.
from plugins.demo import DemoIndex
PLUGINS["Demo"] = DemoIndex
Tests the quadtree results if they are the same as exudative searching.
python rend.py -t