package org.activityinfo.server.database.hibernate.dao;
import com.google.common.collect.Lists;
import com.sun.jersey.api.core.InjectParam;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Polygon;
import org.activityinfo.server.database.hibernate.entity.AdminEntity;
import javax.persistence.EntityManager;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;
/**
* Some how alot of our geometry has been corrupted, and stored
* as Geometry Collections instead of Polygon / Multipolygon.
* Fix now.
*/
@Path("/tasks/fixGeometry")
public class FixGeometryTask {
private GeometryFactory gf = new GeometryFactory();
@GET @Produces(MediaType.TEXT_PLAIN)
public String correctGeometry(@InjectParam EntityManager em) {
while (true) {
em.getTransaction().begin();
List<AdminEntity> entities = em.createNativeQuery(
"select * from adminentity where GeometryType(Geometry) = 'GEOMETRYCOLLECTION' limit 50",
AdminEntity.class).getResultList();
for (AdminEntity entity : entities) {
entity.setGeometry(fixGeometry((GeometryCollection) entity.getGeometry()));
}
em.getTransaction().commit();
if (entities.isEmpty()) {
break;
}
}
return "OK";
}
private Geometry fixGeometry(GeometryCollection collection) {
List<Polygon> polygons = Lists.newArrayList();
findPolygons(collection, polygons);
if (polygons.size() == 0) {
return null;
} else if (polygons.size() == 1) {
return polygons.get(0);
} else {
return gf.createMultiPolygon(polygons.toArray(new Polygon[polygons.size()]));
}
}
private void findPolygons(GeometryCollection collection, List<Polygon> polygons) {
for (int i = 0; i != collection.getNumGeometries(); ++i) {
Geometry geometry = collection.getGeometryN(i);
if (geometry instanceof Polygon) {
polygons.add((Polygon) geometry);
} else if (geometry instanceof GeometryCollection) {
findPolygons((GeometryCollection) geometry, polygons);
}
}
}
}