Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1010 / applications / appgvSIG / src / com / vividsolutions / jump / util / CoordinateArrays.java @ 12804

History | View | Annotate | Download (7.79 KB)

1

    
2
/*
3
 * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI 
4
 * for visualizing and manipulating spatial features with geometry and attributes.
5
 *
6
 * Copyright (C) 2003 Vivid Solutions
7
 * 
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 * 
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 * 
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 * 
22
 * For more information, contact:
23
 *
24
 * Vivid Solutions
25
 * Suite #1A
26
 * 2328 Government Street
27
 * Victoria BC  V8T 5G5
28
 * Canada
29
 *
30
 * (250)385-6040
31
 * www.vividsolutions.com
32
 */
33

    
34
package com.vividsolutions.jump.util;
35

    
36
import java.util.ArrayList;
37
import java.util.Iterator;
38
import java.util.List;
39

    
40
import com.vividsolutions.jts.algorithm.CGAlgorithms;
41
import com.vividsolutions.jts.algorithm.RobustCGAlgorithms;
42
import com.vividsolutions.jts.geom.Coordinate;
43
import com.vividsolutions.jts.geom.Geometry;
44
import com.vividsolutions.jts.geom.GeometryCollection;
45
import com.vividsolutions.jts.geom.GeometryFactory;
46
import com.vividsolutions.jts.geom.LineString;
47
import com.vividsolutions.jts.geom.Polygon;
48
import com.vividsolutions.jts.util.Assert;
49

    
50

    
51
/**
52
 * Some utility functions for handling Coordinate arrays.
53
 */
54
public class CoordinateArrays {
55
    //<<TODO:REFACTORING>> JTS already has a class named CoordinateArrays.
56
    //I wonder if we should collapse this class into that one. [Jon Aquino]
57
    // MD - yep, at some point.
58
    private static final CGAlgorithms cga = new RobustCGAlgorithms();
59
    private final static Coordinate[] coordArrayType = new Coordinate[0];
60

    
61
    public static Coordinate[] toCoordinateArray(List coordList) {
62
        return (Coordinate[]) coordList.toArray(coordArrayType);
63
    }
64

    
65
    //<<TODO:REFACTORING>> This functionality is duplicated in
66
    //the protected method Geometry#reversePointOrder. Perhaps we should
67
    //make that method public and deprecate this method, or have this method
68
    //delegate to the other. [Jon Aquino]
69
    //MD: Geometry#reversePointOrder could delegate to this method.  Can't do it other way around.
70
    public static void reverse(Coordinate[] coord) {
71
        int last = coord.length - 1;
72
        int mid = last / 2;
73

    
74
        for (int i = 0; i <= mid; i++) {
75
            Coordinate tmp = coord[i];
76
            coord[i] = coord[last - i];
77
            coord[last - i] = tmp;
78
        }
79
    }
80

    
81
    /**
82
     * Converts an array of coordinates to a line or point, as appropriate.
83
     * @param coords the coordinates of a line or point
84
     * @param fact a factory used to create the Geometry
85
     * @return a line if there is more than one coordinate; a point if there is
86
     * just one coordinate; an empty point otherwise
87
     */
88
    public static Geometry toLineOrPoint(Coordinate[] coords,
89
        GeometryFactory fact) {
90
        if (coords.length > 1) {
91
            return fact.createLineString(coords);
92
        }
93

    
94
        if (coords.length == 1) {
95
            return fact.createPoint(coords[0]);
96
        }
97

    
98
        return fact.createPoint((Coordinate)null);
99
    }
100

    
101
    public static boolean equals(Coordinate[] coord1, Coordinate[] coord2) {
102
        if (coord1 == coord2) {
103
            return true;
104
        }
105

    
106
        if ((coord1 == null) || (coord2 == null)) {
107
            return false;
108
        }
109

    
110
        if (coord1.length != coord2.length) {
111
            return false;
112
        }
113

    
114
        for (int i = 0; i < coord1.length; i++) {
115
            if (!coord1[i].equals(coord2[i])) {
116
                return false;
117
            }
118
        }
119

    
120
        return true;
121
    }
122

    
123
    /**
124
     * Converts a collection of coordinate arrays to a collection of geometries.
125
     * @param coordArrays a collection of Coordinate[]
126
     * @param fact a factory used to create the Geometries
127
     * @return a collection of LineStrings and Points
128
     */
129
    public static List fromCoordinateArrays(List coordArrays,
130
        GeometryFactory fact) {
131
        List geomList = new ArrayList();
132

    
133
        for (Iterator i = coordArrays.iterator(); i.hasNext();) {
134
            Coordinate[] coords = (Coordinate[]) i.next();
135
            Geometry geom = toLineOrPoint(coords, fact);
136
            geomList.add(geom);
137
        }
138

    
139
        return geomList;
140
    }
141

    
142
    /**
143
     * Extract the coordinate arrays for a geometry into a List.
144
     * @param g the Geometry to extract from
145
     * @param coordArrayList the List to add the coordinate arrays to
146
     * @param orientPolygons whether or not the arrays in the List should be
147
     * oriented (clockwise for the shell, counterclockwise for the holes)
148
     */
149
    public static void addCoordinateArrays(Geometry g, boolean orientPolygons,
150
        List coordArrayList) {
151
        if (g.getDimension() <= 0) {
152
            return;
153
        } else if (g instanceof LineString) {
154
            LineString l = (LineString) g;
155
            coordArrayList.add(l.getCoordinates());
156
        } else if (g instanceof Polygon) {
157
            Polygon poly = (Polygon) g;
158
            Coordinate[] shell = poly.getExteriorRing().getCoordinates();
159

    
160
            if (orientPolygons) {
161
                shell = ensureOrientation(shell, CGAlgorithms.CLOCKWISE);
162
            }
163

    
164
            coordArrayList.add(shell);
165

    
166
            for (int i = 0; i < poly.getNumInteriorRing(); i++) {
167
                Coordinate[] hole = poly.getInteriorRingN(i).getCoordinates();
168

    
169
                if (orientPolygons) {
170
                    hole = ensureOrientation(hole, CGAlgorithms.COUNTERCLOCKWISE);
171
                }
172

    
173
                coordArrayList.add(hole);
174
            }
175
        } else if (g instanceof GeometryCollection) {
176
            GeometryCollection gc = (GeometryCollection) g;
177

    
178
            for (int i = 0; i < gc.getNumGeometries(); i++) {
179
                addCoordinateArrays(gc.getGeometryN(i), orientPolygons,
180
                    coordArrayList);
181
            }
182
        } else {
183
            Assert.shouldNeverReachHere("Geometry of type " +
184
                g.getClass().getName() + " not handled");
185
        }
186
    }
187

    
188
    /**
189
     * Sets the orientation of an array of coordinates.
190
     * @param coord the coordinates to inspect
191
     * @param desiredOrientation CGAlgorithms.CLOCKWISE or CGAlgorithms.COUNTERCLOCKWISE
192
     * @return a new array with entries in reverse order, if the orientation is
193
     * incorrect; otherwise, the original array
194
     */
195
    public static Coordinate[] ensureOrientation(Coordinate[] coord,
196
        int desiredOrientation) {
197
        if (coord.length == 0) {
198
            return coord;
199
        }
200

    
201
        int orientation = cga.isCCW(coord) ? CGAlgorithms.COUNTERCLOCKWISE
202
                                           : CGAlgorithms.CLOCKWISE;
203

    
204
        if (orientation != desiredOrientation) {
205
            Coordinate[] reverse = (Coordinate[]) coord.clone();
206
            CoordinateArrays.reverse(reverse);
207

    
208
            return reverse;
209
        }
210

    
211
        return coord;
212
    }
213

    
214
    /**
215
     * Extract the coordinate arrays for a geometry.
216
     * Polygons will be checked to ensure their rings are oriented correctly.
217
     * Note: coordinates from Points or MultiPoints will not be extracted.
218
     * @param g the Geometry to extract from
219
     * @param orientPolygons ensure that Polygons are correctly oriented
220
     * @return a list of Coordinate[]
221
     */
222
    public static List toCoordinateArrays(Geometry g, boolean orientPolygons) {
223
        List coordArrayList = new ArrayList();
224
        addCoordinateArrays(g, orientPolygons, coordArrayList);
225

    
226
        return coordArrayList;
227
    }
228
}