Skip to content

Commit

Permalink
Micro-improvements 2
Browse files Browse the repository at this point in the history
  • Loading branch information
sherfert authored and Lojjs committed Feb 15, 2018
1 parent 031754c commit bd21b4a
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 144 deletions.
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2002-2018 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.gis.spatial.index.curves;

import org.neo4j.gis.spatial.index.Envelope;

/**
* N-dimensional searchEnvelope
*/
class SearchEnvelope
{
long[] min; // inclusive lower bounds
long[] max; // exclusive upper bounds
int nbrDim;

SearchEnvelope( SpaceFillingCurve curve, Envelope referenceEnvelope )
{
this.min = curve.getNormalizedCoord( referenceEnvelope.getMin() );
this.max = curve.getNormalizedCoord( referenceEnvelope.getMax() );
this.nbrDim = referenceEnvelope.getDimension();
for ( int i = 0; i < nbrDim; i++ )
{
this.max[i] += 1;
}
}

private SearchEnvelope( long[] min, long[] max )
{
this.min = min;
this.max = max;
this.nbrDim = min.length;
}

SearchEnvelope( long min, long max, int nbrDim )
{
this.nbrDim = nbrDim;
this.min = new long[nbrDim];
this.max = new long[nbrDim];

for ( int dim = 0; dim < nbrDim; dim++ )
{
this.min[dim] = min;
this.max[dim] = max;
}
}

SearchEnvelope quadrant( int[] quadNbrs )
{
long[] newMin = new long[nbrDim];
long[] newMax = new long[nbrDim];

for ( int dim = 0; dim < nbrDim; dim++ )
{
long extent = (max[dim] - min[dim]) / 2;
newMin[dim] = this.min[dim] + quadNbrs[dim] * extent;
newMax[dim] = this.min[dim] + (quadNbrs[dim] + 1) * extent;
}
return new SearchEnvelope( newMin, newMax );
}

boolean contains( long[] coord )
{
for ( int dim = 0; dim < nbrDim; dim++ )
{
if ( coord[dim] < min[dim] || coord[dim] >= max[dim] )
{
return false;
}
}
return true;
}

boolean intersects( SearchEnvelope other )
{
for ( int dim = 0; dim < nbrDim; dim++ )
{
if ( this.max[dim] <= other.min[dim] || other.max[dim] <= this.min[dim] )
{
return false;
}
}
return true;
}

double fractionOf( SearchEnvelope other )
{
double fraction = 1.0;
for ( int i = 0; i < min.length; i++ )
{
long min = Math.max( this.min[i], other.min[i] );
long max = Math.min( this.max[i], other.max[i] );
final double innerFraction = (double) (max - min) / (double) (other.max[i] - other.min[i]);
fraction *= innerFraction;
}
return fraction;
}
}
Expand Up @@ -265,7 +265,7 @@ public List<LongRange> getTilesIntersectingEnvelope( Envelope referenceEnvelope
*/
List<LongRange> getTilesIntersectingEnvelope( Envelope referenceEnvelope, RecursionStats stats )
{
SearchEnvelope search = new SearchEnvelope( referenceEnvelope );
SearchEnvelope search = new SearchEnvelope( this, referenceEnvelope );
ArrayList<LongRange> results = new ArrayList<>(1000);

addTilesIntersectingEnvelopeAt( stats, 0, search, new SearchEnvelope( 0, this.getWidth(), nbrDim ), rootCurve(), 0, this.getValueWidth(), results );
Expand Down Expand Up @@ -311,7 +311,7 @@ private void addTilesIntersectingEnvelopeAt( RecursionStats stats, int depth, Se
else if ( search.intersects( currentExtent ) )
{
double overlap = search.fractionOf( currentExtent );
if ( overlap >= 0.50 )
if ( overlap >= 0.99 )
{
// Note that LongRange upper bound is inclusive, hence the '-1' in several places
LongRange current = (results.size() > 0) ? results.get( results.size() - 1 ) : null;
Expand Down Expand Up @@ -358,7 +358,7 @@ private int[] bitValues( int npoint )
/**
* Given a coordinate, find the corresponding normalized coordinate
*/
private long[] getNormalizedCoord( double[] coord )
long[] getNormalizedCoord( double[] coord )
{
long[] normalizedCoord = new long[nbrDim];

Expand Down Expand Up @@ -463,145 +463,4 @@ public String toString()
return "LongRange(" + min + "," + max + ")";
}
}

/**
* N-dimensional searchEnvelope
*/
private class SearchEnvelope
{
long[] min; // inclusive lower bounds
long[] max; // exclusive upper bounds
int nbrDim;

private SearchEnvelope( Envelope referenceEnvelope )
{
this.min = getNormalizedCoord( referenceEnvelope.getMin() );
this.max = getNormalizedCoord( referenceEnvelope.getMax() );
this.nbrDim = referenceEnvelope.getDimension();
for ( int i = 0; i < nbrDim; i++ )
{
this.max[i] += 1;
}
}

private SearchEnvelope( long[] min, long[] max )
{
this.min = min;
this.max = max;
this.nbrDim = min.length;
}

private SearchEnvelope( long min, long max, int nbrDim )
{
this.nbrDim = nbrDim;
this.min = new long[nbrDim];
this.max = new long[nbrDim];

for ( int dim = 0; dim < nbrDim; dim++ )
{
this.min[dim] = min;
this.max[dim] = max;
}
}

private SearchEnvelope quadrant( int[] quadNbrs )
{
long[] newMin = new long[nbrDim];
long[] newMax = new long[nbrDim];

for ( int dim = 0; dim < nbrDim; dim++ )
{
long extent = (max[dim] - min[dim]) / 2;
newMin[dim] = this.min[dim] + quadNbrs[dim] * extent;
newMax[dim] = this.min[dim] + (quadNbrs[dim] + 1) * extent;
}
return new SearchEnvelope( newMin, newMax );
}

private boolean contains( long[] coord )
{
for ( int dim = 0; dim < nbrDim; dim++ )
{
if ( coord[dim] < min[dim] || coord[dim] >= max[dim] )
{
return false;
}
}
return true;
}

private boolean intersects( SearchEnvelope other )
{
for ( int dim = 0; dim < nbrDim; dim++ )
{
if ( this.max[dim] <= other.min[dim] || other.max[dim] <= this.min[dim] )
{
return false;
}
}
return true;
}

/**
* The smallest possible envelope has unit area 1
*/
public double getArea()
{
long area = 1;
for ( int i = 0; i < min.length; i++ )
{
area *= max[i] - min[i];
}
return area;
}

public double fractionOf( SearchEnvelope other )
{
SearchEnvelope intersection = this.intersection(other);
return intersection == null ? 0.0 : intersection.getArea() / other.getArea();
}

/**
* Returns true for the smallest possible envelope, of area 1
*/
public boolean isUnit()
{
for ( int i = 0; i < min.length; i++ )
{
if ( max[i] - min[i] > 1 )
{
return false;
}
}
return true;
}

public SearchEnvelope intersection( SearchEnvelope other )
{
if ( nbrDim == other.nbrDim )
{
long[] i_min = new long[this.min.length];
long[] i_max = new long[this.min.length];
boolean result = true;
for ( int i = 0; i < min.length && result; i++ )
{
if ( other.min[i] < this.max[i] && this.min[i] < other.max[i] )
{
i_min[i] = Math.max(this.min[i], other.min[i]);
i_max[i] = Math.min(this.max[i], other.max[i]);
}
else
{
result = false;
}
}
return result ? new SearchEnvelope( i_min, i_max ) : null;
}
else
{
throw new IllegalArgumentException(
"Cannot calculate intersection of Envelopes with different dimensions: " + this.nbrDim + " != " + other.nbrDim );
}
}
}
}

0 comments on commit bd21b4a

Please sign in to comment.