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 |
*/
|