FortranGIS  Version2.5
ung2shp.F90
1 PROGRAM ung2shp
2 ! Silly application that converts an Arc/Info ungenerate arc file
3 ! into a shapefile, the input file is passed as a command-line argument.
4 !
5 ! Source of data in this format:
6 ! http://www.ngdc.noaa.gov/mgg/coast/
7 ! References:
8 ! http://www.grass-kr.org/html/v.in.arc.html
9 ! http://www.intevation.de/~jan/gen2shp/gen2shp.html
10 USE shapelib
11 IMPLICIT NONE
12 
13 CHARACTER(len=1024) :: filein, fileout
14 TYPE(shpobject) :: shapes
15 TYPE(shpfileobject) :: shapefile
16 INTEGER,ALLOCATABLE :: shapesize(:)
17 INTEGER :: i, j, dot, nshape, id
18 DOUBLE PRECISION,ALLOCATABLE :: shp(:,:)
19 
20 CALL getarg(1, filein)
21 dot = index(filein, '.', back=.true.)
22 IF (dot == 0) THEN
23  fileout = trim(filein)//'_out'
24 ELSE IF (dot == 1) THEN
25  fileout = 'out'
26 ELSE
27  fileout = filein(:dot-1)
28 ENDIF
29 
30 OPEN(10, file=filein)
31 ! count shapes
32 nshape = 0
33 DO WHILE(read_ungenerate_shape(10) >= 0)
34  nshape = nshape + 1
35 ENDDO
36 
37 IF (nshape <= 0) THEN
38  print*,'Error, bad number of shapes ',nshape,' in file ',trim(filein)
39  stop
40 ENDIF
41 print*,'Found ',nshape,' shapes'
42 ALLOCATE(shapesize(nshape))
43 
44 rewind(10)
45 ! count size of each shape
46 DO i = 1, nshape
47  shapesize(i) = read_ungenerate_shape(10)
48  IF (shapesize(i) < 0) THEN
49  print*,'Error, bad size of shape ',i,shapesize(i),' in file ',trim(filein)
50  stop
51  ENDIF
52 ENDDO
53 print*,'Counted shapes'
54 ALLOCATE(shp(maxval(shapesize),2))
55 
56 shapefile = shpcreate(fileout, shpt_arc)
57 IF (shpfileisnull(shapefile) .OR. dbffileisnull(shapefile)) THEN
58  print*,'Error, opening output shapefile ',trim(fileout)
59  stop
60 ENDIF
61 j = dbfaddfield(shapefile, 'ID', ftinteger, 9, 0)
62 rewind(10)
63 ! import each shape
64 DO i = 1, nshape
65  j = read_ungenerate_shape(10, shapeid=id, values=shp)
66  shapes = shpcreatesimpleobject(shpt_arc, shapesize(i), shp(1,1), shp(1,2))
67  j = shpwriteobject(shapefile, -1, shapes)
68  j = dbfwriteattribute(shapefile, i-1, 0, id)
69  CALL shpdestroyobject(shapes)
70 ENDDO
71 
72 CLOSE(10)
73 CALL shpclose(shapefile)
74 
75 CONTAINS
76 
77 ! Reads next shape from ungenerate file.
78 ! Returns the number of points in the shape, -1 for end of file or -2
79 ! in case of error.
80 FUNCTION read_ungenerate_shape(unit, shapeid, values) RESULT(read_status)
81 INTEGER,INTENT(in) :: unit
82 INTEGER,INTENT(out),OPTIONAL :: shapeid
83 DOUBLE PRECISION,INTENT(out),OPTIONAL :: values(:,:)
84 INTEGER :: read_status
85 
86 CHARACTER(len=1024) :: line
87 INTEGER :: npts, nptsmax, lshapeid
88 DOUBLE PRECISION :: x(2)
89 
90 nptsmax = 0
91 IF (PRESENT(values)) THEN
92  IF (SIZE(values,2) >= 2) THEN
93  nptsmax = SIZE(values,1)
94  ENDIF
95 ENDIF
96 
97 READ(unit,'(A)',end=120,err=120)line
98 IF (line == 'END') THEN ! end of file
99  read_status = -1
100  RETURN
101 ENDIF
102 
103 READ(line,'(I10.0)',end=120,err=120) lshapeid
104 IF (PRESENT(shapeid)) shapeid = lshapeid
105 IF (lshapeid < 0) GOTO 120
106 
107 npts=0
108 DO WHILE (.true.)
109  READ(unit,'(A)',end=120,err=120)line
110  IF (line == 'END') THEN ! end of shape
111  read_status = npts
112  RETURN
113  ELSE
114  READ(line,*,end=120,err=120)x
115  npts = npts + 1
116  IF (nptsmax >= npts) values(npts,1:2) = x(:)
117  ENDIF
118 ENDDO
119 
120 RETURN ! never reached
121 
122 120 read_status = -2
123 RETURN
124 
125 END FUNCTION read_ungenerate_shape
126 
127 END PROGRAM ung2shp
128 
Interface to FUNCTIONs for setting dbf attributes.
Definition: shapelib.F90:156
Object describing the geometrical properties of a shape.
Definition: shapelib.F90:95
Fortran 2003 interface to the shapelib http://shapelib.maptools.org/ library.
Definition: shapelib.F90:53
Object describing a shapefile dataset.
Definition: shapelib.F90:84