View Javadoc

1   /**
2    * 
3    * MIGRATOOL Program to migrate spatial databsets.
4    * Copyright (C) 2007 Fábio Luiz Leite Júnior
5    * Universidade Federal de Campina Grande
6    * contact: fabioleite@gmail.com
7    *
8    * This program is free software; you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License
10   * as published by the Free Software Foundation; either version 2
11   * of the License, or (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   *
18   * You should have received a copy of the GNU General Public License
19   * along with this program; if not, write to the Free Software
20   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21   *
22   * @author André Gomes
23   *
24   */
25   
26  package migratool.ora2pgsql;
27  
28  import java.util.Enumeration;
29  
30  import oracle.sdoapi.geom.CoordPointImpl;
31  import oracle.sdoapi.geom.Geometry;
32  import oracle.sdoapi.geom.LineString;
33  import oracle.sdoapi.geom.MultiLineString;
34  import oracle.sdoapi.geom.MultiPolygon;
35  import oracle.sdoapi.geom.Point;
36  import oracle.sdoapi.geom.Polygon;
37  import oracle.sdoapi.geom.impl.LinearSegmentImpl;
38  
39  import org.apache.log4j.Logger;
40  
41  /**
42   * 
43   * MIGRATOOL Program to migrate spatial databsets.
44   * Copyright (C) 2007 Fábio Luiz Leite Júnior
45   * Universidade Federal de Campina Grande
46   * contact: fabioleite@gmail.com
47   *
48   * This program is free software; you can redistribute it and/or
49   * modify it under the terms of the GNU General Public License
50   * as published by the Free Software Foundation; either version 2
51   * of the License, or (at your option) any later version.
52   *
53   * This program is distributed in the hope that it will be useful,
54   * but WITHOUT ANY WARRANTY; without even the implied warranty of
55   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
56   * GNU General Public License for more details.
57   *
58   * You should have received a copy of the GNU General Public License
59   * along with this program; if not, write to the Free Software
60   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
61   *
62   * @author camilo
63   *
64   */
65  
66  public class OracleGeometryParser {
67  
68  	static final int BIDIMENSIONAL = 2000;
69  	static final int GTYPE_POINT = 01;
70  	static final int GTYPE_LINE = 02;
71  	static final int GTYPE_POLYGON = 03;
72  	static final int GTYPE_MULTIPOLYGON = 07;
73  	
74  	static Logger logger = Logger.getLogger(OracleGeometryParser.class.getName());
75  	
76  	public StringBuffer parse(Geometry oracleGeometry) {
77  		StringBuffer postgisGeometry = new StringBuffer();
78  
79  		if (oracleGeometry.getGeometryType() == Point.class) {
80  			logger.info("Convertendo um ponto");
81  			createPoint(oracleGeometry, postgisGeometry);
82  		} else if (oracleGeometry.getGeometryType() == Polygon.class) {
83  			logger.info("Convertendo um Pol�gono");
84  			createPolygon(oracleGeometry, postgisGeometry);
85  		} else if (oracleGeometry.getGeometryType() == MultiPolygon.class) {
86  			logger.info("Convertendo um MultiPol�gono");
87  			createMultiPolygon(oracleGeometry, postgisGeometry);
88  		} else if (oracleGeometry.getGeometryType() == LineString.class) {
89  			logger.info("Convertendo um LineString");
90  			createLineString(oracleGeometry, postgisGeometry);
91  		} else if (oracleGeometry.getGeometryType() == MultiLineString.class) {
92  			logger.info("Convertendo um MultiLineString");
93  			createMultiLineString(oracleGeometry, postgisGeometry);
94  		}
95  
96  		return postgisGeometry;
97  	}
98  
99  	/**
100 	 * @param oracleGeometry
101 	 * @param postgisGeometry
102 	 */
103 	private void createMultiLineString(
104 		Geometry oracleGeometry,
105 		StringBuffer postgisGeometry) {
106 		int srid = oracleGeometry.getSpatialReference().getID();
107 		srid =
108 			SRIDConverter.getSRID(
109 				SRIDConverter.ORACLE,
110 				SRIDConverter.POSTGIS,
111 				srid);
112 		MultiLineString multiLineString = (MultiLineString) oracleGeometry;
113 		//logger.info("MultiLineString - SRID " + srid);
114 		postgisGeometry.append(
115 			"GeometryFromText('MULTILINESTRING("
116 				+ getOrdinateArray(multiLineString)
117 				+ ")',"
118 				+ srid
119 				+ ")");
120 	}
121 
122 	/**
123 	 * @param oracleGeometry
124 	 * @param postgisGeometry
125 	 */
126 	private void createLineString(
127 		Geometry oracleGeometry,
128 		StringBuffer postgisGeometry) {
129 		int srid = oracleGeometry.getSpatialReference().getID();
130 		srid =
131 			SRIDConverter.getSRID(
132 				SRIDConverter.ORACLE,
133 				SRIDConverter.POSTGIS,
134 				srid);
135 		LineString lineString = (LineString) oracleGeometry;
136 		postgisGeometry.append(
137 			"GeometryFromText('LINESTRING"
138 				+ getOrdinateArray(lineString)
139 				+ "',"
140 				+ srid
141 				+ ")");
142 	}
143 
144 	/**
145 	 * @param lineString
146 	 * @return
147 	 */
148 	private String getOrdinateArray(Geometry geom) {
149 		StringBuffer ordinate = new StringBuffer();
150 		Enumeration e = geom.getAllSegments();
151 		CoordPointImpl firstCoord = null;
152 		while (e.hasMoreElements()) {			
153 			boolean firstPoint = true;			
154 			LinearSegmentImpl linearS = (LinearSegmentImpl) e.nextElement();
155 			
156 			int quantidadeDePontos = 0;
157 			/*
158 			 * Descomentar esse trecho em situa��es em que n�o s�o aceitos pol�gonos com apenas 2 pontos iguais
159 			*/
160 			/*if ((geom.getGeometryType() == Polygon.class)|| (geom.getGeometryType() == MultiPolygon.class)){			
161 				if ( linearS.getNumPoints() == 2){
162 					Enumeration points = linearS.getPoints();
163 					boolean doisPontosIguais = false;
164 					CoordPointImpl point1 = null;
165 					CoordPointImpl point2 = null;
166 					while (points.hasMoreElements()) {							
167 						point1 = (CoordPointImpl) points.nextElement();
168 						point2 = (CoordPointImpl) points.nextElement();
169 						doisPontosIguais = point1.getX() == point2.getX() && point1.getY() == point2.getY(); 									
170 					}
171 					if ( doisPontosIguais ){						
172 						System.err.println("Dois pontos iguais: " + point1 + " e " + point2);					
173 						continue;
174 					}
175 				}
176 			}*/
177 			Enumeration points = linearS.getPoints();
178 			ordinate.append("(");
179 			while (points.hasMoreElements()) {
180 				quantidadeDePontos++;
181 				CoordPointImpl point = (CoordPointImpl) points.nextElement();
182 				if (firstPoint) {
183 					firstCoord = point;
184 					firstPoint = false;
185 				}
186 				ordinate.append(point.getX() + " " + point.getY() + ", ");
187 
188 				if ((geom.getGeometryType() == Polygon.class)
189 					|| (geom.getGeometryType() == MultiPolygon.class)) {
190 					if (!points.hasMoreElements()) {
191 						if ((point.getX() != firstCoord.getX())
192 							|| (point.getY() != firstCoord.getY())) {
193 							ordinate.append(
194 								firstCoord.getX()
195 									+ " "
196 									+ firstCoord.getY()
197 									+ ", ");
198 						}
199 					}
200 				}
201 			}
202 			if (quantidadeDePontos <= 3) {
203 				//logger.error("Quantidade de pontos menor que 3");
204 			}
205 			if (ordinate.toString().endsWith(", ")) {
206 				int index = ordinate.toString().lastIndexOf(",");
207 				ordinate.delete(index, index + 2);
208 			}
209 			ordinate.append(")");
210 			if (e.hasMoreElements()) {
211 				ordinate.append(", ");
212 			}
213 		}
214 
215 		return ordinate.toString();
216 	}
217 
218 	/**
219 	 * @param oracleGeometry
220 	 * @param postgisGeometry
221 	 */
222 	private void createMultiPolygon(
223 		Geometry oracleGeometry,
224 		StringBuffer postgisGeometry) {
225 		int srid = oracleGeometry.getSpatialReference().getID();
226 		srid =
227 			SRIDConverter.getSRID(
228 				SRIDConverter.ORACLE,
229 				SRIDConverter.POSTGIS,
230 				srid);
231 		MultiPolygon multiPolygon = (MultiPolygon) oracleGeometry;
232 		postgisGeometry.append(
233 			"GeometryFromText('MULTIPOLYGON(("
234 				+ getOrdinateArray(multiPolygon)
235 				+ "))',"
236 				+ srid
237 				+ ")");
238 	}
239 
240 	/**
241 	 * @param oracleGeometry
242 	 * @param postgisGeometry
243 	 */
244 	private void createPolygon(
245 		Geometry oracleGeometry,
246 		StringBuffer postgisGeometry) {
247 		int srid = oracleGeometry.getSpatialReference().getID();
248 		srid =
249 			SRIDConverter.getSRID(
250 				SRIDConverter.ORACLE,
251 				SRIDConverter.POSTGIS,
252 				srid);
253 		Polygon polygon = (Polygon) oracleGeometry;
254 		postgisGeometry.append(
255 			"GeometryFromText('POLYGON("
256 				+ getOrdinateArray(polygon)
257 				+ ")',"
258 				+ srid
259 				+ ")");
260 	}
261 
262 	/**
263 	 * @param oracleGeometry
264 	 * @param postgisGeometry
265 	 */
266 	private void createPoint(
267 		Geometry oracleGeometry,
268 		StringBuffer postgisGeometry) {
269 		int srid = oracleGeometry.getSpatialReference().getID();
270 		srid =
271 			SRIDConverter.getSRID(
272 				SRIDConverter.ORACLE,
273 				SRIDConverter.POSTGIS,
274 				srid);
275 		Point point = (Point) oracleGeometry;
276 		double x = point.getX();
277 		double y = point.getY();
278 		postgisGeometry.append(
279 			"GeometryFromText('POINT(" + x + " " + y + ")'," + srid + ")");
280 	}	
281 }