Java生成地图正六边形出现垂直拉伸的问题求助
解决六边形网格地图垂直拉伸问题
问题原因
你直接在WGS84(EPSG:4326,地理坐标系,单位为度)下创建六边形网格,而地理坐标系中,经度方向的1度距离会随纬度升高而缩小,但纬度方向的1度距离基本固定(约111km)。当你设置边长为0.1度时,六边形在经度和纬度方向的实际地面长度不一致,投影到地图(通常用Web墨卡托等平面投影)就会出现垂直拉伸的变形,修改六边形方向无法解决这个本质问题。
解决方案
核心思路是在投影坐标系(单位为米,各方向距离一致)下创建六边形网格,再转换回WGS84用于地图可视化:
- 选择合适的投影坐标系(比如Web墨卡托EPSG:3857,或针对目标区域的UTM分区)
- 将原始WGS84边界转换为投影坐标系下的边界
- 在投影坐标系中创建六边形(边长单位设为米,比如10000米即10km)
- 将生成的六边形几何对象转换回WGS84
修改后代码示例
List<Geometry> hexagons = new ArrayList<>(); CoordinateReferenceSystem wgs84 = DefaultGeographicCRS.WGS84; // 选择Web墨卡托作为投影坐标系(也可根据区域选UTM) CoordinateReferenceSystem projectedCRS = CRS.decode("EPSG:3857"); // 1. 转换原始WGS84边界到投影坐标系 ReferencedEnvelope wgs84Bounds = new ReferencedEnvelope(box[0], box[2], box[1], box[3], wgs84); MathTransform transformToProjected = CRS.findMathTransform(wgs84, projectedCRS); ReferencedEnvelope projectedBounds = wgs84Bounds.transform(transformToProjected, true); // 2. 在投影坐标系下创建六边形网格(边长单位为米,这里设为10000米=10km) double sideLenInMeters = 10000; GridFeatureBuilder builder = new DefaultGridFeatureBuilder(); SimpleFeatureSource grid = Hexagons.createGrid(projectedBounds, sideLenInMeters, HexagonOrientation.FLAT, builder); try { SimpleFeatureCollection collection = grid.getFeatures(); try (FeatureIterator<SimpleFeature> iterator = collection.features()) { // 3. 将每个六边形转换回WGS84 MathTransform transformToWGS84 = CRS.findMathTransform(projectedCRS, wgs84); while (iterator.hasNext()) { SimpleFeature sFeature = iterator.next(); Geometry projectedGeom = (Geometry) sFeature.getAttribute(0); Geometry wgs84Geom = JTS.transform(projectedGeom, transformToWGS84); hexagons.add(wgs84Geom); } } } catch (Exception e) { e.printStackTrace(); } return hexagons;
额外说明
- 如果你的地图本身使用的是Web墨卡托(EPSG:3857),也可以直接在该坐标系下创建网格并使用,无需转换回WGS84,能提升性能。
- 若目标区域在高纬度,Web墨卡托会有一定变形,建议使用对应区域的UTM投影(比如中国大部分区域用EPSG:32650到32653),能获得更准确的六边形形状。
内容的提问来源于stack exchange,提问作者Ante
相关产品推荐
相关产品推荐

