# JTS GeometricShapeFactory generate an ellipse properly

This is what use to get a circle:

``````GeometricShapeFactory shape = new GeometricShapeFactory(gf);
shape.setCentre(new Coordinate(40.748754,-73.985460));//Empire Sate Building
shape.setNumPoints(64);
final Polygon circle = shape.createEllipse();//createCircle deprecated
``````

What I get is a weird ellipse. I know that closer to the equator we get 'more perfect' circle but still, is it valid circle for radius of `10km` with `ESB` as a center point ? Reading Dr. Ian Turton posts, github repo, and other great materials he shares, I know that I can use `geotools` and do that differently but I would like to stick with that approach.

EDITED:

I am writting an application. In `MySQL` I store `mall`s with their `location` (spatial type `Point`). What I want to do is to get malls from db that are in a certain circle (via ORM). In order to do that I have to create a `Polygon`(circle, linearring) in which orm will look. And Instead of using complicated calculations (and additional library). I thought I can use `GeometricShapeFactory` from `jts` lib I am already using. But because I am less than beginner what it comes to these things, all I wanted to ask, is whether or not the vertical ellipse generated by `jts` is valid for my purposes or not ?

I am using google maps (as basemap).

My question: Based on the fact that my ellipse is just wrong (considering given radius it should be a perfect circle - @whuber comment), how can I generate a proper `Polygon`(circle, linearring) based on radius and center point ? (I am going to use it in `hibernate-spatial`: `(...).add(SpatialRestrictions.within(Mall.LOCATION, getCircle(centerPoint, 10)));`)

• Please Edit the question to be less opinion-based and more problem-oriented. You need to include crucial information -- the projection of the basemap -- because the answer to "Why is my geodetic circle elongated on a Web Mercator map" is "Because it's Web Mercator". Jan 20 '18 at 14:14
• Your code generates the circle in longitude/latidude units. You expect wrong that 10*0.009 degrees is about 10 km in both N-S and E-W directions when you location is at latitude of 40 degrees N. Just check what the E-W distance would be as kilometers at 80 degrees N. Nothing weird at all. Jan 20 '18 at 16:52
• You still haven't stated what basemap your graphic uses. Jan 20 '18 at 16:54
• @Vince I used darrinward.com/lat-long Jan 20 '18 at 17:04
• Please edit the question to clarify it. It's not fair to those who would answer to need to mine the comments for critical information. Jan 20 '18 at 17:57

My first approach was giving me wrong results (wrong circle - a vertically elongated ellipse). It is not the right one because (to quote @whuber):

"Because Mercator projections are conformal, a small circle (and 10 km radius is very small compared to the globe) should appear on the map as a circle, period".

After @user30184 help/comment/suggestion, I think I got something, that can be called an answer. Snippet about conversion from geogrpahic to projected coordiante system is taken from here. This code gives me a perfect circle over `NYC`:

``````final GeometricShapeFactory shape = new GeometricShapeFactory(new GeometryFactory());//INFO :jts lib
final PointWrapper circleCenterPoint = getCircleCenterPoint();

final Coordinate centreInUTM = new Coordinate(projectedToGeographic(circleCenterPoint.getLatitude(),
circleCenterPoint.getLongitude()));
shape.setCentre(centreInUTM);
shape.setNumPoints(64);

//WGS 1984 is a geographic coordinate system, and UTM is a projected coordinate system
Polygon polygon = new GeometryFactory().createPolygon(Arrays.stream(shape.createEllipse().getCoordinates())
.map(c -> geographicToProjected(c.getOrdinate(X),
c.getOrdinate(Y)))
.toArray(Coordinate[]::new));

private Coordinate projectedToGeographic(double latitude, double longitude) {

LatLong latlong = LatLong.valueOf(latitude, longitude, NonSI.DEGREE_ANGLE);

UTM utm = UTM.latLongToUtm(latlong, ReferenceEllipsoid.WGS84); //INFO :jscience lib

double cX = utm.getCoordinates();
double cY = utm.getCoordinates();

return new Coordinate(cX, cY);
}

private Coordinate geographicToProjected(double easting, double northing) {

UTM utm = UTM.valueOf(18, 'T', easting, northing, METRE);//INFO :18T UTM for NYC
CoordinatesConverter<UTM, LatLong> utmToLatLong = UTM.CRS.getConverterTo(LatLong.CRS);
LatLong latLong = utmToLatLong.convert(utm);

double cX = latLong.getCoordinates();
double cY = latLong.getCoordinates();

return new Coordinate(cX, cY);
}
``````

This essentially comes down to a choice as to how accurate you need your circle to be versus how much effort you want to expend calculating the circles.

The reason you need to make this choice is that the Earth is spherical and you want to draw your map on a flat screen (or paper). Thus this, and all other maps are a compromise. It is impossible to accurately portray a curved shape on a flat map and preserve its shape and area.

You have chosen a "quick" and "dirty" method to calculate your circle by assuming that lengths are the same in the N-S direction as the W-E direction. This is not the case in your chosen projection (Web Mercator, EPSG:3857) so you end up with an ellipse. This is the smaller ellipse in the picture below.

If you had used the GeoTools code I gave in the other question you refer to then it would have transformed the point into a projection where lengths were the same in both directions, calculated the circle and transformed it back to lat/lon (EPSG:4326). This is the solid circle shown in the picture.

The other dotted ellipse is what you get if you take the average of 10km N-S and E-W and use that distance for a simple buffer. But if we switch the map to EPSG:4326 (Lat/Lon degrees) we get: Now the "simple" circles look closer to round and the "real" circle looks elliptical, but they are all enclosing exactly the same points on the map.

• I think that the problem was in believing that the distances in N-S and W-E directions are the same if EPSG:4326 degrees are converted into meters. EPSG:3857 is almost conformal and circles remain almost round but the size of the circle would be nonsense cartonerd.blogspot.fi/2014/08/web-mercator-and-comparisons.html. Jan 22 '18 at 13:40
• Your assertions about impossibility misinterpret the facts. It not only is possible to map a spherical circle with perfect accuracy of shape and area, it's easy to do so. No compromise is necessary. What is not possible is to map all shapes on an intrinsically curved surface with perfect metric accuracy. The distinction is important, because it helps us understand what we may reasonably hope to accomplish with a map. Jan 22 '18 at 18:30
``````double latitude = 40.748754d;
double longitude = -73.985460d;
double diameterInMeters = 20000d; //20km

GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
shapeFactory.setCentre(new Coordinate(latitude, longitude));

// Length in meters of 1° of latitude = always 111.32 km
shapeFactory.setHeight(diameterInMeters/111320d);

// Length in meters of 1° of longitude = 40075 km * cos( latitude ) / 360
shapeFactory.setWidth(diameterInMeters / (40075000 * Math.cos(Math.toRadians(latitude)) / 360));

Polygon circle = shapeFactory.createEllipse();
`````` • As the user @heyhey2k said in other place, keep in mind that JTS uses longitude first, so the `new Coordinate` when setting the center should be inverted. Feb 25 at 13:26