root / branches / v2_0_0_prep / libraries / libFMap / src / org / gvsig / fmap / drivers / writing / PruebaVicenteExpansionFile2.java @ 20989
History | View | Annotate | Download (28 KB)
1 |
/* 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 org.gvsig.fmap.drivers.writing; |
42 |
|
43 |
import java.awt.geom.Point2D; |
44 |
import java.io.File; |
45 |
import java.io.FileInputStream; |
46 |
import java.io.FileNotFoundException; |
47 |
import java.io.IOException; |
48 |
import java.io.RandomAccessFile; |
49 |
import java.io.UnsupportedEncodingException; |
50 |
import java.nio.ByteBuffer; |
51 |
import java.nio.ByteOrder; |
52 |
import java.nio.channels.FileChannel; |
53 |
import java.nio.channels.WritableByteChannel; |
54 |
import java.nio.channels.FileChannel.MapMode; |
55 |
import java.nio.charset.Charset; |
56 |
import java.sql.Types; |
57 |
import java.text.DateFormat; |
58 |
import java.text.ParseException; |
59 |
import java.util.ArrayList; |
60 |
import java.util.Date; |
61 |
import java.util.HashMap; |
62 |
import java.util.Locale; |
63 |
|
64 |
import org.gvsig.fmap.core.features.DefaultFeature; |
65 |
import org.gvsig.fmap.core.features.DefaultRowEdited; |
66 |
import org.gvsig.fmap.core.features.IFeature; |
67 |
import org.gvsig.fmap.core.features.IRow; |
68 |
import org.gvsig.fmap.core.features.IRowEdited; |
69 |
import org.gvsig.fmap.core.geometries.IGeometry; |
70 |
import org.gvsig.fmap.core.geometries.utils.FConstant; |
71 |
import org.gvsig.fmap.core.shapes.FShape; |
72 |
import org.gvsig.fmap.core.shapes.GeneralPathX; |
73 |
import org.gvsig.fmap.core.shapes.ShapeFactory; |
74 |
import org.gvsig.fmap.drivers.exceptions.CloseExpansionFileException; |
75 |
import org.gvsig.fmap.drivers.exceptions.ExpansionFileReadException; |
76 |
import org.gvsig.fmap.drivers.exceptions.ExpansionFileWriteException; |
77 |
import org.gvsig.fmap.drivers.exceptions.OpenExpansionFileException; |
78 |
import org.gvsig.fmap.drivers.formats.shp.reading.DbaseFileWriterNIO; |
79 |
import org.gvsig.fmap.drivers.formats.shp.reading.SHP; |
80 |
import org.gvsig.fmap.drivers.formats.shp.reading.write.SHPShape; |
81 |
import org.gvsig.fmap.drivers.formats.shp.reading.write.ShapefileException; |
82 |
import org.gvsig.fmap.drivers.reading.FieldDescription; |
83 |
import org.gvsig.fmap.drivers.writing.adapters.EditableAdapter; |
84 |
|
85 |
import com.hardcode.gdbms.engine.data.driver.DriverException; |
86 |
import com.hardcode.gdbms.engine.values.BooleanValue; |
87 |
import com.hardcode.gdbms.engine.values.DateValue; |
88 |
import com.hardcode.gdbms.engine.values.NullValue; |
89 |
import com.hardcode.gdbms.engine.values.NumericValue; |
90 |
import com.hardcode.gdbms.engine.values.StringValue; |
91 |
import com.hardcode.gdbms.engine.values.Value; |
92 |
import com.hardcode.gdbms.engine.values.ValueFactory; |
93 |
import com.iver.utiles.bigfile.BigByteBuffer2; |
94 |
|
95 |
|
96 |
/**
|
97 |
* Implementaci?n en memoria de ExpansionFile.
|
98 |
*
|
99 |
* @author Vicente Caballero Navarro
|
100 |
*/
|
101 |
public class PruebaVicenteExpansionFile2 implements ExpansionFile { |
102 |
//ArrayList rows = new ArrayList();
|
103 |
private static Locale ukLocale = new Locale("en", "UK"); // English, UK version |
104 |
private EditableAdapter edAdapter;
|
105 |
private Charset charset = Charset.forName("ISO-8859-1"); |
106 |
private DbaseFileWriterNIO.FieldFormatter formatter = new DbaseFileWriterNIO.FieldFormatter(); |
107 |
|
108 |
private final Number NULL_NUMBER = new Integer(0); |
109 |
private final String NULL_STRING = ""; |
110 |
private final String NULL_DATE = " "; |
111 |
|
112 |
//private WritableByteChannel dbfchannelWriter;
|
113 |
//private WritableByteChannel shxchannelWriter;
|
114 |
|
115 |
|
116 |
private SHPShape m_shape = null; |
117 |
|
118 |
private FileChannel readChannel; |
119 |
private FileChannel shpChannelWriter; |
120 |
private FileChannel shxChannelWriter; |
121 |
private FileChannel dbfChannelWriter; |
122 |
|
123 |
private int m_pos = 0; |
124 |
private int m_offset; |
125 |
private int m_cnt; |
126 |
private ArrayList indexControl=new ArrayList(); |
127 |
|
128 |
private BigByteBuffer2 bbRead;
|
129 |
private BigByteBuffer2 bbShxRead;
|
130 |
private BigByteBuffer2 bbDbfRead;
|
131 |
private ByteBuffer bbWriter = null; |
132 |
private ByteBuffer bbShxWriter = null; |
133 |
|
134 |
private FileChannel readChannelShx; |
135 |
private ByteBuffer cachedRecordRead = null; |
136 |
|
137 |
private int posActual = -1; |
138 |
private int recordOffset; |
139 |
private byte[] bytesCachedRecord = null; |
140 |
private Charset chars; |
141 |
private RandomAccessFile raf; |
142 |
private MapMode mode;
|
143 |
private FileInputStream finShx; |
144 |
private ByteBuffer dbfBuffer; |
145 |
|
146 |
|
147 |
private class Index{ |
148 |
private int internalIndex; |
149 |
private int position; |
150 |
private int status; |
151 |
private int type; |
152 |
public Index(int type,int indexInternalFields, int pos,int status) { |
153 |
this.type=type;
|
154 |
internalIndex=indexInternalFields; |
155 |
position=pos; |
156 |
this.status=status;
|
157 |
} |
158 |
public int getInternalIndex() { |
159 |
return internalIndex;
|
160 |
} |
161 |
public void setInternalIndex(int internalIndex) { |
162 |
this.internalIndex = internalIndex;
|
163 |
} |
164 |
public int getPosition() { |
165 |
return position;
|
166 |
} |
167 |
public void setPosition(int position) { |
168 |
this.position = position;
|
169 |
} |
170 |
public int getStatus() { |
171 |
return status;
|
172 |
} |
173 |
public void setStatus(int status) { |
174 |
this.status = status;
|
175 |
} |
176 |
public int getType() { |
177 |
return type;
|
178 |
} |
179 |
public void setType(int type) { |
180 |
this.type = type;
|
181 |
} |
182 |
} |
183 |
|
184 |
private class InternalRow |
185 |
{ |
186 |
private IRowEdited row;
|
187 |
private int indexInternalFields; |
188 |
public InternalRow(IRowEdited row, int indexInternalFields) |
189 |
{ |
190 |
this.row = row;
|
191 |
this.indexInternalFields = indexInternalFields;
|
192 |
} |
193 |
public int getIndexInternalFields() { |
194 |
return indexInternalFields;
|
195 |
} |
196 |
public IRowEdited getRow() {
|
197 |
return row;
|
198 |
} |
199 |
} |
200 |
|
201 |
public PruebaVicenteExpansionFile2(EditableAdapter edAdapter){
|
202 |
this.edAdapter = edAdapter;
|
203 |
} |
204 |
|
205 |
//BitSet invalidRows = new BitSet();
|
206 |
/**
|
207 |
* @see org.gvsig.fmap.drivers.writing.ExpansionFile#addRow(IRow, int)
|
208 |
*/
|
209 |
public int addRow(IRow row, int status, int indexInternalFields) throws ExpansionFileWriteException { |
210 |
int newIndex = indexControl.size();
|
211 |
IRowEdited edRow = new DefaultRowEdited(row,
|
212 |
status, newIndex); |
213 |
//InternalRow iRow = new InternalRow(edRow, indexInternalFields);
|
214 |
Value[] values=edRow.getAttributes();
|
215 |
IGeometry geometry=((IFeature)edRow.getLinkedRow()).getGeometry(); |
216 |
int pos=doAddRow(values,geometry);
|
217 |
indexControl.add(new Index(geometry.getGeometryType(),indexInternalFields,pos,status));
|
218 |
return newIndex;
|
219 |
} |
220 |
|
221 |
/**
|
222 |
* Devuelve la geometria a partir de un ?ndice.
|
223 |
*
|
224 |
* @param index DOCUMENT ME!
|
225 |
*
|
226 |
* @return DOCUMENT ME!
|
227 |
*
|
228 |
* @throws IOException DOCUMENT ME!
|
229 |
*/
|
230 |
public synchronized IGeometry getShape(int position,int index,int type) { |
231 |
Point2D.Double p = new Point2D.Double(); |
232 |
int numParts;
|
233 |
int numPoints;
|
234 |
int i;
|
235 |
int j;
|
236 |
/* int numReg;
|
237 |
int numeroPuntos;
|
238 |
int hasta;
|
239 |
int desde; */
|
240 |
int shapeType;
|
241 |
|
242 |
//Rectangle2D.Double BoundingBox;
|
243 |
// if (m_posShapes[index] == 0)
|
244 |
|
245 |
// bb.position(m_posShapes[index]);
|
246 |
bbRead.position(getPositionForRecord(index)); |
247 |
bbRead.order(ByteOrder.LITTLE_ENDIAN);
|
248 |
|
249 |
///bb.position(bb.position()+4);
|
250 |
shapeType = bbRead.getInt(); |
251 |
System.err.println("type= "+shapeType); |
252 |
//el shape tal con tema tal y n?mro tal es null
|
253 |
if (shapeType==SHP.NULL){
|
254 |
return null; |
255 |
} |
256 |
|
257 |
// retrieve that shape.
|
258 |
// tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
|
259 |
switch (type) {
|
260 |
case (SHP.POINT2D):
|
261 |
p = readPoint(bbRead); |
262 |
System.err.println("Point= "+p.getX()+", "+p.getY()); |
263 |
return ShapeFactory.createPoint2D(p.getX(), p.getY());
|
264 |
|
265 |
case (SHP.POLYLINE2D):
|
266 |
|
267 |
//BoundingBox = readRectangle(bb);
|
268 |
//bb.getDouble();
|
269 |
//bb.getDouble();
|
270 |
//bb.getDouble();
|
271 |
//bb.getDouble();
|
272 |
bbRead.position(bbRead.position() + 32);
|
273 |
numParts = bbRead.getInt(); |
274 |
numPoints = bbRead.getInt(); |
275 |
|
276 |
// part indexes.
|
277 |
// Geometry geom = GeometryFactory.toGeometryArray();
|
278 |
GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
|
279 |
numPoints); |
280 |
|
281 |
int[] tempParts = new int[numParts]; |
282 |
|
283 |
for (i = 0; i < numParts; i++) { |
284 |
tempParts[i] = bbRead.getInt(); |
285 |
} |
286 |
|
287 |
j = 0;
|
288 |
|
289 |
for (i = 0; i < numPoints; i++) { |
290 |
p = readPoint(bbRead); |
291 |
|
292 |
if (i == tempParts[j]) {
|
293 |
elShape.moveTo(p.x, p.y); |
294 |
|
295 |
if (j < (numParts - 1)) { |
296 |
j++; |
297 |
} |
298 |
} else {
|
299 |
elShape.lineTo(p.x, p.y); |
300 |
} |
301 |
} |
302 |
|
303 |
return ShapeFactory.createPolyline2D(elShape);
|
304 |
|
305 |
case (SHP.POLYGON2D):
|
306 |
|
307 |
// BoundingBox = readRectangle(bb);
|
308 |
bbRead.getDouble(); |
309 |
bbRead.getDouble(); |
310 |
bbRead.getDouble(); |
311 |
bbRead.getDouble(); |
312 |
|
313 |
numParts = bbRead.getInt(); |
314 |
|
315 |
numPoints = bbRead.getInt(); |
316 |
|
317 |
// part indexes.
|
318 |
// Geometry geom = GeometryFactory.toGeometryArray();
|
319 |
elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
|
320 |
|
321 |
tempParts = new int[numParts]; |
322 |
|
323 |
for (i = 0; i < numParts; i++) { |
324 |
tempParts[i] = bbRead.getInt(); |
325 |
} |
326 |
|
327 |
j = 0;
|
328 |
|
329 |
for (i = 0; i < numPoints; i++) { |
330 |
p = readPoint(bbRead); |
331 |
|
332 |
if (i == tempParts[j]) {
|
333 |
elShape.moveTo(p.x, p.y); |
334 |
|
335 |
if (j < (numParts - 1)) { |
336 |
j++; |
337 |
} |
338 |
} else {
|
339 |
elShape.lineTo(p.x, p.y); |
340 |
} |
341 |
} |
342 |
|
343 |
return ShapeFactory.createPolygon2D(elShape);
|
344 |
|
345 |
case (SHP.POINT3D):
|
346 |
|
347 |
double x = bbRead.getDouble();
|
348 |
double y = bbRead.getDouble();
|
349 |
double z = bbRead.getDouble();
|
350 |
|
351 |
return ShapeFactory.createPoint3D(x, y, z);
|
352 |
|
353 |
case (SHP.POLYLINE3D):
|
354 |
bbRead.position(bbRead.position() + 32);
|
355 |
numParts = bbRead.getInt(); |
356 |
numPoints = bbRead.getInt(); |
357 |
elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
|
358 |
tempParts = new int[numParts]; |
359 |
|
360 |
for (i = 0; i < numParts; i++) { |
361 |
tempParts[i] = bbRead.getInt(); |
362 |
} |
363 |
|
364 |
j = 0;
|
365 |
|
366 |
for (i = 0; i < numPoints; i++) { |
367 |
p = readPoint(bbRead); |
368 |
|
369 |
if (i == tempParts[j]) {
|
370 |
elShape.moveTo(p.x, p.y); |
371 |
|
372 |
if (j < (numParts - 1)) { |
373 |
j++; |
374 |
} |
375 |
} else {
|
376 |
elShape.lineTo(p.x, p.y); |
377 |
} |
378 |
} |
379 |
|
380 |
double[] boxZ = new double[2]; |
381 |
boxZ[0] = bbRead.getDouble();
|
382 |
boxZ[1] = bbRead.getDouble();
|
383 |
|
384 |
double[] pZ = new double[numPoints]; |
385 |
|
386 |
for (i = 0; i < numPoints; i++) { |
387 |
pZ[i] = bbRead.getDouble(); |
388 |
} |
389 |
|
390 |
return ShapeFactory.createPolyline3D(elShape, pZ);
|
391 |
case (SHP.POLYGON3D):
|
392 |
bbRead.position(bbRead.position() + 32);
|
393 |
numParts = bbRead.getInt(); |
394 |
numPoints = bbRead.getInt(); |
395 |
elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
|
396 |
tempParts = new int[numParts]; |
397 |
|
398 |
for (i = 0; i < numParts; i++) { |
399 |
tempParts[i] = bbRead.getInt(); |
400 |
} |
401 |
|
402 |
j = 0;
|
403 |
|
404 |
for (i = 0; i < numPoints; i++) { |
405 |
p = readPoint(bbRead); |
406 |
|
407 |
if (i == tempParts[j]) {
|
408 |
elShape.moveTo(p.x, p.y); |
409 |
|
410 |
if (j < (numParts - 1)) { |
411 |
j++; |
412 |
} |
413 |
} else {
|
414 |
elShape.lineTo(p.x, p.y); |
415 |
} |
416 |
} |
417 |
|
418 |
double[] boxpoZ = new double[2]; |
419 |
boxpoZ[0] = bbRead.getDouble();
|
420 |
boxpoZ[1] = bbRead.getDouble();
|
421 |
|
422 |
double[] poZ = new double[numPoints]; |
423 |
|
424 |
for (i = 0; i < numPoints; i++) { |
425 |
poZ[i] = bbRead.getDouble(); |
426 |
} |
427 |
|
428 |
return ShapeFactory.createPolygon3D(elShape, poZ);
|
429 |
|
430 |
case (SHP.MULTIPOINT2D):
|
431 |
bbRead.position(bbRead.position() + 32);
|
432 |
numPoints = bbRead.getInt(); |
433 |
|
434 |
double[] tempX = new double[numPoints]; |
435 |
double[] tempY = new double[numPoints]; |
436 |
|
437 |
for (i = 0; i < numPoints; i++) { |
438 |
tempX[i] = bbRead.getDouble(); |
439 |
tempY[i] = bbRead.getDouble(); |
440 |
} |
441 |
|
442 |
return ShapeFactory.createMultipoint2D(tempX, tempY);
|
443 |
|
444 |
case (SHP.MULTIPOINT3D):
|
445 |
bbRead.position(bbRead.position() + 32);
|
446 |
numPoints = bbRead.getInt(); |
447 |
|
448 |
double[] temX = new double[numPoints]; |
449 |
double[] temY = new double[numPoints]; |
450 |
double[] temZ = new double[numPoints]; |
451 |
|
452 |
for (i = 0; i < numPoints; i++) { |
453 |
temX[i] = bbRead.getDouble(); |
454 |
temY[i] = bbRead.getDouble(); |
455 |
//temZ[i] = bb.getDouble();
|
456 |
} |
457 |
|
458 |
for (i = 0; i < numPoints; i++) { |
459 |
temZ[i] = bbRead.getDouble(); |
460 |
} |
461 |
return ShapeFactory.createMultipoint3D(temX, temY, temZ);
|
462 |
} |
463 |
|
464 |
return null; |
465 |
} |
466 |
|
467 |
private int doAddRow(Value[] values,IGeometry geometry) { |
468 |
try {
|
469 |
write(values); |
470 |
return writeIGeometry(geometry);
|
471 |
} catch (IOException e) { |
472 |
e.printStackTrace(); |
473 |
} catch (ShapefileException e) {
|
474 |
e.printStackTrace(); |
475 |
} |
476 |
return -1; |
477 |
} |
478 |
|
479 |
public int modifyRow(int index, IRow row, int indexInternalFields) throws ExpansionFileWriteException { |
480 |
// InternalRow iOldRow = (InternalRow) rows.get(index);
|
481 |
// IRowEdited edRow = new DefaultRowEdited(row,
|
482 |
// iOldRow.getRow().getStatus(), index);
|
483 |
//
|
484 |
// InternalRow iRow = new InternalRow(edRow, indexInternalFields);
|
485 |
// rows.add(iRow);
|
486 |
//
|
487 |
//
|
488 |
// return rows.size() - 1;
|
489 |
return -1; |
490 |
} |
491 |
|
492 |
/**
|
493 |
* @see org.gvsig.fmap.drivers.writing.ExpansionFile#getRow(int)
|
494 |
*/
|
495 |
public IRowEdited getRow(int index) throws ExpansionFileReadException { |
496 |
//Index indexControl=(Index)this.index.get(index);
|
497 |
IRowEdited row=doGetRow(index); |
498 |
return row;
|
499 |
// InternalRow iRow = (InternalRow) rows.get(index);
|
500 |
// int indexInternalFields = indexControl.getInternalIndex();
|
501 |
// return edAdapter.createExternalRow(iRow.getRow(), indexInternalFields);
|
502 |
// return iRow.getRow();
|
503 |
|
504 |
} |
505 |
private IRowEdited doGetRow(int index) { |
506 |
Index indexControl=(Index)this.indexControl.get(index);
|
507 |
IGeometry geometry=getShape(indexControl.getPosition(),indexControl.getInternalIndex(),indexControl.getType()); |
508 |
FieldDescription[] fds=edAdapter.getFieldsDescription();
|
509 |
int length=fds.length;
|
510 |
Value[] values=new Value[length]; |
511 |
int lengthRow=0; |
512 |
for (int i=0;i<fds.length;i++) { |
513 |
lengthRow+=fds[i].getFieldLength(); |
514 |
} |
515 |
for (int i=0;i<length;i++) { |
516 |
try {
|
517 |
values[i]=getFieldValue(indexControl.getInternalIndex(),i,lengthRow); |
518 |
} catch (DriverException e) {
|
519 |
e.printStackTrace(); |
520 |
} |
521 |
} |
522 |
DefaultFeature fea = new DefaultFeature(geometry,values);
|
523 |
IRowEdited edRow = new DefaultRowEdited(fea,
|
524 |
indexControl.getStatus(), index); |
525 |
return edRow;
|
526 |
} |
527 |
/**
|
528 |
* @see com.iver.cit.gvsig.fmap.edition.ExpansionFile#invalidateRow(int)
|
529 |
*/
|
530 |
/*public void invalidateRow(int index) {
|
531 |
invalidRows.set(index, true);
|
532 |
}
|
533 |
*/
|
534 |
/**
|
535 |
* @see org.gvsig.fmap.drivers.writing.ExpansionFile#compact()
|
536 |
*/
|
537 |
public void compact(HashMap relations) { |
538 |
/* ArrayList geoAux = new ArrayList();
|
539 |
Iterator iter = relations.keySet().iterator();
|
540 |
HashMap aux = new HashMap();
|
541 |
int n = 0;
|
542 |
|
543 |
while (iter.hasNext()) {
|
544 |
Integer virtualIndex = (Integer) iter.next();
|
545 |
Integer expansionIndex = (Integer) relations.get(virtualIndex);
|
546 |
|
547 |
if (!invalidRows.get(expansionIndex.intValue())){
|
548 |
geoAux.add(rows.get(expansionIndex.intValue()));
|
549 |
aux.put(new Integer(n), new Integer(geoAux.size()-1));
|
550 |
n++;
|
551 |
}
|
552 |
}
|
553 |
|
554 |
invalidRows.clear();
|
555 |
rows = geoAux;
|
556 |
relations.clear();
|
557 |
relations.putAll(aux);
|
558 |
*/
|
559 |
|
560 |
} |
561 |
|
562 |
/**
|
563 |
* @see org.gvsig.fmap.drivers.writing.ExpansionFile#getRowCount()
|
564 |
*/
|
565 |
/*public int getRowCount() {
|
566 |
return rows.size() - invalidRows.cardinality();
|
567 |
}
|
568 |
*/
|
569 |
public void deleteLastRow() { |
570 |
// rows.remove(rows.size()-1);
|
571 |
} |
572 |
|
573 |
public void open() throws OpenExpansionFileException { |
574 |
initDBFBuffer(); |
575 |
try {
|
576 |
shpChannelWriter=(FileChannel) getWriteChannel("c:/pruebaVicente.shp"); |
577 |
|
578 |
dbfChannelWriter=(FileChannel)getWriteChannel("c:/pruebaVicente.dbf"); |
579 |
shxChannelWriter=(FileChannel)getWriteChannel("c:/pruebaVicente.shx"); |
580 |
File file=new File("c:/pruebaVicente.dbf"); |
581 |
if (file.canWrite()) {
|
582 |
try {
|
583 |
raf = new RandomAccessFile(file, "rw"); |
584 |
mode = FileChannel.MapMode.READ_WRITE;
|
585 |
} catch (FileNotFoundException e) { |
586 |
raf = new RandomAccessFile(file, "r"); |
587 |
mode = FileChannel.MapMode.READ_ONLY;
|
588 |
} |
589 |
} else {
|
590 |
raf = new RandomAccessFile(file, "r"); |
591 |
mode = FileChannel.MapMode.READ_ONLY;
|
592 |
} |
593 |
readChannel = raf.getChannel(); |
594 |
|
595 |
bbRead = new BigByteBuffer2(readChannel, FileChannel.MapMode.READ_ONLY); |
596 |
finShx = new FileInputStream(getShxFile(file)); |
597 |
bbDbfRead = new BigByteBuffer2(readChannel, mode);
|
598 |
// Open the file and then get a channel from the stream
|
599 |
readChannelShx = finShx.getChannel(); |
600 |
bbShxRead = new BigByteBuffer2(readChannelShx, FileChannel.MapMode.READ_ONLY); |
601 |
bbShxRead.order(ByteOrder.BIG_ENDIAN);
|
602 |
|
603 |
chars = Charset.forName("ISO-8859-1"); |
604 |
} catch (IOException e1) { |
605 |
throw new OpenExpansionFileException("",e1); |
606 |
} |
607 |
} |
608 |
public File getShxFile(File f) { |
609 |
String str = f.getAbsolutePath();
|
610 |
|
611 |
return new File(str.substring(0, str.length() - 3) + "shx"); |
612 |
} |
613 |
|
614 |
public void close() throws CloseExpansionFileException { |
615 |
try {
|
616 |
bbDbfRead = null;
|
617 |
dbfBuffer=null;
|
618 |
dbfChannelWriter.close(); |
619 |
m_shape = null;
|
620 |
bbShxWriter = null;
|
621 |
shpChannelWriter.close(); |
622 |
shxChannelWriter.close(); |
623 |
shpChannelWriter = null;
|
624 |
shxChannelWriter = null;
|
625 |
indexControl.clear(); |
626 |
readChannel.close(); |
627 |
readChannelShx.close(); |
628 |
} catch (IOException e) { |
629 |
throw new CloseExpansionFileException("",e); |
630 |
} |
631 |
//rows.clear();
|
632 |
System.gc();
|
633 |
} |
634 |
|
635 |
public int getSize() { |
636 |
return indexControl.size();
|
637 |
} |
638 |
public void write(Object[] record) throws IOException{ |
639 |
FieldDescription[] fds=edAdapter.getFieldsDescription();
|
640 |
dbfBuffer.position(0);
|
641 |
|
642 |
// put the 'not-deleted' marker
|
643 |
dbfBuffer.put( (byte) ' '); |
644 |
|
645 |
for (int i = 0; i < fds.length; i++) { |
646 |
String fieldString = fieldString(record[i], i);
|
647 |
// if ( header.getFieldLength(i) != fieldString.getBytes().length) {
|
648 |
// System.out.println(i + " : " + header.getFieldName(i));
|
649 |
// }
|
650 |
|
651 |
|
652 |
dbfBuffer.put(fieldString.getBytes(charset.name())); |
653 |
|
654 |
} |
655 |
|
656 |
|
657 |
write(); |
658 |
} |
659 |
|
660 |
private void write() throws IOException { |
661 |
dbfBuffer.position(0);
|
662 |
int r = dbfBuffer.remaining();
|
663 |
while ( (r -= dbfChannelWriter.write(dbfBuffer)) > 0) { |
664 |
; // do nothing
|
665 |
} |
666 |
} |
667 |
private void initDBFBuffer() { |
668 |
FieldDescription[] fds=edAdapter.getFieldsDescription();
|
669 |
int tempLength =-1; |
670 |
for (int i = 0; i < fds.length; i++) { |
671 |
tempLength += fds[i].getFieldLength()+1;
|
672 |
} |
673 |
dbfBuffer = ByteBuffer.allocateDirect(tempLength);
|
674 |
bytesCachedRecord = new byte[tempLength]; |
675 |
} |
676 |
private String fieldString(Object obj,final int col) { |
677 |
FieldDescription[] fds=edAdapter.getFieldsDescription();
|
678 |
String o;
|
679 |
final int fieldLen = fds[col].getFieldLength(); |
680 |
switch (fds[col].getFieldType()) {
|
681 |
case Types.VARCHAR: |
682 |
o = formatter.getFieldString( |
683 |
fieldLen, |
684 |
(obj instanceof NullValue)? NULL_STRING : ((StringValue) obj).getValue()
|
685 |
); |
686 |
break;
|
687 |
case Types.BOOLEAN: |
688 |
o = (obj instanceof NullValue) ? "F" : ((BooleanValue)obj).getValue() == true ? "T" : "F"; |
689 |
break;
|
690 |
case Types.DOUBLE: |
691 |
case Types.INTEGER: |
692 |
case Types.FLOAT: |
693 |
Number number = null; |
694 |
if(obj instanceof NullValue){ |
695 |
number = NULL_NUMBER; |
696 |
}else{
|
697 |
NumericValue gVal = (NumericValue) obj; |
698 |
number = new Double(gVal.doubleValue()); |
699 |
} |
700 |
o = formatter.getFieldString(fieldLen, |
701 |
fds[col].getFieldDecimalCount(), |
702 |
number); |
703 |
break;
|
704 |
case Types.DATE: |
705 |
if (obj instanceof NullValue) |
706 |
o = NULL_DATE; |
707 |
else
|
708 |
o = formatter.getFieldString(((DateValue)obj).getValue()); |
709 |
break;
|
710 |
default:
|
711 |
throw new RuntimeException("Unknown type " + fds[col].getFieldType()); |
712 |
} |
713 |
|
714 |
return o;
|
715 |
} |
716 |
private WritableByteChannel getWriteChannel(String path) |
717 |
throws IOException { |
718 |
WritableByteChannel channel;
|
719 |
|
720 |
File f = new File(path); |
721 |
|
722 |
if (!f.exists()) {
|
723 |
System.out.println("Creando fichero " + f.getAbsolutePath()); |
724 |
|
725 |
if (!f.createNewFile()) {
|
726 |
throw new IOException("Cannot create file " + f); |
727 |
} |
728 |
} |
729 |
|
730 |
RandomAccessFile raf = new RandomAccessFile(f, "rw"); |
731 |
channel = raf.getChannel(); |
732 |
|
733 |
return channel;
|
734 |
} |
735 |
|
736 |
|
737 |
|
738 |
|
739 |
public int writeIGeometry(IGeometry g) throws IOException, ShapefileException |
740 |
{ |
741 |
int shapeType = getShapeType(g.getGeometryType());
|
742 |
m_shape = SHP.create(shapeType); |
743 |
// m_shape.setFlatness(flatness);
|
744 |
return writeGeometry(g,shapeType);
|
745 |
} |
746 |
public synchronized int writeGeometry(IGeometry g,int type) throws IOException { |
747 |
if (bbWriter == null) { |
748 |
allocateBuffers(); |
749 |
m_offset =50;
|
750 |
m_cnt = 0;
|
751 |
|
752 |
shpChannelWriter.position(0);
|
753 |
shxChannelWriter.position(0);
|
754 |
|
755 |
// throw new IOException("Must write headers first");
|
756 |
} |
757 |
|
758 |
int posInit=m_offset;
|
759 |
m_pos = bbWriter.position(); |
760 |
m_shape.obtainsPoints(g); |
761 |
int length = m_shape.getLength(g);
|
762 |
|
763 |
// must allocate enough for shape + header (2 ints)
|
764 |
checkShapeBuffer(length + 8);
|
765 |
|
766 |
length /= 2;
|
767 |
|
768 |
bbWriter.order(ByteOrder.BIG_ENDIAN);
|
769 |
bbWriter.putInt(++m_cnt); |
770 |
bbWriter.putInt(length); |
771 |
bbWriter.order(ByteOrder.LITTLE_ENDIAN);
|
772 |
bbWriter.putInt(type); |
773 |
m_shape.write(bbWriter, g); |
774 |
|
775 |
///assert (length * 2 == (m_bb.position() - m_pos) - 8);
|
776 |
m_pos = bbWriter.position(); |
777 |
|
778 |
// write to the shx
|
779 |
bbShxWriter.putInt(m_offset); |
780 |
bbShxWriter.putInt(length); |
781 |
m_offset += (length + 4);
|
782 |
drain(); |
783 |
///assert(m_bb.position() == 0);
|
784 |
return posInit; // Devolvemos hasta donde hemos escrito |
785 |
} |
786 |
private void allocateBuffers() { |
787 |
bbWriter = ByteBuffer.allocateDirect(16 * 1024); |
788 |
bbShxWriter = ByteBuffer.allocateDirect(100); |
789 |
} |
790 |
/**
|
791 |
* Returns a shapeType compatible with shapeFile constants from a gvSIG's IGeometry type
|
792 |
* @param geometryType
|
793 |
* @return a shapeType compatible with shapeFile constants from a gvSIG's IGeometry type
|
794 |
*/
|
795 |
public int getShapeType(int geometryType) { |
796 |
if (geometryType>=FShape.Z){
|
797 |
switch (geometryType - FShape.Z) {
|
798 |
case (FShape.POINT):
|
799 |
return FConstant.SHAPE_TYPE_POINTZ;
|
800 |
|
801 |
case (FShape.LINE):
|
802 |
return FConstant.SHAPE_TYPE_POLYLINEZ;
|
803 |
|
804 |
case FShape.POLYGON:
|
805 |
return FConstant.SHAPE_TYPE_POLYGONZ;
|
806 |
|
807 |
case FShape.MULTIPOINT:
|
808 |
return FConstant.SHAPE_TYPE_MULTIPOINTZ; //TODO falta aclarar cosas aqu?. |
809 |
} |
810 |
|
811 |
}else{
|
812 |
switch (geometryType) {
|
813 |
case FShape.POINT:
|
814 |
return FConstant.SHAPE_TYPE_POINT;
|
815 |
|
816 |
case FShape.LINE:
|
817 |
case FShape.ELLIPSE:
|
818 |
case FShape.CIRCLE:
|
819 |
case FShape.ARC:
|
820 |
return FConstant.SHAPE_TYPE_POLYLINE;
|
821 |
|
822 |
case FShape.POLYGON:
|
823 |
return FConstant.SHAPE_TYPE_POLYGON;
|
824 |
|
825 |
case FShape.MULTIPOINT:
|
826 |
return FConstant.SHAPE_TYPE_MULTIPOINT; //TODO falta aclarar cosas aqu?. |
827 |
} |
828 |
} |
829 |
return FConstant.SHAPE_TYPE_NULL;
|
830 |
} |
831 |
|
832 |
|
833 |
/**
|
834 |
* Make sure our buffer is of size.
|
835 |
*
|
836 |
* @param size DOCUMENT ME!
|
837 |
*/
|
838 |
private void checkShapeBuffer(int size) { |
839 |
if (bbWriter.capacity() < size) {
|
840 |
bbWriter = ByteBuffer.allocateDirect(size);
|
841 |
} |
842 |
} |
843 |
|
844 |
/**
|
845 |
* Drain internal buffers into underlying channels.
|
846 |
*
|
847 |
* @throws IOException DOCUMENT ME!
|
848 |
*/
|
849 |
private void drain() throws IOException { |
850 |
bbWriter.flip(); |
851 |
bbShxWriter.flip(); |
852 |
|
853 |
while (bbWriter.remaining() > 0) |
854 |
shpChannelWriter.write(bbWriter); |
855 |
|
856 |
while (bbShxWriter.remaining() > 0) |
857 |
shxChannelWriter.write(bbShxWriter); |
858 |
|
859 |
bbWriter.flip().limit(bbWriter.capacity()); |
860 |
bbShxWriter.flip().limit(bbShxWriter.capacity()); |
861 |
} |
862 |
/**
|
863 |
* Reads the Point from the shape file.
|
864 |
*
|
865 |
* @param in ByteBuffer.
|
866 |
*
|
867 |
* @return Point2D.
|
868 |
*/
|
869 |
private synchronized Point2D.Double readPoint(BigByteBuffer2 in) { |
870 |
// create a new point
|
871 |
Point2D.Double tempPoint = new Point2D.Double(); |
872 |
|
873 |
// bytes 1 to 4 are the type and have already been read.
|
874 |
// bytes 4 to 12 are the X coordinate
|
875 |
in.order(ByteOrder.LITTLE_ENDIAN);
|
876 |
tempPoint.setLocation(in.getDouble(), in.getDouble()); |
877 |
|
878 |
return tempPoint;
|
879 |
} |
880 |
|
881 |
private synchronized long getPositionForRecord(int numRec) { |
882 |
// shx file has a 100 bytes header, then, records
|
883 |
// 8 bytes length, one for each entity.
|
884 |
// first 4 bytes are the offset
|
885 |
// next 4 bytes are length
|
886 |
|
887 |
int posIndex = 100 + (numRec * 8); |
888 |
// bbShx.position(posIndex);
|
889 |
long pos = 8 + 2 * bbShxRead.getInt(posIndex); |
890 |
|
891 |
return pos;
|
892 |
} |
893 |
|
894 |
public Value getFieldValue(long rowIndex, int fieldId, int position) |
895 |
throws DriverException {
|
896 |
FieldDescription[] fds=edAdapter.getFieldsDescription();
|
897 |
position*=rowIndex; |
898 |
for (int i=0;i<fieldId;i++) { |
899 |
position+=fds[i].getFieldLength(); |
900 |
} |
901 |
int fieldType=fds[fieldId].getFieldType();
|
902 |
// Field Type (C or M)
|
903 |
//char fieldType = fieldTypes[fieldId];
|
904 |
|
905 |
if (fieldType == Types.BOOLEAN) { |
906 |
return ValueFactory.createValue(getBooleanFieldValue(
|
907 |
(int) rowIndex, fieldId));
|
908 |
|
909 |
/* }else if (fieldType == 'N'){
|
910 |
String strValue = dbf.getStringFieldValue(rowIndex, fieldId);
|
911 |
long value = Long.parseLong(strValue);
|
912 |
if ((value > Integer.MIN_VALUE) && (value < Integer.MAX_VALUE)){
|
913 |
return new IntValue((int) value);
|
914 |
}else{
|
915 |
return new LongValue(value);
|
916 |
}
|
917 |
*/
|
918 |
} else if ((fieldType == Types.DOUBLE) || (fieldType == Types.FLOAT)) { |
919 |
String strValue;
|
920 |
try {
|
921 |
strValue = getStringFieldValue((int) rowIndex, fieldId,position)
|
922 |
.trim(); |
923 |
} catch (UnsupportedEncodingException e1) { |
924 |
e1.printStackTrace(); |
925 |
throw new DriverException(e1); |
926 |
} |
927 |
|
928 |
if (strValue.length() == 0) { |
929 |
return null; |
930 |
} |
931 |
double value = 0; |
932 |
try {
|
933 |
value = Double.parseDouble(strValue);
|
934 |
} catch (Exception e) { |
935 |
return ValueFactory.createValue(0D); |
936 |
} |
937 |
return ValueFactory.createValue(value);
|
938 |
} else if (fieldType == Types.VARCHAR) { |
939 |
try {
|
940 |
return ValueFactory.createValue(getStringFieldValue(
|
941 |
(int) rowIndex, fieldId,position).trim());
|
942 |
} catch (UnsupportedEncodingException e) { |
943 |
throw new DriverException(e); |
944 |
} |
945 |
} else if (fieldType == Types.DATE) { |
946 |
String date;
|
947 |
try {
|
948 |
date = getStringFieldValue((int) rowIndex, fieldId,position).trim();
|
949 |
} catch (UnsupportedEncodingException e1) { |
950 |
throw new DriverException(e1); |
951 |
} |
952 |
// System.out.println(rowIndex + " data=" + date);
|
953 |
if (date.length() == 0) { |
954 |
return null; |
955 |
} |
956 |
|
957 |
String year = date.substring(0, 4); |
958 |
String month = date.substring(4, 6); |
959 |
String day = date.substring(6, 8); |
960 |
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, |
961 |
ukLocale); |
962 |
/* Calendar c = Calendar.getInstance();
|
963 |
c.clear();
|
964 |
c.set(Integer.parseInt(year), Integer.parseInt(month),
|
965 |
Integer.parseInt(day));
|
966 |
c.set(Calendar.MILLISECOND, 0); */
|
967 |
String strAux = month + "/" + day + "/" + year; |
968 |
Date dat;
|
969 |
try {
|
970 |
dat = df.parse(strAux); |
971 |
} catch (ParseException e) { |
972 |
throw new DriverException("Bad Date Format"); |
973 |
} |
974 |
|
975 |
// System.out.println("numReg = " + rowIndex + " date:" + dat.getTime());
|
976 |
|
977 |
return ValueFactory.createValue(dat);
|
978 |
} else {
|
979 |
throw new DriverException("Unknown field type"); |
980 |
} |
981 |
} |
982 |
/**
|
983 |
* DOCUMENT ME!
|
984 |
*
|
985 |
* @param rowIndex
|
986 |
* DOCUMENT ME!
|
987 |
* @param fieldId
|
988 |
* DOCUMENT ME!
|
989 |
*
|
990 |
* @return DOCUMENT ME!
|
991 |
*/
|
992 |
public boolean getBooleanFieldValue(int rowIndex, int fieldId) { |
993 |
FieldDescription[] fds=edAdapter.getFieldsDescription();
|
994 |
int recordOffset = (fds.length * rowIndex)
|
995 |
+ 0;
|
996 |
|
997 |
// Se calcula el offset del campo
|
998 |
int fieldOffset = 0; |
999 |
|
1000 |
for (int i = 0; i < (fieldId - 1); i++) { |
1001 |
fieldOffset += fds[i].getFieldLength(); |
1002 |
} |
1003 |
|
1004 |
bbDbfRead.position(recordOffset + fieldOffset); |
1005 |
|
1006 |
char bool = (char) bbDbfRead.get(); |
1007 |
|
1008 |
return ((bool == 't') || (bool == 'T') || (bool == 'Y') || (bool == 'y')); |
1009 |
} |
1010 |
public String getStringFieldValue(int rowIndex, int fieldId, int position) |
1011 |
throws UnsupportedEncodingException { |
1012 |
FieldDescription[] fds=edAdapter.getFieldsDescription();
|
1013 |
int fieldOffset = position;
|
1014 |
byte[] data = new byte[fds[fieldId].getFieldLength()]; |
1015 |
if (rowIndex != posActual) {
|
1016 |
recordOffset = (fds.length * rowIndex) |
1017 |
+ 0;
|
1018 |
|
1019 |
/*
|
1020 |
* System.err.println("getStringFieldValue: rowIndex = " +
|
1021 |
* rowIndex); System.err.println("recordOffset = " + recordOffset + "
|
1022 |
* fieldOffset=" + fieldOffset);
|
1023 |
*/
|
1024 |
bbDbfRead.position(recordOffset); |
1025 |
bbDbfRead.get(bytesCachedRecord); |
1026 |
cachedRecordRead = ByteBuffer.wrap(bytesCachedRecord);
|
1027 |
posActual = rowIndex; |
1028 |
|
1029 |
} |
1030 |
cachedRecordRead.position(fieldOffset); |
1031 |
cachedRecordRead.get(data); |
1032 |
|
1033 |
return new String(data, chars.name()); |
1034 |
|
1035 |
} |
1036 |
} |