4

I'm trying to create regular hexagon polygons, but when visualized on a map they are stretched vertically.

This is how I do it:

List<Geometry> hexagons = new ArrayList<>();
        CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
        ReferencedEnvelope gridBounds = new ReferencedEnvelope(box[0], box[2], box[1], box[3], sourceCRS);
        double sideLen = 0.1;
        GridFeatureBuilder builder = new DefaultGridFeatureBuilder();
        SimpleFeatureSource grid = Hexagons.createGrid(gridBounds, sideLen, HexagonOrientation.FLAT, builder);
        try{
            SimpleFeatureCollection collection = grid.getFeatures();
            FeatureIterator iterator = collection.features();
            while (iterator.hasNext()){
                Feature feature = iterator.next();
                SimpleFeature sFeature = (SimpleFeature) feature;
                
                Geometry geometry = (Geometry) sFeature.getAttribute(0);
                hexagons.add(geometry);
            }

        } catch(Exception e){
            e.printStackTrace();
        }
        return hexagons;

This

is how it looks like on a map. I tried to change the orientation from FLAT to ANGLE, but that didn't fix the problem.

Ian Turton
  • 10,018
  • 1
  • 28
  • 47
Ante
  • 41
  • 3

1 Answers1

7

You've been caught out by the Earth being round not flat.

You've asked for the hexagons to be in degrees of lat/lon or EPSG:4326 and if you displayed them in that projection then they would look fine:

enter image description here

but when you reproject your map to Pseudo Mercator (EPSG:3857) they (and the rest of the map) become stretched, it's worse the further north you go.

enter image description here

If you want unstretched hexagons on a stretched map then you need to generate them in that projection, something like this:

    List<Geometry> hexagons = new ArrayList<>();
    CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
    ReferencedEnvelope
            gridBounds = new ReferencedEnvelope(-5,5,50,60, sourceCRS);
    ReferencedEnvelope nGridBounds = gridBounds.transform(CRS.decode("EPSG:3857"),true);
    double sideLen = 100000.0;
    GridFeatureBuilder builder = new DefaultGridFeatureBuilder();
    SimpleFeatureSource
            grid = Hexagons.createGrid(nGridBounds, sideLen, HexagonOrientation.FLAT, builder);

Where I have changed the bounding box to be in EPSG:3857 and changed the length of the sides to 100Km.

enter image description here

In general EPSG:3857 is a bad projection to do any analysis (or anything but a web map) in, so you may want to pick a better projection for your area of study.

Ian Turton
  • 10,018
  • 1
  • 28
  • 47