Appendix 4. The
Hull implementation of the Douglas and Peucker algorithm.
(c) Phil Wade, 1984;
as the supervisor of both Whyatt and Wade,
I (Mahes Visvalingam) note this omission in the original
publications.
PROGRAM PEUCKER
INTEGER X(10000),Y(10000),GCODE(10000)
INTEGER COUNTER,INCOUNT,NUMSEGS,NUMCOORDS,NFCO
INTEGER XMIN,XMAX,YMIN,YMAX,DISTTOL
C 5 ‑ READ FILE ; 6 ‑ WRITE FILE ;
C Read tolerance value from keyboard.
1 FORMAT ('PLEASE ENTER A TOLERANCE
VALUE')
WRITE (*,1)
READ (*,*) DISTTOL
C Read limits of data from file header.
2 FORMAT (16,lX,I6,lX,I6,lX,I6)
READ (5,2) XMIN,XMAX,YMIN,YMAX
C Read the number of chains from file
header.
READ (5,*) NUMSEGS
C Output the limits of this data.
3 FORMAT
('LIMITS=',I6,1X,I6,1X,I6,1X,I6,1X)
WRITE (6,3) XMIN,XMAX,YMIN,YMAX
C Output the number of chains.
4 FORMAT ('NUMBER OF SEGMENTS=',I4)
WRITE (6,4) NUMSEGS
C Main loop.
DO 100,COUNTER=1,NUMSEGS
C Read the number of coordinates in a
chain from file header.
READ (5,*) NUMCOORDS
C Read in a chain of
co‑ordinates.
CALL COORDSIN(NUMCOORDS,X,Y)
C Generalize this chain using Douglas
and Peucker method.
CALL GENERALIZE(X,Y,NUMCOORDS,GCODE)
C Count the number of filtered
co‑ordinates in this chain.
NFCO=0
DO 150,INCOUNT=1,NUMCOORDS
IF (GCODE(INCOUNT).GT.DISTTOL) THEN
NFCO=NFCO+1
ENDIF
150 CONTINUE
C Output the number of filtered
co‑ordinates.
5 FORMAT ('COORDINATE PAIRS WHICH EXCEED
CHOSEN TOLERANCE=',I4)
WRITE (6,5) NFCO
WRITE (6,*)
C Output the chain of filtered
co‑ordinates.
DO 200,INCOUNT=1,NUMCOORDS
IF (GCODE(INCOUNT).GT.DISTTOL) THEN
WRITE (6,2)
X(INCOUNT),Y(INCOUNT),GCODE(INCOUNT)
ENDIF
200 CONTINUE
100 CONTINUE
END
SUBROUTINE
COORDSIN(NOCDS,A,B)
INTEGER NOCDS,A(NOCDS),B(NOCDS)
READ (5,*) A,B
RETURN
END
SUBROUTINE
GENERALIZE(XCOORD,YCOORD,PTSINCHAIN,GENCODE)
IMPLICIT NONE
INTEGER PTSINCHAIN,I,J,CORDSTART,CORDEND,POINT
INTEGER XCOORD(PTSINCHAIN),YCOORD(PTSINCHAIN)
INTEGER GENCODE(PTSINCHAIN)
REAL DIS,MAXDIS
C Set the generalization code of the first and
last points to 999999
C and set the others to ‑1.
GENCODE(1)=999999
DO 30,I=2,PTSINCHAIN‑1
GENCODE(I)=‑1
30 CONTINUE
GENCODE(PTSINCHAIN)=999999
CORDSTART=1
C Main loop to give a generalization code to
each point.
DO 50,I=1,PTSINCHAIN‑2
C Find the first point on the line to have a
generalization code.
DO WHILE (GENCODE(CORDSTART+1) .GT. ‑1)
CORDSTART=CORDSTART+1
END DO
C Find the first point after this with a
generalization code.
CORDEND=CORDSTART+2
DO WHILE(GENCODE(CORDEND) .EQ. ‑1)
CORDEND=CORDEND+1
END DO
C
Find the point with the maximum distance from the
"Anchor‑Floater" line
MAXDIS=‑1.0
DO 40,J=CORDSTART+1,CORDEND‑1
CALL
CLCDIS(DIS,XCOORD(CORDSTART),YCOORD(CORDSTART),
‑ XCOORD(CORDEND),YCOORD(CORDEND),
‑ XCOORD(J),YCOORD(J))
IF (DIS .GT. MAXDIS) THEN
POINT‑J
MAXDIS=DIS
END IF
40 CONTINUE