package com.revolsys.geometry.model.editor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.MultiPolygon; import com.revolsys.geometry.model.Polygon; import com.revolsys.geometry.model.Polygonal; import com.revolsys.util.Exceptions; import com.revolsys.util.number.Doubles; public class MultiPolygonEditor implements MultiPolygon, PolygonalEditor { private static final long serialVersionUID = 1L; private final Polygonal polygonal; private PolygonEditor[] newPolygons; private GeometryFactory newGeometryFactory; public MultiPolygonEditor(final Polygonal polygonal) { this.polygonal = polygonal; this.newGeometryFactory = polygonal.getGeometryFactory(); } @Override public Polygonal clone() { try { return (Polygonal)super.clone(); } catch (final CloneNotSupportedException e) { throw Exceptions.wrap(e); } } @Override public boolean equals(final Object other) { if (other instanceof Geometry) { final Geometry geometry = (Geometry)other; return equals(2, geometry); } else { return false; } } @Override public int getAxisCount() { return this.newGeometryFactory.getAxisCount(); } @SuppressWarnings("unchecked") @Override public <V extends Geometry> List<V> getGeometries() { if (this.newPolygons == null) { return this.polygonal.getGeometries(); } else { return (List<V>)new ArrayList<>(Arrays.asList(this.newPolygons)); } } @SuppressWarnings("unchecked") @Override public <V extends Geometry> V getGeometry(final int partIndex) { if (this.newPolygons == null) { return this.polygonal.getGeometry(partIndex); } else { return (V)this.newPolygons[partIndex]; } } @Override public int getGeometryCount() { if (this.newPolygons == null) { return this.polygonal.getGeometryCount(); } else { return this.newPolygons.length; } } @Override public GeometryFactory getGeometryFactory() { return this.newGeometryFactory; } @Override public int hashCode() { return getBoundingBox().hashCode(); } @Override public boolean isEmpty() { return this.polygonal.isEmpty(); } @Override public Polygonal newGeometry() { if (this.newPolygons == null) { return this.polygonal; } else { final Polygon[] polygons = new Polygon[this.newPolygons.length]; for (int i = 0; i < this.newPolygons.length; i++) { final PolygonEditor editor = this.newPolygons[i]; polygons[i] = editor.newGeometry(); } return this.polygonal.newPolygonal(this.newGeometryFactory, polygons); } } @Override public Polygonal newPolygonal(final GeometryFactory geometryFactory, final Polygon... polygons) { return this.polygonal.newPolygonal(geometryFactory, polygons); } @Override public int setAxisCount(final int axisCount) { final int oldAxisCount = getAxisCount(); if (oldAxisCount != axisCount) { final int geometryCount = getGeometryCount(); if (this.newPolygons == null) { final PolygonEditor[] editors = new PolygonEditor[geometryCount]; for (int ringIndex = 0; ringIndex < geometryCount; ringIndex++) { final Polygon polygon = getGeometry(ringIndex); final PolygonEditor editor = polygon.newGeometryEditor(axisCount); editors[ringIndex] = editor; } this.newPolygons = editors; } else { for (int ringIndex = 0; ringIndex < geometryCount; ringIndex++) { final PolygonEditor editor = this.newPolygons[ringIndex]; editor.setAxisCount(axisCount); } } this.newGeometryFactory = this.newGeometryFactory.convertAxisCount(axisCount); } return oldAxisCount; } @Override public double setCoordinate(final int axisIndex, final double coordinate, final int... vertexId) { if (vertexId.length == 2) { final int partIndex = vertexId[0]; final int ringIndex = vertexId[1]; final int vertexIndex = vertexId[2]; return setCoordinate(partIndex, ringIndex, vertexIndex, axisIndex, coordinate); } else { return Double.NaN; } } @Override public double setCoordinate(final int partIndex, final int ringIndex, final int vertexIndex, final int axisIndex, final double coordinate) { final int geometryCount = getGeometryCount(); if (partIndex >= 0 && partIndex < geometryCount) { final int axisCount = getAxisCount(); if (axisIndex >= 0 && axisIndex < axisCount) { final double oldValue = this.polygonal.getCoordinate(partIndex, ringIndex, vertexIndex, axisIndex); if (!Doubles.equal(coordinate, oldValue)) { if (this.newPolygons == null) { final PolygonEditor[] editors = new PolygonEditor[geometryCount]; for (int i = 0; i < geometryCount; i++) { final Polygon polygon = getGeometry(i); final PolygonEditor editor = polygon.newGeometryEditor(axisCount); editors[i] = editor; } this.newPolygons = editors; } final PolygonEditor editor = this.newPolygons[partIndex]; editor.setCoordinate(ringIndex, vertexIndex, axisIndex, coordinate); } } } return Double.NaN; } @Override public String toString() { return toEwkt(); } }