svn-gvsig-desktop / tags / v1_0_2_Build_908 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / shp / IndexedShpDriver.java @ 11054
History | View | Annotate | Download (25.8 KB)
1 | 2717 | fjp | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | *
|
||
19 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Ib??ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * IVER T.I. S.A
|
||
34 | * Salamanca 50
|
||
35 | * 46005 Valencia
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 963163400
|
||
39 | * dac@iver.es
|
||
40 | */
|
||
41 | package com.iver.cit.gvsig.fmap.drivers.shp; |
||
42 | |||
43 | import java.awt.geom.Point2D; |
||
44 | import java.awt.geom.Rectangle2D; |
||
45 | import java.io.File; |
||
46 | import java.io.FileInputStream; |
||
47 | 4564 | fjp | import java.io.FileNotFoundException; |
48 | import java.io.FileOutputStream; |
||
49 | 2717 | fjp | import java.io.IOException; |
50 | import java.nio.ByteOrder; |
||
51 | import java.nio.channels.FileChannel; |
||
52 | 4387 | fjp | import java.util.Properties; |
53 | 2717 | fjp | |
54 | import org.apache.log4j.Logger; |
||
55 | |||
56 | 4564 | fjp | import com.hardcode.gdbms.driver.DriverUtilities; |
57 | 2717 | fjp | import com.iver.cit.gvsig.fmap.core.FShape; |
58 | import com.iver.cit.gvsig.fmap.core.GeneralPathX; |
||
59 | import com.iver.cit.gvsig.fmap.core.IGeometry; |
||
60 | import com.iver.cit.gvsig.fmap.core.ShapeFactory; |
||
61 | import com.iver.cit.gvsig.fmap.drivers.BoundedShapes; |
||
62 | import com.iver.cit.gvsig.fmap.drivers.DriverAttributes; |
||
63 | import com.iver.cit.gvsig.fmap.drivers.ExternalData; |
||
64 | 5558 | fjp | import com.iver.cit.gvsig.fmap.drivers.ITableDefinition; |
65 | 2717 | fjp | import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver; |
66 | 4387 | fjp | import com.iver.cit.gvsig.fmap.edition.EditionException; |
67 | import com.iver.cit.gvsig.fmap.edition.IRowEdited; |
||
68 | import com.iver.cit.gvsig.fmap.edition.ISpatialWriter; |
||
69 | 5595 | fjp | import com.iver.cit.gvsig.fmap.edition.IWriteable; |
70 | import com.iver.cit.gvsig.fmap.edition.IWriter; |
||
71 | 4387 | fjp | import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter; |
72 | 3557 | fjp | import com.iver.utiles.bigfile.BigByteBuffer2; |
73 | 2717 | fjp | |
74 | |||
75 | /**
|
||
76 | 3670 | fjp | * Driver del formato SHP. Usa ByteBuffer2, que no consume
|
77 | * memoria (bueno, 8KBytes... !) y no le importa que le pidan
|
||
78 | * entidades desordenadas del fichero, lo cual es indispensable
|
||
79 | * para trabajar con ?ndices espaciales.
|
||
80 | * Adem?s, el tiempo de espera para abrir un fichero y empezar a pintar es
|
||
81 | * pr?cticamente nulo, tanto desde disco duro como por red.
|
||
82 | * La ?nica pega es que en ficheros grandes puede ser unos
|
||
83 | * milisegundos un poco m?s lento que el otro, pero muy poco.
|
||
84 | 2717 | fjp | *
|
85 | * @author Francisco Jos? Pe?arrubia
|
||
86 | */
|
||
87 | public class IndexedShpDriver implements VectorialFileDriver, BoundedShapes, |
||
88 | 5595 | fjp | ExternalData, IWriteable, ISpatialWriter { |
89 | 2717 | fjp | private static Logger logger = Logger.getLogger(IndexedShpDriver.class.getName()); |
90 | 4564 | fjp | private static String tempDirectoryPath = System.getProperty("java.io.tmpdir"); |
91 | private File fileShp; |
||
92 | private File fTemp; |
||
93 | 3557 | fjp | private BigByteBuffer2 bb;
|
94 | 2717 | fjp | private FileChannel channel; |
95 | private FileInputStream fin; |
||
96 | private int type; |
||
97 | 2723 | fjp | // private long[] m_posShapes;
|
98 | 2717 | fjp | private int numReg; |
99 | private Rectangle2D extent; |
||
100 | 5389 | caballero | |
101 | 3670 | fjp | // private File shxFile;
|
102 | 4564 | fjp | private BigByteBuffer2 bbShx;
|
103 | 2717 | fjp | private FileChannel channelShx; |
104 | private FileInputStream finShx; |
||
105 | 5389 | caballero | |
106 | 4387 | fjp | private ShpWriter shpWriter = new ShpWriter(); |
107 | 2717 | fjp | |
108 | 5389 | caballero | |
109 | 2717 | fjp | /**
|
110 | * Cierra el fichero.
|
||
111 | *
|
||
112 | * @throws IOException
|
||
113 | *
|
||
114 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#close()
|
||
115 | */
|
||
116 | public void close() throws IOException { |
||
117 | IOException ret = null; |
||
118 | 5389 | caballero | |
119 | 2717 | fjp | try {
|
120 | channel.close(); |
||
121 | channelShx.close(); |
||
122 | } catch (IOException e) { |
||
123 | ret = e; |
||
124 | } finally {
|
||
125 | try {
|
||
126 | fin.close(); |
||
127 | } catch (IOException e1) { |
||
128 | ret = e1; |
||
129 | } |
||
130 | } |
||
131 | |||
132 | if (ret != null) { |
||
133 | throw ret;
|
||
134 | } |
||
135 | else // Si todo ha ido bien, preparamos para liberar memoria. |
||
136 | { |
||
137 | bb = null;
|
||
138 | bbShx = null;
|
||
139 | } |
||
140 | } |
||
141 | |||
142 | /**
|
||
143 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#open(java.io.File)
|
||
144 | */
|
||
145 | public void open(File f) throws IOException { |
||
146 | 4564 | fjp | fileShp = f; |
147 | 2717 | fjp | |
148 | fin = new FileInputStream(f); |
||
149 | |||
150 | // Open the file and then get a channel from the stream
|
||
151 | channel = fin.getChannel(); |
||
152 | |||
153 | 3670 | fjp | // long size = channel.size();
|
154 | 2717 | fjp | |
155 | // Get the file's size and then map it into memory
|
||
156 | // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
||
157 | 3557 | fjp | bb = new BigByteBuffer2(channel, FileChannel.MapMode.READ_ONLY); |
158 | 5389 | caballero | |
159 | 2717 | fjp | finShx = new FileInputStream(getShxFile(f)); |
160 | |||
161 | // Open the file and then get a channel from the stream
|
||
162 | channelShx = finShx.getChannel(); |
||
163 | |||
164 | long sizeShx = channelShx.size();
|
||
165 | |||
166 | // Get the file's size and then map it into memory
|
||
167 | // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
||
168 | 4564 | fjp | // bbShx = channelShx.map(FileChannel.MapMode.READ_ONLY, 0, sizeShx);
|
169 | bbShx = new BigByteBuffer2(channelShx, FileChannel.MapMode.READ_ONLY); |
||
170 | 2717 | fjp | bbShx.order(ByteOrder.BIG_ENDIAN);
|
171 | } |
||
172 | |||
173 | /**
|
||
174 | * DOCUMENT ME!
|
||
175 | *
|
||
176 | * @param index DOCUMENT ME!
|
||
177 | *
|
||
178 | * @return DOCUMENT ME!
|
||
179 | *
|
||
180 | * @throws IOException
|
||
181 | *
|
||
182 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShape(int)
|
||
183 | */
|
||
184 | |||
185 | /* public FShape getShapeByID(int ID) {
|
||
186 | Point2D.Double p = new Point2D.Double();
|
||
187 | Point2D.Double pAnt = null;
|
||
188 | int numParts;
|
||
189 | int numPoints;
|
||
190 | int i;
|
||
191 | int j;
|
||
192 | int numReg;
|
||
193 | int numeroPuntos;
|
||
194 | int hasta;
|
||
195 | int desde;
|
||
196 | Rectangle2D.Double BoundingBox = new Rectangle2D.Double();
|
||
197 | 5389 | caballero | |
198 | 2717 | fjp | SHPShape shapeShp=null;
|
199 | FShape resulShape = null;
|
||
200 | try {
|
||
201 | bb.position(m_posShapes[ID]);
|
||
202 | bb.order(ByteOrder.LITTLE_ENDIAN);
|
||
203 | int tipoShape = bb.getInt();
|
||
204 | m_shapeType = tipoShape;
|
||
205 | // retrieve that shape.
|
||
206 | // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
|
||
207 | if (tipoShape == FConstant.SHAPE_TYPE_POINT) {
|
||
208 | p = readPoint(bb);
|
||
209 | resulShape = new FShape(new FPoint(p.getX(),p.getY()),FConstant.SHAPE_TYPE_POINT);
|
||
210 | //Comprobaci?n punto.
|
||
211 | //System.err.println("p.x = "+p.x);
|
||
212 | //System.err.println("p.y = "+p.y);
|
||
213 | 5389 | caballero | |
214 | 2717 | fjp | } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINE) ||
|
215 | (tipoShape == FConstant.SHAPE_TYPE_POLYGON)) {
|
||
216 | // BoundingBox
|
||
217 | BoundingBox = readRectangle(bb);
|
||
218 | numParts = bb.getInt();
|
||
219 | numPoints = bb.getInt();
|
||
220 | // part indexes.
|
||
221 | // Geometry geom = GeometryFactory.toGeometryArray();
|
||
222 | GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
|
||
223 | numPoints);
|
||
224 | int[] tempParts = new int[numParts];
|
||
225 | for (i = 0; i < numParts; i++) {
|
||
226 | tempParts[i] = bb.getInt();
|
||
227 | }
|
||
228 | j = 0;
|
||
229 | ///Line2D.Double line2D;
|
||
230 | FPoint[] points=new FPoint[numPoints];
|
||
231 | for (i = 0; i < numPoints; i++) {
|
||
232 | p=readPoint(bb);
|
||
233 | points[i] = new FPoint(p.x,p.y);
|
||
234 | // System.out.println("x= " + p.x + " y=" + p.y);
|
||
235 | // System.out.println("x= " + (float) p.x + " y=" + (float) p.y);
|
||
236 | if (i == tempParts[j]) {
|
||
237 | elShape.moveTo(p.x, p.y);
|
||
238 | if (j < (numParts - 1)) {
|
||
239 | j++;
|
||
240 | }
|
||
241 | } else {
|
||
242 | elShape.lineTo(p.x, p.y);
|
||
243 | }
|
||
244 | }
|
||
245 | //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
|
||
246 | 5389 | caballero | |
247 | 2717 | fjp | resulShape = new FShape(tipoShape,elShape);
|
248 | } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINT) {
|
||
249 | // BoundingBox
|
||
250 | BoundingBox = readRectangle(bb);
|
||
251 | numPoints = bb.getInt();
|
||
252 | FPoint[] tempPoints = new FPoint[numPoints];
|
||
253 | for (i = 0; i < numPoints; i++) {
|
||
254 | Point2D p2=readPoint(bb);
|
||
255 | tempPoints[i] = new FPoint(p2.getX(),p2.getY(),0);
|
||
256 | }
|
||
257 | FMultiPoint multipoint = new FMultiPoint(tempPoints,BoundingBox);
|
||
258 | resulShape = new FShape(multipoint,tipoShape);
|
||
259 | } else if (tipoShape == FConstant.SHAPE_TYPE_POINTZ) {
|
||
260 | FPoint p3d = new FPoint();
|
||
261 | p3d.read(bb);
|
||
262 | resulShape = new FShape(p3d,tipoShape);
|
||
263 | } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINEZ) ||
|
||
264 | (tipoShape == FConstant.SHAPE_TYPE_POLYGONZ)) {
|
||
265 | // BoundingBox
|
||
266 | BoundingBox = readRectangle(bb);
|
||
267 | numParts = bb.getInt();
|
||
268 | numPoints = bb.getInt();
|
||
269 | // part indexes.
|
||
270 | // Geometry geom = GeometryFactory.toGeometryArray();
|
||
271 | 5389 | caballero | |
272 | 2717 | fjp | GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
|
273 | numPoints);
|
||
274 | int[] tempParts = new int[numParts];
|
||
275 | for (i = 0; i < numParts; i++) {
|
||
276 | tempParts[i] = bb.getInt();
|
||
277 | }
|
||
278 | j = 0;
|
||
279 | //Line2D.Double line2D;
|
||
280 | FPoint[] points=new FPoint[numPoints];
|
||
281 | for (i = 0; i < numPoints; i++) {
|
||
282 | p = readPoint(bb);
|
||
283 | points[i]=new FPoint(p.x,p.y);
|
||
284 | 5389 | caballero | |
285 | 2717 | fjp | if (i == tempParts[j]) {
|
286 | elShape.moveTo(p.x, p.y);
|
||
287 | if (j < (numParts - 1)) {
|
||
288 | j++;
|
||
289 | }
|
||
290 | } else {
|
||
291 | elShape.lineTo(p.x, p.y);
|
||
292 | }
|
||
293 | 5389 | caballero | |
294 | 2717 | fjp | }
|
295 | 5389 | caballero | |
296 | 2717 | fjp | double[] boxZ = new double[2];
|
297 | boxZ[0] = bb.getDouble();
|
||
298 | boxZ[1] = bb.getDouble();
|
||
299 | double[] pZ = new double[numPoints];
|
||
300 | for (i = 0; i < numPoints; i++) {
|
||
301 | pZ[i] = bb.getDouble();
|
||
302 | }
|
||
303 | //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
|
||
304 | resulShape = new FShape(tipoShape, elShape, pZ);
|
||
305 | } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINTZ) {
|
||
306 | // BoundingBox
|
||
307 | BoundingBox = readRectangle(bb);
|
||
308 | numPoints = bb.getInt();
|
||
309 | FPoint[] tempPoints3D = new FPoint[numPoints];
|
||
310 | for (i = 0; i < numPoints; i++) {
|
||
311 | tempPoints3D[i] = new FPoint();
|
||
312 | tempPoints3D[i].read(bb);
|
||
313 | }
|
||
314 | FMultiPoint multipoint3D = new FMultiPoint(tempPoints3D,BoundingBox);
|
||
315 | resulShape = new FShape(multipoint3D,tipoShape);
|
||
316 | }
|
||
317 | } catch (Exception e) {
|
||
318 | System.err.println("Fallo en getShapeByID. ID=" + ID +
|
||
319 | " m_posShapes[ID]=" + m_posShapes[ID]);
|
||
320 | System.err.println("getShapeByID: " + e.getMessage());
|
||
321 | e.printStackTrace();
|
||
322 | }
|
||
323 | return resulShape;
|
||
324 | }
|
||
325 | */
|
||
326 | |||
327 | /**
|
||
328 | * Devuelve la geometria a partir de un ?ndice.
|
||
329 | *
|
||
330 | * @param index DOCUMENT ME!
|
||
331 | *
|
||
332 | * @return DOCUMENT ME!
|
||
333 | *
|
||
334 | * @throws IOException DOCUMENT ME!
|
||
335 | */
|
||
336 | 5168 | fjp | public synchronized IGeometry getShape(int index) throws IOException { |
337 | 2717 | fjp | Point2D.Double p = new Point2D.Double(); |
338 | int numParts;
|
||
339 | int numPoints;
|
||
340 | int i;
|
||
341 | int j;
|
||
342 | 3670 | fjp | /* int numReg;
|
343 | 2717 | fjp | int numeroPuntos;
|
344 | int hasta;
|
||
345 | 3670 | fjp | int desde; */
|
346 | 2717 | fjp | int shapeType;
|
347 | |||
348 | //Rectangle2D.Double BoundingBox;
|
||
349 | // if (m_posShapes[index] == 0)
|
||
350 | 5389 | caballero | |
351 | 2717 | fjp | // bb.position(m_posShapes[index]);
|
352 | bb.position(getPositionForRecord(index)); |
||
353 | bb.order(ByteOrder.LITTLE_ENDIAN);
|
||
354 | |||
355 | ///bb.position(bb.position()+4);
|
||
356 | shapeType = bb.getInt(); |
||
357 | //el shape tal con tema tal y n?mro tal es null
|
||
358 | if (shapeType==SHP.NULL){
|
||
359 | 5258 | jmvivo | logger.info("El shape ="+index+ " de la capa ="+this.toString()+" es null"); |
360 | 2717 | fjp | return null; |
361 | } |
||
362 | 5389 | caballero | |
363 | 2717 | fjp | // retrieve that shape.
|
364 | // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
|
||
365 | switch (type) {
|
||
366 | case (SHP.POINT2D):
|
||
367 | p = readPoint(bb); |
||
368 | |||
369 | 5880 | fjp | return ShapeFactory.createPoint2D(p.getX(), p.getY());
|
370 | |||
371 | 2717 | fjp | case (SHP.POLYLINE2D):
|
372 | |||
373 | 5880 | fjp | //BoundingBox = readRectangle(bb);
|
374 | //bb.getDouble();
|
||
375 | //bb.getDouble();
|
||
376 | //bb.getDouble();
|
||
377 | //bb.getDouble();
|
||
378 | 2717 | fjp | bb.position(bb.position() + 32);
|
379 | numParts = bb.getInt(); |
||
380 | numPoints = bb.getInt(); |
||
381 | |||
382 | // part indexes.
|
||
383 | // Geometry geom = GeometryFactory.toGeometryArray();
|
||
384 | GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
|
||
385 | numPoints); |
||
386 | |||
387 | int[] tempParts = new int[numParts]; |
||
388 | |||
389 | for (i = 0; i < numParts; i++) { |
||
390 | tempParts[i] = bb.getInt(); |
||
391 | } |
||
392 | |||
393 | j = 0;
|
||
394 | |||
395 | for (i = 0; i < numPoints; i++) { |
||
396 | p = readPoint(bb); |
||
397 | |||
398 | if (i == tempParts[j]) {
|
||
399 | elShape.moveTo(p.x, p.y); |
||
400 | |||
401 | if (j < (numParts - 1)) { |
||
402 | j++; |
||
403 | } |
||
404 | } else {
|
||
405 | elShape.lineTo(p.x, p.y); |
||
406 | } |
||
407 | } |
||
408 | 5880 | fjp | |
409 | return ShapeFactory.createPolyline2D(elShape);
|
||
410 | |||
411 | 2717 | fjp | case (SHP.POLYGON2D):
|
412 | |||
413 | // BoundingBox = readRectangle(bb);
|
||
414 | bb.getDouble(); |
||
415 | bb.getDouble(); |
||
416 | bb.getDouble(); |
||
417 | bb.getDouble(); |
||
418 | |||
419 | numParts = bb.getInt(); |
||
420 | |||
421 | numPoints = bb.getInt(); |
||
422 | |||
423 | // part indexes.
|
||
424 | // Geometry geom = GeometryFactory.toGeometryArray();
|
||
425 | elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
|
||
426 | |||
427 | tempParts = new int[numParts]; |
||
428 | |||
429 | for (i = 0; i < numParts; i++) { |
||
430 | tempParts[i] = bb.getInt(); |
||
431 | } |
||
432 | |||
433 | j = 0;
|
||
434 | |||
435 | for (i = 0; i < numPoints; i++) { |
||
436 | p = readPoint(bb); |
||
437 | |||
438 | if (i == tempParts[j]) {
|
||
439 | elShape.moveTo(p.x, p.y); |
||
440 | |||
441 | if (j < (numParts - 1)) { |
||
442 | j++; |
||
443 | } |
||
444 | } else {
|
||
445 | elShape.lineTo(p.x, p.y); |
||
446 | } |
||
447 | } |
||
448 | |||
449 | 5880 | fjp | return ShapeFactory.createPolygon2D(elShape);
|
450 | |||
451 | 2717 | fjp | case (SHP.POINT3D):
|
452 | |||
453 | double x = bb.getDouble();
|
||
454 | double y = bb.getDouble();
|
||
455 | double z = bb.getDouble();
|
||
456 | |||
457 | 5880 | fjp | return ShapeFactory.createPoint3D(x, y, z);
|
458 | |||
459 | 2717 | fjp | case (SHP.POLYLINE3D):
|
460 | bb.position(bb.position() + 32);
|
||
461 | numParts = bb.getInt(); |
||
462 | numPoints = bb.getInt(); |
||
463 | elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
|
||
464 | tempParts = new int[numParts]; |
||
465 | |||
466 | for (i = 0; i < numParts; i++) { |
||
467 | tempParts[i] = bb.getInt(); |
||
468 | } |
||
469 | |||
470 | j = 0;
|
||
471 | |||
472 | for (i = 0; i < numPoints; i++) { |
||
473 | p = readPoint(bb); |
||
474 | |||
475 | if (i == tempParts[j]) {
|
||
476 | elShape.moveTo(p.x, p.y); |
||
477 | |||
478 | if (j < (numParts - 1)) { |
||
479 | j++; |
||
480 | } |
||
481 | } else {
|
||
482 | elShape.lineTo(p.x, p.y); |
||
483 | } |
||
484 | } |
||
485 | |||
486 | double[] boxZ = new double[2]; |
||
487 | boxZ[0] = bb.getDouble();
|
||
488 | boxZ[1] = bb.getDouble();
|
||
489 | |||
490 | double[] pZ = new double[numPoints]; |
||
491 | |||
492 | for (i = 0; i < numPoints; i++) { |
||
493 | pZ[i] = bb.getDouble(); |
||
494 | } |
||
495 | 5880 | fjp | |
496 | return ShapeFactory.createPolyline3D(elShape, pZ);
|
||
497 | 2717 | fjp | case (SHP.POLYGON3D):
|
498 | bb.position(bb.position() + 32);
|
||
499 | numParts = bb.getInt(); |
||
500 | numPoints = bb.getInt(); |
||
501 | elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
|
||
502 | tempParts = new int[numParts]; |
||
503 | |||
504 | for (i = 0; i < numParts; i++) { |
||
505 | tempParts[i] = bb.getInt(); |
||
506 | } |
||
507 | |||
508 | j = 0;
|
||
509 | |||
510 | for (i = 0; i < numPoints; i++) { |
||
511 | p = readPoint(bb); |
||
512 | |||
513 | if (i == tempParts[j]) {
|
||
514 | elShape.moveTo(p.x, p.y); |
||
515 | |||
516 | if (j < (numParts - 1)) { |
||
517 | j++; |
||
518 | } |
||
519 | } else {
|
||
520 | elShape.lineTo(p.x, p.y); |
||
521 | } |
||
522 | } |
||
523 | |||
524 | double[] boxpoZ = new double[2]; |
||
525 | boxpoZ[0] = bb.getDouble();
|
||
526 | boxpoZ[1] = bb.getDouble();
|
||
527 | |||
528 | double[] poZ = new double[numPoints]; |
||
529 | |||
530 | for (i = 0; i < numPoints; i++) { |
||
531 | poZ[i] = bb.getDouble(); |
||
532 | } |
||
533 | |||
534 | 5880 | fjp | return ShapeFactory.createPolygon3D(elShape, poZ);
|
535 | |||
536 | 2717 | fjp | case (SHP.MULTIPOINT2D):
|
537 | bb.position(bb.position() + 32);
|
||
538 | numPoints = bb.getInt(); |
||
539 | |||
540 | double[] tempX = new double[numPoints]; |
||
541 | double[] tempY = new double[numPoints]; |
||
542 | |||
543 | for (i = 0; i < numPoints; i++) { |
||
544 | tempX[i] = bb.getDouble(); |
||
545 | tempY[i] = bb.getDouble(); |
||
546 | } |
||
547 | |||
548 | 5880 | fjp | return ShapeFactory.createMultipoint2D(tempX, tempY);
|
549 | |||
550 | 2717 | fjp | case (SHP.MULTIPOINT3D):
|
551 | bb.position(bb.position() + 32);
|
||
552 | numPoints = bb.getInt(); |
||
553 | |||
554 | double[] temX = new double[numPoints]; |
||
555 | double[] temY = new double[numPoints]; |
||
556 | double[] temZ = new double[numPoints]; |
||
557 | |||
558 | for (i = 0; i < numPoints; i++) { |
||
559 | temX[i] = bb.getDouble(); |
||
560 | temY[i] = bb.getDouble(); |
||
561 | //temZ[i] = bb.getDouble();
|
||
562 | } |
||
563 | 5389 | caballero | |
564 | 2717 | fjp | for (i = 0; i < numPoints; i++) { |
565 | temZ[i] = bb.getDouble(); |
||
566 | } |
||
567 | 5880 | fjp | return ShapeFactory.createMultipoint3D(temX, temY, temZ);
|
568 | 2717 | fjp | } |
569 | |||
570 | 5880 | fjp | return null; |
571 | 2717 | fjp | } |
572 | |||
573 | /**
|
||
574 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShapeCount()
|
||
575 | */
|
||
576 | public int getShapeCount() { |
||
577 | return numReg;
|
||
578 | } |
||
579 | |||
580 | /**
|
||
581 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getShapeType()
|
||
582 | */
|
||
583 | public int getShapeType() { |
||
584 | int auxType = 0; |
||
585 | |||
586 | switch (type) {
|
||
587 | case (SHP.POINT2D):
|
||
588 | case (SHP.POINT3D):
|
||
589 | auxType = auxType | FShape.POINT; |
||
590 | |||
591 | break;
|
||
592 | |||
593 | case (SHP.POLYLINE2D):
|
||
594 | case (SHP.POLYLINE3D):
|
||
595 | auxType = auxType | FShape.LINE; |
||
596 | |||
597 | break;
|
||
598 | |||
599 | case (SHP.POLYGON2D):
|
||
600 | case (SHP.POLYGON3D):
|
||
601 | auxType = auxType | FShape.POLYGON; |
||
602 | |||
603 | break;
|
||
604 | case (SHP.MULTIPOINT2D):
|
||
605 | case (SHP.MULTIPOINT3D):
|
||
606 | auxType = auxType | FShape.MULTIPOINT; |
||
607 | |||
608 | break;
|
||
609 | } |
||
610 | |||
611 | return auxType;
|
||
612 | } |
||
613 | |||
614 | |||
615 | /**
|
||
616 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
|
||
617 | */
|
||
618 | public void initialize() throws IOException { |
||
619 | // create a new header.
|
||
620 | 3557 | fjp | ShapeFileHeader2 myHeader = new ShapeFileHeader2();
|
621 | 5389 | caballero | |
622 | 5326 | jmvivo | bb.position(0);
|
623 | 2717 | fjp | |
624 | // read the header
|
||
625 | myHeader.readHeader(bb); |
||
626 | |||
627 | extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin, |
||
628 | myHeader.myXmax - myHeader.myXmin, |
||
629 | myHeader.myYmax - myHeader.myYmin); |
||
630 | 6714 | caballero | |
631 | 2717 | fjp | type = myHeader.myShapeType; |
632 | 6714 | caballero | |
633 | 2717 | fjp | double x = myHeader.myXmin;
|
634 | double y = myHeader.myYmin;
|
||
635 | double w = myHeader.myXmax - myHeader.myXmin;
|
||
636 | double h = myHeader.myYmax - myHeader.myYmin;
|
||
637 | |||
638 | if (w == 0) { |
||
639 | x -= 0.1;
|
||
640 | w = 0.2;
|
||
641 | } |
||
642 | |||
643 | if (h == 0) { |
||
644 | y -= 0.1;
|
||
645 | h = 0.2;
|
||
646 | } |
||
647 | |||
648 | // String strFichDbf = m_Path.toLowerCase().replaceAll("\\.shp", ".dbf");
|
||
649 | 4564 | fjp | String strFichDbf = fileShp.getAbsolutePath().replaceAll("\\.shp", ".dbf"); |
650 | 2717 | fjp | strFichDbf = strFichDbf.replaceAll("\\.SHP", ".DBF"); |
651 | |||
652 | DbaseFileNIO m_FichDbf = new DbaseFileNIO();
|
||
653 | |||
654 | m_FichDbf.open(new File(strFichDbf)); |
||
655 | numReg = m_FichDbf.getRecordCount(); |
||
656 | 5389 | caballero | |
657 | 4426 | fjp | // shpWriter.initialize(file);
|
658 | 2723 | fjp | // m_posShapes = new long[numReg];
|
659 | 2717 | fjp | |
660 | // read the records.
|
||
661 | /* int tempCurrentLength = myHeader.getHeaderLength();
|
||
662 | int numReg = 0;
|
||
663 | |||
664 | long pos1;
|
||
665 | |||
666 | while (tempCurrentLength < myHeader.myFileLength) {
|
||
667 | // read the record header
|
||
668 | // ShapeFileRecord tempRecord = new ShapeFileRecord();
|
||
669 | // Bytes 0 to 4 represent the record number in the file, these may be out of order.
|
||
670 | bb.order(ByteOrder.BIG_ENDIAN);
|
||
671 | |||
672 | // tempRecord.setIndex(in.readInt());
|
||
673 | bb.getInt();
|
||
674 | |||
675 | // read the content length of this record in 16 bit words, excluding the index.
|
||
676 | // in.setLittleEndianMode(false);
|
||
677 | int tempContentLength = bb.getInt();
|
||
678 | |||
679 | pos1 = bb.position();
|
||
680 | |||
681 | m_posShapes[numReg] = bb.position();
|
||
682 | |||
683 | // Posicionamos
|
||
684 | bb.position((pos1 + (2 * tempContentLength)));
|
||
685 | numReg = numReg + 1;
|
||
686 | |||
687 | // update the current length the 4 is for the index, and content length.
|
||
688 | tempCurrentLength = tempCurrentLength + 4 + tempContentLength;
|
||
689 | } */
|
||
690 | } |
||
691 | |||
692 | /**
|
||
693 | * Reads the Point from the shape file.
|
||
694 | *
|
||
695 | * @param in ByteBuffer.
|
||
696 | *
|
||
697 | * @return Point2D.
|
||
698 | */
|
||
699 | 5168 | fjp | private synchronized Point2D.Double readPoint(BigByteBuffer2 in) { |
700 | 2717 | fjp | // create a new point
|
701 | Point2D.Double tempPoint = new Point2D.Double(); |
||
702 | |||
703 | // bytes 1 to 4 are the type and have already been read.
|
||
704 | // bytes 4 to 12 are the X coordinate
|
||
705 | in.order(ByteOrder.LITTLE_ENDIAN);
|
||
706 | tempPoint.setLocation(in.getDouble(), in.getDouble()); |
||
707 | |||
708 | return tempPoint;
|
||
709 | } |
||
710 | |||
711 | /**
|
||
712 | * Lee un rect?ngulo del fichero.
|
||
713 | *
|
||
714 | * @param in ByteBuffer.
|
||
715 | *
|
||
716 | * @return Rect?ngulo.
|
||
717 | *
|
||
718 | * @throws IOException
|
||
719 | */
|
||
720 | 5168 | fjp | private synchronized Rectangle2D.Double readRectangle(BigByteBuffer2 in) |
721 | 2717 | fjp | throws IOException { |
722 | Rectangle2D.Double tempRect = new Rectangle2D.Double(); |
||
723 | in.order(ByteOrder.LITTLE_ENDIAN);
|
||
724 | tempRect.x = in.getDouble(); |
||
725 | tempRect.y = in.getDouble(); |
||
726 | |||
727 | tempRect.width = in.getDouble() - tempRect.x; |
||
728 | |||
729 | if (tempRect.width == 0) { |
||
730 | tempRect.width = 0.2;
|
||
731 | tempRect.x -= 0.1;
|
||
732 | } |
||
733 | |||
734 | tempRect.height = in.getDouble() - tempRect.y; |
||
735 | |||
736 | if (tempRect.height == 0) { |
||
737 | tempRect.height = 0.2;
|
||
738 | tempRect.y -= 0.1;
|
||
739 | } |
||
740 | |||
741 | return tempRect;
|
||
742 | } |
||
743 | |||
744 | /**
|
||
745 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
|
||
746 | */
|
||
747 | public Rectangle2D getFullExtent() throws IOException { |
||
748 | return extent;
|
||
749 | } |
||
750 | |||
751 | /**
|
||
752 | * Obtiene el extent del shape a partir de un ?ndice.
|
||
753 | *
|
||
754 | * @param index ?ndice.
|
||
755 | *
|
||
756 | * @return Rect?ngulo.
|
||
757 | *
|
||
758 | * @throws IOException
|
||
759 | *
|
||
760 | * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeBounds()
|
||
761 | */
|
||
762 | 5168 | fjp | public synchronized Rectangle2D getShapeBounds(int index) throws IOException { |
763 | 2717 | fjp | Point2D p = new Point2D.Double(); |
764 | Rectangle2D BoundingBox = new Rectangle2D.Double(); |
||
765 | bb.position(getPositionForRecord(index)); |
||
766 | bb.order(ByteOrder.LITTLE_ENDIAN);
|
||
767 | |||
768 | int tipoShape = bb.getInt();
|
||
769 | |||
770 | 5682 | azabala | //AZABALA: si tipoShape viene con valores erroneos deja de funcionar
|
771 | //el metodo getShape(i)
|
||
772 | // if (tipoShape != SHP.NULL) {
|
||
773 | // type = tipoShape;
|
||
774 | //
|
||
775 | // }
|
||
776 | 2717 | fjp | |
777 | // retrieve that shape.
|
||
778 | // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
|
||
779 | switch (tipoShape) {
|
||
780 | case (SHP.POINT2D):
|
||
781 | case (SHP.POINT3D):
|
||
782 | p = readPoint(bb); |
||
783 | BoundingBox = new Rectangle2D.Double(p.getX() - 0.1, |
||
784 | p.getY() - 0.1, 0.2, 0.2); |
||
785 | |||
786 | break;
|
||
787 | |||
788 | case (SHP.POLYLINE2D):
|
||
789 | case (SHP.POLYGON2D):
|
||
790 | case (SHP.MULTIPOINT2D):
|
||
791 | case (SHP.POLYLINE3D):
|
||
792 | case (SHP.POLYGON3D):
|
||
793 | case (SHP.MULTIPOINT3D):
|
||
794 | |||
795 | // BoundingBox
|
||
796 | BoundingBox = readRectangle(bb); |
||
797 | |||
798 | break;
|
||
799 | } |
||
800 | |||
801 | return BoundingBox;
|
||
802 | } |
||
803 | |||
804 | /**
|
||
805 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#accept(java.io.File)
|
||
806 | */
|
||
807 | public boolean accept(File f) { |
||
808 | return (f.getName().toUpperCase().endsWith("SHP")); |
||
809 | } |
||
810 | |||
811 | /**
|
||
812 | * @see com.hardcode.driverManager.Driver#getType()
|
||
813 | */
|
||
814 | public String getName() { |
||
815 | 3670 | fjp | // Para que se use este driver en lugar del viejo DemoShpDriver.
|
816 | 5389 | caballero | |
817 | 3670 | fjp | // return "gvSIG indexed shp driver";
|
818 | return "gvSIG shp driver"; |
||
819 | 2717 | fjp | } |
820 | |||
821 | /**
|
||
822 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataDriverName()
|
||
823 | */
|
||
824 | public String getDataDriverName() { |
||
825 | return "gdbms dbf driver"; |
||
826 | } |
||
827 | |||
828 | /**
|
||
829 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataFile(java.io.File)
|
||
830 | */
|
||
831 | public File getDataFile(File f) { |
||
832 | String str = f.getAbsolutePath();
|
||
833 | |||
834 | return new File(str.substring(0, str.length() - 3) + "dbf"); |
||
835 | } |
||
836 | |||
837 | public File getShxFile(File f) { |
||
838 | String str = f.getAbsolutePath();
|
||
839 | |||
840 | return new File(str.substring(0, str.length() - 3) + "shx"); |
||
841 | } |
||
842 | 5389 | caballero | |
843 | |||
844 | 2717 | fjp | /* (non-Javadoc)
|
845 | * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeType(int)
|
||
846 | */
|
||
847 | public int getShapeType(int index) { |
||
848 | // Por ahora todos los fichero .shp contienen
|
||
849 | // entidades del mismo tipo. Si trabajamos con
|
||
850 | // alguno mixto, tendremos que cambiar esta funci?n.
|
||
851 | return getShapeType();
|
||
852 | } |
||
853 | |||
854 | /* (non-Javadoc)
|
||
855 | * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
|
||
856 | */
|
||
857 | public DriverAttributes getDriverAttributes() {
|
||
858 | return null; |
||
859 | } |
||
860 | 5389 | caballero | |
861 | 5168 | fjp | private synchronized long getPositionForRecord(int numRec) |
862 | 2717 | fjp | { |
863 | // shx file has a 100 bytes header, then, records
|
||
864 | // 8 bytes length, one for each entity.
|
||
865 | // first 4 bytes are the offset
|
||
866 | // next 4 bytes are length
|
||
867 | 5389 | caballero | |
868 | 2717 | fjp | int posIndex = 100 + (numRec * 8); |
869 | // bbShx.position(posIndex);
|
||
870 | long pos = 8 + 2*bbShx.getInt(posIndex); |
||
871 | 5389 | caballero | |
872 | 2717 | fjp | return pos;
|
873 | } |
||
874 | 3720 | fjp | |
875 | public File getFile() { |
||
876 | 4564 | fjp | return fileShp;
|
877 | 3720 | fjp | } |
878 | 5389 | caballero | |
879 | 6323 | fjp | public void reload() throws IOException { |
880 | 5713 | fjp | open(fileShp); |
881 | 3952 | fjp | initialize(); |
882 | } |
||
883 | 4387 | fjp | |
884 | 5389 | caballero | public boolean canWriteGeometry(int gvSIGgeometryType) { |
885 | 4387 | fjp | return shpWriter.canWriteGeometry(gvSIGgeometryType);
|
886 | } |
||
887 | |||
888 | 4426 | fjp | /* (non-Javadoc)
|
889 | * @see com.iver.cit.gvsig.fmap.edition.IWriter#preProcess()
|
||
890 | */
|
||
891 | 4387 | fjp | public void preProcess() throws EditionException { |
892 | 4564 | fjp | // Necesitamos crear un fichero temporal porque a la vez que esic
|
893 | 5389 | caballero | // La cabecera ya existe, as? que no la sobreescribimos.
|
894 | 4564 | fjp | // shpWriter.setWriteHeaders(false);
|
895 | 4387 | fjp | shpWriter.preProcess(); |
896 | 5389 | caballero | |
897 | 4387 | fjp | } |
898 | |||
899 | public void process(IRowEdited row) throws EditionException { |
||
900 | shpWriter.process(row); |
||
901 | 5389 | caballero | |
902 | 4387 | fjp | } |
903 | |||
904 | public void postProcess() throws EditionException { |
||
905 | 5389 | caballero | shpWriter.postProcess(); |
906 | |||
907 | 4564 | fjp | try {
|
908 | 5389 | caballero | |
909 | 4564 | fjp | // close();
|
910 | 5389 | caballero | |
911 | 4564 | fjp | // Shp
|
912 | FileChannel fcinShp = new FileInputStream(fTemp).getChannel(); |
||
913 | FileChannel fcoutShp = new FileOutputStream(fileShp).getChannel(); |
||
914 | DriverUtilities.copy(fcinShp, fcoutShp); |
||
915 | |||
916 | // Shx
|
||
917 | File shxFile = getShxFile(fTemp);
|
||
918 | FileChannel fcinShx = new FileInputStream(shxFile).getChannel(); |
||
919 | FileChannel fcoutShx = new FileOutputStream(getShxFile(fileShp)).getChannel(); |
||
920 | DriverUtilities.copy(fcinShx, fcoutShx); |
||
921 | |||
922 | // Dbf
|
||
923 | File dbfFile = getDataFile(fTemp);
|
||
924 | FileChannel fcinDbf = new FileInputStream(dbfFile).getChannel(); |
||
925 | FileChannel fcoutDbf = new FileOutputStream(getDataFile(fileShp)).getChannel(); |
||
926 | DriverUtilities.copy(fcinDbf, fcoutDbf); |
||
927 | 5389 | caballero | |
928 | 4564 | fjp | // Borramos los temporales
|
929 | fTemp.delete(); |
||
930 | shxFile.delete(); |
||
931 | dbfFile.delete(); |
||
932 | 6323 | fjp | reload(); |
933 | 5389 | caballero | |
934 | |||
935 | |||
936 | 4564 | fjp | } catch (FileNotFoundException e) { |
937 | throw new EditionException(e); |
||
938 | } catch (IOException e) { |
||
939 | throw new EditionException(e); |
||
940 | } |
||
941 | 5389 | caballero | |
942 | |||
943 | 4387 | fjp | } |
944 | |||
945 | public String getCapability(String capability) { |
||
946 | return shpWriter.getCapability(capability);
|
||
947 | } |
||
948 | |||
949 | public void setCapabilities(Properties capabilities) { |
||
950 | shpWriter.setCapabilities(capabilities); |
||
951 | 5389 | caballero | |
952 | 4387 | fjp | } |
953 | |||
954 | public boolean canWriteAttribute(int sqlType) { |
||
955 | return shpWriter.canWriteAttribute(sqlType);
|
||
956 | } |
||
957 | |||
958 | public ShpWriter getShpWriter() {
|
||
959 | return shpWriter;
|
||
960 | } |
||
961 | |||
962 | public void setShpWriter(ShpWriter shpWriter) { |
||
963 | this.shpWriter = shpWriter;
|
||
964 | } |
||
965 | 4430 | fjp | |
966 | 5558 | fjp | public void initialize(ITableDefinition layerDef) throws EditionException { |
967 | 4564 | fjp | int aux = (int)(Math.random() * 1000); |
968 | fTemp = new File(tempDirectoryPath + "/tmpShp" + aux + ".shp"); |
||
969 | shpWriter.setFile(fTemp); |
||
970 | 5558 | fjp | shpWriter.initialize(layerDef); |
971 | 5389 | caballero | |
972 | 4430 | fjp | } |
973 | 5389 | caballero | |
974 | 6714 | caballero | // public void setFlatness(double flatness) {
|
975 | // shpWriter.setFlatness(flatness);
|
||
976 | // }
|
||
977 | 5389 | caballero | |
978 | 5521 | caballero | public boolean isWritable() { |
979 | return fileShp.canWrite();
|
||
980 | } |
||
981 | |||
982 | 5595 | fjp | public IWriter getWriter()
|
983 | { |
||
984 | return this; |
||
985 | } |
||
986 | 6259 | fjp | |
987 | public ITableDefinition getTableDefinition() {
|
||
988 | return shpWriter.getTableDefinition();
|
||
989 | } |
||
990 | 6356 | fjp | |
991 | public boolean canAlterTable() { |
||
992 | return true; |
||
993 | } |
||
994 | 6856 | fjp | |
995 | public boolean canSaveEdits() { |
||
996 | return shpWriter.canSaveEdits();
|
||
997 | } |
||
998 | 8913 | fjp | |
999 | public boolean isWriteAll() { |
||
1000 | return true; |
||
1001 | } |
||
1002 | 2717 | fjp | } |