Revision 38034 branches/v2_0_0_prep/extensions/org.gvsig.oracle/src/org/gvsig/fmap/dal/store/oracle/OracleUtils.java
OracleUtils.java | ||
---|---|---|
3731 | 3731 |
public static STRUCT geometryToSTRUCT(Geometry geom, Connection conn, |
3732 | 3732 |
int osrid, boolean agu_b, boolean hasSrid) throws SQLException { |
3733 | 3733 |
|
3734 |
GeometryType geometryType = geom.getGeometryType(); |
|
3735 |
if (geometryType.isTypeOf(Geometry.TYPES.NULL)) { |
|
3736 |
// null geometry |
|
3737 |
return null; |
|
3738 |
} |
|
3739 |
|
|
3740 |
|
|
3741 |
|
|
3734 | 3742 |
boolean three = false; |
3735 | 3743 |
|
3736 | 3744 |
if (geom.getDimension() == 3) { |
... | ... | |
3739 | 3747 |
|
3740 | 3748 |
STRUCT resp = null; |
3741 | 3749 |
|
3742 |
GeometryType geometryType = geom.getGeometryType(); |
|
3743 |
|
|
3744 |
if (geometryType.isTypeOf(Geometry.TYPES.MULTIPOINT)) { |
|
3750 |
if (geom instanceof MultiPoint2D) { |
|
3745 | 3751 |
resp = multiPoint2DToStruct((MultiPoint2D) geom, conn, osrid, |
3746 | 3752 |
hasSrid); |
3747 | 3753 |
return resp; |
3748 |
} else if (geometryType.isTypeOf(Geometry.TYPES.POINT)) { // point 2/3d |
|
3754 |
} |
|
3755 |
|
|
3756 |
if (geom instanceof org.gvsig.fmap.geom.primitive.impl.Point2D) { // point 2/3d |
|
3749 | 3757 |
Coordinate p = getSingleCoordinate((Point) geom); |
3750 | 3758 |
resp = getMultiPointAsStruct(p, osrid, three, conn, hasSrid); |
3751 |
} else if (geometryType.isTypeOf(Geometry.TYPES.CURVE)) { // curve 2/3d |
|
3752 |
List<LineString3D> _lines = getLineStrings(geom); |
|
3753 |
resp = getMultiLineAsStruct(_lines, osrid, three, conn, hasSrid); |
|
3754 |
} else if (geometryType.isTypeOf(Geometry.TYPES.SURFACE)) { // surface 2/3d |
|
3755 |
if (geometryType.getType() == Geometry.TYPES.CIRCLE) { |
|
3756 |
resp = getCircleAsStruct((Circle2D) geom, osrid, conn, |
|
3757 |
hasSrid); |
|
3758 |
} else { |
|
3759 |
// also FEllipse2D |
|
3760 |
resp = getMultiPolygonAsStruct(geom, osrid, three, conn, |
|
3761 |
agu_b, hasSrid); |
|
3759 |
} else { |
|
3760 |
if (geom instanceof Surface2D) { // polygon 2/3d |
|
3761 |
|
|
3762 |
if (geom instanceof Circle2D) { |
|
3763 |
resp = getCircleAsStruct((Circle2D) geom, osrid, conn, |
|
3764 |
hasSrid); |
|
3765 |
} else { |
|
3766 |
// also FEllipse2D |
|
3767 |
resp = getMultiPolygonAsStruct(geom, osrid, three, conn, |
|
3768 |
agu_b, hasSrid); |
|
3769 |
} |
|
3770 |
} else { // line 2/3d |
|
3771 |
|
|
3772 |
List<LineString3D> _lines = getLineStrings(geom); |
|
3773 |
resp = getMultiLineAsStruct(_lines, osrid, three, conn, hasSrid); |
|
3762 | 3774 |
} |
3763 |
} else if (geometryType.isTypeOf(Geometry.TYPES.NULL)) { // null geometry |
|
3764 |
return null; |
|
3765 |
} |
|
3775 |
} |
|
3766 | 3776 |
|
3767 | 3777 |
return resp; |
3768 | 3778 |
} |
... | ... | |
4222 | 4232 |
Geometry geome, |
4223 | 4233 |
String ora_srid, |
4224 | 4234 |
boolean is_geo, |
4225 |
Connection conn) { |
|
4235 |
Connection conn) {
|
|
4226 | 4236 |
|
4227 | 4237 |
String resp = ""; |
4228 | 4238 |
String view_sdo = ""; |
... | ... | |
4246 | 4256 |
|
4247 | 4257 |
} else { |
4248 | 4258 |
|
4249 |
view_sdo = binaryUnionEnvs(envs, ora_srid, is_geo, GEOM_DEFAULT_TOL); |
|
4250 |
resp = "(sdo_relate(" + geo_col_name + ", " + view_sdo + |
|
4251 |
", 'mask=anyinteract querytype=window') = 'TRUE')"; |
|
4259 |
try { |
|
4260 |
view_sdo = binaryUnionEnvs(envs, ora_srid, is_geo, GEOM_DEFAULT_TOL, conn, 0); |
|
4261 |
resp = "(sdo_relate(" + geo_col_name + ", " + view_sdo + |
|
4262 |
", 'mask=anyinteract querytype=window') = 'TRUE')"; |
|
4263 |
} catch (Exception e) { |
|
4264 |
logger.error("While getting union: " + e.getMessage(), e); |
|
4265 |
resp = null; |
|
4266 |
} |
|
4252 | 4267 |
} |
4253 | 4268 |
|
4254 | 4269 |
return resp; |
... | ... | |
4262 | 4277 |
* @return |
4263 | 4278 |
*/ |
4264 | 4279 |
public static String binaryUnionEnvs( |
4265 |
Envelope[] envs, |
|
4280 |
Envelope[] enves,
|
|
4266 | 4281 |
String ora_srid, |
4267 | 4282 |
boolean is_geo, |
4268 |
String tol) { |
|
4283 |
String tol, |
|
4284 |
Connection conn, |
|
4285 |
int depth) throws Exception { |
|
4269 | 4286 |
|
4270 |
if (envs == null || envs.length == 0) {
|
|
4271 |
logger.error("Unexpected empty envelope array: " + envs); |
|
4287 |
if (enves == null || enves.length == 0) {
|
|
4288 |
logger.error("Unexpected empty envelope array: " + enves);
|
|
4272 | 4289 |
return ""; |
4273 | 4290 |
} |
4274 | 4291 |
|
4275 |
if (envs.length == 1) { |
|
4276 |
return getSdoConstructor(envs[0], ora_srid, is_geo); |
|
4292 |
Envelope[] valid_enve = null; |
|
4293 |
if (depth == 0) { |
|
4294 |
valid_enve = getValidEnvelopes(enves, ora_srid, is_geo, tol, conn); |
|
4277 | 4295 |
} else { |
4278 |
int s1 = envs.length / 2; |
|
4279 |
int s2 = envs.length - s1; |
|
4296 |
valid_enve = enves; |
|
4297 |
} |
|
4298 |
|
|
4299 |
if (valid_enve.length == 1) { |
|
4300 |
return getSdoConstructor(valid_enve[0], ora_srid, is_geo); |
|
4301 |
} else { |
|
4302 |
int s1 = valid_enve.length / 2; |
|
4303 |
int s2 = valid_enve.length - s1; |
|
4280 | 4304 |
Envelope[] p1 = new Envelope[s1]; |
4281 | 4305 |
Envelope[] p2 = new Envelope[s2]; |
4282 | 4306 |
for (int i=0; i<s1; i++) { |
4283 |
p1[i] = envs[i];
|
|
4307 |
p1[i] = valid_enve[i];
|
|
4284 | 4308 |
} |
4285 | 4309 |
for (int i=0; i<s2; i++) { |
4286 |
p2[i] = envs[s1 + i];
|
|
4310 |
p2[i] = valid_enve[s1 + i];
|
|
4287 | 4311 |
} |
4288 | 4312 |
String resp = "sdo_geom.sdo_union("; |
4289 |
resp = resp + binaryUnionEnvs(p1, ora_srid, is_geo, tol) + ", "; |
|
4290 |
resp = resp + binaryUnionEnvs(p2, ora_srid, is_geo, tol) + ", " + tol + ")"; |
|
4313 |
resp = resp + binaryUnionEnvs(p1, ora_srid, is_geo, tol, conn, depth+1) + ", ";
|
|
4314 |
resp = resp + binaryUnionEnvs(p2, ora_srid, is_geo, tol, conn, depth+1) + ", " + tol + ")";
|
|
4291 | 4315 |
return resp; |
4292 | 4316 |
} |
4293 | 4317 |
} |
4294 | 4318 |
|
4295 |
/** |
|
4319 |
private static Envelope[] getValidEnvelopes(Envelope[] enves, |
|
4320 |
String ora_srid, boolean is_geo, String tol, Connection conn) throws Exception { |
|
4321 |
|
|
4322 |
boolean valid = false; |
|
4323 |
Envelope[] resp = enves; |
|
4324 |
String union_str = null; |
|
4325 |
|
|
4326 |
while (!valid) { |
|
4327 |
|
|
4328 |
union_str = binaryUnionEnvs( |
|
4329 |
resp, |
|
4330 |
ora_srid, |
|
4331 |
is_geo, |
|
4332 |
tol, |
|
4333 |
conn, |
|
4334 |
1000); |
|
4335 |
|
|
4336 |
valid = testUnion(union_str, conn); |
|
4337 |
if (!valid) { |
|
4338 |
int[] mergeinds = getGoodMergeCoupe(resp); |
|
4339 |
resp = mergeEnvelopes(resp, mergeinds); |
|
4340 |
} |
|
4341 |
} |
|
4342 |
return resp; |
|
4343 |
} |
|
4344 |
|
|
4345 |
private static Envelope[] mergeEnvelopes( |
|
4346 |
Envelope[] envs, int[] inds) throws Exception { |
|
4347 |
|
|
4348 |
if (envs == null || envs.length < 2) { |
|
4349 |
logger.error("Unexpected envs (len must be >= 2): " + inds); |
|
4350 |
return envs; |
|
4351 |
} |
|
4352 |
|
|
4353 |
if (inds == null || inds.length != 2) { |
|
4354 |
logger.error("Unexpected inds (len must be 2): " + inds); |
|
4355 |
return envs; |
|
4356 |
} |
|
4357 |
|
|
4358 |
GeometryManager gm = GeometryLocator.getGeometryManager(); |
|
4359 |
|
|
4360 |
int len = envs.length; |
|
4361 |
Envelope[] resp = new Envelope[len-1]; |
|
4362 |
|
|
4363 |
double minx = 0; |
|
4364 |
double miny = 0; |
|
4365 |
double maxx = 0; |
|
4366 |
double maxy = 0; |
|
4367 |
|
|
4368 |
Envelope e1 = envs[inds[0]]; |
|
4369 |
Envelope e2 = envs[inds[1]]; |
|
4370 |
|
|
4371 |
minx = Math.min(e1.getMinimum(0), e2.getMinimum(0)); |
|
4372 |
miny = Math.min(e1.getMinimum(1), e2.getMinimum(1)); |
|
4373 |
maxx = Math.max(e1.getMaximum(0), e2.getMaximum(0)); |
|
4374 |
maxy = Math.max(e1.getMaximum(1), e2.getMaximum(1)); |
|
4375 |
|
|
4376 |
Envelope bigenv = gm.createEnvelope( |
|
4377 |
minx, miny, maxx, maxy, SUBTYPES.GEOM2D); |
|
4378 |
|
|
4379 |
ArrayList<Envelope> accum = new ArrayList<Envelope>(); |
|
4380 |
for (int i=0; i<len; i++) { |
|
4381 |
if (i != inds[0] && i != inds[1]) { |
|
4382 |
accum.add(envs[i]); |
|
4383 |
} |
|
4384 |
} |
|
4385 |
|
|
4386 |
resp[0] = bigenv; |
|
4387 |
len = resp.length; |
|
4388 |
for (int i=1; i<len; i++) { |
|
4389 |
if ((i-1) < accum.size() && accum.get(i-1) != null) { |
|
4390 |
resp[i] = accum.get(i-1); |
|
4391 |
} |
|
4392 |
} |
|
4393 |
return resp; |
|
4394 |
} |
|
4395 |
|
|
4396 |
private static boolean testUnion( |
|
4397 |
String union_str, |
|
4398 |
Connection conn) { |
|
4399 |
|
|
4400 |
String qry = "SELECT " + union_str + " FROM DUAL"; |
|
4401 |
|
|
4402 |
try { |
|
4403 |
PreparedStatement _st = conn.prepareStatement(qry); |
|
4404 |
_st.executeQuery(); |
|
4405 |
_st.close(); |
|
4406 |
return true; |
|
4407 |
} catch (Exception ex) { |
|
4408 |
logger.warn("Oracle error. Envs will be simplified: " + ex.getMessage()); |
|
4409 |
return false; |
|
4410 |
} |
|
4411 |
} |
|
4412 |
|
|
4413 |
public static int[] getGoodMergeCoupe(Envelope[] envs) { |
|
4414 |
|
|
4415 |
int len = envs.length; |
|
4416 |
int[] resp = new int[2]; |
|
4417 |
|
|
4418 |
for (int i=0; i<(len - 1); i++) { |
|
4419 |
if (sameY(envs[i], envs[i+1])) { |
|
4420 |
resp[0] = i; |
|
4421 |
resp[1] = i+1; |
|
4422 |
return resp; |
|
4423 |
} |
|
4424 |
} |
|
4425 |
|
|
4426 |
// nothing found with same Y |
|
4427 |
double mindif = Double.MAX_VALUE; |
|
4428 |
double itemdif = 0; |
|
4429 |
int indi = 0; |
|
4430 |
for (int i=0; i<(len - 1); i++) { |
|
4431 |
itemdif = difY(envs[i], envs[i+1]); |
|
4432 |
if (itemdif < mindif) { |
|
4433 |
mindif = itemdif; |
|
4434 |
indi = i; |
|
4435 |
} |
|
4436 |
} |
|
4437 |
|
|
4438 |
resp[0] = indi; |
|
4439 |
resp[1] = indi+1; |
|
4440 |
return resp; |
|
4441 |
} |
|
4442 |
|
|
4443 |
|
|
4444 |
private static double difY(Envelope enva, Envelope envb) { |
|
4445 |
return Math.abs(enva.getMaximum(1) - envb.getMaximum(1)); |
|
4446 |
} |
|
4447 |
|
|
4448 |
private static boolean sameY(Envelope enva, Envelope envb) { |
|
4449 |
|
|
4450 |
double tol = 0.1 * Math.min(enva.getLength(0), enva.getLength(1)); |
|
4451 |
if (Math.abs(enva.getMaximum(1) - envb.getMaximum(1)) < tol) { |
|
4452 |
return true; |
|
4453 |
} else { |
|
4454 |
return false; |
|
4455 |
} |
|
4456 |
} |
|
4457 |
|
|
4458 |
/** |
|
4296 | 4459 |
* @param geome |
4297 | 4460 |
* @return |
4298 | 4461 |
*/ |
Also available in: Unified diff