Skip to content

Commit

Permalink
Merge pull request #250 from jdgarrett/create_index_bounds
Browse files Browse the repository at this point in the history
Add ability to specify bounds for spatial indexes.
  • Loading branch information
groldan committed Feb 17, 2017
2 parents 384335f + fe7bbf2 commit e29d05c
Show file tree
Hide file tree
Showing 19 changed files with 637 additions and 96 deletions.
2 changes: 2 additions & 0 deletions doc/manpages/source/indexcreate.rst
Expand Up @@ -25,6 +25,8 @@ OPTIONS

--index-history If specified, indexes will be created for all commits in the history.

--bounds If specified, the max bounds of the spatial index will be set to this parameter. <minx,miny,maxx,maxy>



SEE ALSO
Expand Down
2 changes: 2 additions & 0 deletions doc/manpages/source/indexupdate.rst
Expand Up @@ -29,6 +29,8 @@ OPTIONS

--overwrite If specified, new attributes will replace the existing set of extra attributes.

--bounds If specified, the max bounds of the spatial index will be updated to this parameter. <minx,miny,maxx,maxy>



SEE ALSO
Expand Down
48 changes: 47 additions & 1 deletion doc/manual/source/interaction/indexing-web-api.rst
Expand Up @@ -10,7 +10,7 @@ Creates a new index on a specified feature tree using a geometry attribute in th

::

PUT /repos/<repo>/index/create[.xml|.json]?treeRefSpec=<treeRefSpec>[&geometryAttributeName=<attributeName>][[&extraAttributes=<attributeName>]+][&indexHistory=<true|false>]
PUT /repos/<repo>/index/create[.xml|.json]?treeRefSpec=<treeRefSpec>[&geometryAttributeName=<attributeName>][[&extraAttributes=<attributeName>]+][&indexHistory=<true|false>][&bounds=<minx,miny,maxx,maxy>]


Parameters
Expand All @@ -28,6 +28,9 @@ Optional. An extra attribute that should be stored in the index to improve perfo
**indexHistory:**
Optional. Boolean indicating whether or not index trees should be built for every commit in the history of the repository. By default only the feature tree in commit indicated by the ``treeRefSpec`` will be indexed.

**bounds:**
Optional. String indicating the max bounds of the spatial index. If not specified, the bounds will be set to the extent of the coordinate reference system of the geometry attribute.

Examples
^^^^^^^^

Expand Down Expand Up @@ -72,6 +75,26 @@ Create an index with extra attributes:
</index>
<indexedTreeId>b3340540d2098ec33b7edab1b38d3ffc18f8e162</indexedTreeId>
</response>
Create an index with custom bounds:
***********************************

::

$ curl -X PUT -v "http://localhost:8182/repos/repo1/index/create?treeRefSpec=Points&bounds=-60,-45,60,45" | xmllint --format -
< HTTP/1.1 201 Created
< Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<response>
<success>true</success>
<index>
<treeName>Points</treeName>
<attributeName>the_geom</attributeName>
<indexType>QUADTREE</indexType>
<bounds>Env[-60,60,-45,45]</bounds>
</index>
<indexedTreeId>b3340540d2098ec33b7edab1b38d3ffc18f8e162</indexedTreeId>
</response>


Index Update
Expand Down Expand Up @@ -105,6 +128,9 @@ Optional. If extra attributes already exist on the index, you must specify eithe
**overwrite:**
Optional: See ``add``. If ``overwrite`` is specified, the extra attributes in the indexed will be replaced with those specified in the parameters. If no extra attributes are supplied, all extra attributes will be removed from the index.

**bounds:**
Optional. String indicating the new max bounds of the spatial index.

Examples
^^^^^^^^

Expand Down Expand Up @@ -176,6 +202,26 @@ In this case Points already has an extra attribute of ``sp``. If we want to rem
</index>
<indexedTreeId>b3340540d2098ec33b7edab1b38d3ffc18f8e162</indexedTreeId>
</response>
Update the max bounds of the Points index:
******************************************

