Statistics
| Revision:

root / branches / Mobile_Compatible_Hito_1 / libFMap / src-test / org / gvsig / data / datastores / vectorial / file / shp / SHPTest.java @ 21847

History | View | Annotate | Download (17.1 KB)

1
package org.gvsig.data.datastores.vectorial.file.shp;
2

    
3
import java.awt.Shape;
4
import java.awt.geom.PathIterator;
5
import java.io.File;
6
import java.util.Date;
7
import java.util.Iterator;
8

    
9
import junit.framework.TestCase;
10

    
11
import org.apache.log4j.FileAppender;
12
import org.apache.log4j.Level;
13
import org.apache.log4j.Logger;
14
import org.apache.log4j.PatternLayout;
15
import org.cresques.cts.IProjection;
16
import org.gvsig.compatible.StringUtil;
17
import org.gvsig.data.CloseException;
18
import org.gvsig.data.DataCollection;
19
import org.gvsig.data.DataManager;
20
import org.gvsig.data.DataStoreParameters;
21
import org.gvsig.data.InitializeException;
22
import org.gvsig.data.OpenException;
23
import org.gvsig.data.ReadException;
24
import org.gvsig.data.datastores.vectorial.file.ResourceReader;
25
import org.gvsig.data.datastores.vectorial.file.Utils;
26
import org.gvsig.data.datastores.vectorial.file.shp.utils.SHP;
27
import org.gvsig.data.datastores.vectorial.file.shp_jni.JNISHPStore;
28
import org.gvsig.data.datastores.vectorial.file.shp_mem.MemSHPStore;
29
import org.gvsig.data.datastores.vectorial.file.shp_util.IGeometricDataStore;
30
import org.gvsig.data.vectorial.Feature;
31
import org.gvsig.data.vectorial.FeatureType;
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.GeometryManager;
34
import org.gvsig.fmap.geom.aggregate.MultiCurve2D;
35
import org.gvsig.fmap.geom.aggregate.MultiPoint2D;
36
import org.gvsig.fmap.geom.aggregate.MultiSurface2D;
37
import org.gvsig.fmap.geom.primitive.Curve2D;
38
import org.gvsig.fmap.geom.primitive.NullGeometry;
39
import org.gvsig.fmap.geom.primitive.Point2D;
40
import org.gvsig.fmap.geom.primitive.Surface2D;
41

    
42
import com.vividsolutions.jts.algorithm.CGAlgorithms;
43
import com.vividsolutions.jts.geom.Coordinate;
44
import com.vividsolutions.jts.geom.CoordinateList;
45

    
46
import es.prodevelop.gvsig.mobile.fmap.driver.vect.shp.ShpReader;
47

    
48
/**
49
 * This class tests the three SHP drivers implemented for gvSIG Mobile.
50
 * These drivers are compatible with the new data access model (june 2008)
51
 * and will share a lot of code with gvsig Desktop.
52
 * 
53
 * The right testdata folder is needed.
54
 * 
55
 *  
56
 * @author jldominguez
57
 *
58
 */
