libsim  Versione 7.1.7
georef_coord_class.F90
1 ! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
2 ! authors:
3 ! Davide Cesari <dcesari@arpa.emr.it>
4 ! Paolo Patruno <ppatruno@arpa.emr.it>
5 
6 ! This program is free software; you can redistribute it and/or
7 ! modify it under the terms of the GNU General Public License as
8 ! published by the Free Software Foundation; either version 2 of
9 ! the License, or (at your option) any later version.
10 
11 ! This program is distributed in the hope that it will be useful,
12 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ! GNU General Public License for more details.
15 
16 ! You should have received a copy of the GNU General Public License
17 ! along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "config.h"
19 
33 MODULE georef_coord_class
34 USE err_handling
37 USE geo_proj_class
38 #ifdef HAVE_SHAPELIB
39 USE shapelib
40 #endif
41 IMPLICIT NONE
42 
47 TYPE georef_coord
48  PRIVATE
49  DOUBLE PRECISION :: x=dmiss, y=dmiss
50 END TYPE georef_coord
51 
53 TYPE(georef_coord),PARAMETER :: georef_coord_miss=georef_coord(dmiss,dmiss)
54 
60  PRIVATE
61  INTEGER,ALLOCATABLE :: parts(:)
62  TYPE(georef_coord),ALLOCATABLE :: coord(:)
63  INTEGER :: topo=imiss
64  TYPE(geo_proj) :: proj
65  TYPE(georef_coord) :: bbox(2)=(/georef_coord_miss, georef_coord_miss/)
66  LOGICAL :: bbox_updated=.false.
67 END TYPE georef_coord_array
68 
69 INTEGER,PARAMETER :: georef_coord_array_point = 1
70 INTEGER,PARAMETER :: georef_coord_array_arc = 3
71 INTEGER,PARAMETER :: georef_coord_array_polygon = 5
72 INTEGER,PARAMETER :: georef_coord_array_multipoint = 8
73 
74 
78 INTERFACE delete
79  MODULE PROCEDURE georef_coord_delete, georef_coord_array_delete
80 END INTERFACE
81 
83 INTERFACE c_e
84  MODULE PROCEDURE georef_coord_c_e, georef_coord_array_c_e
85 END INTERFACE
86 
88 INTERFACE getval
89  MODULE PROCEDURE georef_coord_getval, georef_coord_proj_getval, georef_coord_array_getval
90 END INTERFACE
91 
92 INTERFACE compute_bbox
93  MODULE PROCEDURE georef_coord_array_compute_bbox
94 END INTERFACE
95 
97 INTERFACE OPERATOR (==)
98  MODULE PROCEDURE georef_coord_eq
99 END INTERFACE
100 
102 INTERFACE OPERATOR (/=)
103  MODULE PROCEDURE georef_coord_ne
104 END INTERFACE
105 
108 INTERFACE OPERATOR (>=)
109  MODULE PROCEDURE georef_coord_ge
110 END INTERFACE
111 
114 INTERFACE OPERATOR (<=)
115  MODULE PROCEDURE georef_coord_le
116 END INTERFACE
117 
118 #ifdef HAVE_SHAPELIB
119 
121 INTERFACE import
122  MODULE PROCEDURE arrayof_georef_coord_array_import
123 END INTERFACE
124 
127 INTERFACE export
128  MODULE PROCEDURE arrayof_georef_coord_array_export
129 END INTERFACE
130 #endif
131 
134 INTERFACE read_unit
135  MODULE PROCEDURE georef_coord_read_unit, georef_coord_vect_read_unit
136 END INTERFACE
137 
140 INTERFACE write_unit
141  MODULE PROCEDURE georef_coord_write_unit, georef_coord_vect_write_unit
142 END INTERFACE
143 
145 INTERFACE inside
146  MODULE PROCEDURE georef_coord_inside, georef_coord_inside_rectang
147 END INTERFACE
148 
150 INTERFACE dist
151  MODULE PROCEDURE georef_coord_dist
152 END INTERFACE
153 
154 #define ARRAYOF_ORIGTYPE TYPE(georef_coord_array)
155 #define ARRAYOF_TYPE arrayof_georef_coord_array
156 !define ARRAYOF_ORIGEQ 0
157 #define ARRAYOF_ORIGDESTRUCTOR(x) CALL delete(x)
158 #include "arrayof_pre.F90"
159 ! from arrayof
160 PUBLIC insert, append, remove, packarray
161 
162 PRIVATE
163 PUBLIC georef_coord, georef_coord_miss, &
164  georef_coord_array, georef_coord_array_point, georef_coord_array_arc, &
165  georef_coord_array_polygon, georef_coord_array_multipoint, &
166  delete, c_e, getval, compute_bbox, OPERATOR(==), OPERATOR(/=), OPERATOR(>=), OPERATOR(<=), &
167 #ifdef HAVE_SHAPELIB
168  import, export, &
169 #endif
171  georef_coord_new, georef_coord_array_new
172 
173 CONTAINS
174 
175 #include "arrayof_post.F90"
176 
177 ! ===================
178 ! == georef_coord ==
179 ! ===================
183 FUNCTION georef_coord_new(x, y) RESULT(this)
184 DOUBLE PRECISION,INTENT(in),OPTIONAL :: x
185 DOUBLE PRECISION,INTENT(in),OPTIONAL :: y
186 TYPE(georef_coord) :: this
187 
188 CALL optio(x, this%x)
189 CALL optio(y, this%y)
190 
191 END FUNCTION georef_coord_new
192 
193 
194 SUBROUTINE georef_coord_delete(this)
195 TYPE(georef_coord),INTENT(inout) :: this
196 
197 this%x = dmiss
198 this%y = dmiss
199 
200 END SUBROUTINE georef_coord_delete
201 
202 
203 ELEMENTAL FUNCTION georef_coord_c_e(this) RESULT (res)
204 TYPE(georef_coord),INTENT(in) :: this
205 LOGICAL :: res
206 
207 res = .NOT. this == georef_coord_miss
208 
209 END FUNCTION georef_coord_c_e
210 
211 
218 ELEMENTAL SUBROUTINE georef_coord_getval(this, x, y)
219 TYPE(georef_coord),INTENT(in) :: this
220 DOUBLE PRECISION,INTENT(out),OPTIONAL :: x
221 DOUBLE PRECISION,INTENT(out),OPTIONAL :: y
222 
223 IF (PRESENT(x)) x = this%x
224 IF (PRESENT(y)) y = this%y
225 
226 END SUBROUTINE georef_coord_getval
227 
228 
237 ELEMENTAL SUBROUTINE georef_coord_proj_getval(this, proj, x, y, lon, lat)
238 TYPE(georef_coord),INTENT(in) :: this
239 TYPE(geo_proj),INTENT(in) :: proj
240 DOUBLE PRECISION,INTENT(out),OPTIONAL :: x
241 DOUBLE PRECISION,INTENT(out),OPTIONAL :: y
242 DOUBLE PRECISION,INTENT(out),OPTIONAL :: lon
243 DOUBLE PRECISION,INTENT(out),OPTIONAL :: lat
244 
245 DOUBLE PRECISION :: llon, llat
246 
247 IF (PRESENT(x)) x = this%x
248 IF (PRESENT(y)) y = this%y
249 IF (PRESENT(lon) .OR. present(lat)) THEN
250  CALL unproj(proj, this%x, this%y, llon, llat)
251  IF (PRESENT(lon)) lon = llon
252  IF (PRESENT(lat)) lat = llat
253 ENDIF
254 
255 END SUBROUTINE georef_coord_proj_getval
256 
257 
258 ! document and improve
259 ELEMENTAL FUNCTION getlat(this)
260 TYPE(georef_coord),INTENT(in) :: this ! oggetto di cui restituire latitudine
261 DOUBLE PRECISION :: getlat ! latitudine geografica
262 
263 getlat = this%y ! change!!!
264 
265 END FUNCTION getlat
266 
267 ! document and improve
268 ELEMENTAL FUNCTION getlon(this)
269 TYPE(georef_coord),INTENT(in) :: this ! oggetto di cui restituire latitudine
270 DOUBLE PRECISION :: getlon ! longitudine geografica
271 
272 getlon = this%x ! change!!!
273 
274 END FUNCTION getlon
275 
276 
277 ELEMENTAL FUNCTION georef_coord_eq(this, that) RESULT(res)
278 TYPE(georef_coord),INTENT(IN) :: this, that
279 LOGICAL :: res
280 
281 res = (this%x == that%x .AND. this%y == that%y)
282 
283 END FUNCTION georef_coord_eq
284 
285 
286 ELEMENTAL FUNCTION georef_coord_ge(this, that) RESULT(res)
287 TYPE(georef_coord),INTENT(IN) :: this, that
288 LOGICAL :: res
289 
290 res = (this%x >= that%x .AND. this%y >= that%y)
291 
292 END FUNCTION georef_coord_ge
293 
294 
295 ELEMENTAL FUNCTION georef_coord_le(this, that) RESULT(res)
296 TYPE(georef_coord),INTENT(IN) :: this, that
297 LOGICAL :: res
298 
299 res = (this%x <= that%x .AND. this%y <= that%y)
300 
301 END FUNCTION georef_coord_le
302 
303 
304 ELEMENTAL FUNCTION georef_coord_ne(this, that) RESULT(res)
305 TYPE(georef_coord),INTENT(IN) :: this, that
306 LOGICAL :: res
307 
308 res = .NOT.(this == that)
309 
310 END FUNCTION georef_coord_ne
311 
312 
318 SUBROUTINE georef_coord_read_unit(this, unit)
319 TYPE(georef_coord),INTENT(out) :: this
320 INTEGER, INTENT(in) :: unit
321 
322 CALL georef_coord_vect_read_unit((/this/), unit)
323 
324 END SUBROUTINE georef_coord_read_unit
325 
326 
332 SUBROUTINE georef_coord_vect_read_unit(this, unit)
333 TYPE(georef_coord) :: this(:)
334 INTEGER, INTENT(in) :: unit
335 
336 CHARACTER(len=40) :: form
337 INTEGER :: i
338 
339 INQUIRE(unit, form=form)
340 IF (form == 'FORMATTED') THEN
341  read(unit,*) (this(i)%x,this(i)%y, i=1,SIZE(this))
342 !TODO bug gfortran compiler !
343 !missing values are unredeable when formatted
344 ELSE
345  READ(unit) (this(i)%x,this(i)%y, i=1,SIZE(this))
346 ENDIF
347 
348 END SUBROUTINE georef_coord_vect_read_unit
349 
350 
355 SUBROUTINE georef_coord_write_unit(this, unit)
356 TYPE(georef_coord),INTENT(in) :: this
357 INTEGER, INTENT(in) :: unit
358 
359 CALL georef_coord_vect_write_unit((/this/), unit)
360 
361 END SUBROUTINE georef_coord_write_unit
362 
363 
368 SUBROUTINE georef_coord_vect_write_unit(this, unit)
369 TYPE(georef_coord),INTENT(in) :: this(:)
370 INTEGER, INTENT(in) :: unit
371 
372 CHARACTER(len=40) :: form
373 INTEGER :: i
374 
375 INQUIRE(unit, form=form)
376 IF (form == 'FORMATTED') THEN
377  WRITE(unit,*) (this(i)%x,this(i)%y, i=1,SIZE(this))
378 !TODO bug gfortran compiler !
379 !missing values are unredeable when formatted
380 ELSE
381  WRITE(unit) (this(i)%x,this(i)%y, i=1,SIZE(this))
382 ENDIF
383 
384 END SUBROUTINE georef_coord_vect_write_unit
385 
386 
389 FUNCTION georef_coord_dist(this, that) RESULT(dist)
391 TYPE(georef_coord), INTENT (IN) :: this
392 TYPE(georef_coord), INTENT (IN) :: that
393 DOUBLE PRECISION :: dist
394 
395 DOUBLE PRECISION :: x,y
396 ! Distanza approssimata, valida per piccoli angoli
397 
398 x = (this%x-that%x)*cos(((this%y+this%y)/2.)*degrad)
399 y = (this%y-that%y)
400 dist = sqrt(x**2 + y**2)*degrad*rearth
401 
402 END FUNCTION georef_coord_dist
403 
404 
410 FUNCTION georef_coord_inside_rectang(this, coordmin, coordmax) RESULT(res)
411 TYPE(georef_coord),INTENT(IN) :: this
412 TYPE(georef_coord),INTENT(IN) :: coordmin
413 TYPE(georef_coord),INTENT(IN) :: coordmax
414 LOGICAL :: res
415 
416 res = (this >= coordmin .AND. this <= coordmax)
417 
418 END FUNCTION georef_coord_inside_rectang
419 
420 
421 ! ========================
422 ! == georef_coord_array ==
423 ! ========================
429 FUNCTION georef_coord_array_new(x, y, topo, proj) RESULT(this)
430 DOUBLE PRECISION,INTENT(in),OPTIONAL :: x(:)
431 DOUBLE PRECISION,INTENT(in),OPTIONAL :: y(:)
432 INTEGER,INTENT(in),OPTIONAL :: topo
433 TYPE(geo_proj),INTENT(in),OPTIONAL :: proj
434 TYPE(georef_coord_array) :: this
435 
436 INTEGER :: lsize
437 
438 IF (PRESENT(x) .AND. PRESENT(y)) THEN
439  lsize = min(SIZE(x), SIZE(y))
440  ALLOCATE(this%coord(lsize))
441  this%coord(1:lsize)%x = x(1:lsize)
442  this%coord(1:lsize)%y = y(1:lsize)
443 ENDIF
444 this%topo = optio_l(topo)
445 IF (PRESENT(proj)) this%proj = proj
446 
447 END FUNCTION georef_coord_array_new
448 
449 
450 SUBROUTINE georef_coord_array_delete(this)
451 TYPE(georef_coord_array),INTENT(inout) :: this
452 
453 TYPE(georef_coord_array) :: lobj
454 
455 this = lobj
456 
457 END SUBROUTINE georef_coord_array_delete
458 
459 
460 ELEMENTAL FUNCTION georef_coord_array_c_e(this) RESULT (res)
461 TYPE(georef_coord_array),INTENT(in) :: this
462 LOGICAL :: res
463 
464 res = ALLOCATED(this%coord)
465 
466 END FUNCTION georef_coord_array_c_e
467 
468 
473 SUBROUTINE georef_coord_array_getval(this, x, y, topo, proj)
474 TYPE(georef_coord_array),INTENT(in) :: this
475 DOUBLE PRECISION,OPTIONAL,ALLOCATABLE,INTENT(out) :: x(:)
476 DOUBLE PRECISION,OPTIONAL,ALLOCATABLE,INTENT(out) :: y(:)
477 ! allocatable per vedere di nascosto l'effetto che fa
478 INTEGER,OPTIONAL,INTENT(out) :: topo
479 TYPE(geo_proj),OPTIONAL,INTENT(out) :: proj
480 
481 
482 IF (PRESENT(x)) THEN
483  IF (ALLOCATED(this%coord)) THEN
484  x = this%coord%x
485  ENDIF
486 ENDIF
487 IF (PRESENT(y)) THEN
488  IF (ALLOCATED(this%coord)) THEN
489  y = this%coord%y
490  ENDIF
491 ENDIF
492 IF (PRESENT(topo)) topo = this%topo
493 IF (PRESENT(proj)) proj = this%proj ! warning proj has no missing value yet
494 
495 END SUBROUTINE georef_coord_array_getval
496 
497 
503 SUBROUTINE georef_coord_array_compute_bbox(this)
504 TYPE(georef_coord_array),INTENT(inout) :: this
505 
506 IF (ALLOCATED(this%coord)) THEN
507  this%bbox(1)%x = minval(this%coord(:)%x)
508  this%bbox(1)%y = minval(this%coord(:)%y)
509  this%bbox(2)%x = maxval(this%coord(:)%x)
510  this%bbox(2)%y = maxval(this%coord(:)%y)
511  this%bbox_updated = .true.
512 ENDIF
513 
514 END SUBROUTINE georef_coord_array_compute_bbox
515 
516 #ifdef HAVE_SHAPELIB
517 ! internal method for importing a single shape
518 SUBROUTINE georef_coord_array_import(this, shphandle, nshp)
519 TYPE(georef_coord_array),INTENT(OUT) :: this
520 TYPE(shpfileobject),INTENT(INOUT) :: shphandle
521 INTEGER,INTENT(IN) :: nshp
522 
523 TYPE(shpobject) :: shpobj
524 
525 ! read shape object
526 shpobj = shpreadobject(shphandle, nshp)
527 IF (.NOT.shpisnull(shpobj)) THEN
528 ! import it in georef_coord object
529  this = georef_coord_array_new(x=dble(shpobj%padfx), y=dble(shpobj%padfy), &
530  topo=shpobj%nshptype)
531  IF (shpobj%nparts > 1 .AND. ASSOCIATED(shpobj%panpartstart)) THEN
532  this%parts = shpobj%panpartstart(:) ! automatic f95 allocation
533  ELSE IF (ALLOCATED(this%parts)) THEN
534  DEALLOCATE(this%parts)
535  ENDIF
536  CALL shpdestroyobject(shpobj)
537  CALL compute_bbox(this)
538 ENDIF
539 
540 
541 END SUBROUTINE georef_coord_array_import
542 
543 
544 ! internal method for exporting a single shape
545 SUBROUTINE georef_coord_array_export(this, shphandle, nshp)
546 TYPE(georef_coord_array),INTENT(in) :: this
547 TYPE(shpfileobject),INTENT(inout) :: shphandle
548 INTEGER,INTENT(IN) :: nshp ! index of shape to write starting from 0, -1 to append
549 
550 INTEGER :: i
551 TYPE(shpobject) :: shpobj
552 
553 IF (ALLOCATED(this%coord)) THEN
554  IF (ALLOCATED(this%parts)) THEN
555  shpobj = shpcreateobject(this%topo, -1, SIZE(this%parts), this%parts, &
556  this%parts, SIZE(this%coord), this%coord(:)%x, this%coord(:)%y)
557  ELSE
558  shpobj = shpcreatesimpleobject(this%topo, SIZE(this%coord), &
559  this%coord(:)%x, this%coord(:)%y)
560  ENDIF
561 ELSE
562  RETURN
563 ENDIF
564 
565 IF (.NOT.shpisnull(shpobj)) THEN
566  i = shpwriteobject(shphandle, nshp, shpobj)
567  CALL shpdestroyobject(shpobj)
568 ENDIF
569 
570 END SUBROUTINE georef_coord_array_export
571 
572 
583 SUBROUTINE arrayof_georef_coord_array_import(this, shpfile)
584 TYPE(arrayof_georef_coord_array),INTENT(out) :: this
585 CHARACTER(len=*),INTENT(in) :: shpfile
586 
587 REAL(kind=fp_d) :: minb(4), maxb(4)
588 INTEGER :: i, ns, shptype, dbfnf, dbfnr
589 TYPE(shpfileobject) :: shphandle
590 
591 shphandle = shpopen(trim(shpfile), 'rb')
592 IF (shpfileisnull(shphandle)) THEN
593  ! log here
594  CALL raise_error()
595  RETURN
596 ENDIF
597 
598 ! get info about file
599 CALL shpgetinfo(shphandle, ns, shptype, minb, maxb, dbfnf, dbfnr)
600 IF (ns > 0) THEN ! allocate and read the object
601  CALL insert(this, nelem=ns)
602  DO i = 1, ns
603  CALL georef_coord_array_import(this%array(i), shphandle=shphandle, nshp=i-1)
604  ENDDO
605 ENDIF
606 
607 CALL shpclose(shphandle)
608 ! pack object to save memory
609 CALL packarray(this)
610 
611 END SUBROUTINE arrayof_georef_coord_array_import
612 
613 
619 SUBROUTINE arrayof_georef_coord_array_export(this, shpfile)
620 TYPE(arrayof_georef_coord_array),INTENT(in) :: this
621 CHARACTER(len=*),INTENT(in) :: shpfile
622 
623 INTEGER :: i
624 TYPE(shpfileobject) :: shphandle
625 
626 IF (this%arraysize > 0) THEN
627  shphandle = shpcreate(trim(shpfile), this%array(1)%topo)
628 ELSE
629  shphandle = shpcreate(trim(shpfile), georef_coord_array_polygon)
630 ENDIF
631 IF (shpfileisnull(shphandle)) THEN
632  ! log here
633  CALL raise_error()
634  RETURN
635 ENDIF
636 
637 DO i = 1, this%arraysize
638  CALL georef_coord_array_export(this%array(i), shphandle=shphandle, nshp=i-1)
639 ENDDO
640 
641 CALL shpclose(shphandle)
642 
643 END SUBROUTINE arrayof_georef_coord_array_export
644 #endif
645 
657 FUNCTION georef_coord_inside(this, poly) RESULT(inside)
658 TYPE(georef_coord), INTENT(IN) :: this
659 TYPE(georef_coord_array), INTENT(IN) :: poly
660 LOGICAL :: inside
661 
662 INTEGER :: i
663 
664 inside = .false.
665 IF (.NOT.c_e(this)) RETURN
666 IF (.NOT.ALLOCATED(poly%coord)) RETURN
667 ! if outside bounding box stop here
668 IF (poly%bbox_updated) THEN
669  IF (.NOT.georef_coord_inside_rectang(this, poly%bbox(1), poly%bbox(2))) RETURN
670 ENDIF
671 
672 IF (ALLOCATED(poly%parts)) THEN
673  DO i = 1, SIZE(poly%parts)-1
674  inside = inside .NEQV. pointinpoly(this%x, this%y, &
675  poly%coord(poly%parts(i)+1:poly%parts(i+1))%x, &
676  poly%coord(poly%parts(i)+1:poly%parts(i+1))%y)
677  ENDDO
678  IF (SIZE(poly%parts) > 0) THEN ! safety check
679  inside = inside .NEQV. pointinpoly(this%x, this%y, &
680  poly%coord(poly%parts(i)+1:)%x, &
681  poly%coord(poly%parts(i)+1:)%y)
682  ENDIF
683 
684 ELSE
685  IF (SIZE(poly%coord) < 1) RETURN ! safety check
686  inside = pointinpoly(this%x, this%y, &
687  poly%coord(:)%x, poly%coord(:)%y)
688 ENDIF
689 
690 CONTAINS
691 
692 FUNCTION pointinpoly(x, y, px, py)
693 DOUBLE PRECISION, INTENT(in) :: x, y, px(:), py(:)
694 LOGICAL :: pointinpoly
695 
696 INTEGER :: i, j, starti
697 
698 pointinpoly = .false.
699 
700 IF (px(1) == px(SIZE(px)) .AND. py(1) == py(SIZE(px))) THEN ! closed polygon
701  starti = 2
702  j = 1
703 ELSE ! unclosed polygon
704  starti = 1
705  j = SIZE(px)
706 ENDIF
707 DO i = starti, SIZE(px)
708  IF ((py(i) <= y .AND. y < py(j)) .OR. &
709  (py(j) <= y .AND. y < py(i))) THEN
710  IF (x < (px(j) - px(i)) * (y - py(i)) / (py(j) - py(i)) + px(i)) THEN
711  pointinpoly = .NOT. pointinpoly
712  ENDIF
713  ENDIF
714  j = i
715 ENDDO
716 
717 END FUNCTION pointinpoly
718 
719 END FUNCTION georef_coord_inside
720 
721 
722 
723 END MODULE georef_coord_class
Compute forward coordinate transformation from geographical system to projected system.
Compute backward coordinate transformation from projected system to geographical system.
Quick method to append an element to the array.
Detructors for the two classes.
Compute the distance in m between two points.
Export an array of georef_coord_array objects to a file in ESRI/Shapefile format.
Methods for returning the value of object members.
Import an array of georef_coord_array objects from a file in ESRI/Shapefile format.
Method for inserting elements of the array at a desired position.
Determine whether a point lies inside a polygon or a rectangle.
Method for packing the array object reducing at a minimum the memory occupation, without destroying i...
Read a single georef_coord object or an array of georef_coord objects from a Fortran FORMATTED or UNF...
Method for removing elements of the array at a desired position.
Write a single georef_coord object or an array of georef_coord objects to a Fortran FORMATTED or UNFO...
Generic subroutine for checking OPTIONAL parameters.
Costanti fisiche (DOUBLEPRECISION).
Definition: phys_const.f90:72
Gestione degli errori.
This module defines objects describing georeferenced sparse points possibly with topology and project...
Definitions of constants and functions for working with missing values.
Module for quickly interpreting the OPTIONAL parameters passed to a subprogram.
Derived type defining a dynamically extensible array of TYPE(georef_coord_array) elements.
Derived type defining a one-dimensional array of georeferenced points with an associated topology (is...
Derive type defining a single georeferenced point, either in geodetic or in projected coordinates.

Generated with Doxygen.