Geo: fixes circle radius calculation
This change fixes the creation circle shapes o it calculates it correctly instead of essentially using the diameter as the radius. The radius has to be converted into degrees but calculating the ratio of the desired radius to the circumference of the earth and then multiplying it by 360 (number of degrees around the earths circumference). This issue here was that it was only multiplied by 180 making the result out by a factor of 2. Also made the test for circles actually check to make sure it has the correct centre and radius. Closes #7301
This commit is contained in:
parent
e2311d5da4
commit
f7ae4d9d86
|
@ -19,12 +19,12 @@
|
||||||
|
|
||||||
package org.elasticsearch.common.geo.builders;
|
package org.elasticsearch.common.geo.builders;
|
||||||
|
|
||||||
|
import com.spatial4j.core.shape.Circle;
|
||||||
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
import org.elasticsearch.common.unit.DistanceUnit;
|
import org.elasticsearch.common.unit.DistanceUnit;
|
||||||
import org.elasticsearch.common.unit.DistanceUnit.Distance;
|
import org.elasticsearch.common.unit.DistanceUnit.Distance;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
|
||||||
import com.spatial4j.core.shape.Circle;
|
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class CircleBuilder extends ShapeBuilder {
|
public class CircleBuilder extends ShapeBuilder {
|
||||||
|
@ -109,7 +109,7 @@ public class CircleBuilder extends ShapeBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Circle build() {
|
public Circle build() {
|
||||||
return SPATIAL_CONTEXT.makeCircle(center.x, center.y, 180 * radius / unit.getEarthCircumference());
|
return SPATIAL_CONTEXT.makeCircle(center.x, center.y, 360 * radius / unit.getEarthCircumference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,9 +19,11 @@
|
||||||
|
|
||||||
package org.elasticsearch.common.geo;
|
package org.elasticsearch.common.geo;
|
||||||
|
|
||||||
|
import com.spatial4j.core.shape.Circle;
|
||||||
import com.spatial4j.core.shape.Point;
|
import com.spatial4j.core.shape.Point;
|
||||||
import com.spatial4j.core.shape.Rectangle;
|
import com.spatial4j.core.shape.Rectangle;
|
||||||
import com.spatial4j.core.shape.Shape;
|
import com.spatial4j.core.shape.Shape;
|
||||||
|
import com.spatial4j.core.shape.impl.PointImpl;
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.LineString;
|
import com.vividsolutions.jts.geom.LineString;
|
||||||
import com.vividsolutions.jts.geom.Polygon;
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
@ -161,11 +163,28 @@ public class ShapeBuilderTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoCircle() {
|
public void testGeoCircle() {
|
||||||
ShapeBuilder.newCircleBuilder().center(0, 0).radius("100m").build();
|
double earthCircumference = 40075016.69;
|
||||||
ShapeBuilder.newCircleBuilder().center(+180, 0).radius("100m").build();
|
Circle circle = ShapeBuilder.newCircleBuilder().center(0, 0).radius("100m").build();
|
||||||
ShapeBuilder.newCircleBuilder().center(-180, 0).radius("100m").build();
|
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
|
||||||
ShapeBuilder.newCircleBuilder().center(0, 90).radius("100m").build();
|
assertEquals((Point) new PointImpl(0, 0, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
|
||||||
ShapeBuilder.newCircleBuilder().center(0, -90).radius("100m").build();
|
circle = ShapeBuilder.newCircleBuilder().center(+180, 0).radius("100m").build();
|
||||||
|
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
|
||||||
|
assertEquals((Point) new PointImpl(180, 0, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
|
||||||
|
circle = ShapeBuilder.newCircleBuilder().center(-180, 0).radius("100m").build();
|
||||||
|
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
|
||||||
|
assertEquals((Point) new PointImpl(-180, 0, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
|
||||||
|
circle = ShapeBuilder.newCircleBuilder().center(0, 90).radius("100m").build();
|
||||||
|
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
|
||||||
|
assertEquals((Point) new PointImpl(0, 90, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
|
||||||
|
circle = ShapeBuilder.newCircleBuilder().center(0, -90).radius("100m").build();
|
||||||
|
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
|
||||||
|
assertEquals((Point) new PointImpl(0, -90, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
|
||||||
|
double randomLat = (randomDouble() * 180) - 90;
|
||||||
|
double randomLon = (randomDouble() * 360) - 180;
|
||||||
|
double randomRadius = randomIntBetween(1, (int) earthCircumference / 4);
|
||||||
|
circle = ShapeBuilder.newCircleBuilder().center(randomLon, randomLat).radius(randomRadius + "m").build();
|
||||||
|
assertEquals((360 * randomRadius) / earthCircumference, circle.getRadius(), 0.00000001);
|
||||||
|
assertEquals((Point) new PointImpl(randomLon, randomLat, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue