class MergePolygonCommand implements CommandHasRequest<MergePolygonRequest, MergePolygonResponse> {

	@Override
	public void execute(MergePolygonRequest request, MergePolygonResponse response) throws Exception {
		Polygon[] polygons = new Polygon[request.getPolygons().length];
		for (int i = 0; i < request.getPolygons().length; i++) {
			try {
				polygons[i] = (Polygon) converter.toInternal(request.getPolygons()[i]);
			} catch (Exception e) {
				throw new GeomajasException(e, ExceptionCode.MERGE_NO_POLYGON);
			}
		}
		int precision = polygons[0].getPrecisionModel().getMaximumSignificantDigits() - 1;
		PrecisionModel precisionModel = new PrecisionModel(Math.pow(10.0, precision));
		GeometryFactory factory = new GeometryFactory(precisionModel, polygons[0].getSRID());

		Geometry temp = factory.createGeometry(polygons[0]);
		for (int i = 1; i < polygons.length; i++) {
			Geometry polygon = factory.createGeometry(polygons[i]);
			temp = temp.union(polygon.buffer(Math.pow(10.0, -(precision - 1))));
		}
		if (temp instanceof Polygon) {
			MultiPolygon mp = factory.createMultiPolygon(new Polygon[] { (Polygon) temp });
			response.setGeometry(converter.toDto(mp));
		} else if (temp instanceof MultiPolygon && temp.getNumGeometries() != 0
				&& (request.isAllowMultiPolygon() || temp.getNumGeometries() == 1)) {
			response.setGeometry(converter.toDto(temp));
		} else {
			throw new GeomajasException(ExceptionCode.MERGE_NO_POLYGON);
		}
	}

}