svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.shp / src / main / java / org / gvsig / fmap / dal / store / shp / utils / SHPFile2.java @ 42811
History | View | Annotate | Download (20 KB)
1 | 41240 | jldominguez | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | *
|
||
4 | * Copyright (C) 2007-2013 gvSIG Association.
|
||
5 | *
|
||
6 | 41556 | jjdelcerro | * This program is free software; you can redistribute it and/or modify it under
|
7 | * the terms of the GNU General Public License as published by the Free Software
|
||
8 | * Foundation; either version 3 of the License, or (at your option) any later
|
||
9 | * version.
|
||
10 | 41240 | jldominguez | *
|
11 | 41556 | jjdelcerro | * This program is distributed in the hope that it will be useful, but WITHOUT
|
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||
14 | * details.
|
||
15 | 41240 | jldominguez | *
|
16 | 41556 | jjdelcerro | * You should have received a copy of the GNU General Public License along with
|
17 | * this program; if not, write to the Free Software Foundation, Inc., 51
|
||
18 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
19 | 41240 | jldominguez | *
|
20 | 41556 | jjdelcerro | * For any additional information, do not hesitate to contact us at info AT
|
21 | * gvsig.com, or visit our website www.gvsig.com.
|
||
22 | 41240 | jldominguez | */
|
23 | package org.gvsig.fmap.dal.store.shp.utils; |
||
24 | |||
25 | import java.io.BufferedReader; |
||
26 | import java.io.File; |
||
27 | import java.io.FileInputStream; |
||
28 | import java.io.FileReader; |
||
29 | import java.io.IOException; |
||
30 | import java.nio.ByteOrder; |
||
31 | import java.nio.channels.FileChannel; |
||
32 | |||
33 | import org.slf4j.Logger; |
||
34 | import org.slf4j.LoggerFactory; |
||
35 | |||
36 | import org.gvsig.fmap.dal.exception.CloseException; |
||
37 | import org.gvsig.fmap.dal.exception.DataException; |
||
38 | import org.gvsig.fmap.dal.exception.FileNotFoundException; |
||
39 | import org.gvsig.fmap.dal.exception.ReadException; |
||
40 | import org.gvsig.fmap.dal.store.shp.SHPStoreParameters; |
||
41 | import org.gvsig.fmap.geom.Geometry; |
||
42 | import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
||
43 | import org.gvsig.fmap.geom.Geometry.TYPES; |
||
44 | import org.gvsig.fmap.geom.GeometryLocator; |
||
45 | import org.gvsig.fmap.geom.GeometryManager; |
||
46 | import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
||
47 | import org.gvsig.fmap.geom.exception.CreateGeometryException; |
||
48 | import org.gvsig.fmap.geom.primitive.Envelope; |
||
49 | import org.gvsig.fmap.geom.primitive.Point; |
||
50 | import org.gvsig.fmap.geom.primitive.PointGeometryType; |
||
51 | import org.gvsig.fmap.geom.type.GeometryType; |
||
52 | import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException; |
||
53 | import org.gvsig.fmap.geom.type.GeometryTypeNotValidException; |
||
54 | 42311 | fdiaz | import org.gvsig.tools.exception.BaseException; |
55 | 41240 | jldominguez | import org.gvsig.utils.bigfile.BigByteBuffer2; |
56 | |||
57 | /**
|
||
58 | * @author jmvivo
|
||
59 | 42311 | fdiaz | *
|
60 | 41240 | jldominguez | */
|
61 | 41556 | jjdelcerro | public class SHPFile2 implements ISHPFile { |
62 | 41240 | jldominguez | |
63 | 41556 | jjdelcerro | private static final Logger logger = LoggerFactory.getLogger(SHPFile2.class); |
64 | 41240 | jldominguez | private Envelope extent;
|
65 | private int type; |
||
66 | private int subType; |
||
67 | private String srsParameters; |
||
68 | |||
69 | private FileInputStream fin; |
||
70 | private FileChannel channel; |
||
71 | private BigByteBuffer2 bb;
|
||
72 | private FileInputStream finShx; |
||
73 | private FileChannel channelShx; |
||
74 | private BigByteBuffer2 bbShx;
|
||
75 | |||
76 | private SHPStoreParameters params;
|
||
77 | |||
78 | private int[] supportedGeometryTypes; |
||
79 | private final GeometryManager gManager = GeometryLocator |
||
80 | 41873 | jjdelcerro | .getGeometryManager(); |
81 | 41240 | jldominguez | |
82 | private GeometryType gtypeNull;
|
||
83 | private PointGeometryType gtypePoint2D;
|
||
84 | private GeometryType gtypeCurve2D;
|
||
85 | private GeometryType gtypeSurface2D;
|
||
86 | private GeometryType gtypeMultiPoint2D;
|
||
87 | |||
88 | 41526 | jjdelcerro | private boolean useNullGeometry = false; |
89 | 42311 | fdiaz | |
90 | private SHPReader reader;
|
||
91 | |||
92 | 41556 | jjdelcerro | public SHPFile2(SHPStoreParameters params) {
|
93 | 41240 | jldominguez | this.params = params;
|
94 | try {
|
||
95 | gtypeNull = gManager.getGeometryType(TYPES.NULL, SUBTYPES.GEOM2D); |
||
96 | 41556 | jjdelcerro | gtypePoint2D |
97 | = (PointGeometryType) gManager.getGeometryType(TYPES.POINT, |
||
98 | 41873 | jjdelcerro | SUBTYPES.GEOM2D); |
99 | 41556 | jjdelcerro | gtypeCurve2D |
100 | = gManager.getGeometryType(TYPES.CURVE, SUBTYPES.GEOM2D); |
||
101 | gtypeSurface2D |
||
102 | = gManager.getGeometryType(TYPES.SURFACE, SUBTYPES.GEOM2D); |
||
103 | gtypeMultiPoint2D |
||
104 | = gManager.getGeometryType(TYPES.MULTIPOINT, SUBTYPES.GEOM2D); |
||
105 | 41240 | jldominguez | |
106 | } catch (GeometryTypeNotSupportedException e) {
|
||
107 | throw new RuntimeException( |
||
108 | 41873 | jjdelcerro | "Unable to get the 2D geometry types to use", e);
|
109 | 41240 | jldominguez | } catch (GeometryTypeNotValidException e) {
|
110 | throw new RuntimeException( |
||
111 | 41873 | jjdelcerro | "Unable to get the 2D geometry types to use", e);
|
112 | 41240 | jldominguez | } |
113 | } |
||
114 | |||
115 | 41526 | jjdelcerro | public void setUseNullGeometry(boolean useNullGeometry) { |
116 | this.useNullGeometry = useNullGeometry;
|
||
117 | } |
||
118 | 42311 | fdiaz | |
119 | 41240 | jldominguez | /*
|
120 | * (non-Javadoc)
|
||
121 | 42311 | fdiaz | *
|
122 | 41240 | jldominguez | * @see org.gvsig.fmap.dal.Resource#doClose()
|
123 | */
|
||
124 | public void close() throws CloseException { |
||
125 | CloseException ret = null;
|
||
126 | |||
127 | 41860 | jjdelcerro | logger.debug("Closing shp/shx file '"+this.params.getSHPFileName()+"'"); |
128 | 42311 | fdiaz | |
129 | 41240 | jldominguez | // FIXME: Arreglar esto para que se acumulen los errores
|
130 | try {
|
||
131 | channel.close(); |
||
132 | channelShx.close(); |
||
133 | } catch (IOException e) { |
||
134 | ret = new CloseException("SHPFile.close", e); |
||
135 | } finally {
|
||
136 | try {
|
||
137 | fin.close(); |
||
138 | finShx.close(); |
||
139 | } catch (IOException e1) { |
||
140 | ret = new CloseException("SHPFile.close", e1); |
||
141 | } |
||
142 | } |
||
143 | |||
144 | if (ret != null) { |
||
145 | throw ret;
|
||
146 | } |
||
147 | bb = null;
|
||
148 | bbShx = null;
|
||
149 | fin = null;
|
||
150 | finShx = null;
|
||
151 | channel = null;
|
||
152 | channelShx = null;
|
||
153 | srsParameters = null;
|
||
154 | } |
||
155 | |||
156 | public boolean isOpen() { |
||
157 | return this.fin != null; |
||
158 | } |
||
159 | |||
160 | public synchronized void open() throws DataException { |
||
161 | try {
|
||
162 | fin = new FileInputStream(this.params.getSHPFile()); |
||
163 | } catch (java.io.FileNotFoundException e) {
|
||
164 | throw new FileNotFoundException(this.params.getSHPFileName()); |
||
165 | } |
||
166 | |||
167 | // Open the file and then get a channel from the stream
|
||
168 | channel = fin.getChannel(); |
||
169 | |||
170 | // long size = channel.size();
|
||
171 | // Get the file's size and then map it into memory
|
||
172 | // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
||
173 | try {
|
||
174 | bb = new BigByteBuffer2(channel, FileChannel.MapMode.READ_ONLY); |
||
175 | } catch (IOException e) { |
||
176 | throw new ReadException(this.params.getSHPFileName(), e); |
||
177 | |||
178 | } |
||
179 | try {
|
||
180 | finShx = new FileInputStream(this.params.getSHXFile()); |
||
181 | } catch (java.io.FileNotFoundException e) {
|
||
182 | throw new FileNotFoundException(this.params.getSHXFileName()); |
||
183 | } |
||
184 | |||
185 | // Open the file and then get a channel from the stream
|
||
186 | channelShx = finShx.getChannel(); |
||
187 | |||
188 | // long sizeShx = channelShx.size();
|
||
189 | // Get the file's size and then map it into memory
|
||
190 | // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
||
191 | // bbShx = channelShx.map(FileChannel.MapMode.READ_ONLY, 0, sizeShx);
|
||
192 | try {
|
||
193 | 41556 | jjdelcerro | bbShx |
194 | = new BigByteBuffer2(channelShx, FileChannel.MapMode.READ_ONLY); |
||
195 | 41240 | jldominguez | } catch (IOException e) { |
196 | throw new ReadException(this.params.getSHXFileName(), e); |
||
197 | |||
198 | } |
||
199 | bbShx.order(ByteOrder.BIG_ENDIAN);
|
||
200 | |||
201 | // create a new header.
|
||
202 | ShapeFileHeader2 myHeader = new ShapeFileHeader2();
|
||
203 | |||
204 | bb.position(0);
|
||
205 | |||
206 | // read the header
|
||
207 | myHeader.readHeader(bb); |
||
208 | |||
209 | double[] min = new double[2]; |
||
210 | min[0] = myHeader.myXmin;
|
||
211 | min[1] = myHeader.myYmin;
|
||
212 | double[] max = new double[2]; |
||
213 | max[0] = myHeader.myXmax;
|
||
214 | max[1] = myHeader.myYmax;
|
||
215 | |||
216 | try {
|
||
217 | 41873 | jjdelcerro | extent = |
218 | gManager.createEnvelope(min[0], min[1], max[0], max[1], |
||
219 | SUBTYPES.GEOM2D); |
||
220 | 41240 | jldominguez | } catch (CreateEnvelopeException e1) {
|
221 | 41860 | jjdelcerro | logger.warn("Error creating the envelope", e1);
|
222 | 41240 | jldominguez | } |
223 | // extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin,
|
||
224 | // myHeader.myXmax - myHeader.myXmin,
|
||
225 | // myHeader.myYmax - myHeader.myYmin);
|
||
226 | |||
227 | type = myHeader.myShapeType; |
||
228 | subType = getGeometrySubType(); |
||
229 | |||
230 | 42311 | fdiaz | switch (subType) {
|
231 | case SUBTYPES.GEOM2D:
|
||
232 | 42811 | jjdelcerro | reader = new SHPReader2D(this.params); |
233 | 42311 | fdiaz | break;
|
234 | case SUBTYPES.GEOM2DM:
|
||
235 | 42811 | jjdelcerro | reader = new SHPReader2DM(this.params); |
236 | 42311 | fdiaz | break;
|
237 | case SUBTYPES.GEOM3DM:
|
||
238 | 42811 | jjdelcerro | reader = new SHPReader3DM(this.params); |
239 | 42311 | fdiaz | break;
|
240 | |||
241 | default:
|
||
242 | break;
|
||
243 | } |
||
244 | |||
245 | |||
246 | 41240 | jldominguez | this.initSupportedGeometryTypes();
|
247 | |||
248 | double x = myHeader.myXmin;
|
||
249 | double y = myHeader.myYmin;
|
||
250 | double w = myHeader.myXmax - myHeader.myXmin;
|
||
251 | double h = myHeader.myYmax - myHeader.myYmin;
|
||
252 | |||
253 | if (w == 0) { |
||
254 | x -= 0.1;
|
||
255 | w = 0.2;
|
||
256 | } |
||
257 | |||
258 | if (h == 0) { |
||
259 | y -= 0.1;
|
||
260 | h = 0.2;
|
||
261 | } |
||
262 | |||
263 | // TODO: SRS
|
||
264 | File prjFile = SHP.getPrjFile(this.params.getSHPFile()); |
||
265 | if (prjFile.exists()) {
|
||
266 | BufferedReader input = null; |
||
267 | try {
|
||
268 | input = new BufferedReader(new FileReader(prjFile)); |
||
269 | } catch (java.io.FileNotFoundException e) {
|
||
270 | throw new FileNotFoundException(prjFile.getAbsolutePath()); |
||
271 | } |
||
272 | |||
273 | try {
|
||
274 | this.srsParameters = input.readLine();
|
||
275 | } catch (IOException e) { |
||
276 | throw new ReadException("SHPFile.open prj", e); |
||
277 | } finally {
|
||
278 | try {
|
||
279 | input.close(); |
||
280 | } catch (IOException e) { |
||
281 | // TODO ???
|
||
282 | } |
||
283 | } |
||
284 | |||
285 | } else {
|
||
286 | this.srsParameters = null; |
||
287 | } |
||
288 | } |
||
289 | |||
290 | public Envelope getFullExtent() throws ReadException { |
||
291 | return this.extent; |
||
292 | } |
||
293 | |||
294 | public boolean isEditable() { |
||
295 | return this.params.getDBFFile().canWrite() |
||
296 | 41873 | jjdelcerro | && this.params.getSHPFile().canWrite()
|
297 | && this.params.getSHXFile().canWrite();
|
||
298 | 41240 | jldominguez | } |
299 | |||
300 | public int getGeometryType() throws ReadException { |
||
301 | int auxType = 0; |
||
302 | |||
303 | switch (type) {
|
||
304 | 41873 | jjdelcerro | case (SHP.POINT2D):
|
305 | case (SHP.POINT3D):
|
||
306 | 42311 | fdiaz | case (SHP.POINTM):
|
307 | 41873 | jjdelcerro | auxType = auxType | Geometry.TYPES.POINT; |
308 | 41240 | jldominguez | |
309 | 41873 | jjdelcerro | break;
|
310 | 41240 | jldominguez | |
311 | 41873 | jjdelcerro | case (SHP.POLYLINE2D):
|
312 | case (SHP.POLYLINE3D):
|
||
313 | 42311 | fdiaz | case (SHP.POLYLINEM):
|
314 | 41873 | jjdelcerro | auxType = auxType | Geometry.TYPES.MULTICURVE; |
315 | 41240 | jldominguez | |
316 | 41873 | jjdelcerro | break;
|
317 | 41240 | jldominguez | |
318 | 41873 | jjdelcerro | case (SHP.POLYGON2D):
|
319 | case (SHP.POLYGON3D):
|
||
320 | 42311 | fdiaz | case (SHP.POLYGONM):
|
321 | 41873 | jjdelcerro | auxType = auxType | Geometry.TYPES.MULTISURFACE; |
322 | 41240 | jldominguez | |
323 | 41873 | jjdelcerro | break;
|
324 | case (SHP.MULTIPOINT2D):
|
||
325 | case (SHP.MULTIPOINT3D):
|
||
326 | 42311 | fdiaz | case (SHP.MULTIPOINTM):
|
327 | 41873 | jjdelcerro | auxType = auxType | Geometry.TYPES.MULTIPOINT; |
328 | 41240 | jldominguez | |
329 | 41873 | jjdelcerro | break;
|
330 | 41240 | jldominguez | } |
331 | |||
332 | return auxType;
|
||
333 | } |
||
334 | |||
335 | public int getGeometrySubType() throws ReadException { |
||
336 | switch (type) {
|
||
337 | 41873 | jjdelcerro | case (SHP.POINT2D):
|
338 | case (SHP.POLYLINE2D):
|
||
339 | case (SHP.POLYGON2D):
|
||
340 | case (SHP.MULTIPOINT2D):
|
||
341 | return SUBTYPES.GEOM2D;
|
||
342 | case (SHP.POINT3D):
|
||
343 | case (SHP.POLYLINE3D):
|
||
344 | case (SHP.POLYGON3D):
|
||
345 | case (SHP.MULTIPOINT3D):
|
||
346 | 42311 | fdiaz | return SUBTYPES.GEOM3DM;
|
347 | 41873 | jjdelcerro | case (SHP.POINTM):
|
348 | case (SHP.POLYLINEM):
|
||
349 | case (SHP.POLYGONM):
|
||
350 | case (SHP.MULTIPOINTM):
|
||
351 | return SUBTYPES.GEOM2DM;
|
||
352 | 41240 | jldominguez | } |
353 | |||
354 | return SUBTYPES.UNKNOWN;
|
||
355 | } |
||
356 | |||
357 | 41808 | jjdelcerro | public Geometry getNullGeometry() throws CreateGeometryException { |
358 | 41556 | jjdelcerro | if (this.useNullGeometry) { |
359 | 41526 | jjdelcerro | return gtypeNull.create();
|
360 | } |
||
361 | return null; |
||
362 | } |
||
363 | 42311 | fdiaz | |
364 | 41240 | jldominguez | /**
|
365 | 41556 | jjdelcerro | * Gets the geometry with the index provided. Set to synchronized to prevent
|
366 | * concurrent threads issue (?)
|
||
367 | 42311 | fdiaz | *
|
368 | 41240 | jldominguez | * @param position
|
369 | * @return
|
||
370 | * @throws ReadException
|
||
371 | * @throws CreateGeometryException
|
||
372 | */
|
||
373 | public synchronized Geometry getGeometry(long position) |
||
374 | 41873 | jjdelcerro | throws ReadException, CreateGeometryException {
|
375 | 41240 | jldominguez | |
376 | int shapeType;
|
||
377 | bb.position(getPositionForRecord(position)); |
||
378 | bb.order(ByteOrder.LITTLE_ENDIAN);
|
||
379 | shapeType = bb.getInt(); |
||
380 | 42311 | fdiaz | |
381 | 41240 | jldominguez | if (shapeType == SHP.NULL) {
|
382 | 41526 | jjdelcerro | return getNullGeometry();
|
383 | 41240 | jldominguez | } |
384 | 42311 | fdiaz | |
385 | 41240 | jldominguez | /*
|
386 | * Inconsistency: this particular shape is not
|
||
387 | * of the expected type. This can be because the SHP file
|
||
388 | * is corrupt and it can cause "out of memory error"
|
||
389 | * because the code will possibly try to instantiate a
|
||
390 | * huge (absurd) array, so it's safer to return a null geometry
|
||
391 | */
|
||
392 | if (shapeType != type) {
|
||
393 | 41808 | jjdelcerro | if( ! this.params.getAllowInconsistenciesInGeometryType() ) { |
394 | 42811 | jjdelcerro | throw new InconsistenciesInGeometryTypeException(shapeType); |
395 | 41808 | jjdelcerro | } |
396 | 41240 | jldominguez | } |
397 | |||
398 | 41873 | jjdelcerro | // retrieve that shape.
|
399 | 41240 | jldominguez | switch (type) {
|
400 | 41873 | jjdelcerro | case (SHP.POINT2D):
|
401 | case (SHP.POINT3D):
|
||
402 | case (SHP.POINTM):
|
||
403 | 42311 | fdiaz | return reader.readPoint(bb);
|
404 | 41240 | jldominguez | |
405 | 41873 | jjdelcerro | case (SHP.POLYLINE2D):
|
406 | case (SHP.POLYLINE3D):
|
||
407 | 42311 | fdiaz | case (SHP.POLYLINEM):
|
408 | return reader.readPoLyline(bb);
|
||
409 | 41240 | jldominguez | |
410 | 42311 | fdiaz | case (SHP.POLYGON2D):
|
411 | 41873 | jjdelcerro | case (SHP.POLYGON3D):
|
412 | 42311 | fdiaz | case (SHP.POLYGONM):
|
413 | try {
|
||
414 | return reader.readPoLygon(bb);
|
||
415 | } catch (BaseException e) {
|
||
416 | throw new CreateGeometryException(Geometry.TYPES.POLYGON, getGeometrySubType(), e); |
||
417 | 41873 | jjdelcerro | } |
418 | 41240 | jldominguez | |
419 | 41873 | jjdelcerro | case (SHP.MULTIPOINT2D):
|
420 | 42311 | fdiaz | case (SHP.MULTIPOINTM):
|
421 | 41240 | jldominguez | |
422 | 41873 | jjdelcerro | case (SHP.MULTIPOINT3D):
|
423 | 42311 | fdiaz | return reader.readMultiPoint(bb);
|
424 | 41240 | jldominguez | } |
425 | return null; |
||
426 | } |
||
427 | 42811 | jjdelcerro | |
428 | private class InconsistenciesInGeometryTypeException extends ReadException { |
||
429 | 41240 | jldominguez | |
430 | 42811 | jjdelcerro | private final static String MESSAGE_FORMAT = "The geometry type (%(geomTypeOfHeader)) of the shape file (%(fname)) does not match the type of the current geometry (%(geomTypeOfGeometry)).\nCheck 'Allow inconsistencies in geometry type' in the shape's properties of the add layer dialog to ignore it."; |
431 | private final static String MESSAGE_KEY = "_InconsistenciesInGeometryTypeException"; |
||
432 | private static final long serialVersionUID = 8991813814092628916L; |
||
433 | |||
434 | public InconsistenciesInGeometryTypeException(int geomTypeOfGeometry) { |
||
435 | super(MESSAGE_FORMAT, null, MESSAGE_KEY, serialVersionUID); |
||
436 | setValue("geomTypeOfHeader", SHP.getTypeName(type));
|
||
437 | setValue("geomTypeOfGeometry", SHP.getTypeName(geomTypeOfGeometry));
|
||
438 | setValue("fname", params.getSHPFile().getName());
|
||
439 | |||
440 | } |
||
441 | } |
||
442 | |||
443 | 41240 | jldominguez | private long getPositionForRecord(long numRec) { |
444 | // shx file has a 100 bytes header, then, records
|
||
445 | // 8 bytes length, one for each entity.
|
||
446 | // first 4 bytes are the offset
|
||
447 | // next 4 bytes are length
|
||
448 | |||
449 | int posIndex = 100 + ((int) numRec * 8); |
||
450 | // bbShx.position(posIndex);
|
||
451 | long pos = 8 + 2 * bbShx.getInt(posIndex); |
||
452 | |||
453 | return pos;
|
||
454 | } |
||
455 | |||
456 | /**
|
||
457 | * Reads the Point from the shape file.
|
||
458 | 42311 | fdiaz | *
|
459 | 41556 | jjdelcerro | * @param in ByteBuffer.
|
460 | 42311 | fdiaz | *
|
461 | 41240 | jldominguez | * @return Point2D.
|
462 | * @throws ReadException
|
||
463 | * @throws CreateGeometryException
|
||
464 | */
|
||
465 | private Point readPoint(BigByteBuffer2 in) |
||
466 | 41873 | jjdelcerro | throws CreateGeometryException, ReadException {
|
467 | 41556 | jjdelcerro | return readPoint(subType, in);
|
468 | } |
||
469 | |||
470 | private Point readPoint(int subtype, BigByteBuffer2 in) |
||
471 | throws CreateGeometryException, ReadException {
|
||
472 | 41240 | jldominguez | // bytes 1 to 4 are the type and have already been read.
|
473 | // bytes 4 to 12 are the X coordinate
|
||
474 | in.order(ByteOrder.LITTLE_ENDIAN);
|
||
475 | 41556 | jjdelcerro | double x = in.getDouble();
|
476 | double y = in.getDouble();
|
||
477 | Point p = gManager.createPoint(x, y, subtype);
|
||
478 | return p;
|
||
479 | 41240 | jldominguez | } |
480 | |||
481 | /**
|
||
482 | * Lee un rect?ngulo del fichero.
|
||
483 | 42311 | fdiaz | *
|
484 | 41556 | jjdelcerro | * @param in ByteBuffer.
|
485 | 42311 | fdiaz | *
|
486 | 41240 | jldominguez | * @return Rect?ngulo.
|
487 | * @throws CreateEnvelopeException
|
||
488 | 42311 | fdiaz | *
|
489 | 41240 | jldominguez | * @throws IOException
|
490 | */
|
||
491 | private Envelope readRectangle(BigByteBuffer2 in)
|
||
492 | 41873 | jjdelcerro | throws CreateEnvelopeException {
|
493 | 41240 | jldominguez | in.order(ByteOrder.LITTLE_ENDIAN);
|
494 | double x = in.getDouble();
|
||
495 | double y = in.getDouble();
|
||
496 | |||
497 | double x2 = in.getDouble();
|
||
498 | |||
499 | if (x2 - x == 0) { |
||
500 | x2 += 0.2;
|
||
501 | x -= 0.1;
|
||
502 | } |
||
503 | |||
504 | double y2 = in.getDouble();
|
||
505 | |||
506 | if (y2 - y == 0) { |
||
507 | y2 += 0.2;
|
||
508 | y -= 0.1;
|
||
509 | } |
||
510 | 41556 | jjdelcerro | Envelope tempEnvelope |
511 | = gManager.createEnvelope(x, y, x2, y2, SUBTYPES.GEOM2D); |
||
512 | 41240 | jldominguez | return tempEnvelope;
|
513 | } |
||
514 | |||
515 | /**
|
||
516 | 41556 | jjdelcerro | * Gets the geometry bbox with the index provided. Set to synchronized to
|
517 | * prevent concurrent threads issue (?)
|
||
518 | 42311 | fdiaz | *
|
519 | 41240 | jldominguez | * @param featureIndex
|
520 | * @return
|
||
521 | * @throws ReadException
|
||
522 | * @throws CreateEnvelopeException
|
||
523 | * @throws CreateGeometryException
|
||
524 | */
|
||
525 | public synchronized Envelope getBoundingBox(long featureIndex) |
||
526 | 41873 | jjdelcerro | throws ReadException, CreateEnvelopeException, CreateGeometryException {
|
527 | 41556 | jjdelcerro | Point p;
|
528 | 41240 | jldominguez | Envelope BoundingBox = null;
|
529 | try {
|
||
530 | bb.position(getPositionForRecord(featureIndex)); |
||
531 | } catch (Exception e) { |
||
532 | throw new ReadException("getBondingBox (" + featureIndex + ")", e); |
||
533 | // logger.error(" Shapefile is corrupted. Drawing aborted. ="+e+
|
||
534 | // " "+"index = "+index);
|
||
535 | } |
||
536 | bb.order(ByteOrder.LITTLE_ENDIAN);
|
||
537 | |||
538 | int tipoShape = bb.getInt();
|
||
539 | |||
540 | // AZABALA: si tipoShape viene con valores erroneos deja de funcionar
|
||
541 | // el metodo getShape(i)
|
||
542 | // if (tipoShape != SHP.NULL) {
|
||
543 | // type = tipoShape;
|
||
544 | // }
|
||
545 | // retrieve that shape.
|
||
546 | // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
|
||
547 | switch (tipoShape) {
|
||
548 | 41873 | jjdelcerro | case (SHP.POINT2D):
|
549 | case (SHP.POINT3D):
|
||
550 | p = readPoint(bb); |
||
551 | 41556 | jjdelcerro | BoundingBox |
552 | = gManager.createEnvelope(p.getX() - 0.1, p.getY() - 0.1, |
||
553 | 41873 | jjdelcerro | p.getX() + 0.2, p.getY() + 0.2, SUBTYPES.GEOM2D); |
554 | // new Rectangle2D.Double(p.getX() - 0.1,
|
||
555 | // p.getY() - 0.1, 0.2, 0.2);
|
||
556 | 41240 | jldominguez | |
557 | 41873 | jjdelcerro | break;
|
558 | 41240 | jldominguez | |
559 | 41873 | jjdelcerro | case (SHP.POLYLINE2D):
|
560 | 42311 | fdiaz | case (SHP.POLYLINEM):
|
561 | 41873 | jjdelcerro | case (SHP.POLYGON2D):
|
562 | 42311 | fdiaz | case (SHP.POLYGONM):
|
563 | 41873 | jjdelcerro | case (SHP.MULTIPOINT2D):
|
564 | 42311 | fdiaz | case (SHP.MULTIPOINTM):
|
565 | 41873 | jjdelcerro | case (SHP.POLYLINE3D):
|
566 | case (SHP.POLYGON3D):
|
||
567 | case (SHP.MULTIPOINT3D):
|
||
568 | 41240 | jldominguez | |
569 | 41873 | jjdelcerro | // BoundingBox
|
570 | BoundingBox = readRectangle(bb); |
||
571 | 41240 | jldominguez | |
572 | 41873 | jjdelcerro | break;
|
573 | 41240 | jldominguez | } |
574 | |||
575 | return BoundingBox;
|
||
576 | } |
||
577 | |||
578 | /**
|
||
579 | * @return
|
||
580 | */
|
||
581 | public String getSRSParameters() { |
||
582 | return this.srsParameters; |
||
583 | } |
||
584 | |||
585 | private void initSupportedGeometryTypes() throws ReadException { |
||
586 | switch (this.getGeometryType()) { |
||
587 | 41873 | jjdelcerro | case Geometry.TYPES.POINT:
|
588 | 41556 | jjdelcerro | supportedGeometryTypes |
589 | = new int[]{Geometry.TYPES.POINT, Geometry.TYPES.NULL}; |
||
590 | 41873 | jjdelcerro | break;
|
591 | case Geometry.TYPES.MULTIPOINT:
|
||
592 | 41556 | jjdelcerro | supportedGeometryTypes |
593 | = new int[]{Geometry.TYPES.MULTIPOINT, Geometry.TYPES.NULL}; |
||
594 | 41873 | jjdelcerro | break;
|
595 | case Geometry.TYPES.MULTICURVE:
|
||
596 | 41556 | jjdelcerro | supportedGeometryTypes |
597 | = new int[]{Geometry.TYPES.CURVE, Geometry.TYPES.ELLIPSE, |
||
598 | 41873 | jjdelcerro | Geometry.TYPES.ARC, Geometry.TYPES.CIRCLE, |
599 | Geometry.TYPES.SURFACE, Geometry.TYPES.NULL, |
||
600 | 41556 | jjdelcerro | Geometry.TYPES.MULTICURVE}; |
601 | 41873 | jjdelcerro | break;
|
602 | case Geometry.TYPES.MULTISURFACE:
|
||
603 | 41556 | jjdelcerro | supportedGeometryTypes |
604 | = new int[]{Geometry.TYPES.ELLIPSE, Geometry.TYPES.CIRCLE, |
||
605 | 41873 | jjdelcerro | Geometry.TYPES.SURFACE, Geometry.TYPES.NULL, |
606 | 41556 | jjdelcerro | Geometry.TYPES.MULTISURFACE}; |
607 | 41873 | jjdelcerro | break;
|
608 | 41240 | jldominguez | |
609 | 41873 | jjdelcerro | default:
|
610 | 41556 | jjdelcerro | supportedGeometryTypes = new int[]{}; |
611 | 41240 | jldominguez | } |
612 | } |
||
613 | |||
614 | public boolean canWriteGeometry(int gvSIGgeometryType) { |
||
615 | for (int i = 0; i < supportedGeometryTypes.length; i++) { |
||
616 | if (gvSIGgeometryType == supportedGeometryTypes[i]) {
|
||
617 | return true; |
||
618 | } |
||
619 | } |
||
620 | return false; |
||
621 | } |
||
622 | } |