Revision 38034 branches/v2_0_0_prep/extensions/org.gvsig.oracle/src/org/gvsig/fmap/dal/store/oracle/OracleUtils.java

View differences:

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