Class UnionInteracting

  1 /*
  2  * Copyright (c) 2016 Vivid Solutions.
  3  *
  4  * All rights reserved. This program and the accompanying materials
  5  * are made available under the terms of the Eclipse Public License 2.0
  6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
  7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
  8  * and the Eclipse Distribution License is available at
  9  *
 10  * http://www.eclipse.org/org/documents/edl-v10.php.
 11  */
 12  
 13 package org.locationtech.jts.operation.union;
 14  
 15 import java.util.ArrayList;
 16 import java.util.List;
 17  
 18 import org.locationtech.jts.geom.Geometry;
 19 import org.locationtech.jts.geom.GeometryFactory;
 20 import org.locationtech.jts.geom.util.GeometryCombiner;
 21  
 22  
 23 /**
 24  * Experimental code to union MultiPolygons
 25  * with processing limited to the elements which actually interact.
 26  * 
 27  * Not currently used, since it doesn't seem to offer much of a performance advantage.
 28  * 
 29  * @author mbdavis
 30  *
 31  */
 32 public class UnionInteracting 
 33 {
 34     public static Geometry union(Geometry g0, Geometry g1)
 35     {
 36         UnionInteracting uue = new UnionInteracting(g0, g1);
 37         return uue.union();
 38     }
 39  
 40     
 41     private GeometryFactory geomFactory;
 42     
 43     private Geometry g0;
 44     private Geometry g1;
 45     
 46     private boolean[] interacts0;
 47     private boolean[] interacts1;
 48     
 49     public UnionInteracting(Geometry g0, Geometry g1)
 50     {
 51         this.g0 = g0;
 52         this.g1 = g1;
 53         geomFactory = g0.getFactory();
 54         interacts0 = new boolean[g0.getNumGeometries()];
 55         interacts1 = new boolean[g1.getNumGeometries()];
 56     }
 57     
 58     public Geometry union()
 59     {
 60         computeInteracting();
 61         
 62         // check for all interacting or none interacting!
 63         
 64         Geometry int0 = extractElements(g0, interacts0, true);
 65         Geometry int1 = extractElements(g1, interacts1, true);
 66         
 67 //        System.out.println(int0);
 68 //        System.out.println(int1);
 69  
 70         if (int0.isEmpty() || int1.isEmpty()) {
 71             System.out.println("found empty!");
 72 //            computeInteracting();
 73         }
 74 //        if (! int0.isValid()) {
 75             //System.out.println(int0);
 76             //throw new RuntimeException("invalid geom!");
 77 //        }
 78         
 79         Geometry union = int0.union(int1);
 80         //Geometry union = bufferUnion(int0, int1);
 81         
 82         Geometry disjoint0 = extractElements(g0, interacts0, false);
 83         Geometry disjoint1 = extractElements(g1, interacts1, false);
 84         
 85       Geometry overallUnion = GeometryCombiner.combine(union, disjoint0, disjoint1);
 86       
 87       return overallUnion;
 88  
 89     }
 90     
 91   private Geometry bufferUnion(Geometry g0, Geometry g1)
 92   {
 93       GeometryFactory factory = g0.getFactory();
 94       Geometry gColl = factory.createGeometryCollection(new Geometry[] { g0, g1 } );
 95       Geometry unionAll = gColl.buffer(0.0);
 96     return unionAll;
 97   }
 98  
 99     private void computeInteracting()
100     {
101         for (int i = 0; i < g0.getNumGeometries(); i++) {
102             Geometry elem = g0.getGeometryN(i);
103             interacts0[i] = computeInteracting(elem);
104         }
105     }
106     
107     private boolean computeInteracting(Geometry elem0)
108     {
109         boolean interactsWithAny = false;
110         for (int i = 0; i < g1.getNumGeometries(); i++) {
111             Geometry elem1 = g1.getGeometryN(i);
112             boolean interacts = elem1.getEnvelopeInternal().intersects(elem0.getEnvelopeInternal());
113             if (interacts) interacts1[i] = true;
114             if (interacts) 
115                 interactsWithAny = true;
116         }
117         return interactsWithAny;
118     }
119     
120   private Geometry extractElements(Geometry geom, 
121           boolean[] interacts, boolean isInteracting)
122   {
123       List extractedGeoms = new ArrayList();
124       for (int i = 0; i < geom.getNumGeometries(); i++) { 
125           Geometry elem = geom.getGeometryN(i);
126           if (interacts[i] == isInteracting)
127               extractedGeoms.add(elem);
128       }
129       return geomFactory.buildGeometry(extractedGeoms);
130   }
131  
132     
133 }
134