package com.bitmonlab.osiris.commons.map.model.geojson; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; import java.util.List; import math.geom2d.Point2D; import math.geom2d.polygon.LinearRing2D; public class LineString extends Geometry { private List<List<Double>> coordinates; private final String type = "LineString"; List<Double> centroid; public List<List<Double>> getCoordinates() { return coordinates; } public void setCoordinates( List<List<Double>> coordinatesList) { this.coordinates = coordinatesList; } public List<Double> getCentroid() { return centroid; } public void setCentroid(List<Double> centroid) { this.centroid = centroid; } public void calculateCentroid(){ /*if(!(coordinates.get(0).equals(coordinates.get(coordinates.size()-1))) ){ return; }*/ Collection<Point2D> points = new ArrayList<Point2D>(); for(List<Double> coord : coordinates ){ Point2D point = new Point2D(coord.get(0), coord.get(1)); points.add(point); } LinearRing2D linearRing2D = new LinearRing2D(points); List<BigDecimal> centroidPoints = computeCentroid(linearRing2D); if(centroidPoints!=null){ centroid = new ArrayList<Double>(); centroid.add(Double.valueOf(centroidPoints.get(0).toString())); centroid.add(Double.valueOf(centroidPoints.get(1).toString())); } } private List<BigDecimal> computeCentroid(LinearRing2D ring) { BigDecimal xc = new BigDecimal(0.0D); BigDecimal yc = new BigDecimal(0.0D); BigDecimal tmp = new BigDecimal(0.0D); int n = ring.vertexNumber(); math.geom2d.Point2D prev = ring.vertex(n - 1); BigDecimal xp = new BigDecimal(prev.x()); BigDecimal yp = new BigDecimal(prev.y()); for (math.geom2d.Point2D point : ring.vertices()) { BigDecimal x = new BigDecimal(point.x()); BigDecimal y = new BigDecimal(point.y()); tmp = xp.multiply(y).subtract(yp.multiply(x)); xc = xc.add((x.add(xp)).multiply(tmp)); yc = yc.add((y.add(yp)).multiply(tmp)); prev = point; xp = x; yp = y; } BigDecimal denom = computeArea(ring).multiply(new BigDecimal(6.0D)); List<BigDecimal> centroid = null; if (denom.compareTo(BigDecimal.ZERO) != 0){ centroid = new ArrayList<BigDecimal>(); centroid.add(xc.divide(denom, 32, RoundingMode.HALF_UP)); centroid.add(yc.divide(denom, 32, RoundingMode.HALF_UP)); } return centroid; } private BigDecimal computeArea(LinearRing2D ring) { BigDecimal area = new BigDecimal(0.0D); int n = ring.vertexNumber(); math.geom2d.Point2D prev = ring.vertex(n - 1); for (math.geom2d.Point2D point : ring.vertices()) { BigDecimal prevx = new BigDecimal(prev.x()); BigDecimal prevy = new BigDecimal(prev.y()); BigDecimal pointx = new BigDecimal(point.x()); BigDecimal pointy = new BigDecimal(point.y()); area = area.add(prevx.multiply(pointy).subtract(prevy.multiply(pointx))); prev = point; } return area.divide(new BigDecimal(2.0D), 4096, RoundingMode.HALF_UP); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((coordinates == null) ? 0 : coordinates.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; LineString other = (LineString) obj; if (coordinates == null) { if (other.coordinates != null) return false; } else if (!coordinates.equals(other.coordinates)) return false; if (type == null) { if (other.type != null) return false; } else if (!type.equals(other.type)) return false; return true; } @Override public String toString() { return "LineString [coordinates=" + coordinates + ", type=" + type + "]"; } }