All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.europa.ec.eurostat.jgiscotools.algo.base.Union Maven / Gradle / Ivy

package eu.europa.ec.eurostat.jgiscotools.algo.base;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.operation.linemerge.LineMerger;
import org.locationtech.jts.operation.union.CascadedPolygonUnion;

/**
 * Efficient union of polygons.
 * 
 * @author julien Perret (from GeOxygene project http://sourceforge.net/projects/oxygene-project/)
 *
 */
public class Union {
	private final static Logger LOGGER = LogManager.getLogger(Union.class.getName());

	public static  Geometry getLineUnion(Collection geoms) {
		return getLine( union_(geoms) );
	}

	public static Geometry getPolygonUnion(Collection geoms) {
		return getPolygon( union_(geoms) );
	}

	private static  ArrayList union_(Collection geoms) {
		ArrayList geoms_ = new ArrayList();
		geoms_.addAll(geoms);

		final int cellSize = 1 + (int)Math.sqrt(geoms_.size());

		Comparator comparator =  new Comparator(){
			public int compare(Geometry geom1, Geometry geom2) {
				if (geom1==null || geom2==null) return 0;
				Envelope env1 = geom1.getEnvelopeInternal();
				Envelope env2 = geom2.getEnvelopeInternal();
				double i1 = env1.getMinX() / cellSize + cellSize*( (int)env1.getMinY() / cellSize );
				double i2 = env2.getMinX() / cellSize + cellSize*( (int)env2.getMinY() / cellSize );
				return i1>=i2? 1 : i1 treeSet;
		while (geoms_.size() > 1) {
			i++;
			if(LOGGER.isTraceEnabled()) LOGGER.trace("Union (" + (i-1) + "/" + nb + ")");
			//System.out.println( "Union (" + (i-1) + "/" + nb + ")" );
			treeSet = new TreeSet(comparator);
			treeSet.addAll(geoms_);
			geoms_ = union(treeSet, 4);
		}
		return geoms_;
	}

	private static ArrayList union(TreeSet treeSet, int groupSize) {
		ArrayList unions = new ArrayList();
		Geometry union = null;
		int i=0;
		for (Geometry geom : treeSet) {
			if ((union==null)||(i%groupSize==0)) union = geom;
			else {
				union = union.union(geom);
				if (groupSize-i%groupSize==1) unions.add(union);
			}
			i++;
			if(LOGGER.isTraceEnabled()) LOGGER.trace(" " + i + " - " + treeSet.size() + " geometries");
		}
		if (groupSize-i%groupSize!=0) unions.add(union);
		return unions;
	}

	private static Geometry getPolygon(ArrayList geoms_) {
		List polys = new ArrayList();
		for (Geometry geom : geoms_) {
			if (geom instanceof Polygon) polys.add((Polygon) geom);
			else if (geom instanceof MultiPolygon) {
				MultiPolygon mp = (MultiPolygon) geom;
				for (int k=0; k geoms_) {
		List ls = new ArrayList();
		for (Geometry geom : geoms_) {
			if (geom instanceof LineString) ls.add((LineString) geom);
			else if (geom instanceof MultiLineString) {
				MultiLineString mls = (MultiLineString) geom;
				for (int k=0; k polys){
		CascadedPolygonUnion cpu = new CascadedPolygonUnion(polys);
		return cpu.union();
	}


	public static LineString getUnionAsLineString(Collection geoms) {
		LineMerger lm = new LineMerger();
		lm.add(geoms);
		Collection ls = lm.getMergedLineStrings();
		if(ls.size()!=1)
			LOGGER.warn("Problem when merging lines into a single LineString: Unexpected number of lines: " + ls.size() + " Around: "+((LineString)ls.iterator().next()).getCoordinate());
		return (LineString)ls.iterator().next();
	}



	public static Geometry polygonsUnionAll(Collection polys) {
		Geometry union = null;
		try {
			if(LOGGER.isTraceEnabled()) LOGGER.trace("Try union with CascadedPolygonUnion");
			union = CascadedPolygonUnion.union(polys);
		} catch (Exception e) {
			try {
				if(LOGGER.isTraceEnabled()) LOGGER.trace("Try union with PolygonUnion");
				union = Union.getPolygonUnion(polys);
			} catch (Exception e1) {
				try {
					if(LOGGER.isTraceEnabled()) LOGGER.trace("Try buffer(0)");
					GeometryCollection gc = new GeometryFactory().createGeometryCollection(polys.toArray(new Geometry[polys.size()]));
					union = gc.buffer(0);
				} catch (Exception e2) {
					if(LOGGER.isTraceEnabled()) LOGGER.trace("Try iterative union");
					for(Geometry poly : polys)
						union = union==null? poly : union.union(poly);
				}
			}
		}
		return union;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy