Revision 32521 trunk/extensions/extOracleSpatial/src/es/prodevelop/cit/gvsig/fmap/drivers/jdbc/oracle/OracleSpatialUtils.java

View differences:

OracleSpatialUtils.java
54 54
import java.sql.Connection;
55 55
import java.sql.PreparedStatement;
56 56
import java.sql.ResultSet;
57
import java.sql.ResultSetMetaData;
57 58
import java.sql.SQLException;
58 59
import java.sql.Types;
59 60
import java.text.DecimalFormat;
......
87 88
import com.iver.cit.gvsig.fmap.core.FShape3D;
88 89
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
89 90
import com.iver.cit.gvsig.fmap.core.IGeometry;
91
import com.iver.cit.gvsig.fmap.core.IGeometry3D;
92
import com.iver.cit.gvsig.fmap.core.IGeometryM;
90 93
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
91 94
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
92 95
import com.iver.cit.gvsig.fmap.drivers.ConnectionJDBC;
......
127 130
    public static final int ORACLE_GTYPE_MULTILINE = 6;
128 131
    public static final int ORACLE_GTYPE_MULTIPOLYGON = 7;
129 132

  
130
    public static final int ORACLE_GTYPE_COMPLEX_VOIDED_POLYON = 3;
133
    public static final int ORACLE_GTYPE_COMPLEX_VOIDED_OR_NORMAL_POLYGON = 3;
131 134
    public static final int ORACLE_GTYPE_COMPLEX_COMPOUND_LINE = 4;
132
    public static final int ORACLE_GTYPE_COMPLEX_COMPOUND_POLYON = 5;
135
    public static final int ORACLE_GTYPE_COMPLEX_COMPOUND_POLYGON = 5;
133 136
    
134 137
    // req by wolfgang qual sept 2009
135 138
    public static final String ORACLE_GEOM_METADATA_TOLERANCE = "0.0005";
139
	public static final int FETCH_BLOCK_SIZE_BYTES = 50 * 1000 * 1000;
136 140

  
141

  
137 142
    /**
138 143
     * COnstructs a geometry from a file that contains a vertex per line:
139 144
     *
......
1678 1683

  
1679 1684
        // String ind_str = printArray(indices);
1680 1685
        // String ord_str = printArray(ords);
1686
        // obj = getTestPolygon();
1681 1687
        resp = new STRUCT(dsc, ((ConnectionJDBC)_conn).getConnection(), obj);
1682 1688

  
1683 1689
        return resp;
1684 1690
    }
1685 1691

  
1686
    public static String printArray(NUMBER[] array) {
1692
    private static Object[] getTestPolygon(boolean b) throws SQLException {
1693
    	
1694
        Object[] resp = new Object[5];
1695
        resp[0] = new NUMBER(3005);
1696
       	resp[1] = null;
1697

  
1698
       	NUMBER[] _ind = new NUMBER[6];
1699
       	_ind[0] = new NUMBER(1.0);
1700
       	_ind[1] = new NUMBER(2005.0);
1701
       	_ind[2] = new NUMBER(1.0);
1702
       	_ind[3] = new NUMBER(1.0);
1703
       	_ind[4] = new NUMBER(2.0);
1704
       	_ind[5] = new NUMBER(2.0);
1705

  
1706
       	NUMBER[] _ord = new NUMBER[33];
1707
       	_ord[0] = new NUMBER(4478106.584);
1708
       	_ord[1] = new NUMBER(5345524.3355);
1709
       	_ord[2] = new NUMBER(0.0); 
1710
       	_ord[3] = new NUMBER(4478103.55781412);
1711
       	_ord[4] = new NUMBER(5345520.13869913);
1712
       	_ord[5] = new NUMBER(0.0); 
1713
       	_ord[6] = new NUMBER(4478094.627);
1714
       	_ord[7] = new NUMBER(5345517.0485);
1715
       	_ord[8] = new NUMBER(0.0 );
1716
       	_ord[9] = new NUMBER(4478088.31210806);
1717
       	_ord[10] = new NUMBER(5345521.30429374);
1718
       	_ord[11] = new NUMBER(0.0 );
1719
       	_ord[12] = new NUMBER(4478087.661);
1720
       	_ord[13] = new NUMBER(5345528.8915);
1721
       	_ord[14] = new NUMBER(0.0 );
1722
       	_ord[15] = new NUMBER(4478093.20816592);
1723
       	_ord[16] = new NUMBER(5345537.22495391);
1724
       	_ord[17] = new NUMBER(0.0 );
1725
       	_ord[18] = new NUMBER(4478103.219);
1726
       	_ord[19] = new NUMBER(5345537.2515);
1727
       	_ord[20] = new NUMBER(0.0 );
1728
       	_ord[21] = new NUMBER(4478107.61580098);
1729
       	_ord[22] = new NUMBER(5345529.07024585);
1730
       	_ord[23] = new NUMBER(0.0 );
1731
       	_ord[24] = new NUMBER(4478107.585);
1732
       	_ord[25] = new NUMBER(5345528.688);
1733
       	_ord[26] = new NUMBER(0.0 );
1734
       	_ord[27] = new NUMBER(4478107.28586386);
1735
       	_ord[28] = new NUMBER(5345526.46542887);
1736
       	_ord[29] = new NUMBER(0.0 );
1737
       	_ord[30] = new NUMBER(4478106.584);
1738
       	_ord[31] = new NUMBER(5345524.3355);
1739
       	_ord[32] = new NUMBER(0.0);
1740
       	
1741
        resp[2] = null;
1742
        resp[3] = _ind;
1743
        resp[4] = _ord;
1744
    	
1745
		return resp;
1746
	}
1747

  
1748
	public static String printArray(NUMBER[] array) {
1687 1749
        String resp = "[ ";
1688 1750

  
1689 1751
        for (int i = 0; i < array.length; i++) {
......
1876 1938
    /**
1877 1939
     * Utility method to deal with oracle coordinate arrays.
1878 1940
     */
1879
    public static ARRAY getDevelopedOrdsArray(ARRAY ords) {
1880
        ARRAY _resp = null;
1941
	public static ARRAY getDevelopedOrdsArray(ARRAY ords, int dim) {
1942
		ARRAY _resp = null;
1881 1943

  
1882
        try {
1883
            Datum[] resp = new Datum[10];
1884
            Datum[] corners = ords.getOracleArray();
1944
		try {
1945
			int n = 5*2; // dim = 2, ignored dim, 3d makes no sense
1946
			Datum[] resp = new Datum[n];
1947
			Datum[] corners = ords.getOracleArray();
1885 1948

  
1886
            // x
1887
            resp[0] = corners[0];
1888
            resp[2] = corners[2];
1889
            resp[4] = corners[2];
1890
            resp[6] = corners[0];
1891
            resp[8] = corners[0];
1949
			for (int i=0; i<5; i++) {
1950
				resp[i*2] = ((i==2) || (i==3)) ? corners[dim] : corners[0];
1951
			}
1952
			for (int i=0; i<5; i++) {
1953
				resp[1+i*2] = ((i==1) || (i==2)) ? corners[dim+1] : corners[1];
1954
			}
1955
			_resp = new ARRAY(ords.getDescriptor(), ords
1956
					.getInternalConnection(), resp);
1957
		} catch (SQLException se) {
1958
			logger.error("While creating ARRAY: " + se.getMessage(), se);
1959
		}
1892 1960

  
1893
            // y
1894
            resp[1] = corners[1];
1895
            resp[3] = corners[1];
1896
            resp[5] = corners[3];
1897
            resp[7] = corners[3];
1898
            resp[9] = corners[1];
1899
            _resp = new ARRAY(ords.getDescriptor(),
1900
                    ords.getInternalConnection(), resp);
1901
        }
1902
        catch (SQLException se) {
1903
            logger.error("While creating ARRAY: " + se.getMessage(), se);
1904
        }
1961
		return _resp;
1962
	}
1905 1963

  
1906
        return _resp;
1907
    }
1908

  
1909 1964
    /**
1910 1965
     * utility method to convert a STRUCT into a GeneralPathX
1911 1966
     * @param aux the struct's datum array
......
1927 1982
            infoARRAY = (ARRAY) aux[3];
1928 1983
            ordsARRAY = (ARRAY) aux[4];
1929 1984

  
1930
            if (polStructIsRectStruct(infoARRAY, ordsARRAY)) {
1931
                infoARRAY = getDevelopedInfoArray(infoARRAY);
1932
                ordsARRAY = getDevelopedOrdsArray(ordsARRAY);
1933
            }
1934

  
1935 1985
            dims = ((NUMBER) aux[0]).intValue() / 1000;
1936 1986

  
1937 1987
            if (dims == 0) {
1938 1988
                dims = 2;
1939 1989
            }
1940 1990

  
1991
            if (polStructIsRectStruct(infoARRAY, ordsARRAY)) {
1992
                infoARRAY = getDevelopedInfoArray(infoARRAY);
1993
                ordsARRAY = getDevelopedOrdsArray(ordsARRAY, dims);
1994
                dims = 2;
1995
            }
1996

  
1941 1997
            info_array = (Datum[]) infoARRAY.getOracleArray();
1942 1998
            ords_array = (Datum[]) ordsARRAY.getOracleArray();
1943 1999
            info_array_size = info_array.length / 3;
......
1974 2030
                            next_must_do_first);
1975 2031
                }
1976 2032
            } else {
2033
            	
1977 2034
                // standard case, do the moveto always
1978 2035
                for (int i = 0; i < info_array_size; i++) {
1979 2036
                    lineType = getLineToType(info_array, i);
......
1981 2038
                        ords_array, dims, lineType, true, true);
1982 2039
                }
1983 2040
            }
1984

  
1985
            // boolean do_the_moves = true;
1986 2041
        }
1987 2042
        catch (SQLException se) {
1988 2043
            logger.error("While creating GPX: " + se.getMessage(), se);
......
2359 2414
     * @param otype
2360 2415
     * @return FShape type
2361 2416
     */
2362
    public static int oracleGTypeToFShapeType(int otype, boolean complex) {
2417
    public static int oracleGTypeToFShapeType(int full_otype, boolean complex) {
2363 2418
    	
2364 2419
    	int resp = FShape.NULL;
2420
    	int simpl_otype = full_otype % 1000;
2365 2421
    	
2366 2422
    	if (complex) {
2367 2423
    		
2368
    		switch (otype) {
2369
    		case ORACLE_GTYPE_COMPLEX_VOIDED_POLYON:
2370
    		case ORACLE_GTYPE_COMPLEX_COMPOUND_POLYON:
2424
    		switch (simpl_otype) {
2425
    		case ORACLE_GTYPE_COMPLEX_VOIDED_OR_NORMAL_POLYGON:
2426
    		case ORACLE_GTYPE_COMPLEX_COMPOUND_POLYGON:
2371 2427
    			resp = FShape.POLYGON;
2372 2428
    			break;
2373 2429
    		case ORACLE_GTYPE_COMPLEX_COMPOUND_LINE:
2374 2430
    			resp = FShape.LINE;
2375 2431
    			break;
2432
    		default:
2433
    			return oracleGTypeToFShapeType(full_otype, false);
2376 2434
    		}
2377 2435

  
2378 2436
    	} else {
2379 2437

  
2380 2438
    		// =========== not complex =================
2381
            switch (otype) {
2439
            switch (simpl_otype) {
2382 2440
            case ORACLE_GTYPE_UNKNOWN:
2383 2441
            	resp = FShape.NULL;
2384 2442
                break;
......
2404 2462
            }
2405 2463
    		// =========== not complex =================
2406 2464
    	}
2407
    	
2408 2465
    	if (resp == FShape.NULL) {
2409
    		logger.error("Unknown oracle geometry type: " + otype);
2466
    		logger.error("Unknown oracle geometry type: " + full_otype);
2410 2467
    	}
2411 2468
        return resp;
2412 2469
    }
......
2654 2711
        return ig;
2655 2712
    }
2656 2713

  
2714
    public static final int COLLECTION_VALUE_NOT_COLLECTION = 0;
2715
    public static final int COLLECTION_VALUE_YES_COLLECTION = 1;
2716
    public static final int COLLECTION_VALUE_MERGE_COLLECTION_IN_POLYGON = 2;
2657 2717
    
2658
    public static boolean isActuallyACollection(Datum[] the_data) {
2718
    public static int isCollection(Datum[] the_data) {
2659 2719
        int[] info = null;
2660 2720

  
2661 2721
        try {
2662 2722
            ARRAY aux = (ARRAY) the_data[3];
2663 2723

  
2664 2724
            if (aux == null) {
2665
                return false;
2725
                return COLLECTION_VALUE_NOT_COLLECTION;
2666 2726
            }
2667 2727

  
2668 2728
            info = aux.getIntArray();
2669 2729
        }
2670 2730
        catch (SQLException se) {
2671 2731
            logger.error("While checking collection: " + se.getMessage());
2672
            return false;
2732
            return COLLECTION_VALUE_NOT_COLLECTION;
2673 2733
        }
2674 2734

  
2675 2735
        if (info == null) {
2676
            return false; // sdo_point
2736
            return COLLECTION_VALUE_NOT_COLLECTION; // sdo_point
2677 2737
        }
2678 2738

  
2679 2739
        int size = info.length / 3;
2680 2740

  
2681 2741
        if (size == 1) {
2682
            return false;
2742
            return COLLECTION_VALUE_NOT_COLLECTION;
2683 2743
        }
2684 2744

  
2685 2745
        if (size == 2) {
2686
            return ((info[1] % 1000) != (info[4] % 1000)) &&
2687
            ( ! ((info[1] == 1005) && (info[4] == 2)) );
2746
        	if (((info[1] == 1003) && (info[2] == 3 || info[2] == 4))
2747
        			|| ((info[4] == 1003 || info[4] == 2003) && (info[5] == 3 || info[5] == 4))) {
2748
        		return COLLECTION_VALUE_MERGE_COLLECTION_IN_POLYGON;
2749
        	} else {
2750
        		boolean aux = ((info[1] % 1000) != (info[4] % 1000))
2751
                && ( ! ((info[1] == 1005) && (info[4] == 2)) );
2752
        		if (aux) {
2753
                    return COLLECTION_VALUE_YES_COLLECTION;
2754
        		} else {
2755
                    return COLLECTION_VALUE_NOT_COLLECTION;
2756
        		}
2757
        	}
2688 2758
        }
2759
        
2760
        // ======================================== check no rects whsn size > 2
2761
        for (int i=0; i<size; i++) { // outer pol
2762
        	if ((info[i*3+1] == 1003) && (info[i*3+2] == 3 || info[i*3+2] == 4)) {
2763
        		return COLLECTION_VALUE_MERGE_COLLECTION_IN_POLYGON; 
2764
        	}
2765
        }
2766
        for (int i=1; i<size; i++) { // inner pol
2767
        	if ((info[i*3+1] == 2003) && (info[i*3+2] == 3 || info[i*3+2] == 4)) {
2768
        		return COLLECTION_VALUE_MERGE_COLLECTION_IN_POLYGON; 
2769
        	}
2770
        }
2771
        // =================================== 
2689 2772

  
2773
        int _first = info[1] % 1000;
2690 2774
        int second = info[4] % 1000;
2691 2775
        int item = 0;
2692

  
2776
        
2693 2777
        for (int i = 2; i < size; i++) {
2694 2778
        	item = info[(i * 3) + 1] % 1000;
2695 2779
            if ((item != second) &&
2696
            		( ! ((item == 5) && (second == 2)) )
2780
            		( ! ((item == 5) && (second == 2)) ) && 
2781
            		( ! ((item == 2) && (second == 5)) )
2697 2782
            		) {
2698
                return true;
2783
                return COLLECTION_VALUE_YES_COLLECTION;
2699 2784
            }
2700 2785
        }
2701 2786

  
2702
        return false;
2787
        return COLLECTION_VALUE_NOT_COLLECTION;
2703 2788
    }
2704 2789

  
2705 2790
    
......
2912 2997
                    }
2913 2998
                }
2914 2999
                else {
2915
                    if (((NUMBER) newaux[1]).intValue() == 2003) {
2916
                        aux = appendDatArrays(aux, newaux);
2917
                    } else {
3000
                	
3001
                    resp.add(aux);
3002
                    aux = getNthGroupOfThree(all_elem, i);
3003
                    // no complex subelements expected
3004
                    /*
3005
                    if (((NUMBER) newaux[1]).intValue() == 1003
3006
                    		|| ((NUMBER) newaux[1]).intValue() == 2003) {
2918 3007
                        resp.add(aux);
2919 3008
                        aux = getNthGroupOfThree(all_elem, i);
3009
                    } else {
3010
                        aux = appendDatArrays(aux, newaux);
2920 3011
                    }
3012
                    */
2921 3013
                }
2922 3014

  
2923 3015
                i++;
2924 3016
            }
2925 3017
        }
2926
        catch (SQLException se) {
3018
        catch (SQLException se) { 
2927 3019
            logger.error("Unexpected error: " + se.getMessage());
2928 3020
        }
2929 3021

  
......
3226 3318
    public static int maxSizeForFieldType(int _type) {
3227 3319
        switch (_type) {
3228 3320
        case Types.VARCHAR:
3229
            return OracleSpatialDriver.VARCHAR2_STANDARD_SIZE;
3230

  
3231 3321
        case Types.LONGVARCHAR:
3232
            return OracleSpatialDriver.VARCHAR2_LONG_SIZE;
3322
            return OracleSpatialDriver.VARCHAR2_MAX_SIZE;
3233 3323
        }
3234 3324

  
3235 3325
        return -1;
3236 3326
    }
3237 3327
    
3238 3328
    
3329
    
3239 3330
    public static String EXPONENTIAL_INDICES_CONDITION = null;
3240 3331
    
3241 3332
    static {
......
3277 3368
			return ShapeFactory.createPolyline2D(gpx);
3278 3369
		}
3279 3370
	}
3371

  
3372
	public static IGeometry mergePolygons(FGeometryCollection gco) {
3373
		GeneralPathX gpx = new GeneralPathX();
3374
		
3375
		IGeometry[] gg = gco.getGeometries();
3376
		int cnt = gg.length;
3377
		IGeometry ig2d;
3378
		for (int i=0; i<cnt; i++) {
3379
			ig2d = gg[i];
3380
			gpx.append(ig2d.getPathIterator(null), false);
3381
		}
3382
		return ShapeFactory.createPolygon2D(gpx);
3383
	}
3384

  
3385
	public static int estimateGoodFetchSize(ResultSetMetaData md) { 
3386
		
3387
		int bytesum = 0;
3388
		try {
3389
			int sz = md.getColumnCount();
3390
			int inc = 0;
3391
			for (int i=1; i<=sz; i++) {
3392
				inc = md.getColumnDisplaySize(i);
3393
				if ((inc >= 0) && (inc <= OracleSpatialDriver.VARCHAR2_MAX_SIZE)) {
3394
					bytesum = bytesum + inc;
3395
				}
3396
			}
3397
			// TODO Auto-generated method stub
3398
		} catch (SQLException se) {
3399
			logger.warn("Error while getting field sizes: " + se.getMessage());
3400
			logger.warn("Used: row size = 5000 bytes.");
3401
			bytesum = 5000;
3402
		}
3403
		
3404
		return Math.max(10, FETCH_BLOCK_SIZE_BYTES / bytesum);
3405
	}
3280 3406
    
3281 3407
	
3282 3408

  

Also available in: Unified diff