::

$ curl -X POST -v "http://localhost:8182/repos/repo1/index/update?treeRefSpec=Points&bounds=-60,-45,60,45" | xmllint --format -
< HTTP/1.1 201 Created
< Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<response>
<success>true</success>
<index>
<treeName>Points</treeName>
<attributeName>the_geom</attributeName>
<indexType>QUADTREE</indexType>
<bounds>Env[-60,60,-45,45]</bounds>
</index>
<indexedTreeId>b3340540d2098ec33b7edab1b38d3ffc18f8e162</indexedTreeId>
</response>


Index Rebuild
Expand Down
Expand Up @@ -21,9 +21,11 @@
import org.locationtech.geogig.porcelain.index.CreateQuadTree;
import org.locationtech.geogig.porcelain.index.Index;
import org.locationtech.geogig.repository.Repository;
import org.locationtech.geogig.repository.impl.SpatialOps;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.vividsolutions.jts.geom.Envelope;

@RequiresRepository(true)
@Parameters(commandNames = {
Expand All @@ -44,17 +46,23 @@ public class CreateIndex extends AbstractCommand implements CLICommand {
"--extra-attributes" }, description = "Comma separated list of extra attribute names to hold inside index")
private List<String> extraAttributes;

@Parameter(names = "--bounds", description = "If specified, the max bounds of the spatial index will be set to this parameter. <minx,miny,maxx,maxy>")
private String bbox;

@Override
protected void runInternal(GeogigCLI cli)
throws InvalidParameterException, CommandFailedException, IOException {

Repository repo = cli.getGeogig().getRepository();

Envelope envelope = SpatialOps.parseNonReferencedBBOX(bbox);

Index index = repo.command(CreateQuadTree.class)//
.setTreeRefSpec(treeRefSpec)//
.setGeometryAttributeName(attribute)//
.setExtraAttributes(extraAttributes)//
.setIndexHistory(indexHistory)//
.setBounds(envelope)//
.setProgressListener(cli.getProgressListener())//
.call();

Expand Down
Expand Up @@ -21,9 +21,11 @@
import org.locationtech.geogig.porcelain.index.Index;
import org.locationtech.geogig.porcelain.index.UpdateIndexOp;
import org.locationtech.geogig.repository.Repository;
import org.locationtech.geogig.repository.impl.SpatialOps;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.vividsolutions.jts.geom.Envelope;

@RequiresRepository(true)
@Parameters(commandNames = {
Expand All @@ -49,6 +51,9 @@ public class UpdateIndex extends AbstractCommand implements CLICommand {
"--add" }, description = "Add new attributes to existing list of extra attributes held by the index")
private boolean add;

@Parameter(names = "--bounds", description = "If specified, the max bounds of the spatial index will be updated to this parameter. <minx,miny,maxx,maxy>")
private String bbox;

@Parameter(names = "--index-history", description = "If specified, indexes will be rebuilt for all commits in the history.")
private boolean indexHistory = false;

Expand All @@ -58,13 +63,16 @@ protected void runInternal(GeogigCLI cli)

Repository repo = cli.getGeogig().getRepository();

Envelope envelope = SpatialOps.parseNonReferencedBBOX(bbox);

Index index = repo.command(UpdateIndexOp.class)//
.setTreeRefSpec(treeRefSpec)
.setTreeRefSpec(treeRefSpec)//
.setAttributeName(attribute)//
.setExtraAttributes(extraAttributes)//
.setOverwrite(overwrite)//
.setAdd(add)//
.setIndexHistory(indexHistory)//
.setBounds(envelope)//
.setProgressListener(cli.getProgressListener())//
.call();

Expand Down
Expand Up @@ -71,6 +71,7 @@
import org.locationtech.geogig.repository.RepositoryResolver;
import org.locationtech.geogig.repository.WorkingTree;
import org.locationtech.geogig.repository.impl.GeoGIG;
import org.locationtech.geogig.repository.impl.SpatialOps;
import org.opengis.feature.Feature;
import org.opengis.feature.type.PropertyDescriptor;
import org.slf4j.Logger;
Expand All @@ -83,6 +84,7 @@
import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import com.google.common.io.Files;
import com.vividsolutions.jts.geom.Envelope;

import cucumber.api.DataTable;
import cucumber.api.Scenario;
Expand Down Expand Up @@ -834,6 +836,23 @@ public void noIndexAtCommit(String headRef) throws Throwable {
assertFalse(indexTreeId.isPresent());
}

@Then("^the repository's \"([^\"]*)\" index bounds should be \"([^\"]*)\"$")
public void verifyIndexBounds(String headRef, String bbox) throws Throwable {
Repository repo = localRepo.geogigCLI.getGeogig().getRepository();
final NodeRef typeTreeRef = IndexUtils.resolveTypeTreeRef(repo.context(), headRef);
String treeName = typeTreeRef.path();
IndexInfo indexInfo = IndexUtils.resolveIndexInfo(repo.indexDatabase(), treeName, null);
Map<String, Object> metadata = indexInfo.getMetadata();
assertTrue(metadata.containsKey(IndexInfo.MD_QUAD_MAX_BOUNDS));
Envelope indexBounds = (Envelope) metadata.get(IndexInfo.MD_QUAD_MAX_BOUNDS);
Envelope expected = SpatialOps.parseNonReferencedBBOX(bbox);
final double EPSILON = 0.00001;
assertEquals(expected.getMinX(), indexBounds.getMinX(), EPSILON);
assertEquals(expected.getMaxX(), indexBounds.getMaxX(), EPSILON);
assertEquals(expected.getMinY(), indexBounds.getMinY(), EPSILON);
assertEquals(expected.getMaxY(), indexBounds.getMaxY(), EPSILON);
}

@SuppressWarnings("unchecked")
@Then("^the repository's \"([^\"]*)\" index should track the extra attribute \"([^\"]*)\"$")
public void verifyIndexExtraAttributes(String headRef, String attributeName) throws Throwable {
Expand Down
51 changes: 44 additions & 7 deletions src/cli/src/test/resources/features/index/CreateIndex.feature
Expand Up @@ -6,11 +6,12 @@ Feature: "index create" command
Scenario: Try to create an index
Given I have a repository
And I have several commits
And I run the command "index create --tree Points"
When I run the command "index create --tree Points"
Then the response should contain "Index created successfully"
And the response should contain "Size: 3"
And the response should not contain "Size: 2"
And the response should contain the index ID for tree "Points"
And the repository's "HEAD:Points" index bounds should be "-90,-180,90,180"
And the repository's "HEAD:Points" index should not track the extra attribute "sp"
And the repository's "HEAD:Points" index should not track the extra attribute "ip"
And the repository's "HEAD:Points" index should have the following features:
Expand All @@ -25,11 +26,12 @@ Feature: "index create" command
Scenario: Try to create an index with extra attributes
Given I have a repository
And I have several commits
And I run the command "index create --tree Points --extra-attributes sp"
When I run the command "index create --tree Points --extra-attributes sp"
Then the response should contain "Index created successfully"
And the response should contain "Size: 3"
And the response should not contain "Size: 2"
And the response should contain the index ID for tree "Points"
And the repository's "HEAD:Points" index bounds should be "-90,-180,90,180"
And the repository's "HEAD:Points" index should track the extra attribute "sp"
And the repository's "HEAD:Points" index should not track the extra attribute "ip"
And the repository's "HEAD:Points" index should have the following features:
Expand All @@ -40,33 +42,66 @@ Feature: "index create" command
And the repository's "HEAD~1:Points" should not have an index
And the repository's "HEAD~2:Points" should not have an index
And the repository's "HEAD~3:Points" should not have an index

Scenario: Try to create an index with user-specified bounds
Given I have a repository
And I have several commits
When I run the command "index create --tree Points --bounds -45,-45,45,45"
Then the response should contain "Index created successfully"
And the response should contain "Size: 3"
And the response should not contain "Size: 2"
And the response should contain the index ID for tree "Points"
And the repository's "HEAD:Points" index bounds should be "-45,-45,45,45"
And the repository's "HEAD:Points" index should not track the extra attribute "sp"
And the repository's "HEAD:Points" index should not track the extra attribute "ip"
And the repository's "HEAD:Points" index should have the following features:
| index |
| Points.1 |
| Points.2 |
| Points.3 |
And the repository's "HEAD~1:Points" should not have an index
And the repository's "HEAD~2:Points" should not have an index
And the repository's "HEAD~3:Points" should not have an index

Scenario: Try to create an index with too few bounds parameters
Given I have a repository
And I have several commits
When I run the command "index create --tree Points --bounds -45,-45,45"
Then the response should contain "Invalid bbox parameter: '-45,-45,45'. Expected format: <minx,miny,maxx,maxy>"

Scenario: Try to create an index with invalid bounds parameters
Given I have a repository
And I have several commits
When I run the command "index create --tree Points --bounds -45,-45,45,A"
Then the response should contain "Invalid bbox parameter: '-45,-45,45,A'. Expected format: <minx,miny,maxx,maxy>"

Scenario: Try to create an index on a nonexistent tree
Given I have a repository
And I have several commits
And I run the command "index create --tree nonexistent"
When I run the command "index create --tree nonexistent"
Then the response should contain "Can't find feature tree 'nonexistent'"

Scenario: Try to create an index on a nonexistent attribute
Given I have a repository
And I have several commits
And I run the command "index create --tree Points --attribute nonexistent"
When I run the command "index create --tree Points --attribute nonexistent"
Then the response should contain "property nonexistent does not exist"

Scenario: Try to create an index on a non-geometry attribute
Given I have a repository
And I have several commits
And I run the command "index create --tree Points --attribute sp"
When I run the command "index create --tree Points --attribute sp"
Then the response should contain "property sp is not a geometry attribute"

Scenario: Try to create an index with the full history
Given I have a repository
And I have several branches
And I run the command "index create --tree Points --index-history"
When I run the command "index create --tree Points --index-history"
Then the response should contain "Index created successfully"
And the response should contain "Size: 3"
And the response should contain "Size: 2"
And the response should contain the index ID for tree "Points"
And the repository's "HEAD:Points" index bounds should be "-90,-180,90,180"
And the repository's "HEAD:Points" index should not track the extra attribute "sp"
And the repository's "HEAD:Points" index should not track the extra attribute "ip"
And the repository's "HEAD:Points" index should have the following features:
Expand Down Expand Up @@ -95,11 +130,12 @@ Feature: "index create" command
Scenario: Try to create an index with the full history and extra attributes
Given I have a repository
And I have several branches
And I run the command "index create --tree Points --extra-attributes sp,ip --index-history"
When I run the command "index create --tree Points --extra-attributes sp,ip --index-history"
Then the response should contain "Index created successfully"
And the response should contain "Size: 3"
And the response should contain "Size: 2"
And the response should contain the index ID for tree "Points"
And the repository's "HEAD:Points" index bounds should be "-90,-180,90,180"
And the repository's "HEAD:Points" index should track the extra attribute "sp"
And the repository's "HEAD:Points" index should track the extra attribute "ip"
And the repository's "HEAD:Points" index should have the following features:
Expand Down Expand Up @@ -144,6 +180,7 @@ Feature: "index create" command
Then the response should contain "Index updated"
And the response should contain "Size: 1"
And the response should contain the index ID for tree "Points"
And the repository's "HEAD:Points" index bounds should be "-90,-180,90,180"
And the repository's "HEAD:Points" index should not track the extra attribute "sp"
And the repository's "HEAD:Points" index should not track the extra attribute "ip"
And the repository's "HEAD:Points" index should have the following features:
Expand Down

0 comments on commit e29d05c

Please sign in to comment.