如何在Java/Spring/PostGIS中计算Polygon的平方英尺等面积
多边形面积单位转换方案选择及代码优化建议
问题背景
需要将Polygon的面积转换为平方英尺、公顷或英亩等面积单位,已引入以下依赖:
<dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-spatial</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.locationtech.jts</groupId> <artifactId>jts-core</artifactId> <version>${jts.version}</version> </dependency>
现有代码实现
已编写部分代码,包含以下组件:
Field实体类
@Entity(name = "field") @Table(name = "field") public class Field { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @Column(updatable = false, nullable = false, unique = true) private Long id; @Column(name = "name", nullable = false) private String name; @Column(name = "area", columnDefinition = "geometry(Polygon, 4326)", nullable = false) private Polygon area; @Column(name = "center", columnDefinition = "geometry(Point, 4326)") private Point center; @Column(name = "size") private Double size; @ManyToOne @JoinColumn(name = "fk_farm_id") private Farm farm; }
FieldRepository
@Repository public interface FieldRepository extends JpaRepository<Field, Long> { }
FieldService接口
public interface FieldService { CreateFieldResponseDto createNewField(UUID publicFarmId, FieldDto fieldDto); }
FieldService实现类
@Override public CreateFieldResponseDto createNewField(UUID publicFarmId, FieldDto fieldDto) { Farm farm = farmRepository.findByPublicId(publicFarmId) .orElseThrow(() -> new FarmNotFoundException("Farm not found")); Field newField = new Field(); newField.setName(fieldDto.getName()); newField.setArea(convertToPolygon(fieldDto.getCoordinates())); newField.setCenter(calculateCenter(newField.getArea())); // newField.setSize(calculateFieldSize(newField.getArea())); newField.setFarm(farm); fieldRepository.save(newField); return fieldMapper.INSTANCE.toCreateFieldResponseDto(newField); } //--------------------------------------------| // HELPER METHODS FOR CREATING A NEW FIELD... | //--------------------------------------------| private Polygon convertToPolygon(List<List<List<Double>>> coordinates) { GeometryFactory geometryFactory = new GeometryFactory(); LinearRing shell = geometryFactory.createLinearRing( convertToCoordinateArray(coordinates.get(0)) ); LinearRing[] holes = new LinearRing[coordinates.size() - 1]; for (int i = 1; i < coordinates.size(); i++) { holes[i - 1] = geometryFactory.createLinearRing( convertToCoordinateArray(coordinates.get(i)) ); } return geometryFactory.createPolygon(shell, holes); } private Coordinate[] convertToCoordinateArray(List<List<Double>> coordinatesList) { Coordinate[] coordinates = new Coordinate[coordinatesList.size()]; for (int i = 0; i < coordinatesList.size(); i++) { List<Double> point = coordinatesList.get(i); coordinates[i] = new Coordinate(point.get(0), point.get(1)); } return coordinates; } private Point calculateCenter(Polygon polygon) { GeometryFactory geometryFactory = new GeometryFactory(); return geometryFactory.createPoint(polygon.getCentroid().getCoordinate()); }
控制器类
@PostMapping("/{publicFarmId}/fields") public ResponseEntity<Object> createField( @PathVariable UUID publicFarmId, @RequestBody FieldDto fieldDTO ) { CreateFieldResponseDto createdField = fieldService.createNewField(publicFarmId, fieldDTO); return ResponseHandler.generateResponse( HttpStatus.CREATED, "success", "Field created successfully.", new LinkedHashMap<>() {{ put("name", createdField.name()); put("coordinates", createdField.coordinates()); put("center", createdField.center()); put("size", createdField.size()); put("unitOfMeasurement", "metric"); // CODE THIS LATER !!! }} ); }
FieldDto请求类
public class FieldDto { private String name; private List<List<List<Double>>> coordinates; }
疑问与需求
不确定最优解决方案:是在Java代码中计算Polygon面积,还是用PostGIS的SQL方法(如存入后执行UPDATE查询)?也不清楚两种方案的性能差异,同时希望得到现有代码的改进建议。
内容的提问来源于stack exchange,提问作者Juhani
相关产品推荐
相关产品推荐

