Statistics
| Revision:

svn-gvsig-desktop / trunk / applications / appgvSIG / src / com / vividsolutions / jump / util / CoordinateArrays.java @ 312

History | View | Annotate | Download (7.49 KB)

1 312 fernando
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.*;
37
38
import com.vividsolutions.jts.algorithm.CGAlgorithms;
39
import com.vividsolutions.jts.algorithm.RobustCGAlgorithms;
40
import com.vividsolutions.jts.geom.*;
41
import com.vividsolutions.jts.util.Assert;
42
43
44
/**
45
 * Some utility functions for handling Coordinate arrays.
46
 */
47
public class CoordinateArrays {
48
    //<<TODO:REFACTORING>> JTS already has a class named CoordinateArrays.
49
    //I wonder if we should collapse this class into that one. [Jon Aquino]
50
    // MD - yep, at some point.
51
    private static final CGAlgorithms cga = new RobustCGAlgorithms();
52
    private final static Coordinate[] coordArrayType = new Coordinate[0];
53
54
    public static Coordinate[] toCoordinateArray(List coordList) {
55
        return (Coordinate[]) coordList.toArray(coordArrayType);
56
    }
57
58
    //<<TODO:REFACTORING>> This functionality is duplicated in
59
    //the protected method Geometry#reversePointOrder. Perhaps we should
60
    //make that method public and deprecate this method, or have this method
61
    //delegate to the other. [Jon Aquino]
62
    //MD: Geometry#reversePointOrder could delegate to this method.  Can't do it other way around.
63
    public static void reverse(Coordinate[] coord) {
64
        int last = coord.length - 1;
65
        int mid = last / 2;
66
67
        for (int i = 0; i <= mid; i++) {
68
            Coordinate tmp = coord[i];
69
            coord[i] = coord[last - i];
70
            coord[last - i] = tmp;
71
        }
72
    }
73
74
    /**
75
     * Converts an array of coordinates to a line or point, as appropriate.
76
     * @param coords the coordinates of a line or point
77
     * @param fact a factory used to create the Geometry
78
     * @return a line if there is more than one coordinate; a point if there is
79
     * just one coordinate; an empty point otherwise
80
     */
81
    public static Geometry toLineOrPoint(Coordinate[] coords,
82
        GeometryFactory fact) {
83
        if (coords.length > 1) {
84
            return fact.createLineString(coords);
85
        }
86
87
        if (coords.length == 1) {
88
            return fact.createPoint(coords[0]);
89
        }
90
91
        return fact.createPoint((Coordinate)null);
92
    }
93
94
    public static boolean equals(Coordinate[] coord1, Coordinate[] coord2) {
95
        if (coord1 == coord2) {
96
            return true;
97
        }
98
99
        if ((coord1 == null) || (coord2 == null)) {
100
            return false;
101
        }
102
103
        if (coord1.length != coord2.length) {
104
            return false;
105
        }
106
107
        for (int i = 0; i < coord1.length; i++) {
108
            if (!coord1[i].equals(coord2[i])) {
109
                return false;
110
            }
111
        }
112
113
        return true;
114
    }
115
116
    /**
117
     * Converts a collection of coordinate arrays to a collection of geometries.
118
     * @param coordArrays a collection of Coordinate[]
119
     * @param fact a factory used to create the Geometries
120
     * @return a collection of LineStrings and Points
121
     */
122
    public static List fromCoordinateArrays(List coordArrays,
123
        GeometryFactory fact) {
124
        List geomList = new ArrayList();
125
126
        for (Iterator i = coordArrays.iterator(); i.hasNext();) {
127
            Coordinate[] coords = (Coordinate[]) i.next();
128
            Geometry geom = toLineOrPoint(coords, fact);
129
            geomList.add(geom);
130
        }
131
132
        return geomList;
133
    }
134
135
    /**
136
     * Extract the coordinate arrays for a geometry into a List.
137
     * @param g the Geometry to extract from
138
     * @param coordArrayList the List to add the coordinate arrays to
139
     * @param orientPolygons whether or not the arrays in the List should be
140
     * oriented (clockwise for the shell, counterclockwise for the holes)
141
     */
142
    public static void addCoordinateArrays(Geometry g, boolean orientPolygons,
143
        List coordArrayList) {
144
        if (g.getDimension() <= 0) {
145
            return;
146
        } else if (g instanceof LineString) {
147
            LineString l = (LineString) g;
148
            coordArrayList.add(l.getCoordinates());
149
        } else if (g instanceof Polygon) {
150
            Polygon poly = (Polygon) g;
151
            Coordinate[] shell = poly.getExteriorRing().getCoordinates();
152
153
            if (orientPolygons) {
154
                shell = ensureOrientation(shell, CGAlgorithms.CLOCKWISE);
155
            }
156
157
            coordArrayList.add(shell);
158
159
            for (int i = 0; i < poly.getNumInteriorRing(); i++) {
160
                Coordinate[] hole = poly.getInteriorRingN(i).getCoordinates();
161
162
                if (orientPolygons) {
163
                    hole = ensureOrientation(hole, CGAlgorithms.COUNTERCLOCKWISE);
164
                }
165
166
                coordArrayList.add(hole);
167
            }
168
        } else if (g instanceof GeometryCollection) {
169
            GeometryCollection gc = (GeometryCollection) g;
170
171
            for (int i = 0; i < gc.getNumGeometries(); i++) {
172
                addCoordinateArrays(gc.getGeometryN(i), orientPolygons,
173
                    coordArrayList);
174
            }
175
        } else {
176
            Assert.shouldNeverReachHere("Geometry of type " +
177
                g.getClass().getName() + " not handled");
178
        }
179
    }
180
181
    /**
182
     * Sets the orientation of an array of coordinates.
183
     * @param coord the coordinates to inspect
184
     * @param desiredOrientation CGAlgorithms.CLOCKWISE or CGAlgorithms.COUNTERCLOCKWISE
185
     * @return a new array with entries in reverse order, if the orientation is
186
     * incorrect; otherwise, the original array
187
     */
188
    public static Coordinate[] ensureOrientation(Coordinate[] coord,
189
        int desiredOrientation) {
190
        if (coord.length == 0) {
191
            return coord;
192
        }
193
194
        int orientation = cga.isCCW(coord) ? CGAlgorithms.COUNTERCLOCKWISE
195
                                           : CGAlgorithms.CLOCKWISE;
196
197
        if (orientation != desiredOrientation) {
198
            Coordinate[] reverse = (Coordinate[]) coord.clone();
199
            CoordinateArrays.reverse(reverse);
200
201
            return reverse;
202
        }
203
204
        return coord;
205
    }
206
207
    /**
208
     * Extract the coordinate arrays for a geometry.
209
     * Polygons will be checked to ensure their rings are oriented correctly.
210
     * Note: coordinates from Points or MultiPoints will not be extracted.
211
     * @param g the Geometry to extract from
212
     * @param orientPolygons ensure that Polygons are correctly oriented
213
     * @return a list of Coordinate[]
214
     */
215
    public static List toCoordinateArrays(Geometry g, boolean orientPolygons) {
216
        List coordArrayList = new ArrayList();
217
        addCoordinateArrays(g, orientPolygons, coordArrayList);
218
219
        return coordArrayList;
220
    }
221
}