Class FacetSequenceTreeBuilder

 1 /*
 2  * Copyright (c) 2016 Martin Davis.
 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.distance;
14  
15 import java.util.ArrayList;
16 import java.util.Iterator;
17 import java.util.List;
18  
19 import org.locationtech.jts.geom.CoordinateSequence;
20 import org.locationtech.jts.geom.Geometry;
21 import org.locationtech.jts.geom.GeometryComponentFilter;
22 import org.locationtech.jts.geom.LineString;
23 import org.locationtech.jts.geom.Point;
24 import org.locationtech.jts.index.strtree.STRtree;
25  
26  
27 public class FacetSequenceTreeBuilder {
28   // 6 seems to be a good facet sequence size
29   private static final int FACET_SEQUENCE_SIZE = 6;
30  
31   // Seems to be better to use a minimum node capacity
32   private static final int STR_TREE_NODE_CAPACITY = 4;
33  
34   public static STRtree build(Geometry g) {
35     STRtree tree = new STRtree(STR_TREE_NODE_CAPACITY);
36     List sections = computeFacetSequences(g);
37     for (Iterator i = sections.iterator(); i.hasNext();) {
38       FacetSequence section = (FacetSequence) i.next();
39       tree.insert(section.getEnvelope(), section);
40     }
41     tree.build();
42     return tree;
43   }
44  
45   /**
46    * Creates facet sequences
47    * 
48    * @param g
49    * @return List<GeometryFacetSequence>
50    */
51   private static List computeFacetSequences(Geometry g) {
52     final List sections = new ArrayList();
53  
54     g.apply(new GeometryComponentFilter() {
55  
56       public void filter(Geometry geom) {
57         CoordinateSequence seq = null;
58         if (geom instanceof LineString) {
59           seq = ((LineString) geom).getCoordinateSequence();
60           addFacetSequences(geom, seq, sections);
61         }
62         else if (geom instanceof Point) {
63           seq = ((Point) geom).getCoordinateSequence();
64           addFacetSequences(geom, seq, sections);
65         }
66       }
67     });
68     return sections;
69   }
70  
71   private static void addFacetSequences(Geometry geom, CoordinateSequence pts, List sections) {
72     int i = 0;
73     int size = pts.size();
74     while (i <= size - 1) {
75       int end = i + FACET_SEQUENCE_SIZE + 1;
76       // if only one point remains after this section, include it in this
77       // section
78       if (end >= size - 1)
79         end = size;
80       FacetSequence sect = new FacetSequence(geom, pts, i, end);
81       sections.add(sect);
82       i = i + FACET_SEQUENCE_SIZE;
83     }
84   }
85 }
86