Revision 30231 branches/v2_0_0_prep/extensions/org.gvsig.oracle/src/org/gvsig/fmap/dal/store/oracle/OracleUtils.java
OracleUtils.java | ||
---|---|---|
1 |
/* gvSIG. Geographic Information System of the Valencian Government
|
|
1 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
|
2 | 2 |
* |
3 |
* Copyright (C) 2007-2008 Infrastructures and Transports Department |
|
4 |
* of the Valencian Government (CIT) |
|
3 |
* Copyright (C) 2006 Prodevelop and Generalitat Valenciana. |
|
5 | 4 |
* |
6 | 5 |
* This program is free software; you can redistribute it and/or |
7 | 6 |
* modify it under the terms of the GNU General Public License |
... | ... | |
15 | 14 |
* |
16 | 15 |
* You should have received a copy of the GNU General Public License |
17 | 16 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
19 |
* MA 02110-1301, USA. |
|
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA. |
|
20 | 18 |
* |
19 |
* For more information, contact: |
|
20 |
* |
|
21 |
* Generalitat Valenciana |
|
22 |
* Conselleria d'Infraestructures i Transport |
|
23 |
* Av. Blasco Ib??ez, 50 |
|
24 |
* 46010 VALENCIA |
|
25 |
* SPAIN |
|
26 |
* |
|
27 |
* +34 963862235 |
|
28 |
* gvsig@gva.es |
|
29 |
* www.gvsig.gva.es |
|
30 |
* |
|
31 |
* or |
|
32 |
* |
|
33 |
* Prodevelop Integraci?n de Tecnolog?as SL |
|
34 |
* Conde Salvatierra de ?lava , 34-10 |
|
35 |
* 46004 Valencia |
|
36 |
* Spain |
|
37 |
* |
|
38 |
* +34 963 510 612 |
|
39 |
* +34 963 510 968 |
|
40 |
* gis@prodevelop.es |
|
41 |
* http://www.prodevelop.es |
|
21 | 42 |
*/ |
22 |
|
|
23 |
/* |
|
24 |
* AUTHORS (In addition to CIT): |
|
25 |
* 2009 Prodevelop S.L. main development |
|
26 |
*/ |
|
27 | 43 |
package org.gvsig.fmap.dal.store.oracle; |
28 | 44 |
|
29 | 45 |
import java.awt.Shape; |
... | ... | |
45 | 61 |
import java.util.ArrayList; |
46 | 62 |
import java.util.HashMap; |
47 | 63 |
import java.util.Iterator; |
48 |
import java.util.List; |
|
49 | 64 |
import java.util.Random; |
50 | 65 |
|
51 | 66 |
import oracle.sql.ARRAY; |
... | ... | |
54 | 69 |
import oracle.sql.STRUCT; |
55 | 70 |
import oracle.sql.StructDescriptor; |
56 | 71 |
|
72 |
import org.apache.log4j.Logger; |
|
57 | 73 |
import org.gvsig.fmap.geom.Geometry; |
58 | 74 |
import org.gvsig.fmap.geom.GeometryLocator; |
59 | 75 |
import org.gvsig.fmap.geom.GeometryManager; |
60 |
import org.gvsig.fmap.geom.aggregate.Aggregate; |
|
61 |
import org.gvsig.fmap.geom.aggregate.MultiCurve; |
|
62 |
import org.gvsig.fmap.geom.aggregate.MultiPrimitive; |
|
63 |
import org.gvsig.fmap.geom.aggregate.MultiSolid; |
|
64 |
import org.gvsig.fmap.geom.aggregate.MultiSurface; |
|
65 | 76 |
import org.gvsig.fmap.geom.aggregate.impl.MultiPoint2D; |
66 | 77 |
import org.gvsig.fmap.geom.aggregate.impl.MultiPoint2DZ; |
67 |
import org.gvsig.fmap.geom.aggregate.impl.MultiSurface2D; |
|
68 | 78 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
69 |
import org.gvsig.fmap.geom.primitive.Curve; |
|
70 | 79 |
import org.gvsig.fmap.geom.primitive.GeneralPathX; |
71 |
import org.gvsig.fmap.geom.primitive.Point; |
|
72 |
import org.gvsig.fmap.geom.primitive.Primitive; |
|
73 | 80 |
import org.gvsig.fmap.geom.primitive.Surface; |
74 |
import org.gvsig.fmap.geom.primitive.impl.Circle2D; |
|
75 |
import org.gvsig.fmap.geom.primitive.impl.Curve2D; |
|
76 |
import org.gvsig.fmap.geom.primitive.impl.Curve2DZ; |
|
77 | 81 |
import org.gvsig.fmap.geom.primitive.impl.Point2DZ; |
78 |
import org.gvsig.fmap.geom.primitive.impl.Surface2D; |
|
79 |
import org.gvsig.fmap.geom.primitive.impl.Surface2DZ; |
|
80 | 82 |
import org.gvsig.oracle.utils.LineString3D; |
81 |
import org.slf4j.Logger; |
|
82 |
import org.slf4j.LoggerFactory; |
|
83 | 83 |
|
84 |
|
|
84 | 85 |
import com.vividsolutions.jts.algorithm.CGAlgorithms; |
85 | 86 |
import com.vividsolutions.jts.geom.Coordinate; |
86 | 87 |
import com.vividsolutions.jts.geom.CoordinateArrays; |
... | ... | |
88 | 89 |
import com.vividsolutions.jts.geom.GeometryFactory; |
89 | 90 |
import com.vividsolutions.jts.geom.LineString; |
90 | 91 |
import com.vividsolutions.jts.geom.LinearRing; |
91 |
import com.vividsolutions.jts.geom.MultiPoint; |
|
92 | 92 |
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence; |
93 | 93 |
|
94 |
|
|
94 | 95 |
/** |
95 | 96 |
* Utility class with static methods. |
96 |
*
|
|
97 |
* @author jldominguez, vsanjaime
|
|
98 |
*
|
|
97 |
* |
|
98 |
* @author jldominguez |
|
99 |
* |
|
99 | 100 |
*/ |
100 | 101 |
public class OracleUtils { |
102 |
private static Logger logger = Logger.getLogger(OracleSpatialUtils.class.getName()); |
|
103 |
private static double FLATNESS = 0.8; |
|
104 |
private static GeometryFactory geomFactory = new GeometryFactory(); |
|
105 |
private static final double IRRELEVANT_DISTANCE = 0.00000001; |
|
106 |
private static Random rnd = new Random(); |
|
107 |
private static DecimalFormat df = new DecimalFormat(); |
|
108 |
private static DecimalFormatSymbols dfs = new DecimalFormatSymbols(); |
|
109 |
|
|
101 | 110 |
|
102 |
private static Logger logger = LoggerFactory.getLogger(OracleUtils.class |
|
103 |
.getName()); |
|
111 |
/** |
|
112 |
* COnstructs a geometry from a file that contains a vertex per line: |
|
113 |
* |
|
114 |
* x1 y1 z1 |
|
115 |
* x2 y2 z2 |
|
116 |
* ... |
|
117 |
* |
|
118 |
* @param filepath vertices text file path |
|
119 |
* @param polygon whether it is a polygon or not |
|
120 |
* @return the created geometry |
|
121 |
*/ |
|
122 |
public static Geometry readGeometry3D(URL filepath, boolean polygon) { |
|
123 |
|
|
124 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
125 |
|
|
126 |
GeneralPathX resp = new GeneralPathX(); |
|
127 |
File file = new File(filepath.getFile()); |
|
128 |
ArrayList z = new ArrayList(); |
|
104 | 129 |
|
105 |
private static Random rnd = new Random(); |
|
106 |
private static DecimalFormat df = new DecimalFormat(); |
|
107 |
private static DecimalFormatSymbols dfs = new DecimalFormatSymbols(); |
|
130 |
try { |
|
131 |
FileReader fr = new FileReader(file); |
|
132 |
BufferedReader br = new BufferedReader(fr); |
|
133 |
double[] coords = new double[3]; |
|
108 | 134 |
|
109 |
/** |
|
110 |
* Constructs a geometry from a file that contains a vertex per line: |
|
111 |
* |
|
112 |
* x1 y1 z1 x2 y2 z2 ... |
|
113 |
* |
|
114 |
* @param filepath |
|
115 |
* vertices text file path |
|
116 |
* @param polygon |
|
117 |
* whether it is a polygon or not |
|
118 |
* @return the created geometry |
|
119 |
*/ |
|
120 |
public static Geometry readGeometry3D(URL filepath, boolean polygon) { |
|
135 |
boolean move = true; |
|
121 | 136 |
|
122 |
GeometryManager gManager = GeometryLocator.getGeometryManager();
|
|
137 |
String line = br.readLine();
|
|
123 | 138 |
|
124 |
GeneralPathX gpath = new GeneralPathX(); |
|
125 |
File file = new File(filepath.getFile()); |
|
126 |
List<Double> z = new ArrayList<Double>(); |
|
139 |
while (line != null) { |
|
140 |
coords = parseLine(line); |
|
127 | 141 |
|
128 |
try { |
|
129 |
FileReader fr = new FileReader(file); |
|
130 |
BufferedReader br = new BufferedReader(fr); |
|
131 |
double[] coords = new double[3]; |
|
142 |
if (line.length() == 0) { |
|
143 |
move = true; |
|
144 |
} |
|
145 |
else { |
|
146 |
if (move) { |
|
147 |
resp.moveTo(coords[0], coords[1]); |
|
148 |
z.add(new Double(coords[2])); |
|
149 |
} |
|
150 |
else { |
|
151 |
resp.lineTo(coords[0], coords[1]); |
|
152 |
z.add(new Double(coords[2])); |
|
153 |
} |
|
132 | 154 |
|
133 |
boolean move = true; |
|
155 |
move = false; |
|
156 |
} |
|
134 | 157 |
|
135 |
String line = br.readLine(); |
|
158 |
line = br.readLine(); |
|
159 |
} |
|
160 |
} |
|
161 |
catch (Exception ex) { |
|
162 |
logger.error("While creating GeneralPathX: " + |
|
163 |
ex.getMessage()); |
|
136 | 164 |
|
137 |
while (line != null) {
|
|
138 |
coords = parseLine(line);
|
|
165 |
return null;
|
|
166 |
}
|
|
139 | 167 |
|
140 |
if (line.length() == 0) { |
|
141 |
move = true; |
|
142 |
} else { |
|
143 |
if (move) { |
|
144 |
gpath.moveTo(coords[0], coords[1]); |
|
145 |
z.add(new Double(coords[2])); |
|
146 |
} else { |
|
147 |
gpath.lineTo(coords[0], coords[1]); |
|
148 |
z.add(new Double(coords[2])); |
|
149 |
} |
|
168 |
double[] zz = new double[z.size()]; |
|
150 | 169 |
|
151 |
move = false; |
|
152 |
} |
|
170 |
for (int i = 0; i < z.size(); i++) { |
|
171 |
zz[i] = ((Double) z.get(i)).doubleValue(); |
|
172 |
} |
|
153 | 173 |
|
154 |
line = br.readLine(); |
|
155 |
} |
|
156 |
} catch (Exception ex) { |
|
157 |
logger.error("While creating GeneralPathX: " + ex.getMessage()); |
|
174 |
if (polygon) { |
|
175 |
Surface surface = (Surface) geomManager.create(Geometry.TYPES.SURFACE, Geometry.SUBTYPES.GEOM2DZ); |
|
176 |
surface. |
|
177 |
return .createSurface(resp, org.gvsig.fmap.geom.Geometry.SUBTYPES.GEOM2DZ).createPolygon3D(resp, zz); |
|
178 |
} |
|
179 |
else { |
|
180 |
return ShapeFactory.createPolyline3D(resp, zz); |
|
181 |
} |
|
182 |
} |
|
158 | 183 |
|
159 |
return null; |
|
160 |
} |
|
184 |
private static double[] parseLine(String line) { |
|
185 |
String[] sep = line.split(" "); |
|
186 |
double[] resp = new double[3]; |
|
161 | 187 |
|
162 |
double[] zz = new double[z.size()]; |
|
188 |
for (int i = 0; i < 3; i++) |
|
189 |
resp[i] = 0.0; |
|
163 | 190 |
|
164 |
for (int i = 0; i < z.size(); i++) { |
|
165 |
zz[i] = ((Double) z.get(i)).doubleValue(); |
|
166 |
} |
|
191 |
try { |
|
192 |
resp[0] = Double.parseDouble(sep[0]); |
|
193 |
} |
|
194 |
catch (Exception ex) { |
|
195 |
} |
|
167 | 196 |
|
168 |
if (polygon) { |
|
169 |
try { |
|
170 |
return gManager.createSurface(gpath, Geometry.SUBTYPES.GEOM3D); |
|
171 |
} catch (CreateGeometryException e) { |
|
172 |
e.printStackTrace(); |
|
173 |
return null; |
|
174 |
} |
|
175 |
} else { |
|
176 |
try { |
|
177 |
return gManager.createCurve(gpath, Geometry.SUBTYPES.GEOM3D); |
|
178 |
} catch (CreateGeometryException e) { |
|
179 |
e.printStackTrace(); |
|
180 |
return null; |
|
181 |
} |
|
182 |
} |
|
183 |
} |
|
197 |
if (sep.length > 1) { |
|
198 |
try { |
|
199 |
resp[1] = Double.parseDouble(sep[1]); |
|
200 |
} |
|
201 |
catch (Exception ex) { |
|
202 |
} |
|
184 | 203 |
|
185 |
/** |
|
186 |
* Parse line |
|
187 |
* |
|
188 |
* @param line |
|
189 |
* @return |
|
190 |
*/ |
|
191 |
private static double[] parseLine(String line) { |
|
192 |
String[] sep = line.split(" "); |
|
193 |
double[] resp = new double[3]; |
|
204 |
if (sep.length > 2) { |
|
205 |
try { |
|
206 |
resp[2] = Double.parseDouble(sep[2]); |
|
207 |
} |
|
208 |
catch (Exception ex) { |
|
209 |
} |
|
210 |
} |
|
211 |
} |
|
194 | 212 |
|
195 |
for (int i = 0; i < 3; i++)
|
|
196 |
resp[i] = 0.0;
|
|
213 |
return resp;
|
|
214 |
}
|
|
197 | 215 |
|
198 |
try { |
|
199 |
resp[0] = Double.parseDouble(sep[0]); |
|
200 |
} catch (Exception ex) { |
|
201 |
} |
|
216 |
|
|
202 | 217 |
|
203 |
if (sep.length > 1) { |
|
204 |
try { |
|
205 |
resp[1] = Double.parseDouble(sep[1]); |
|
206 |
} catch (Exception ex) { |
|
207 |
} |
|
218 |
private static STRUCT multiPoint2DToStruct(MultiPoint2D mp2d, |
|
219 |
Connection c, int srid, boolean hasSrid) throws SQLException { |
|
220 |
int np = mp2d.getNumPoints(); |
|
221 |
boolean threed = (mp2d instanceof MultiPoint2DZ); |
|
222 |
int gtype = 2005; |
|
223 |
int dim = 2; |
|
224 |
MultiPoint2DZ mp3d = null; |
|
208 | 225 |
|
209 |
if (sep.length > 2) { |
|
210 |
try { |
|
211 |
resp[2] = Double.parseDouble(sep[2]); |
|
212 |
} catch (Exception ex) { |
|
213 |
} |
|
214 |
} |
|
215 |
} |
|
226 |
if (threed) { |
|
227 |
gtype = 3005; |
|
228 |
dim = 3; |
|
229 |
mp3d = (MultiPoint2DZ) mp2d; |
|
230 |
} |
|
216 | 231 |
|
217 |
return resp; |
|
218 |
} |
|
232 |
NUMBER[] indices = new NUMBER[3]; |
|
233 |
indices[0] = new NUMBER(1); |
|
234 |
indices[1] = new NUMBER(1); |
|
235 |
indices[2] = new NUMBER(np); |
|
219 | 236 |
|
220 |
/** |
|
221 |
* Utility method to convert a gvSIG FShape into a oracle struct |
|
222 |
* |
|
223 |
* @param geom |
|
224 |
* the FShape object |
|
225 |
* @param c |
|
226 |
* the connection |
|
227 |
* @param srid |
|
228 |
* the SRS (oracle code) |
|
229 |
* @param agu_b |
|
230 |
* whether to check holes validity |
|
231 |
* @param hasSrid |
|
232 |
* whether the SRS is non-NULL |
|
233 |
* @return a oracle struct representing the geometry |
|
234 |
* |
|
235 |
* @throws SQLException |
|
236 |
*/ |
|
237 |
public static STRUCT GeometryToSTRUCT(Geometry geom, Connection c, |
|
238 |
int srid, boolean agu_b, boolean hasSrid) throws SQLException { |
|
237 |
NUMBER[] ords = new NUMBER[dim * np]; |
|
239 | 238 |
|
240 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
241 |
|
|
242 |
STRUCT resp = null; |
|
243 |
|
|
244 |
// PRIMITIVES |
|
245 |
if (geom instanceof Primitive ) { |
|
246 |
//POINT |
|
247 |
if (geom instanceof Point ) { |
|
248 |
// POINT 2D |
|
249 |
if (geom instanceof Point2D) { |
|
250 |
Coordinate p = getSingleCoordinate2D((Point2D) geom); |
|
251 |
resp = getMultiPointAsStruct(p, srid, false, c, hasSrid); |
|
252 |
return resp; |
|
253 |
} |
|
254 |
// POINT 2DZ |
|
255 |
if (geom instanceof Point2DZ) { |
|
256 |
Coordinate p = getSingleCoordinate3D((Point2DZ) geom); |
|
257 |
resp = getMultiPointAsStruct(p, srid, true, c, hasSrid); |
|
258 |
return resp; |
|
259 |
} |
|
260 |
} |
|
261 |
// CURVE |
|
262 |
if (geom instanceof Curve ) { |
|
263 |
|
|
264 |
} |
|
265 |
// SURFACE |
|
266 |
if (geom instanceof Surface ) { |
|
267 |
|
|
268 |
} |
|
269 |
} |
|
270 |
|
|
271 |
// AGGREGATE |
|
272 |
if (geom instanceof Aggregate ) { |
|
273 |
// MULTIPRIMITIVE |
|
274 |
if (geom instanceof MultiPrimitive ) { |
|
275 |
|
|
276 |
} |
|
277 |
// MULTIPOINT |
|
278 |
if (geom instanceof MultiPoint ) { |
|
279 |
// MULTIPOINT 2D |
|
280 |
if (geom instanceof MultiPoint2D) { |
|
281 |
resp = multiPoint2DToStruct((MultiPoint2D) geom, c, srid, hasSrid); |
|
282 |
return resp; |
|
283 |
} |
|
284 |
// MULTIPOINT 2DZ |
|
285 |
if (geom instanceof MultiPoint2DZ) { |
|
286 |
resp = multiPoint2DZToStruct((MultiPoint2DZ) geom, c, srid, hasSrid); |
|
287 |
return resp; |
|
288 |
} |
|
289 |
} |
|
290 |
// MULTICURVE |
|
291 |
if (geom instanceof MultiCurve ) { |
|
292 |
|
|
293 |
} |
|
294 |
// MULTISURFACE |
|
295 |
if (geom instanceof MultiSurface ) { |
|
296 |
|
|
297 |
} |
|
298 |
// MULTISOLID |
|
299 |
if (geom instanceof MultiSolid ) { |
|
300 |
return null; |
|
301 |
} |
|
302 |
} |
|
303 |
|
|
304 |
|
|
305 |
|
|
239 |
for (int i = 0; i < np; i++) { |
|
240 |
ords[dim * i] = new NUMBER(mp2d.getPoint(i).getX()); |
|
241 |
ords[(dim * i) + 1] = new NUMBER(mp2d.getPoint(i).getY()); |
|
306 | 242 |
|
307 |
|
|
243 |
if (threed) { |
|
244 |
ords[(dim * i) + 2] = new NUMBER(mp3d.getZs()[i]); |
|
245 |
} |
|
246 |
} |
|
308 | 247 |
|
309 |
|
|
248 |
STRUCT resp; |
|
249 |
StructDescriptor dsc = StructDescriptor.createDescriptor("MDSYS.SDO_GEOMETRY", |
|
250 |
((ConnectionJDBC)c).getConnection()); |
|
251 |
Object[] obj = new Object[5]; |
|
252 |
obj[0] = new NUMBER(gtype); |
|
310 | 253 |
|
311 |
|
|
312 |
// POINT |
|
313 |
if (geom instanceof Point2D) { |
|
254 |
if (hasSrid) { |
|
255 |
obj[1] = new NUMBER(srid); |
|
256 |
} |
|
257 |
else { // , boolean hasSrid |
|
258 |
obj[1] = null; |
|
259 |
} |
|
314 | 260 |
|
315 |
Coordinate p = getSingleCoordinate((Point2D) geom);
|
|
316 |
resp = getMultiPointAsStruct(p, srid, three, c, hasSrid);
|
|
317 |
} else {
|
|
318 |
if (geom instanceof Surface2D) { // polygon 2/3d
|
|
261 |
obj[2] = null;
|
|
262 |
obj[3] = indices;
|
|
263 |
obj[4] = ords;
|
|
264 |
resp = new STRUCT(dsc, ((ConnectionJDBC)c).getConnection(), obj);
|
|
319 | 265 |
|
320 |
if (geom instanceof Circle2D) { |
|
321 |
resp = getCircleAsStruct((Circle2D) geom, srid, c, hasSrid); |
|
322 |
} else { |
|
323 |
// also FEllipse2D |
|
324 |
resp = getMultiPolygonAsStruct((MultiSurface) geom, srid, |
|
325 |
three, c, agu_b, hasSrid); |
|
266 |
return resp; |
|
267 |
} |
|
326 | 268 |
|
327 |
} |
|
328 |
} |
|
329 |
//LINE |
|
330 |
else { // line 2/3d |
|
269 |
private static STRUCT getCircleAsStruct(FCircle2D fcirc, int srid, |
|
270 |
Connection _conn, boolean hasSrid) throws SQLException { |
|
271 |
int geotype = 2003; |
|
272 |
NUMBER[] indices = new NUMBER[3]; |
|
273 |
indices[0] = new NUMBER(1); |
|
274 |
indices[1] = new NUMBER(1003); |
|
275 |
indices[2] = new NUMBER(4); |
|
331 | 276 |
|
332 |
List<LineString3D> _lines = getLineStrings((Shape) geom); |
|
333 |
resp = getMultiLineAsStruct(_lines, srid, three, c, hasSrid); |
|
334 |
} |
|
335 |
} |
|
277 |
NUMBER[] ords = new NUMBER[6]; |
|
278 |
Coordinate[] three_points = getThreePointsOfCircumference(fcirc.getCenter(), |
|
279 |
fcirc.getRadio()); |
|
336 | 280 |
|
337 |
return resp; |
|
338 |
} |
|
281 |
for (int i = 0; i < three_points.length; i++) { |
|
282 |
ords[i * 2] = new NUMBER(three_points[i].x); |
|
283 |
ords[(i * 2) + 1] = new NUMBER(three_points[i].y); |
|
284 |
} |
|
339 | 285 |
|
340 |
private static STRUCT multiPoint2DToStruct(MultiPoint2D mp2d, Connection c, |
|
341 |
int srid, boolean hasSrid) throws SQLException { |
|
342 |
int np = mp2d.getPrimitivesNumber(); |
|
343 |
boolean threed = (mp2d instanceof MultiPoint2DZ); |
|
344 |
int gtype = 2005; |
|
345 |
int dim = 2; |
|
346 |
MultiPoint2DZ mp3d = null; |
|
286 |
STRUCT resp; |
|
287 |
StructDescriptor dsc = StructDescriptor.createDescriptor("MDSYS.SDO_GEOMETRY", |
|
288 |
((ConnectionJDBC)_conn).getConnection()); |
|
289 |
Object[] obj = new Object[5]; |
|
290 |
obj[0] = new NUMBER(geotype); |
|
347 | 291 |
|
348 |
if (threed) { |
|
349 |
gtype = 3005; |
|
350 |
dim = 3; |
|
351 |
mp3d = (MultiPoint2DZ) mp2d; |
|
352 |
} |
|
292 |
if (hasSrid) { |
|
293 |
obj[1] = new NUMBER(srid); |
|
294 |
} |
|
295 |
else { |
|
296 |
obj[1] = null; |
|
297 |
} |
|
353 | 298 |
|
354 |
NUMBER[] indices = new NUMBER[3];
|
|
355 |
indices[0] = new NUMBER(1);
|
|
356 |
indices[1] = new NUMBER(1);
|
|
357 |
indices[2] = new NUMBER(np);
|
|
299 |
obj[2] = null;
|
|
300 |
obj[3] = indices;
|
|
301 |
obj[4] = ords;
|
|
302 |
resp = new STRUCT(dsc, ((ConnectionJDBC)_conn).getConnection(), obj);
|
|
358 | 303 |
|
359 |
NUMBER[] ords = new NUMBER[dim * np]; |
|
304 |
return resp; |
|
305 |
} |
|
360 | 306 |
|
361 |
for (int i = 0; i < np; i++) { |
|
362 |
ords[dim * i] = new NUMBER(mp2d.getPoint(i).getX()); |
|
363 |
ords[(dim * i) + 1] = new NUMBER(mp2d.getPoint(i).getY()); |
|
307 |
private static Coordinate[] getThreePointsOfCircumference(Point2D cntr, |
|
308 |
double radius) { |
|
309 |
Coordinate[] resp = new Coordinate[3]; |
|
310 |
double x; |
|
311 |
double y; |
|
312 |
double alpha = 0; |
|
364 | 313 |
|
365 |
if (threed) { |
|
366 |
ords[(dim * i) + 2] = new NUMBER(mp3d.getZs()[i]); |
|
367 |
} |
|
368 |
} |
|
314 |
for (int i = 0; i < 3; i++) { |
|
315 |
alpha = (i * 120.0 * Math.PI) / 180.0; |
|
316 |
x = cntr.getX() + (radius * Math.cos(alpha)); |
|
317 |
y = cntr.getY() + (radius * Math.sin(alpha)); |
|
318 |
resp[i] = new Coordinate(x, y); |
|
319 |
} |
|
369 | 320 |
|
370 |
STRUCT resp; |
|
371 |
StructDescriptor dsc = StructDescriptor.createDescriptor( |
|
372 |
"MDSYS.SDO_GEOMETRY", c); |
|
373 |
Object[] obj = new Object[5]; |
|
374 |
obj[0] = new NUMBER(gtype); |
|
321 |
return resp; |
|
322 |
} |
|
375 | 323 |
|
376 |
if (hasSrid) {
|
|
377 |
obj[1] = new NUMBER(srid);
|
|
378 |
} else { // , boolean hasSrid
|
|
379 |
obj[1] = null;
|
|
380 |
}
|
|
324 |
private static Coordinate getSingleCoordinate(Point2D p2d) {
|
|
325 |
// TODO Auto-generated method stub
|
|
326 |
Coordinate resp = new Coordinate();
|
|
327 |
resp.x = p2d.getX();
|
|
328 |
resp.y = p2d.getY();
|
|
381 | 329 |
|
382 |
obj[2] = null; |
|
383 |
obj[3] = indices; |
|
384 |
obj[4] = ords; |
|
385 |
resp = new STRUCT(dsc, c, obj); |
|
330 |
if (p2d instanceof Point2DZ) { |
|
331 |
resp.z = ((Point2DZ) p2d).getZs()[0]; |
|
332 |
} |
|
386 | 333 |
|
387 |
return resp;
|
|
388 |
}
|
|
334 |
return resp;
|
|
335 |
}
|
|
389 | 336 |
|
390 |
/** |
|
391 |
* Get struct from circle |
|
392 |
* |
|
393 |
* @param fcirc |
|
394 |
* @param srid |
|
395 |
* @param _conn |
|
396 |
* @param hasSrid |
|
397 |
* @return |
|
398 |
* @throws SQLException |
|
399 |
*/ |
|
400 |
private static STRUCT getCircleAsStruct(Circle2D fcirc, int srid, |
|
401 |
Connection _conn, boolean hasSrid) throws SQLException { |
|
402 |
int geotype = 2003; |
|
403 |
NUMBER[] indices = new NUMBER[3]; |
|
404 |
indices[0] = new NUMBER(1); |
|
405 |
indices[1] = new NUMBER(1003); |
|
406 |
indices[2] = new NUMBER(4); |
|
337 |
private static ArrayList ensureSensibleLineString(ArrayList cc) { |
|
338 |
if (cc.size() == 2) { |
|
339 |
if (sameCoordinate((Coordinate) cc.get(0), |
|
340 |
(Coordinate) cc.get(cc.size() - 1))) { |
|
341 |
ArrayList resp = new ArrayList(); |
|
342 |
resp.add(cc.get(0)); |
|
407 | 343 |
|
408 |
NUMBER[] ords = new NUMBER[6];
|
|
409 |
Coordinate[] three_points = getThreePointsOfCircumference(
|
|
410 |
(Point2D) fcirc.getCenter(), fcirc.getRadious());
|
|
344 |
Coordinate newc = new Coordinate((Coordinate) cc.get(0));
|
|
345 |
newc.x = newc.x + IRRELEVANT_DISTANCE;
|
|
346 |
resp.add(newc);
|
|
411 | 347 |
|
412 |
for (int i = 0; i < three_points.length; i++) { |
|
413 |
ords[i * 2] = new NUMBER(three_points[i].x); |
|
414 |
ords[(i * 2) + 1] = new NUMBER(three_points[i].y); |
|
415 |
} |
|
348 |
return resp; |
|
349 |
} |
|
350 |
} |
|
416 | 351 |
|
417 |
STRUCT resp; |
|
418 |
StructDescriptor dsc = StructDescriptor.createDescriptor( |
|
419 |
"MDSYS.SDO_GEOMETRY", _conn); |
|
420 |
Object[] obj = new Object[5]; |
|
421 |
obj[0] = new NUMBER(geotype); |
|
352 |
return cc; |
|
353 |
} |
|
422 | 354 |
|
423 |
if (hasSrid) { |
|
424 |
obj[1] = new NUMBER(srid); |
|
425 |
} else { |
|
426 |
obj[1] = null; |
|
427 |
} |
|
355 |
private static boolean sameCoordinate(Coordinate c1, Coordinate c2) { |
|
356 |
if (c1.x != c2.x) { |
|
357 |
return false; |
|
358 |
} |
|
428 | 359 |
|
429 |
obj[2] = null; |
|
430 |
obj[3] = indices; |
|
431 |
obj[4] = ords; |
|
432 |
resp = new STRUCT(dsc, _conn, obj); |
|
360 |
if (c1.y != c2.y) { |
|
361 |
return false; |
|
362 |
} |
|
433 | 363 |
|
434 |
return resp;
|
|
435 |
}
|
|
364 |
return true;
|
|
365 |
}
|
|
436 | 366 |
|
437 |
private static Coordinate[] getThreePointsOfCircumference(Point2D cntr, |
|
438 |
double radius) { |
|
439 |
Coordinate[] resp = new Coordinate[3]; |
|
440 |
double x; |
|
441 |
double y; |
|
442 |
double alpha = 0; |
|
367 |
private static ArrayList getClosedRelevantPolygon(ArrayList cc) { |
|
368 |
if (cc.size() == 2) { |
|
369 |
return getMinClosedCoords((Coordinate) cc.get(0)); |
|
370 |
} |
|
443 | 371 |
|
444 |
for (int i = 0; i < 3; i++) { |
|
445 |
alpha = (i * 120.0 * Math.PI) / 180.0; |
|
446 |
x = cntr.getX() + (radius * Math.cos(alpha)); |
|
447 |
y = cntr.getY() + (radius * Math.sin(alpha)); |
|
448 |
resp[i] = new Coordinate(x, y); |
|
449 |
} |
|
372 |
if (cc.size() == 3) { |
|
373 |
if (sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(1))) { |
|
374 |
return getMinClosedCoords((Coordinate) cc.get(0)); |
|
375 |
} |
|
450 | 376 |
|
451 |
return resp; |
|
452 |
} |
|
377 |
if (sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(2))) { |
|
378 |
return getMinClosedCoords((Coordinate) cc.get(0)); |
|
379 |
} |
|
453 | 380 |
|
454 |
/** |
|
455 |
* Get coordinate 2d |
|
456 |
* |
|
457 |
* @param p2d |
|
458 |
* @return |
|
459 |
*/ |
|
460 |
private static Coordinate getSingleCoordinate2D(Point2D p2d) { |
|
461 |
Coordinate resp = new Coordinate(); |
|
462 |
resp.x = p2d.getX(); |
|
463 |
resp.y = p2d.getY(); |
|
464 |
return resp; |
|
465 |
} |
|
466 |
|
|
467 |
/** |
|
468 |
* Get coordinate 3d |
|
469 |
* |
|
470 |
* @param p2dz |
|
471 |
* @return |
|
472 |
*/ |
|
473 |
private static Coordinate getSingleCoordinate3D(Point2DZ p2dz) { |
|
474 |
Coordinate resp = new Coordinate(); |
|
475 |
resp.x = p2dz.getX(); |
|
476 |
resp.y = p2dz.getY(); |
|
477 |
resp.z = p2dz.getCoordinateAt(3); |
|
478 |
return resp; |
|
479 |
} |
|
381 |
if (sameCoordinate((Coordinate) cc.get(1), (Coordinate) cc.get(2))) { |
|
382 |
return getMinClosedCoords((Coordinate) cc.get(1)); |
|
383 |
} |
|
480 | 384 |
|
481 |
/** |
|
482 |
* tolerance |
|
483 |
* |
|
484 |
* @param cc |
|
485 |
* @return |
|
486 |
*/ |
|
487 |
private static List<Coordinate> ensureSensibleLineString(List<Coordinate> cc) { |
|
488 |
if (cc.size() == 2) { |
|
489 |
if (sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(cc |
|
490 |
.size() - 1))) { |
|
491 |
List<Coordinate> resp = new ArrayList<Coordinate>(); |
|
492 |
resp.add(cc.get(0)); |
|
385 |
cc.add(cc.get(0)); |
|
493 | 386 |
|
494 |
Coordinate newc = new Coordinate((Coordinate) cc.get(0)); |
|
495 |
newc.x = newc.x + OracleValues.IRRELEVANT_DISTANCE; |
|
496 |
resp.add(newc); |
|
387 |
return cc; |
|
388 |
} |
|
497 | 389 |
|
498 |
return resp; |
|
499 |
} |
|
500 |
} |
|
390 |
if (!sameCoordinate((Coordinate) cc.get(0), |
|
391 |
(Coordinate) cc.get(cc.size() - 1))) { |
|
392 |
cc.add(cc.get(0)); |
|
393 |
} |
|
501 | 394 |
|
502 |
return cc;
|
|
503 |
}
|
|
395 |
return cc;
|
|
396 |
}
|
|
504 | 397 |
|
505 |
/** |
|
506 |
* Validate if two coordinates are equal |
|
507 |
* |
|
508 |
* @param c1 |
|
509 |
* @param c2 |
|
510 |
* @return |
|
511 |
*/ |
|
512 |
private static boolean sameCoordinate(Coordinate c1, Coordinate c2) { |
|
513 |
if (c1.x != c2.x) { |
|
514 |
return false; |
|
515 |
} |
|
398 |
private static ArrayList getMinClosedCoords(Coordinate c) { |
|
399 |
ArrayList resp = new ArrayList(); |
|
400 |
resp.add(c); |
|
516 | 401 |
|
517 |
if (c1.y != c2.y) {
|
|
518 |
return false;
|
|
519 |
}
|
|
402 |
Coordinate nc = new Coordinate(c);
|
|
403 |
nc.x = nc.x + IRRELEVANT_DISTANCE;
|
|
404 |
resp.add(nc);
|
|
520 | 405 |
|
521 |
return true; |
|
522 |
} |
|
406 |
Coordinate nc2 = new Coordinate(nc); |
|
407 |
nc2.y = nc2.y + IRRELEVANT_DISTANCE; |
|
408 |
resp.add(nc2); |
|
523 | 409 |
|
524 |
private static List<Coordinate> getClosedRelevantPolygon(List<Coordinate> cc) { |
|
525 |
if (cc.size() == 2) { |
|
526 |
return getMinClosedCoords((Coordinate) cc.get(0)); |
|
527 |
} |
|
410 |
resp.add(new Coordinate(c)); |
|
528 | 411 |
|
529 |
if (cc.size() == 3) { |
|
530 |
if (sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(1))) { |
|
531 |
return getMinClosedCoords((Coordinate) cc.get(0)); |
|
532 |
} |
|
412 |
return resp; |
|
413 |
} |
|
533 | 414 |
|
534 |
if (sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(2))) {
|
|
535 |
return getMinClosedCoords((Coordinate) cc.get(0));
|
|
536 |
}
|
|
415 |
private static LinearRing getMinLinearRing(Coordinate c) {
|
|
416 |
Coordinate[] p = new Coordinate[4];
|
|
417 |
p[0] = c;
|
|
537 | 418 |
|
538 |
if (sameCoordinate((Coordinate) cc.get(1), (Coordinate) cc.get(2))) { |
|
539 |
return getMinClosedCoords((Coordinate) cc.get(1)); |
|
540 |
} |
|
419 |
Coordinate nc = new Coordinate(c); |
|
420 |
nc.x = nc.x + IRRELEVANT_DISTANCE; |
|
541 | 421 |
|
542 |
cc.add(cc.get(0)); |
|
422 |
Coordinate nc2 = new Coordinate(nc); |
|
423 |
nc2.y = nc2.y - IRRELEVANT_DISTANCE; |
|
424 |
p[1] = nc; |
|
425 |
p[2] = nc2; |
|
426 |
p[3] = new Coordinate(c); |
|
543 | 427 |
|
544 |
return cc;
|
|
545 |
}
|
|
428 |
CoordinateArraySequence cs = new CoordinateArraySequence(p);
|
|
429 |
LinearRing ls = new LinearRing(cs, geomFactory);
|
|
546 | 430 |
|
547 |
if (!sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(cc |
|
548 |
.size() - 1))) { |
|
549 |
cc.add(cc.get(0)); |
|
550 |
} |
|
431 |
return ls; |
|
432 |
} |
|
551 | 433 |
|
552 |
return cc;
|
|
553 |
}
|
|
434 |
private static double[] getMinLinearRingZ() {
|
|
435 |
double[] resp = new double[4];
|
|
554 | 436 |
|
555 |
private static List<Coordinate> getMinClosedCoords(Coordinate c) { |
|
556 |
List<Coordinate> resp = new ArrayList<Coordinate>(); |
|
557 |
resp.add(c); |
|
437 |
for (int i = 0; i < 4; i++) |
|
438 |
resp[i] = 0.0; |
|
558 | 439 |
|
559 |
Coordinate nc = new Coordinate(c); |
|
560 |
nc.x = nc.x + OracleValues.IRRELEVANT_DISTANCE; |
|
561 |
resp.add(nc); |
|
440 |
return resp; |
|
441 |
} |
|
562 | 442 |
|
563 |
Coordinate nc2 = new Coordinate(nc); |
|
564 |
nc2.y = nc2.y + OracleValues.IRRELEVANT_DISTANCE; |
|
565 |
resp.add(nc2); |
|
443 |
private static boolean pointInList(Coordinate testPoint, |
|
444 |
Coordinate[] pointList) { |
|
445 |
int t; |
|
446 |
int numpoints; |
|
447 |
Coordinate p; |
|
566 | 448 |
|
567 |
resp.add(new Coordinate(c));
|
|
449 |
numpoints = Array.getLength(pointList);
|
|
568 | 450 |
|
569 |
return resp;
|
|
570 |
}
|
|
451 |
for (t = 0; t < numpoints; t++) {
|
|
452 |
p = pointList[t];
|
|
571 | 453 |
|
572 |
private static LinearRing getMinLinearRing(Coordinate c) { |
|
573 |
Coordinate[] p = new Coordinate[4]; |
|
574 |
p[0] = c; |
|
454 |
if ((testPoint.x == p.x) && (testPoint.y == p.y) && |
|
455 |
((testPoint.z == p.z) || (!(testPoint.z == testPoint.z))) //nan test; x!=x iff x is nan |
|
456 |
) { |
|
457 |
return true; |
|
458 |
} |
|
459 |
} |
|
575 | 460 |
|
576 |
Coordinate nc = new Coordinate(c);
|
|
577 |
nc.x = nc.x + OracleValues.IRRELEVANT_DISTANCE;
|
|
461 |
return false;
|
|
462 |
}
|
|
578 | 463 |
|
579 |
Coordinate nc2 = new Coordinate(nc); |
|
580 |
nc2.y = nc2.y - OracleValues.IRRELEVANT_DISTANCE; |
|
581 |
p[1] = nc; |
|
582 |
p[2] = nc2; |
|
583 |
p[3] = new Coordinate(c); |
|
464 |
private static ArrayList getPolygonsEasily(FShape mpolygon) { |
|
465 |
boolean threed = false; |
|
584 | 466 |
|
585 |
CoordinateArraySequence cs = new CoordinateArraySequence(p); |
|
586 |
LinearRing ls = new LinearRing(cs, geomFactory); |
|
467 |
if (mpolygon instanceof FPolygon3D) { |
|
468 |
threed = true; |
|
469 |
} |
|
587 | 470 |
|
588 |
return ls; |
|
589 |
} |
|
471 |
int start_ind = 0; |
|
472 |
int end_ind = 0; |
|
473 |
int ind = 0; |
|
474 |
int new_size; |
|
475 |
ArrayList arrayCoords = null; |
|
476 |
ArrayList resp = new ArrayList(); |
|
477 |
Coordinate[] points = null; |
|
478 |
int theType = -99; |
|
479 |
double[] theData = new double[6]; |
|
480 |
Coordinate onlyCoord = null; |
|
481 |
int numParts = 0; |
|
590 | 482 |
|
591 |
private static double[] getMinLinearRingZ() { |
|
592 |
double[] resp = new double[4]; |
|
483 |
PathIterator theIterator = mpolygon.getPathIterator(null, FLATNESS); |
|
593 | 484 |
|
594 |
for (int i = 0; i < 4; i++) |
|
595 |
resp[i] = 0.0; |
|
485 |
while (!theIterator.isDone()) { |
|
486 |
//while not done |
|
487 |
theType = theIterator.currentSegment(theData); |
|
596 | 488 |
|
597 |
return resp; |
|
598 |
} |
|
489 |
if (onlyCoord == null) { |
|
490 |
onlyCoord = new Coordinate(); |
|
491 |
onlyCoord.x = theData[0]; |
|
492 |
onlyCoord.y = theData[1]; |
|
493 |
} |
|
599 | 494 |
|
600 |
private static boolean pointInList(Coordinate testPoint, |
|
601 |
Coordinate[] pointList) { |
|
602 |
int t; |
|
603 |
int numpoints; |
|
604 |
Coordinate p; |
|
495 |
switch (theType) { |
|
496 |
case PathIterator.SEG_MOVETO: |
|
605 | 497 |
|
606 |
numpoints = Array.getLength(pointList); |
|
498 |
if (arrayCoords == null) { |
|
499 |
arrayCoords = new ArrayList(); |
|
500 |
} |
|
501 |
else { |
|
502 |
end_ind = ind - 1; |
|
607 | 503 |
|
608 |
for (t = 0; t < numpoints; t++) {
|
|
609 |
p = pointList[t];
|
|
504 |
arrayCoords = getClosedRelevantPolygon(arrayCoords);
|
|
505 |
new_size = arrayCoords.size();
|
|
610 | 506 |
|
611 |
if ((testPoint.x == p.x) |
|
612 |
&& (testPoint.y == p.y) |
|
613 |
&& ((testPoint.z == p.z) || (!(testPoint.z == testPoint.z)))) { |
|
614 |
return true; |
|
615 |
} |
|
616 |
} |
|
507 |
if (arrayCoords != null) { |
|
508 |
points = CoordinateArrays.toCoordinateArray(arrayCoords); |
|
617 | 509 |
|
618 |
return false; |
|
619 |
} |
|
510 |
try { |
|
511 |
LinearRing aux = geomFactory.createLinearRing(points); |
|
512 |
double[] z = null; |
|
620 | 513 |
|
621 |
private static List<LineString3D> getPolygonsEasily(Geometry mpolygon) { |
|
622 |
boolean threed = false; |
|
514 |
if (threed) { |
|
515 |
z = getZ((FPolygon3D) mpolygon, start_ind, |
|
516 |
end_ind, new_size); |
|
517 |
} |
|
623 | 518 |
|
624 |
if (mpolygon instanceof Surface2DZ) { |
|
625 |
threed = true; |
|
626 |
} |
|
519 |
LineString3D ring = new LineString3D(aux, z); |
|
627 | 520 |
|
628 |
int start_ind = 0; |
|
629 |
int end_ind = 0; |
|
630 |
int ind = 0; |
|
631 |
int new_size; |
|
632 |
List<Coordinate> arrayCoords = null; |
|
633 |
List<LineString3D> resp = new ArrayList<LineString3D>(); |
|
634 |
Coordinate[] points = null; |
|
635 |
int theType = -99; |
|
636 |
double[] theData = new double[6]; |
|
637 |
Coordinate onlyCoord = null; |
|
638 |
int numParts = 0; |
|
521 |
if (CGAlgorithms.isCCW(points)) { |
|
522 |
resp.add(ring); |
|
523 |
} |
|
524 |
else { |
|
525 |
resp.add(ring.createReverse()); |
|
526 |
} |
|
527 |
} |
|
528 |
catch (Exception e) { |
|
529 |
logger.error("Topology exception: " + |
|
530 |
e.getMessage()); |
|
639 | 531 |
|
640 |
PathIterator theIterator = mpolygon.getPathIterator(null, OracleValues.FLATNESS); |
|
532 |
return null; |
|
533 |
} |
|
534 |
} |
|
641 | 535 |
|
642 |
while (!theIterator.isDone()) { |
|
643 |
// while not done |
|
644 |
theType = theIterator.currentSegment(theData); |
|
536 |
arrayCoords = new ArrayList(); |
|
645 | 537 |
|
646 |
if (onlyCoord == null) { |
|
647 |
onlyCoord = new Coordinate(); |
|
648 |
onlyCoord.x = theData[0]; |
|
649 |
onlyCoord.y = theData[1]; |
|
650 |
} |
|
538 |
start_ind = ind; |
|
539 |
} |
|
651 | 540 |
|
652 |
switch (theType) { |
|
653 |
case PathIterator.SEG_MOVETO: |
|
541 |
numParts++; |
|
654 | 542 |
|
655 |
if (arrayCoords == null) { |
|
656 |
arrayCoords = new ArrayList<Coordinate>(); |
|
657 |
} else { |
|
658 |
end_ind = ind - 1; |
|
543 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
544 |
ind++; |
|
659 | 545 |
|
660 |
arrayCoords = getClosedRelevantPolygon(arrayCoords); |
|
661 |
new_size = arrayCoords.size(); |
|
546 |
break; |
|
662 | 547 |
|
663 |
if (arrayCoords != null) {
|
|
664 |
points = CoordinateArrays
|
|
665 |
.toCoordinateArray(arrayCoords);
|
|
548 |
case PathIterator.SEG_LINETO:
|
|
549 |
arrayCoords.add(new Coordinate(theData[0], theData[1]));
|
|
550 |
ind++;
|
|
666 | 551 |
|
667 |
try { |
|
668 |
LinearRing aux = geomFactory |
|
669 |
.createLinearRing(points); |
|
670 |
double[] z = null; |
|
552 |
break; |
|
671 | 553 |
|
672 |
if (threed) { |
|
673 |
z = getZ((Surface2DZ) mpolygon, start_ind, |
|
674 |
end_ind, new_size); |
|
675 |
} |
|
554 |
case PathIterator.SEG_QUADTO: |
|
555 |
logger.info("SEG_QUADTO Not supported here"); |
|
556 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
557 |
arrayCoords.add(new Coordinate(theData[2], theData[3])); |
|
558 |
ind++; |
|
559 |
ind++; |
|
676 | 560 |
|
677 |
LineString3D ring = new LineString3D(aux, z);
|
|
561 |
break;
|
|
678 | 562 |
|
679 |
if (CGAlgorithms.isCCW(points)) {
|
|
680 |
resp.add(ring);
|
|
681 |
} else {
|
|
682 |
resp.add(ring.createReverse());
|
|
683 |
}
|
|
684 |
} catch (Exception e) {
|
|
685 |
logger.error("Topology exception: "
|
|
686 |
+ e.getMessage());
|
|
563 |
case PathIterator.SEG_CUBICTO:
|
|
564 |
logger.info("SEG_CUBICTO Not supported here");
|
|
565 |
arrayCoords.add(new Coordinate(theData[0], theData[1]));
|
|
566 |
arrayCoords.add(new Coordinate(theData[2], theData[3]));
|
|
567 |
arrayCoords.add(new Coordinate(theData[4], theData[5]));
|
|
568 |
ind++;
|
|
569 |
ind++;
|
|
570 |
ind++;
|
|
687 | 571 |
|
688 |
return null; |
|
689 |
} |
|
690 |
} |
|
572 |
break; |
|
691 | 573 |
|
692 |
arrayCoords = new ArrayList<Coordinate>();
|
|
574 |
case PathIterator.SEG_CLOSE:
|
|
693 | 575 |
|
694 |
start_ind = ind; |
|
695 |
} |
|
576 |
// Coordinate firstCoord = (Coordinate) arrayCoords.get(0); |
|
577 |
// arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y)); |
|
578 |
break; |
|
579 |
} //end switch |
|
696 | 580 |
|
697 |
numParts++; |
|
581 |
theIterator.next(); |
|
582 |
} //end while loop |
|
698 | 583 |
|
699 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
700 |
ind++; |
|
584 |
end_ind = ind - 1; |
|
701 | 585 |
|
702 |
break; |
|
586 |
// null shape: |
|
587 |
if (arrayCoords == null) { |
|
588 |
arrayCoords = new ArrayList(); |
|
703 | 589 |
|
704 |
case PathIterator.SEG_LINETO: |
|
705 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
706 |
ind++; |
|
590 |
Coordinate _c = new Coordinate(0, 0, 0); |
|
591 |
arrayCoords.add(new Coordinate(_c)); |
|
592 |
arrayCoords.add(new Coordinate(_c)); |
|
593 |
} |
|
707 | 594 |
|
708 |
break; |
|
595 |
// -------------------------------------------- |
|
596 |
arrayCoords = getClosedRelevantPolygon(arrayCoords); |
|
597 |
new_size = arrayCoords.size(); |
|
709 | 598 |
|
710 |
case PathIterator.SEG_QUADTO: |
|
711 |
logger.info("SEG_QUADTO Not supported here"); |
|
712 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
713 |
arrayCoords.add(new Coordinate(theData[2], theData[3])); |
|
714 |
ind++; |
|
715 |
ind++; |
|
599 |
if (arrayCoords != null) { |
|
600 |
points = CoordinateArrays.toCoordinateArray(arrayCoords); |
|
716 | 601 |
|
717 |
break; |
|
602 |
try { |
|
603 |
LinearRing aux = geomFactory.createLinearRing(points); |
|
604 |
double[] z = null; |
|
718 | 605 |
|
719 |
case PathIterator.SEG_CUBICTO: |
|
720 |
logger.info("SEG_CUBICTO Not supported here"); |
|
721 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
722 |
arrayCoords.add(new Coordinate(theData[2], theData[3])); |
|
723 |
arrayCoords.add(new Coordinate(theData[4], theData[5])); |
|
724 |
ind++; |
|
725 |
ind++; |
|
726 |
ind++; |
|
606 |
if (threed) { |
|
607 |
z = getZ((FPolygon3D) mpolygon, start_ind, end_ind, new_size); |
|
608 |
} |
|
727 | 609 |
|
728 |
break;
|
|
610 |
LineString3D ring = new LineString3D(aux, z);
|
|
729 | 611 |
|
730 |
case PathIterator.SEG_CLOSE: |
|
612 |
if (CGAlgorithms.isCCW(points)) { |
|
613 |
resp.add(ring); |
|
614 |
} |
|
615 |
else { |
|
616 |
resp.add(ring.createReverse()); |
|
617 |
} |
|
618 |
} |
|
619 |
catch (Exception e) { |
|
620 |
logger.error("Topology exception: " + e.getMessage()); |
|
731 | 621 |
|
732 |
// Coordinate firstCoord = (Coordinate) arrayCoords.get(0); |
|
733 |
// arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y)); |
|
734 |
break; |
|
735 |
} // end switch |
|
622 |
return null; |
|
623 |
} |
|
624 |
} |
|
736 | 625 |
|
737 |
theIterator.next(); |
|
738 |
} // end while loop |
|
626 |
if (resp.size() == 0) { |
|
627 |
resp.add(new LineString3D(getMinLinearRing(onlyCoord), |
|
628 |
getMinLinearRingZ())); |
|
629 |
} |
|
739 | 630 |
|
740 |
end_ind = ind - 1; |
|
631 |
return resp; |
|
632 |
} |
|
741 | 633 |
|
742 |
// null shape: |
|
743 |
if (arrayCoords == null) { |
|
744 |
arrayCoords = new ArrayList<Coordinate>(); |
|
634 |
/** |
|
635 |
* Utility method to reverse an array of doubles. |
|
636 |
* |
|
637 |
* @param _z an array of doubles to be reversed. |
|
638 |
* |
|
639 |
* @return the reversed array of doubles |
|
640 |
*/ |
|
641 |
public static double[] reverseArray(double[] _z) { |
|
642 |
int size = _z.length; |
|
643 |
double[] resp = new double[size]; |
|
745 | 644 |
|
746 |
Coordinate _c = new Coordinate(0, 0, 0); |
|
747 |
arrayCoords.add(new Coordinate(_c)); |
|
748 |
arrayCoords.add(new Coordinate(_c)); |
|
749 |
} |
|
645 |
for (int i = 0; i < size; i++) { |
|
646 |
resp[i] = _z[size - 1 - i]; |
|
647 |
} |
|
750 | 648 |
|
751 |
// -------------------------------------------- |
|
752 |
arrayCoords = getClosedRelevantPolygon(arrayCoords); |
|
753 |
new_size = arrayCoords.size(); |
|
649 |
return resp; |
|
650 |
} |
|
754 | 651 |
|
755 |
if (arrayCoords != null) { |
|
756 |
points = CoordinateArrays.toCoordinateArray(arrayCoords); |
|
652 |
/** |
|
653 |
* Utility method to reverse an array of coordinates |
|
654 |
* |
|
655 |
* @param _z an array of coordinaes to be reversed. |
|
656 |
* |
|
657 |
* @return the reversed array of coordinates |
|
658 |
*/ |
|
659 |
public static Coordinate[] reverseCoordinateArray(Coordinate[] _z) { |
|
660 |
int size = _z.length; |
|
661 |
Coordinate[] resp = new Coordinate[size]; |
|
757 | 662 |
|
758 |
try {
|
|
759 |
LinearRing aux = geomFactory.createLinearRing(points);
|
|
760 |
double[] z = null;
|
|
663 |
for (int i = 0; i < size; i++) {
|
|
664 |
resp[i] = _z[size - 1 - i];
|
|
665 |
}
|
|
761 | 666 |
|
762 |
if (threed) { |
|
763 |
z = getZ(mpolygon, start_ind, end_ind, new_size); |
|
764 |
} |
|
667 |
return resp; |
|
668 |
} |
|
765 | 669 |
|
766 |
LineString3D ring = new LineString3D(aux, z); |
|
670 |
private static double[] getZ(FShape3D p3d, int _str, int _end, int size) { |
|
671 |
double[] resp = new double[size]; |
|
672 |
double[] allz = p3d.getZs(); |
|
767 | 673 |
|
768 |
if (CGAlgorithms.isCCW(points)) { |
|
769 |
resp.add(ring); |
|
770 |
} else { |
|
771 |
resp.add(ring.createReverse()); |
|
772 |
} |
|
773 |
} catch (Exception e) { |
|
774 |
logger.error("Topology exception: " + e.getMessage()); |
|
674 |
for (int i = _str; ((i <= _end) && ((i - _str) < size)); i++) { |
|
675 |
resp[i - _str] = allz[i]; |
|
676 |
} |
|
775 | 677 |
|
776 |
return null; |
|
777 |
} |
|
778 |
} |
|
678 |
if ((_end - _str + 1) < size) { |
|
679 |
double repe = allz[_end]; |
|
779 | 680 |
|
780 |
if (resp.size() == 0) {
|
|
781 |
resp.add(new LineString3D(getMinLinearRing(onlyCoord),
|
|
782 |
getMinLinearRingZ()));
|
|
783 |
}
|
|
681 |
for (int i = (_end - _str + 1); i < size; i++) {
|
|
682 |
resp[i] = repe;
|
|
683 |
}
|
|
684 |
}
|
|
784 | 685 |
|
785 |
return resp;
|
|
786 |
}
|
|
686 |
return resp;
|
|
687 |
}
|
|
787 | 688 |
|
788 |
/** |
|
789 |
* Utility method to reverse an array of doubles. |
|
790 |
* |
|
791 |
* @param _z |
|
792 |
* an array of doubles to be reversed. |
|
793 |
* |
|
794 |
* @return the reversed array of doubles |
|
795 |
*/ |
|
796 |
public static double[] reverseArray(double[] _z) { |
|
797 |
int size = _z.length; |
|
798 |
double[] resp = new double[size]; |
|
689 |
private static ArrayList getLineStrings(FShape mlines) { |
|
690 |
boolean threed = false; |
|
799 | 691 |
|
800 |
for (int i = 0; i < size; i++) {
|
|
801 |
resp[i] = _z[size - 1 - i];
|
|
802 |
}
|
|
692 |
if (mlines instanceof FPolyline3D) {
|
|
693 |
threed = true;
|
|
694 |
}
|
|
803 | 695 |
|
804 |
return resp; |
|
805 |
} |
|
696 |
int start_ind = 0; |
|
697 |
int end_ind = 0; |
|
698 |
int ind = 0; |
|
699 |
int new_size = 0; |
|
806 | 700 |
|
807 |
/** |
|
808 |
* Utility method to reverse an array of coordinates |
|
809 |
* |
|
810 |
* @param _z |
|
811 |
* an array of coordinaes to be reversed. |
|
812 |
* |
|
813 |
* @return the reversed array of coordinates |
|
814 |
*/ |
|
815 |
public static Coordinate[] reverseCoordinateArray(Coordinate[] _z) { |
|
816 |
int size = _z.length; |
|
817 |
Coordinate[] resp = new Coordinate[size]; |
|
701 |
LineString3D lin; |
|
818 | 702 |
|
819 |
for (int i = 0; i < size; i++) { |
|
820 |
resp[i] = _z[size - 1 - i]; |
|
821 |
} |
|
703 |
ArrayList arrayLines = new ArrayList(); |
|
704 |
PathIterator theIterator = mlines.getPathIterator(null, FLATNESS); |
|
705 |
int theType = -99; |
|
706 |
double[] theData = new double[6]; |
|
707 |
ArrayList arrayCoords = null; |
|
708 |
int numParts = 0; |
|
822 | 709 |
|
823 |
return resp; |
|
824 |
} |
|
710 |
while (!theIterator.isDone()) { |
|
711 |
//while not done |
|
712 |
theType = theIterator.currentSegment(theData); |
|
825 | 713 |
|
826 |
private static double[] getZ(Geometry geom3d, int _str, int _end, int size) { |
|
827 |
double[] resp = new double[size]; |
|
828 |
|
|
829 |
if(geom3d instanceof ) |
|
830 |
double[] allz = p3d.getZs(); |
|
714 |
switch (theType) { |
|
715 |
case PathIterator.SEG_MOVETO: |
|
831 | 716 |
|
832 |
for (int i = _str; ((i <= _end) && ((i - _str) < size)); i++) { |
|
833 |
resp[i - _str] = allz[i]; |
|
834 |
} |
|
717 |
if (arrayCoords == null) { |
|
718 |
arrayCoords = new ArrayList(); |
|
719 |
} |
|
720 |
else { |
|
721 |
end_ind = ind - 1; |
|
722 |
arrayCoords = ensureSensibleLineString(arrayCoords); |
|
723 |
new_size = arrayCoords.size(); |
|
835 | 724 |
|
836 |
if ((_end - _str + 1) < size) { |
|
837 |
double repe = allz[_end]; |
|
725 |
LineString aux = geomFactory.createLineString(CoordinateArrays.toCoordinateArray( |
|
726 |
arrayCoords)); |
|
727 |
double[] z = null; |
|
838 | 728 |
|
839 |
for (int i = (_end - _str + 1); i < size; i++) {
|
|
840 |
resp[i] = repe;
|
|
841 |
}
|
|
842 |
}
|
|
729 |
if (threed) {
|
|
730 |
z = getZ((FPolyline3D) mlines, start_ind, end_ind,
|
|
731 |
new_size);
|
|
732 |
}
|
|
843 | 733 |
|
844 |
return resp; |
|
845 |
} |
|
734 |
lin = new LineString3D(aux, z); |
|
735 |
arrayLines.add(lin); |
|
736 |
arrayCoords = new ArrayList(); |
|
846 | 737 |
|
847 |
private static List<LineString3D> getLineStrings(Shape mlines) {
|
|
848 |
boolean threed = false;
|
|
738 |
start_ind = ind;
|
|
739 |
}
|
|
849 | 740 |
|
850 |
if (mlines instanceof Curve2DZ) { |
|
851 |
threed = true; |
|
852 |
} |
|
741 |
numParts++; |
|
742 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
853 | 743 |
|
854 |
int start_ind = 0; |
|
855 |
int end_ind = 0; |
|
856 |
int ind = 0; |
|
857 |
int new_size = 0; |
|
744 |
break; |
|
858 | 745 |
|
859 |
LineString3D lin; |
|
746 |
case PathIterator.SEG_LINETO: |
|
747 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
860 | 748 |
|
861 |
List<LineString3D> arrayLines = new ArrayList<LineString3D>(); |
|
862 |
PathIterator theIterator = mlines.getPathIterator(null, OracleValues.FLATNESS); |
|
863 |
int theType = -99; |
|
864 |
double[] theData = new double[6]; |
|
865 |
List<Coordinate> arrayCoords = null; |
|
866 |
int numParts = 0; |
|
749 |
break; |
|
867 | 750 |
|
868 |
while (!theIterator.isDone()) { |
|
869 |
// while not done |
|
870 |
theType = theIterator.currentSegment(theData); |
|
751 |
case PathIterator.SEG_QUADTO: |
|
752 |
logger.info("Not supported here: SEG_QUADTO"); |
|
871 | 753 |
|
872 |
switch (theType) { |
|
873 |
case PathIterator.SEG_MOVETO: |
|
754 |
break; |
|
874 | 755 |
|
875 |
if (arrayCoords == null) { |
|
876 |
arrayCoords = new ArrayList<Coordinate>(); |
|
877 |
} else { |
|
878 |
end_ind = ind - 1; |
|
879 |
arrayCoords = ensureSensibleLineString(arrayCoords); |
|
880 |
new_size = arrayCoords.size(); |
|
756 |
case PathIterator.SEG_CUBICTO: |
|
757 |
logger.info("Not supported here: SEG_CUBICTO"); |
|
881 | 758 |
|
882 |
LineString aux = geomFactory |
|
883 |
.createLineString(CoordinateArrays |
|
884 |
.toCoordinateArray(arrayCoords)); |
|
885 |
double[] z = null; |
|
759 |
break; |
|
886 | 760 |
|
887 |
if (threed) { |
|
888 |
z = getZ((Curve2DZ) mlines, start_ind, end_ind, |
|
889 |
new_size); |
|
890 |
} |
|
761 |
case PathIterator.SEG_CLOSE: |
|
891 | 762 |
|
892 |
lin = new LineString3D(aux, z); |
|
893 |
arrayLines.add(lin); |
|
894 |
arrayCoords = new ArrayList<Coordinate>(); |
|
763 |
Coordinate firstCoord = (Coordinate) arrayCoords.get(0); |
|
764 |
arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y)); |
|
895 | 765 |
|
896 |
start_ind = ind;
|
|
897 |
}
|
|
766 |
break;
|
|
767 |
} //end switch
|
|
898 | 768 |
|
899 |
numParts++; |
|
900 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
769 |
theIterator.next(); |
|
770 |
ind++; |
|
771 |
} //end while loop |
|
901 | 772 |
|
902 |
break; |
|
773 |
arrayCoords = ensureSensibleLineString(arrayCoords); |
|
774 |
new_size = arrayCoords.size(); |
|
903 | 775 |
|
904 |
case PathIterator.SEG_LINETO: |
|
905 |
arrayCoords.add(new Coordinate(theData[0], theData[1])); |
|
776 |
LineString aux = geomFactory.createLineString(CoordinateArrays.toCoordinateArray( |
|
777 |
arrayCoords)); |
|
778 |
double[] z = null; |
|
906 | 779 |
|
907 |
break; |
|
780 |
if (threed) { |
|
781 |
z = getZ((FPolyline3D) mlines, start_ind, end_ind, new_size); |
|
782 |
} |
|
908 | 783 |
|
909 |
case PathIterator.SEG_QUADTO:
|
|
910 |
logger.info("Not supported here: SEG_QUADTO");
|
|
784 |
lin = new LineString3D(aux, z);
|
|
785 |
arrayLines.add(lin);
|
|
911 | 786 |
|
912 |
break; |
|
787 |
return arrayLines; |
|
788 |
} |
|
913 | 789 |
|
914 |
case PathIterator.SEG_CUBICTO: |
|
915 |
logger.info("Not supported here: SEG_CUBICTO"); |
|
790 |
private static String lineStringToWKT(LineString3D ls, boolean threed) { |
|
791 |
String resp = "("; |
|
792 |
Coordinate[] cc = ls.getLs().getCoordinates(); |
|
793 |
double[] z = ls.getZc(); |
|
794 |
int size = cc.length; |
|
916 | 795 |
|
917 |
break; |
|
796 |
if (threed) { |
|
797 |
for (int i = 0; i < size; i++) { |
|
798 |
resp = resp + cc[i].x + " " + cc[i].y + " " + z[i] + ", "; |
|
799 |
} |
|
918 | 800 |
|
919 |
case PathIterator.SEG_CLOSE: |
|
801 |
resp = resp.substring(0, resp.length() - 2); |
|
802 |
resp = resp + ")"; |
|
803 |
} |
|
804 |
else { |
|
805 |
for (int i = 0; i < size; i++) { |
|
806 |
resp = resp + cc[i].x + " " + cc[i].y + ", "; |
|
807 |
} |
|
920 | 808 |
|
921 |
Coordinate firstCoord = (Coordinate) arrayCoords.get(0); |
|
922 |
arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y)); |
|
809 |
resp = resp.substring(0, resp.length() - 2); |
|
810 |
resp = resp + ")"; |
|
811 |
} |
|
923 | 812 |
|
924 |
break;
|
|
925 |
} // end switch
|
|
813 |
return resp;
|
|
814 |
}
|
|
926 | 815 |
|
927 |
theIterator.next(); |
|
928 |
ind++; |
|
929 |
} // end while loop |
|
816 |
private static String multiLineStringToWKT(ArrayList ml, boolean threed) { |
|
817 |
String resp = "MULTILINESTRING("; |
|
930 | 818 |
|
931 |
arrayCoords = ensureSensibleLineString(arrayCoords); |
Also available in: Unified diff