59
public class SHPTest extends TestCase {
60
        
61
        private static Logger logger = Logger.getLogger(SHPTest.class);
62
        
63
        /**
64
         * Test IDs
65
         */
66
        public static final int TEST_PUNTO = 0; 
67
        public static final int TEST_MPUNTO = 1; 
68
        public static final int TEST_LINEA = 2; 
69
        public static final int TEST_POLIGONO = 3; 
70
        public static final int TEST_NULL = 4; 
71
        public static final int TEST_ATT = 5; 
72

    
73
        private File filePunto, fileMPunto, fileLinea, filePoligono, fileNull, fileAtt;
74

    
75
        public static void main(String[] args) {
76
                junit.textui.TestRunner.run(SHPTest.class);
77
        }
78

    
79
        public void publicSetup() {
80
                
81
                try {
82
                        setUp();
83
                } catch (Exception e) {
84
                        logger.error("While doing setup: " + e.getMessage());
85
                }
86
        }
87
        
88
        protected void setUp() throws Exception {
89
                super.setUp();
90
                
91
                // call static section to self-registration
92
                new Point2D();
93
                new MultiPoint2D((IProjection) null);
94
                new MultiCurve2D(null, null);
95
                new MultiSurface2D(null, null);
96
                new NullGeometry();
97
                
98
                ShpReader.touch();
99
                initLogger();
100
        }
101

    
102
        public void testInitialize() {
103
                
104
                if (Utils.USING_PDA) {
105
                        filePunto = ResourceReader.getPdaTestFile(PerformanceTest.SD_FOLDER, "testdata", "puntos_grande.shp");
106
                        fileMPunto = ResourceReader.getPdaTestFile(PerformanceTest.SD_FOLDER, "testdata", "multipuntos_grande.shp");
107
                        fileLinea = ResourceReader.getPdaTestFile(PerformanceTest.SD_FOLDER, "testdata", "lineas_grande.shp");
108
                        filePoligono = ResourceReader.getPdaTestFile(PerformanceTest.SD_FOLDER, "testdata", "poligonos_grande.shp");
109
                        fileNull = ResourceReader.getPdaTestFile(PerformanceTest.SD_FOLDER, "testdata", "pruebaNull.shp");
110
                        fileAtt = ResourceReader.getPdaTestFile(PerformanceTest.SD_FOLDER, "testdata", "atttest.shp");
111
                } else {
112
                        filePunto = ResourceReader.getResourceFile("testdata", "puntos_grande.shp");
113
                        fileMPunto = ResourceReader.getResourceFile("testdata", "multipuntos_grande.shp");
114
                        fileLinea = ResourceReader.getResourceFile("testdata", "lineas_grande.shp");
115
                        filePoligono = ResourceReader.getResourceFile("testdata", "poligonos_grande.shp");
116
                        fileNull = ResourceReader.getResourceFile("testdata", "pruebaNull.shp");
117
                        fileAtt = ResourceReader.getResourceFile("testdata", "atttest.shp");
118
                }
119

    
120
                new SHPStore();
121
                doTest(SHPStore.DATASTORE_NAME);
122
                new MemSHPStore();
123
                doTest(MemSHPStore.DATASTORE_NAME);
124
                new JNISHPStore();
125
                doTest(JNISHPStore.DATASTORE_NAME);
126
        }
127
        
128
        /**
129
         * Performs a test with a given data sorce name
130
         * 
131
         * @see SHPStore
132
         * @see MemSHPStore
133
         * @see JNISHPStore
134
         * 
135
         * @param ds_name
136
         */
137
        public void doTest(String ds_name) {
138
                
139
                logger.debug("DATASOURCE: " + ds_name + ", FILE = " + filePunto.getName() + "...");
140
                shp(filePunto, TEST_PUNTO, ds_name);
141
                
142
                if (ds_name.compareTo(JNISHPStore.DATASTORE_NAME) != 0) {
143
                        logger.debug("DATASOURCE: " + ds_name + ", FILE = " + fileMPunto.getName() + "...");
144
                        shp(fileMPunto, TEST_MPUNTO, ds_name);
145
                }
146

    
147
                logger.debug("DATASOURCE: " + ds_name + ", FILE = " + fileLinea.getName() + "...");
148
                shp(fileLinea, TEST_LINEA, ds_name);
149
                
150
                logger.debug("DATASOURCE: " + ds_name + ", FILE = " + filePoligono.getName() + "...");
151
                shp(filePoligono, TEST_POLIGONO, ds_name);
152
                
153
                logger.debug("DATASOURCE: " + ds_name + ", FILE = " + fileNull.getName() + "...");
154
                shp(fileNull, TEST_NULL, ds_name);
155
                
156
                logger.debug("DATASOURCE: " + ds_name + ", FILE = " + fileAtt.getName() + "...");
157
                shp(fileAtt, TEST_ATT, ds_name);
158
                
159
                // shp(fileGeometryNull);
160
        }
161
        
162
        private void shp(File file, int fileid, String datastore_name) {
163
                DataManager manager = DataManager.getManager();
164
                IGeometricDataStore store = null;
165
                SHPStoreParameters shpParameters=null;
166
                shpParameters =(SHPStoreParameters) manager.createDataStoreParameters(datastore_name);
167
                shpParameters.setFile(file);
168
                shpParameters.setDBFFile(SHP.getDbfFile(file));
169
                shpParameters.setSHXFile(SHP.getShxFile(file));
170
                shpParameters.setDataStoreName(datastore_name);
171
                
172

    
173
                try {
174
                        store = (IGeometricDataStore)
175
                        manager.createDataStore((DataStoreParameters)shpParameters);
176
                } catch (InitializeException e) {
177
                        // TODO Auto-generated catch block
178
                        e.printStackTrace();
179
                }
180
                try {
181
                        store.doOpen();
182
                } catch (OpenException e2) {
183
                        // TODO Auto-generated catch block
184
                        e2.printStackTrace();
185
                }
186

    
187
                FeatureType ft = store.getDefaultFeatureType();
188
                DataCollection dataCollection = null;
189
                try {
190
                        dataCollection = store.getDataCollection(ft,null,null);
191
                } catch (ReadException e1) {
192
                        e1.printStackTrace();
193
                }
194
                Iterator iter = dataCollection.iterator();
195
                int feature_count = 0;
196
                
197
                while (iter.hasNext()) {
198
                        Feature feature = (Feature)iter.next();
199

    
200
                        boolean simple = (datastore_name.compareTo(JNISHPStore.DATASTORE_NAME) == 0);
201
                        check(feature, ft, fileid, simple);
202
                        feature_count++;
203
                }
204
                iter=null;
205
                dataCollection.dispose();
206

    
207
                try {
208
                        store.doClose();
209
                        store.doDispose();
210
                } catch (CloseException e) {
211
                        // TODO Auto-generated catch block
212
                        e.printStackTrace();
213
                }
214

    
215
        }
216
        
217
        private void check(Feature feature, FeatureType att_desc, int fileid, boolean simpletypes) {
218

    
219
                double expected = 0;
220
                
221
                switch (fileid) {
222
                
223
                case TEST_PUNTO:
224
                        expected = feature.getDouble("X");
225
                        Point2D p =  (Point2D) ((Geometry) feature.getDefaultGeometry()).getInternalShape();
226
                        checkPoint(feature, p, expected, simpletypes);
227
                        break;
228
                case TEST_MPUNTO:
229
                        checkMPoint(feature, simpletypes);
230
                        break;
231
                case TEST_LINEA:
232
                        expected = feature.getDouble("LEN");
233
                        Curve2D pl =  (Curve2D) ((Geometry) feature.getDefaultGeometry()).getInternalShape();
234
                        checkLineLength(feature, pl, expected, simpletypes);
235
                        break;
236
                case TEST_POLIGONO:
237
                        expected = feature.getDouble("AREA");
238
                        Surface2D pg =  (Surface2D) ((Geometry) feature.getDefaultGeometry()).getInternalShape();
239
                        checkPolygonArea(feature, pg, expected, simpletypes);
240
                        break;
241
                case TEST_NULL:
242
                        checkNullGeometry(feature);
243
                        break;
244
                case TEST_ATT:
245
                        checkAttributes(feature, simpletypes);
246
                        break;
247
                }
248
        }
249

    
250
        private void checkAttributes(Feature feat, boolean simpl) {
251
                
252
                if (! simpl) {
253
                        Date d = feat.getDate("ATT_DATE");
254
                        
255
                        if (d == null) {
256
                                Thread.activeCount();
257
                        }
258
                        String str = d.toString().toLowerCase();
259
                        boolean boo =
260
                                ((str.indexOf("99") != -1)
261
                                        && (
262
                                                        (str.indexOf("12") != -1)
263
                                                        || (str.indexOf("dec") != -1)
264
                                                        || (str.indexOf("dic") != -1))
265
                                        && (str.indexOf("31") != -1));
266
                        assertTrue("Found a date different to 1999 12 31", boo);
267

    
268
                }
269

    
270
                String str = feat.getString("ATT_STRING").trim();
271
                assertEquals(str, "DFGDFGDFG");
272
                
273
                double real = feat.getDouble("ATT_REAL");
274
                boolean boo = ((real == 4.4444) || (real == 4));
275
                assertTrue("REAL = " + real + ", EXP = 4, 4.4444", boo);
276
                
277
                boolean bool = feat.getBoolean("ATT_BOOLEA");
278
                assertTrue("EXP = FALSE, RET = " + (!bool), !bool);
279

    
280

    
281
                int integ = 0;
282
                if (simpl) {
283
                        integ = (int) Math.round(feat.getDouble("ATT_INTEGE"));
284
                } else {
285
                        integ = feat.getInt("ATT_INTEGE");
286
                }
287
                
288
                assertTrue("REAL = " + integ + ", EXP = 44444", integ == 44444);
289
        }
290
        
291
        /**
292
         * Gets the area of the path iterator
293
         * @param piter the path iterator
294
         * @return the area of the path iterator
295
         */
296
        public static double getPathIteratorArea(PathIterator piter) {
297
                
298
                if (piter == null) {
299
                        return 0;
300
                }
301

    
302
                double resp = 0;
303

    
304
                double[] theData = new double[6];
305
                Coordinate c1 = null;
306
                Coordinate firstc = null;
307
                CoordinateList coordList = null;
308

    
309
                while (!piter.isDone()) {
310

    
311
                        int type = piter.currentSegment(theData);
312
                        
313
                        if (type == PathIterator.SEG_MOVETO) {
314
                                if (coordList != null) {
315
                                        coordList.add(firstc, true);
316
                                        // printCoordList(coordList);
317
                                        resp = resp + CGAlgorithms.signedArea(coordList.toCoordinateArray());
318
                                }
319
                                firstc = new Coordinate(theData[0], theData[1]);
320
                                coordList = new CoordinateList();
321
                        }
322
                        c1 = new Coordinate(theData[0], theData[1]);
323
                        coordList.add(c1, true);
324
                        piter.next();
325
                }
326
                
327
                if (coordList != null) {
328
                        coordList.add(firstc, true);
329
                        // printCoordList(coordList);
330
                        // resp = resp + Math.abs(CGAlgorithms.signedArea(coordList.toCoordinateArray()));
331
                        resp = resp + CGAlgorithms.signedArea(coordList.toCoordinateArray());
332
                }
333
                return Math.abs(resp);
334
        }
335

    
336
        private void checkPolygonArea(Feature feature, Surface2D poly, double expected, boolean simpl) {
337

    
338
                int id = 0;
339
                
340
                if (simpl) {
341
                        id = (int) Math.round(feature.getDouble("GUIA_ID"));
342
                } else {
343
                        id = feature.getInt("GUIA_ID");
344
                }
345

    
346
                double ar = getPathIteratorArea(poly.getPathIterator(null));
347
                assertTrue("AREA = " + ar + ", EXP = " + expected, acceptablySimilar(expected, ar, 0.1));
348

    
349
                switch (id) {
350
                case 174996:
351
                        assertTrue("AREA = " + ar + ", EXP = " + 357.7, acceptablySimilar(ar, 357.7, 0.1));
352
                        break;
353
                case 569303133:
354
                        assertTrue("AREA = " + ar + ", EXP = " + 409.46, acceptablySimilar(ar, 409.46, 0.1));
355
                        break;
356
                case 1229222137:
357
                        assertTrue("AREA = " + ar + ", EXP = " + 49.285, acceptablySimilar(ar, 49.285, 0.1));
358
                        break;
359
                case 1795370359:
360
                        assertTrue("AREA = " + ar + ", EXP = " + 98.165, acceptablySimilar(ar, 98.165, 0.1));
361
                        break;
362
                }
363
        }
364

    
365
    /**
366
     * Gets the Euclidean distance between points A and B.
367
     * 
368
     * @param x1 x coordinate of point A
369
     * @param y1 y coordinate of point A
370
     * @param x2 x coordinate of point B
371
     * @param y2 y coordinate of point B
372
     * @return the Euclidean distance between points A and B.
373
     */
374
        public static double distance(double x1, double y1, double x2, double y2) {
375
                double dx = x2 - x1;
376
                double dy = y2 - y1;
377
                return Math.sqrt(dx * dx + dy * dy);
378
        }
379
        
380
        /**
381
         * Gets the length of the path iterator and of the last of its arcs.
382
         * No SRS or unit conversion is used, just the plain length between coordinates.
383
         * 
384
         * @param piter the path iterator of interest
385
         * @return the length of the path iterator and of the last of its arcs.
386
         */
387
        public static double[] getIteratorLengthAndLast(PathIterator piter) {
388

    
389
                double[] resp = new double[2];
390
                resp[0] = 0;
391
                resp[1] = 0;
392

    
393
                if (piter == null)
394
                        return resp;
395

    
396
                double lastx = 0;
397
                double lasty = 0;
398
                boolean conn = true;
399
                float[] current = new float[6];
400

    
401
                // logger.debug("UTILS getIteratorLength. PITER = " + piter);
402

    
403
                while (!piter.isDone()) {
404
                        if (piter.currentSegment(current) != PathIterator.SEG_MOVETO) {
405
                                conn = true;
406
                        } else {
407
                                conn = false;
408
                        }
409
                        resp[1] = distance(lastx, lasty, current[0], current[1]);
410
                        if (conn)
411
                                resp[0] = resp[0] + resp[1];
412
                        lastx = current[0];
413
                        lasty = current[1];
414
                        piter.next();
415
                }
416
                return resp;
417
        }
418

    
419
        private void checkLineLength(Feature feature, Curve2D pl, double expected, boolean simpl) {
420
                int color = 0;
421
                int eleva = 0;
422
                
423
                if (simpl) {
424
                        color = (int) Math.round(feature.getDouble("COLOR"));
425
                        eleva = (int) Math.round(feature.getDouble("ELEVACION"));
426
                } else {
427
                        color = feature.getInt("COLOR");
428
                        eleva = feature.getInt("ELEVACION");
429
                }
430
                                
431
                double len = getIteratorLengthAndLast(pl.getPathIterator(null))[0];
432
                assertTrue("Not good: " + len  + " and " + expected, acceptablySimilar(expected, len, 0.05));
433

    
434
                switch (color) {
435
                case 888830465:
436
                        assertEquals(eleva, -1519669334);
437
                        break;
438
                case 135691458:
439
                        assertEquals(eleva, -1594772521);
440
                        break;
441
                case 631009463:
442
                        assertEquals(eleva, -409958687);
443
                        break;
444
                case 601164227:
445
                        assertEquals(eleva, -1632831996);
446
                        break;
447
                case 1766834083:
448
                        assertEquals(eleva, -671796992);
449
                        break;
450
                }
451
        }
452

    
453
        private void checkMPoint(Feature feature, boolean simpl) {
454
                
455
                int tipocont = 0;
456
                
457
                if (simpl) {
458
                        tipocont = (int) Math.round(feature.getDouble("TIPOCONT"));
459
                } else {
460
                        tipocont = feature.getInt("TIPOCONT");                }                
461

    
462
                tipocont = feature.getInt("TIPOCONT");
463
                
464
                String nomb = feature.getString("FIRST_NOMB").trim();
465
                MultiPoint2D mp = (MultiPoint2D) feature.getDefaultGeometry(); 
466

    
467
                switch (tipocont) {
468
                case 116:
469
                        assertEquals(nomb, "MARIN (EL)");
470
                        assertTrue("Checking presence of coordinate X: ", oneOfXInMPoint(mp, 272463.83));
471
                        break;
472
                case 118:
473
                        assertEquals(nomb, "SALAMANCA");
474
                        assertTrue("Checking presence of coordinate X: ", oneOfXInMPoint(mp, 276024.43));
475
                        break;
476
                case 15035:
477
                        assertEquals(nomb, "ORBISO");
478
                        assertTrue("Checking presence of coordinate X: ", oneOfXInMPoint(mp, 554478.48));
479
                        break;
480
                case 19586:
481
                        assertEquals(nomb, "VALDEZORRAS");
482
                        assertTrue("Checking presence of coordinate X: ", oneOfXInMPoint(mp, 241343.25));
483
                        break;
484
                case 30000:
485
                         assertEquals(nomb, "ORZOLA");
486
                         assertTrue("Checking presence of coordinate X: ", oneOfXInMPoint(mp, -619386.36));
487
                        break;
488
                }
489
        }
490

    
491
        private boolean oneOfXInMPoint(Shape pointorpoints, double d) {
492
                
493
                if (pointorpoints instanceof MultiPoint2D) {
494
                        MultiPoint2D mp = (MultiPoint2D) pointorpoints;
495
                        int np = mp.getNumPoints();
496
                        for (int i=0; i<np; i++) {
497
                                double itemx = mp.getPoint(i).getX();
498
                                if (acceptablySimilar(d, itemx, 0.01)) return true; 
499
                        }
500
                        return false;
501
                } else {
502
                        Point2D p = (Point2D) pointorpoints;
503
                        return acceptablySimilar(d, p.getX(), 0.01); 
504
                }
505
        }
506
        
507
        private void checkNullGeometry(Feature feature) {
508
                Object obj = feature.getDefaultGeometry();
509
                assertNotNull("Checking not NULL geometry: ", obj);
510
        }
511
        
512

    
513
        private void checkPoint(Feature feature, Point2D point, double expected, boolean simpl) {
514
                int id = 0;
515

    
516
                if (simpl) {
517
                        id = (int) Math.round(feature.getDouble("NUMEROENT"));
518
                } else {
519
                        id = feature.getInt("NUMEROENT");
520
                }
521

    
522
                String nomb = feature.getString("NOMBRE").trim();
523
                assertTrue(acceptablySimilar(expected, point.getX(), 0.01));
524

    
525
                switch (id) {
526
                case 58:
527
                        assertEquals(nomb, "MARIN (EL)");
528
                        break;
529
                case 59:
530
                        assertEquals(nomb, "SALAMANCA");
531
                        break;
532
                case 2825:
533
                        assertEquals(nomb, "NAVAHONDILLA");
534
                        break;
535
                case 6474:
536
                        assertEquals(nomb, "CENTENERA");
537
                        break;
538
                case 27761:
539
                        assertEquals(nomb, "EVAN DE ARRIBA");
540
                        break;
541
                }
542
        }
543

    
544

    
545
        private boolean acceptablySimilar(double expec, double area, double tol) {
546
                double diff = Math.abs(expec - area);
547
                return ((diff / Math.abs((expec + area) / 2)) < tol);
548
        }
549

    
550
        
551

    
552
//        public void test_Resources(){
553
//
554
//                DataManager manager = DataManager.getManager();
555
//                Register.selfRegister();
556
//
557
//                SHPStoreParameters shpParameters;
558
//
559
//                shpParameters=(SHPStoreParameters)manager.createDataStoreParameters(SHPStore.DATASTORE_NAME);
560
//                shpParameters.setFile(fileNormal);
561
//
562
//
563
//                DataStoreTest.doFileResourceTest(shpParameters);
564
//        }
565
        
566

    
567
        private void initLogger() {
568

    
569
                Date now = new Date(System.currentTimeMillis());
570
                String nowstr = now.toString();
571
                
572
                nowstr = StringUtil.replaceAllString(nowstr, " ", "_");
573
                nowstr = StringUtil.replaceAllString(nowstr, ":", "_") + ".txt";
574
                
575
                
576
                String outlogpath = "";
577
                
578
                if (Utils.USING_PDA) {
579
                        outlogpath = ResourceReader.getPdaTestFile(PerformanceTest.SD_FOLDER, "testdata", "performance_" + nowstr).getAbsolutePath();
580
                } else {
581
                        outlogpath = ResourceReader.getResourceFile("testdata", "performance_" + nowstr).getAbsolutePath();
582
                }
583

    
584
                System.out.println("Log file: " + outlogpath);
585

    
586
                try {
587
                    PatternLayout l = new PatternLayout("%5p [%t] - %m%n");
588
                    FileAppender fa = new FileAppender(l, outlogpath, false);
589
                    // ConsoleAppender ca = new ConsoleAppender(l);
590
                    Logger.getRootLogger().setLevel(Level.DEBUG);
591
                    Logger.getRootLogger().addAppender(fa);
592
                    // Logger.getRootLogger().addAppender(ca);
593
                } catch (Exception ex) {
594
                        System.err.println("Error while initializing log4j: " + ex.getMessage());
595
                }
596
                
597
        }
598

    
599
}