[Pkg-octave-commit] [octave-octclip] 01/03: Imported Upstream version 1.0.8

Rafael Laboissière rlaboiss-guest at moszumanska.debian.org
Sun Feb 7 14:05:27 UTC 2016


This is an automated email from the git hooks/post-receive script.

rlaboiss-guest pushed a commit to branch master
in repository octave-octclip.

commit ba2211591577cbb78f4067fe426287a37aeb1f2c
Author: Rafael Laboissiere <rafael at laboissiere.net>
Date:   Sun Feb 7 08:47:38 2016 -0200

    Imported Upstream version 1.0.8
---
 COPYING                  |  674 +++++++++++++++++
 DESCRIPTION              |   13 +
 INDEX                    |    5 +
 NEWS                     |   32 +
 doc/octclip.pdf          |  Bin 0 -> 206232 bytes
 doc/octclip.tex          |  247 +++++++
 inst/oc_polybool.m       |  265 +++++++
 src/Makefile             |   44 ++
 src/_oc_polybool.cc      |  241 ++++++
 src/calctopo.c           |   71 ++
 src/compilador.c         |   82 +++
 src/dpeucker.c           |  472 ++++++++++++
 src/errores.c            |  119 +++
 src/eucli.c              |  238 ++++++
 src/fgeneral.c           |  880 ++++++++++++++++++++++
 src/geocnan.c            |  184 +++++
 src/geocomp.c            |  129 ++++
 src/greiner.c            | 1840 ++++++++++++++++++++++++++++++++++++++++++++++
 src/libgeoc/calctopo.h   |   81 ++
 src/libgeoc/compilador.h |   96 +++
 src/libgeoc/constantes.h |  264 +++++++
 src/libgeoc/dpeucker.h   |  261 +++++++
 src/libgeoc/errores.h    | 1058 ++++++++++++++++++++++++++
 src/libgeoc/eucli.h      |  237 ++++++
 src/libgeoc/fgeneral.h   |  646 ++++++++++++++++
 src/libgeoc/general.h    |   61 ++
 src/libgeoc/geocnan.h    |  233 ++++++
 src/libgeoc/geocomp.h    |  208 ++++++
 src/libgeoc/geom.h       |   64 ++
 src/libgeoc/greiner.h    |  827 +++++++++++++++++++++
 src/libgeoc/polig.h      | 1101 +++++++++++++++++++++++++++
 src/libgeoc/polil.h      |  799 ++++++++++++++++++++
 src/libgeoc/ptopol.h     |  947 ++++++++++++++++++++++++
 src/libgeoc/recpolil.h   |  439 +++++++++++
 src/libgeoc/segmento.h   |  299 ++++++++
 src/libgeoc/ventorno.h   |  100 +++
 src/octclip.h            |   31 +
 src/polig.c              | 1815 +++++++++++++++++++++++++++++++++++++++++++++
 src/polil.c              | 1463 ++++++++++++++++++++++++++++++++++++
 src/ptopol.c             | 1007 +++++++++++++++++++++++++
 src/recpolil.c           | 1402 +++++++++++++++++++++++++++++++++++
 src/segmento.c           |  292 ++++++++
 src/ventorno.c           |   86 +++
 43 files changed, 19353 insertions(+)

diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..28b5ad2
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,13 @@
+Name: OctCLIP
+Version: 1.0.8
+Date: 2015-06-16
+Author: José Luis García Pallero <jgpallero at gmail.com>
+Maintainer: José Luis García Pallero <jgpallero at gmail.com>
+Title: GNU Octave clipping polygons tool
+Description: This package allows to do boolean operations with polygons using
+ the Greiner-Hormann algorithm.
+Depends: Octave (>= 2.9.7)
+Url: http://davis.wpi.edu/~matt/courses/clipping/
+ https://bitbucket.org/jgpallero/octclip
+Autoload: no
+License: GPLv3+, modified BSD
diff --git a/INDEX b/INDEX
new file mode 100644
index 0000000..23fe7c2
--- /dev/null
+++ b/INDEX
@@ -0,0 +1,5 @@
+toolbox >> OctCLIP
+Category Kernel functions
+ _oc_polybool
+Category Driver functions
+ oc_polybool
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..25596af
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,32 @@
+Summary of important user-visible changes for version 1.0.8:
+------------------------------------------------------------
+
+** Minor changes in src/Makefile
+
+Summary of important user-visible changes for version 1.0.7:
+------------------------------------------------------------
+
+** Minor changes and corrections in help strings
+
+Summary of important user-visible changes for version 1.0.6:
+------------------------------------------------------------
+
+** All calls to ismatrix() are changed by isnumeric()
+
+Summary of important user-visible changes for version 1.0.5:
+------------------------------------------------------------
+
+** Only minor changes in Mercurial repository managment
+
+Summary of important user-visible changes for version 1.0.3:
+------------------------------------------------------------
+
+** Change 'autoload' option to 'no' by default
+
+** Correct the way of calculation of the minumum perturbation number
+
+** Add number of polygons output argument
+
+** Fix number of input arguments control
+
+** Documentation updates
diff --git a/doc/octclip.pdf b/doc/octclip.pdf
new file mode 100644
index 0000000..7059395
Binary files /dev/null and b/doc/octclip.pdf differ
diff --git a/doc/octclip.tex b/doc/octclip.tex
new file mode 100644
index 0000000..5b0247c
--- /dev/null
+++ b/doc/octclip.tex
@@ -0,0 +1,247 @@
+\documentclass[10pt,a4paper]{article}
+\usepackage{tocbibind}
+\usepackage{hyperref}
+\hypersetup{colorlinks,citecolor=red,linkcolor=red,urlcolor=red}
+
+\newcommand{\octclip}{\texttt{OctCLIP}}
+\newcommand{\octave}{GNU Octave}
+
+\title{Clipping polygons from \octave\footnote{This document is distributed
+       under the terms of the GNU Free Documentation License. Please, see
+       \url{http://www.gnu.org/licenses/}}}
+\author{Jos\'e Luis Garc\'ia Pallero\footnote{ETSI en Topograf\'ia, Geodesia y
+        Cartograf\'ia, Universidad Polit\'ecnica de Madrid.
+        \texttt{jlg.pallero at upm.es}, \texttt{jgpallero at gmail.com}}}
+\date{February 13, 2015 (version 1.0.6)\\
+      June 20, 2013 (version 1.0.5)\\
+      October 1, 2012 (version 1.0.2)\\
+      November 21, 2011 (version 1.0.1)\\
+      May 24, 2011 (version 1.0.0)}
+
+\begin{document}
+\maketitle
+% \tableofcontents
+
+\nocite{eat-om}
+\nocite{kim2006a}
+
+\begin{abstract}
+This is a small introduction to using the \octclip{} package. In this text, you
+can overview the basic usage of the functions in
+\octave\footnote{\url{http://www.octave.org}}. If you need a detailed
+description about the Greiner-Hormann implemented algorithm, please read
+\cite{greiner1998} and visit \url{http://davis.wpi.edu/~matt/courses/clipping/}.
+\end{abstract}
+
+\section{Overview}
+
+The \octclip{} package allows you to perform boolean operations (intersection,
+union, difference and exclusive or) between two polygons in \octave{} using the
+Greiner-Hormann algorithm\footnote{\cite{greiner1998} and
+\url{http://davis.wpi.edu/~matt/courses/clipping/}}.
+
+Greiner-Hormann is an efficient algorithm for clipping arbitrary 2D polygons.
+The algorithm can handle arbitrary closed polygons, specifically where the
+subject and clip polygons may self-intersect.
+
+\section{Installation}
+
+As most of \octave{} packages, \octclip{} installation consists in compiling the
+C++ kernel sources, link them against \octave{} library to generate
+\texttt{*.oct} functions and copy this \texttt{*.oct} executables and other
+\texttt{*.m} functions into a working directory.
+
+The automagic procedure can be easily done by running the command:
+
+\begin{verbatim}
+octave:1> pkg install octclip-x.x.x.tar.gz
+\end{verbatim}
+where \texttt{x.x.x} is the version number.
+
+After that, the functions and documentation are installed in your machine and
+you are ready for use the package.
+
+\section{\octave{} functions}
+
+Two types of functions are programmed for \octave: one \texttt{*.oct} function
+and one \texttt{*.m} function.
+
+\subsection{\texttt{*.oct} function}
+\label{op-of}
+
+This function are linked with the C code that actually make the computations.
+You can use it, but is no recommended because the input arguments are more
+strict than \texttt{*.m} functions and don't check for some errors.
+
+The function is:
+\begin{itemize}
+\item \texttt{\_oc\_polybool}: Performs boolean operation between two polygons.
+\end{itemize}
+
+\subsection{\texttt{*.m} function}
+
+This function makes the computations by calling the \texttt{*.oct} function. You
+must call this function because you can use different number of input arguments
+and checking of input arguments is performed.
+
+The function is the same as in section \ref{op-of} (without the \texttt{\_} at
+the beginning of the name):
+\begin{itemize}
+\item \texttt{oc\_polybool}: Performs boolean operation between two polygons
+      by calling the \texttt{\_oc\_polybool}.
+\end{itemize}
+
+\texttt{oc\_polybool} includes too some demonstration code in order to test the
+functionality of the functions. The demo code can be executed as:
+\begin{verbatim}
+octave:1> demo oc_polybool
+\end{verbatim}
+
+\subsection{Error handling}
+
+\texttt{*.oct} and \texttt{*.m} functions can emit errors, some due to errors
+with input arguments and other due to errors in functions from the
+C\footnote{The algorithm is internally implemented in C (C99 standard).} code.
+
+Errors due to wrong input arguments (data types, dimensions, etc.) can be only
+given for \texttt{*.m} function and this is the reason because the use of this
+function is recommended. In this case, the execution is aborted and nothing is
+stored in output arguments.
+
+The \texttt{*.oct} function can emit errors due to wrong number of input
+arguments, wrong value of the operation identifier and internal errors of memory
+allocation.
+
+\section{Caveats of Greiner-Hormann algorithm}
+
+To do.
+
+\section{Examples}
+
+To do.
+
+\section{Notes}
+
+Apart from \url{http://octave.sourceforge.net/octclip/index.html}, an up to date
+version of \octclip{} can be downloaded from
+\url{https://bitbucket.org/jgpallero/octclip/}.
+
+% \subsection{Geodetic to geocentric and vice versa}
+%
+% \begin{verbatim}
+% lon=-6*pi/180;lat=43*pi/180;h=1000;
+% [x,y,z]=op_geod2geoc(lon,lat,h,6378388,1/297)
+% x =  4647300.72326257
+% y = -488450.988568138
+% z =  4328259.36425774
+%
+% [lon,lat,h]=op_geoc2geod(x,y,z,6378388,1/297);
+% lon*=180/pi,lat*=180/pi,h
+% lon = -6
+% lat =  43
+% h =  1000.00000000074
+% \end{verbatim}
+%
+% \subsection{Forward and inverse projection}
+%
+% \begin{verbatim}
+% lon=-6*pi/180;lat=43*pi/180;
+% [x,y]=op_fwd(lon,lat,'+proj=utm +lon_0=3w +ellps=GRS80')
+% x =  255466.980547577
+% y =  4765182.93268401
+%
+% [lon,lat]=op_inv(x,y,'+proj=utm +lon_0=3w +ellps=GRS80');
+% lon*=180/pi,lat*=180/pi
+% lon = -6.00000000003597
+% lat =  42.9999999999424
+% \end{verbatim}
+%
+% \subsection{Forward and inverse projection: \texttt{op\_transform}}
+%
+% \subsubsection{With altitude}
+%
+% \begin{verbatim}
+% lon=-6*pi/180;lat=43*pi/180;h=1000;
+% [x,y,h]=op_transform(lon,lat,h,'+proj=latlong +ellps=GRS80',...
+%                      '+proj=utm +lon_0=3w +ellps=GRS80')
+% x =  255466.980547577
+% y =  4765182.93268401
+% h =  1000
+%
+% [lon,lat,h]=op_transform(x,y,h,...
+%                          '+proj=utm +lon_0=3w +ellps=GRS80',...
+%                          '+proj=latlong +ellps=GRS80');
+% lon*=180/pi,lat*=180/pi,h
+% lon = -6.00000000003597
+% lat =  42.9999999999424
+% h =  1000
+% \end{verbatim}
+%
+% \subsubsection{Without altitude}
+%
+% \begin{verbatim}
+% lon=-6*pi/180;lat=43*pi/180;
+% [x,y]=op_transform(lon,lat,'+proj=latlong +ellps=GRS80',...
+%                    '+proj=utm +lon_0=3w +ellps=GRS80')
+% x =  255466.980547577
+% y =  4765182.93268401
+%
+% [lon,lat]=op_transform(x,y,'+proj=utm +lon_0=3w +ellps=GRS80',...
+%                        '+proj=latlong +ellps=GRS80');
+% lon*=180/pi,lat*=180/pi
+% lon = -6.00000000003597
+% lat =  42.9999999999424
+% \end{verbatim}
+%
+% \subsection{Error due to an erroneous parameter}
+%
+% \begin{verbatim}
+% lon=-6*pi/180;lat=43*pi/180;
+% [x,y]=op_fwd(lon,lat,'+proj=utm +lon_0=3w +ellps=GRS8')
+% error:
+%         In function op_fwd:
+%         In function _op_fwd:
+%         Projection parameters
+%         unknown elliptical parameter name
+%         +proj=utm +lon_0=3w +ellps=GRS8
+% \end{verbatim}
+%
+% \subsection{Error due to latitude too big}
+%
+% \begin{verbatim}
+% lon=[-6*pi/180;-6*pi/180];lat=[43*pi/180;43];
+% [x,y]=op_fwd(lon,lat,'+proj=utm +lon_0=3w +ellps=GRS80')
+% warning: _op_fwd:
+%
+% warning: Projection error in point 2 (index starts at 1)
+% x =
+%
+%    255466.980547577
+%                 Inf
+%
+% y =
+%
+%    4765182.93268401
+%                 Inf
+% \end{verbatim}
+
+\begin{thebibliography}{99}
+\bibitem{eat-om} \textsc{Eaton}, John W.; \textsc{Bateman}, David, and
+                 \textsc{Hauberg}, S\o{}ren; \textit{GNU Octave. A high-level
+                 interactive language for numerical computations}; Edition 3 for
+                 Octave version 3.2.3; July 2007; Permanently updated at
+                 \url{http://www.gnu.org/software/octave/docs.html}.
+\bibitem{greiner1998} \textsc{Greiner}, G\"unter, and \textsc{Hormann}, Kai;
+                      \textit{Efficient clipping of arbitrary polygons};
+                      ACM Transactions on Graphics; Volume 17(2), April 1998;
+                      Pages 71--83.
+                      There is a web link with some example code at
+                      \url{http://davis.wpi.edu/~matt/courses/clipping/}.
+\bibitem{kim2006a} \textsc{Kim}, Dae Hyun, and \textsc{Kim}, Myoung-Jun;
+                   \textit{An Extension of Polygon Clipping To Resolve
+                           Degenerate Cases};
+                   Computer-Aided Design \& Applications; Vol. 3; Numbers 1--4,
+                   2006; Pages 447--456.
+\end{thebibliography}
+
+\end{document}
diff --git a/inst/oc_polybool.m b/inst/oc_polybool.m
new file mode 100644
index 0000000..2ed1608
--- /dev/null
+++ b/inst/oc_polybool.m
@@ -0,0 +1,265 @@
+## Copyright (C) 2011-2015, José Luis García Pallero, <jgpallero at gmail.com>
+##
+## This file is part of OctCLIP.
+##
+## OctCLIP is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn{Function File}{[@var{X}, at var{Y}, at var{nPol}, at var{nInt}, at var{nPert}] =}oc_polybool(@var{sub}, at var{clip}, at var{op})
+## @deftypefnx{Function File}{[@var{X}, at var{Y}, at var{nPol}, at var{nInt}, at var{nPert}] =}oc_polybool(@var{sub}, at var{clip})
+##
+## This function performs boolean operations between two polygons using the
+## Greiner-Hormann algorithm (http://davis.wpi.edu/~matt/courses/clipping/).
+##
+## @var{sub} is a two column matrix containing the X and Y coordinates of the
+## vertices for the subject polygon.
+##
+## @var{clip} is a two column matrix containing the X and Y coordinates of the
+## vertices for the clipper polygon.
+##
+## @var{op} is a text string containing the operation to perform between
+## @var{sub} and @var{clip}. Possible values are:
+##
+## @itemize @bullet
+## @item @var{'AND'}
+## Intersection of @var{sub} and @var{clip} (value by default).
+## @item @var{'OR'}
+## Union of @var{subt} and @var{clip}.
+## @item @var{'AB'}
+## Operation @var{sub} - @var{clip}.
+## @item @var{'BA'}
+## Operation of @var{clip} - @var{sub}.
+## @end itemize
+##
+## For the matrices @var{sub} and @var{clip}, the first point is not needed to
+## be repeated at the end (but is permitted). Pairs of (NaN,NaN) coordinates in
+## @var{sub} and/or @var{clip} are omitted, so they are treated as if each one
+## stored a single polygon.
+##
+## @var{X} is a column vector containing the X coordinates of the vertices of
+## the resultant polygon(s).
+##
+## @var{Y} is a column vector containing the Y coordinates of the vertices of
+## the resultant polygon(s).
+##
+## @var{nPol} is the number of output polygons.
+##
+## @var{nInt} is the number of intersections between @var{sub} and @var{clip}.
+##
+## @var{nPert} is the number of perturbed points of the @var{clip} polygon in
+## any particular case (points in the oborder of the other polygon) occurs see
+## http://davis.wpi.edu/~matt/courses/clipping/ for details.
+## @end deftypefn
+
+
+
+
+function [X,Y,nPol,nInt,nPert] = oc_polybool(sub,clip,op)
+
+try
+    functionName = 'oc_polybool';
+    minArg = 2;
+    maxArg = 3;
+
+%*******************************************************************************
+%NUMBER OF INPUT ARGUMENTS CHECKING
+%*******************************************************************************
+
+    %number of input arguments checking
+    if (nargin<minArg)||(nargin>maxArg)
+        error(['Incorrect number of input arguments (%d)\n\t         ',...
+               'Correct number of input arguments = %d or %d'],...
+              nargin,minArg,maxArg);
+    end
+    %check if we omit the op argument
+    if nargin==minArg
+        %by default, use AND
+        op = 'AND';
+    end
+
+%*******************************************************************************
+%INPUT ARGUMENTS CHECKING
+%*******************************************************************************
+
+    %checking input arguments
+    [op] = checkInputArguments(sub,clip,op);
+catch
+    %error message
+    error('\n\tIn function %s:\n\t -%s ',functionName,lasterr);
+end
+
+%*******************************************************************************
+%COMPUTATION
+%*******************************************************************************
+
+try
+    %calling oct function
+    [X,Y,nPol,nInt,nPert] = _oc_polybool(sub,clip,op);
+catch
+    %error message
+    error('\n\tIn function %s:\n\tIn function %s ',functionName,lasterr);
+end
+
+
+
+
+%*******************************************************************************
+%AUXILIARY FUNCTION
+%*******************************************************************************
+
+
+
+
+function [outOp] = checkInputArguments(sub,clip,inOp)
+
+%sub must be matrix type
+if isnumeric(sub)
+    %a dimensions
+    [rowSub,colSub] = size(sub);
+else
+    error('The first input argument is not numeric');
+end
+%clip must be matrix type
+if isnumeric(clip)
+    %b dimensions
+    [rowClip,colClip] = size(clip);
+else
+    error('The second input argument is not numeric');
+end
+%checking dimensions
+if (colSub~=2)||(colClip~=2)
+    error('The columns of input arguments must be 2');
+end
+%operation must be a text string
+if ~ischar(inOp)
+    error('The third input argument is not a text string');
+else
+    %upper case
+    outOp = toupper(inOp);
+    %check values
+    if (~strcmp(outOp,'AND'))&&(~strcmp(outOp,'OR'))&& ...
+        (~strcmp(outOp,'AB'))&&(~strcmp(outOp,'BA'))
+        error('The third input argument is not correct');
+    end
+end
+
+
+
+
+%*****END OF FUNCIONS*****
+
+
+
+
+%*****FUNCTION TESTS*****
+
+
+
+
+%tests for input arguments
+%!error(oc_polybool)
+%!error(oc_polybool(1,2,3,4))
+%!error(oc_polybool('string',2,3))
+%!error(oc_polybool(1,'string',3))
+%!error(oc_polybool(1,2,3))
+%demo program
+%!demo
+%!  %subject polygon
+%!  clSub = [9.0 7.5
+%!           9.0 3.0
+%!           2.0 3.0
+%!           2.0 4.0
+%!           8.0 4.0
+%!           8.0 5.0
+%!           2.0 5.0
+%!           2.0 6.0
+%!           8.0 6.0
+%!           8.0 7.0
+%!           2.0 7.0
+%!           2.0 7.5
+%!           9.0 7.5];
+%!  %clipper polygon
+%!  clClip = [2.5 1.0
+%!            7.0 1.0
+%!            7.0 8.0
+%!            6.0 8.0
+%!            6.0 2.0
+%!            5.0 2.0
+%!            5.0 8.0
+%!            4.0 8.0
+%!            4.0 2.0
+%!            3.0 2.0
+%!            3.0 8.0
+%!            2.5 8.0
+%!            2.5 1.0];
+%!  %limits for the plots
+%!  clXLim = [1.5 11.75];
+%!  clYLim = [0.5  8.50];
+%!  %compute intersection
+%!  [clXI,clYI] = oc_polybool(clSub,clClip,'and');
+%!  %compute union
+%!  [clXU,clYU] = oc_polybool(clSub,clClip,'or');
+%!  %compute A-B
+%!  [clXA,clYA] = oc_polybool(clSub,clClip,'ab');
+%!  %compute B-A
+%!  [clXB,clYB] = oc_polybool(clSub,clClip,'ba');
+%!  %plot window for intersection
+%!  subplot(2,2,1);
+%!  plot(clXI,clYI,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
+%!       clClip(:,1),clClip(:,2));
+%!  axis('equal');
+%!  xlim(clXLim);
+%!  ylim(clYLim);
+%!  title('OctCLIP intersection');
+%!  legend('Intersection','Subject polygon','Clipper polygon',...
+%!         'location','southeast');
+%!  %plot window for union
+%!  subplot(2,2,2);
+%!  plot(clXU,clYU,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
+%!       clClip(:,1),clClip(:,2));
+%!  axis('equal');
+%!  xlim(clXLim);
+%!  ylim(clYLim);
+%!  title('OctCLIP union');
+%!  legend('Union','Subject polygon','Clipper polygon','location','southeast');
+%!  %plot window for A-B
+%!  subplot(2,2,3);
+%!  plot(clXA,clYA,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
+%!       clClip(:,1),clClip(:,2));
+%!  axis('equal');
+%!  xlim(clXLim);
+%!  ylim(clYLim);
+%!  title('OctCLIP A-B');
+%!  legend('A-B','Subject polygon','Clipper polygon','location','southeast');
+%!  %plot window for B-A
+%!  subplot(2,2,4);
+%!  plot(clXB,clYB,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
+%!       clClip(:,1),clClip(:,2));
+%!  axis('equal');
+%!  xlim(clXLim);
+%!  ylim(clYLim);
+%!  title('OctCLIP B-A');
+%!  legend('B-A','Subject polygon','Clipper polygon','location','southeast');
+%!  %input message
+%!  disp('Press ENTER to continue ...');
+%!  pause();
+%!  %kill and close the plot window
+%!  clf();
+%!  close();
+
+
+
+
+%*****END OF TESTS*****
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..454d544
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+#Compiler
+MKOCTFILE=mkoctfile
+#Common warning flags for C and C++
+FLAGSCOMW=-Wall -Wextra -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings
+#Common optimization flags for C and C++
+FLAGSCOMO=-O2 -funroll-loops -fno-common -fshort-enums
+#Flags for C
+CFLAGS=-std=c99 -pedantic $(FLAGSCOMW) -Wconversion -Wmissing-prototypes
+CFLAGS+=-Wstrict-prototypes -Wnested-externs $(FLAGSCOMO)
+#Flags for C++
+CXXFLAGS=$(FLAGSCOMW) $(FLAGSCOMO)
+#Export flags for compilers and linker
+export CFLAGS CXXFLAGS
+
+.PHONY: all
+all: compile
+
+.PHONY: compile
+compile:
+	$(MKOCTFILE) -c -I. calctopo.c -o calctopo.o
+	$(MKOCTFILE) -c -I. compilador.c -o compilador.o
+	$(MKOCTFILE) -c -I. dpeucker.c -o dpeucker.o
+	$(MKOCTFILE) -c -I. errores.c -o errores.o
+	$(MKOCTFILE) -c -I. eucli.c -o eucli.o
+	$(MKOCTFILE) -c -I. fgeneral.c -o fgeneral.o
+	$(MKOCTFILE) -c -I. geocnan.c -o geocnan.o
+	$(MKOCTFILE) -c -I. geocomp.c -o geocomp.o
+	$(MKOCTFILE) -c -I. greiner.c -o greiner.o
+	$(MKOCTFILE) -c -I. polig.c -o polig.o
+	$(MKOCTFILE) -c -I. polil.c -o polil.o
+	$(MKOCTFILE) -c -I. ptopol.c -o ptopol.o
+	$(MKOCTFILE) -c -I. recpolil.c -o recpolil.o
+	$(MKOCTFILE) -c -I. segmento.c -o segmento.o
+	$(MKOCTFILE) -c -I. ventorno.c -o ventorno.o
+	$(MKOCTFILE) -s -I. _oc_polybool.cc *.o
+
+.PHONY: clean
+clean:
+	rm -rf *.o *~
+
+.PHONY: cleanall
+cleanall:
+	rm -rf *~ *.o *.oct
diff --git a/src/_oc_polybool.cc b/src/_oc_polybool.cc
new file mode 100644
index 0000000..bcee558
--- /dev/null
+++ b/src/_oc_polybool.cc
@@ -0,0 +1,241 @@
+/* -*- coding: utf-8 -*- */
+/* Copyright (C) 2011-2015  José Luis García Pallero, <jgpallero at gmail.com>
+ *
+ * This file is part of OctCLIP.
+ *
+ * OctCLIP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+/******************************************************************************/
+/******************************************************************************/
+#define HELPTEXT "\
+-*- texinfo -*-\n\
+ at deftypefn{Loadable Function}{[@var{X}, at var{Y}, at var{nPol}, at var{nInt},\
+ at var{nPert}] =}_oc_polybool(@var{sub}, at var{clip}, at var{op})\n\
+\n\
+ at cindex Performs boolean operations between two polygons.\n\
+\n\
+This function performs boolean operations between two polygons using the\n\
+Greiner-Hormann algorithm (http://davis.wpi.edu/~matt/courses/clipping/).\n\
+\n\
+ at var{sub} is a two column matrix containing the X and Y coordinates of the\n\
+vertices for the subject polygon.\n\n\
+ at var{clip} is a two column matrix containing the X and Y coordinates of the\n\
+vertices for the clipper polygon.\n\n\
+ at var{op} is a text string containing the operation to perform between\n\
+ at var{sub} and @var{clip}. Possible values are:\n\
+\n\
+ at itemize @bullet\n\
+ at item @var{'AND'}\n\
+Intersection of @var{sub} and @var{clip}.\n\n\
+ at item @var{'OR'}\n\
+Union of @var{subt} and @var{clip}.\n\n\
+ at item @var{'AB'}\n\
+Operation @var{sub} - @var{clip}.\n\n\
+ at item @var{'BA'}\n\
+Operation of @var{clip} - @var{sub}.\n\
+ at end itemize\n\
+\n\
+For the matrices @var{sub} and @var{clip}, the first point is not needed to\n\
+be repeated at the end (but is permitted). Pairs of (NaN,NaN) coordinates in\n\
+ at var{sub} and/or @var{clip} are omitted, so they are treated as if each one\n\
+stored a single polygon.\n\
+\n\
+ at var{X} is a column vector containing the X coordinates of the vertices of\n\
+the resultant polygon(s).\n\n\
+ at var{Y} is a column vector containing the Y coordinates of the vertices of\n\
+the resultant polygon(s).\n\n\
+ at var{nPol} is the number of output polygons.\n\n\
+ at var{nInt} is the number of intersections between @var{sub} and @var{clip}.\n\n\
+ at var{nPert} is the number of perturbed points of the @var{clip} polygon in\n\
+any particular case (points in the oborder of the other polygon) occurs see\n\
+http://davis.wpi.edu/~matt/courses/clipping/ for details.\n\
+\n\
+This function do not check if the dimensions of @var{sub} and @var{clip} are\n\
+correct.\n\
+\n\
+ at end deftypefn"
+/******************************************************************************/
+/******************************************************************************/
+#include<octave/oct.h>
+#include<cstdio>
+#include<cstring>
+#include<cstdlib>
+#include<cmath>
+#include"octclip.h"
+/******************************************************************************/
+/******************************************************************************/
+#define ERRORTEXT 1000
+/******************************************************************************/
+/******************************************************************************/
+DEFUN_DLD(_oc_polybool,args,,HELPTEXT)
+{
+    //error message
+    char errorText[ERRORTEXT+1]="_oc_polybool:\n\t";
+    //output list
+    octave_value_list outputList;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //checking input arguments
+    if(args.length()!=3)
+    {
+        //error text
+        sprintf(&errorText[strlen(errorText)],
+                "Incorrect number of input arguments\n\t"
+                "See help _oc_polybool");
+        //error message
+        error(errorText);
+    }
+    else
+    {
+        //loop index
+        size_t i=0;
+        //polygons and operation
+        ColumnVector xSubj=args(0).matrix_value().column(0);
+        ColumnVector ySubj=args(0).matrix_value().column(1);
+        ColumnVector xClip=args(1).matrix_value().column(0);
+        ColumnVector yClip=args(1).matrix_value().column(1);
+        std::string opchar=args(2).string_value();
+        //computation vectors
+        double* xA=NULL;
+        double* yA=NULL;
+        double* xB=NULL;
+        double* yB=NULL;
+        //double linked lists
+        vertPoliClip* polA=NULL;
+        vertPoliClip* polB=NULL;
+        //operation identifier
+        enum GEOC_OP_BOOL_POLIG op=GeocOpBoolInter;
+        //output struct
+        polig* result=NULL;
+        //number of polygons, intersections and perturbations
+        size_t nPol=0,nInter=0,nPert=0;
+        //number of elements for the output vectors
+        size_t nElem=0;
+        ////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////
+        //pointers to data
+        xA = xSubj.fortran_vec();
+        yA = ySubj.fortran_vec();
+        xB = xClip.fortran_vec();
+        yB = yClip.fortran_vec();
+        //create double linked lists for subject and clipper polygons
+        polA = CreaPoliClip(xA,yA,static_cast<size_t>(xSubj.length()),1,1);
+        polB = CreaPoliClip(xB,yB,static_cast<size_t>(xClip.length()),1,1);
+        //error checking
+        if((polB==NULL)||(polB==NULL))
+        {
+            //free peviously allocated memory
+            LibMemPoliClip(polA);
+            LibMemPoliClip(polB);
+            //error text
+            sprintf(&errorText[strlen(errorText)],"Error in memory allocation");
+            //error message
+            error(errorText);
+            //exit
+            return outputList;
+        }
+        ////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////
+        //select operation
+        if((!strcmp(opchar.c_str(),"AND"))||(!strcmp(opchar.c_str(),"and")))
+        {
+            op = GeocOpBoolInter;
+        }
+        else if((!strcmp(opchar.c_str(),"OR"))||(!strcmp(opchar.c_str(),"or")))
+        {
+            op = GeocOpBoolUnion;
+        }
+        else if((!strcmp(opchar.c_str(),"AB"))||(!strcmp(opchar.c_str(),"ab")))
+        {
+            op = GeocOpBoolAB;
+        }
+        else if((!strcmp(opchar.c_str(),"BA"))||(!strcmp(opchar.c_str(),"ba")))
+        {
+            op = GeocOpBoolBA;
+        }
+        else
+        {
+            //free peviously allocated memory
+            LibMemPoliClip(polA);
+            LibMemPoliClip(polB);
+            //error text
+            sprintf(&errorText[strlen(errorText)],
+                    "The third input argument (op=%s) is not correct",
+                    opchar.c_str());
+            //error message
+            error(errorText);
+            //exit
+            return outputList;
+        }
+        ////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////
+        //clipping
+        result = PoliBoolGreiner(polA,polB,op,GEOC_GREINER_FAC_EPS_PERTURB,
+                                 &nInter,&nPert);
+        //error checking
+        if(result==NULL)
+        {
+            //free peviously allocated memory
+            LibMemPoliClip(polA);
+            LibMemPoliClip(polB);
+            //error text
+            sprintf(&errorText[strlen(errorText)],"Error in memory allocation");
+            //error message
+            error(errorText);
+            //exit
+            return outputList;
+        }
+        ////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////
+        //number or output polygons
+        nPol = result->nPolig;
+        //dimensions for the output vectors
+        if(nPol)
+        {
+            nElem = result->nElem;
+        }
+        else
+        {
+            nElem = 0;
+        }
+        //output vectors
+        ColumnVector xResult(nElem);
+        ColumnVector yResult(nElem);
+        //copy output data
+        for(i=0;i<nElem;i++)
+        {
+            xResult(i) = result->x[i];
+            yResult(i) = result->y[i];
+        }
+        ////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////
+        //output parameters list
+        outputList(0) = xResult;
+        outputList(1) = yResult;
+        outputList(2) = nPol;
+        outputList(3) = nInter;
+        outputList(4) = nPert;
+        ////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////
+        //free memory
+        LibMemPoliClip(polA);
+        LibMemPoliClip(polB);
+        LibMemPolig(result);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //exit
+    return outputList;
+}
diff --git a/src/calctopo.c b/src/calctopo.c
new file mode 100644
index 0000000..ab3c595
--- /dev/null
+++ b/src/calctopo.c
@@ -0,0 +1,71 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geodesia geom
+@{
+\file calctopo.c
+\brief Definición de funciones para cálculos de topografía.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 05 de julio de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/calctopo.h"
+/******************************************************************************/
+/******************************************************************************/
+double AcimutTopografico(const double x1,
+                         const double y1,
+                         const double x2,
+                         const double y2)
+{
+    //acimut calculado
+    double acimut=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el acimut en el dominio [-pi pi]
+    acimut = atan2(x2-x1,y2-y1);
+    //comprobamos si ha salido un valor negativo
+    if(acimut<0.0)
+    {
+        //metemos el valor en dominio
+        acimut += 2.0*GEOC_CONST_PI;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return acimut;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/compilador.c b/src/compilador.c
new file mode 100755
index 0000000..aa35e74
--- /dev/null
+++ b/src/compilador.c
@@ -0,0 +1,82 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup general geopot
+@{
+\file compilador.c
+\brief Definición de funciones para la detección de compiladores.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 28 de abril de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/compilador.h"
+/******************************************************************************/
+/******************************************************************************/
+int EsCompiladorGNU(int* noGnu)
+{
+    //variable de salida
+    int salida=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable noGnu, si ha lugar
+    if(noGnu!=NULL)
+    {
+        //inicializamos la variable a 0
+        *noGnu = 0;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //para que sea GCC, la constante __GNUC__ ha de estar definida
+#if defined(__GNUC__)
+    //el compilador es GCC
+    salida = 1;
+        //comprobamos si es el compilador de intel
+#if defined(__INTEL_COMPILER)
+    if(noGnu!=NULL)
+    {
+        //el compilador es de intel
+        *noGnu = 1;
+    }
+#endif
+#endif
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/dpeucker.c b/src/dpeucker.c
new file mode 100644
index 0000000..f63f53d
--- /dev/null
+++ b/src/dpeucker.c
@@ -0,0 +1,472 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom
+@{
+\file dpeucker.c
+\brief Definición de funciones para el aligerado de polilíneas basadas en el
+       algoritmo de Douglas-Peucker.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 04 de julio de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/dpeucker.h"
+/******************************************************************************/
+/******************************************************************************/
+size_t* AligeraPolilinea(const double* x,
+                         const double* y,
+                         const size_t nPtos,
+                         const size_t incX,
+                         const size_t incY,
+                         const double tol,
+                         const enum GEOC_DPEUCKER_ROBUSTO robusto,
+                         const size_t nPtosRobusto,
+                         const size_t nSegRobusto,
+                         size_t* nPtosSal)
+{
+    //índice para recorrer bucles
+    size_t p=0;
+    //índice de los puntos de trabajo
+    size_t i=0,j=0,k=0;
+    //coordenadas de trabajo
+    double xIni=0.0,yIni=0.0,xFin=0.0,yFin=0.0,xTrab=0.0,yTrab=0.0;
+    //altura del triángulo de trabajo
+    double h=0.0;
+    //variable indicadora de punto a mantener
+    int usado=0;
+    //número de elementos de trabajo internos del vector de salida
+    size_t nElem=0;
+    //vector de salida
+    size_t* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //iniciamos la variable de salida de número de puntos a 0
+    *nPtosSal = 0;
+    //comprobamos casos especiales de nPtos
+    if(nPtos==0)
+    {
+        //salimos de la función con NULL
+        return NULL;
+    }
+    else if(nPtos<=2)
+    {
+        //asignamos el número de puntos usados
+        *nPtosSal = nPtos;
+        //asignamos memoria para el vector de salida
+        sal = (size_t*)malloc((*nPtosSal)*sizeof(size_t));
+        //comprobamos los posibles errores
+        if(sal==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //asignamos valores al vector de salida
+        for(i=0;i<(*nPtosSal);i++)
+        {
+            //asignamos el índice de trabajo
+            sal[i] = i;
+        }
+        //salimos de la función
+        return sal;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el indicador interno de tamaño del vector
+    nElem = GEOC_DPEUCKER_BUFFER_PTOS;
+    //asignamos memoria para el vector de salida
+    sal = (size_t*)malloc(nElem*sizeof(size_t));
+    //comprobamos los posibles errores
+    if(sal==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //indicamos que el primer punto siempre se usa
+    *nPtosSal = 1;
+    sal[0] = 0;
+    //puntos de trabajo para iniciar los cálculos
+    i = 0;
+    j = 1;
+    k = 2;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //entramos en un bucle infinito
+    while(1)
+    {
+        //comprobamos si hay que salir del bucle
+        if(k>(nPtos-1))
+        {
+            //salimos del bucle
+            break;
+        }
+        //coordenadas de la base del triángulo
+        xIni = x[i*incX];
+        yIni = y[i*incY];
+        xFin = x[k*incX];
+        yFin = y[k*incY];
+        //inicializamos a 0 la variable de punto usado
+        usado = 0;
+        //recorremos los puntos a testear
+        for(p=j;p<k;p++)
+        {
+            //coordenadas del vértice del triángulo
+            xTrab = x[p*incX];
+            yTrab = y[p*incY];
+            //calculamos la altura del triángulo
+            h = AlturaTriangulo(xTrab,yTrab,xIni,yIni,xFin,yFin);
+            //comprobamos si la altura supera a la tolerancia
+            if(h>tol)
+            {
+                //indicamos que el punto ha sido usado
+                usado = 1;
+                //comprobamos si se utiliza el algoritmo robusto
+                if(robusto!=GeocDPeuckerRobNo)
+                {
+                    //comprobamos si hay que aplicar el algoritmo de
+                    //intersección con puntos originales
+                    if((robusto==GeocDPeuckerRobSi)||
+                       (robusto==GeocDPeuckerRobOrig))
+                    {
+                        //aplicamos el algoritmo
+                        AligPolilRobIntersecOrig(x,y,nPtos,incX,incY,
+                                                 nPtosRobusto,i,&p);
+                    }
+                    //comprobamos si hay que aplicar el algoritmo de auto
+                    //intersección
+                    if((robusto==GeocDPeuckerRobSi)||
+                       (robusto==GeocDPeuckerRobAuto))
+                    {
+                        //indicamos un número de puntos para el vector de salida
+                        //una unidad menor que el número realmente almacenado
+                        //para evitar el segmento inmediatamente anterior al que
+                        //vamos a crear
+                        AligPolilRobAutoIntersec(x,y,incX,incY,sal,
+                                                 (*nPtosSal)-1,nSegRobusto,i,
+                                                 &p);
+                    }
+                }
+                //añadimos al contador este nuevo punto
+                (*nPtosSal)++;
+                //comprobamos si hay que reasignar memoria
+                if((*nPtosSal)>nElem)
+                {
+                    //añadimos otro grupo de puntos
+                    nElem += GEOC_DPEUCKER_BUFFER_PTOS;
+                    //asignamos memoria para el vector de salida
+                    sal = (size_t*)realloc(sal,nElem*sizeof(size_t));
+                    //comprobamos los posibles errores
+                    if(sal==NULL)
+                    {
+                        //mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                }
+                //añadimos el nuevo punto usado
+                sal[(*nPtosSal)-1] = p;
+                //actualizamos los índices de los puntos de trabajo
+                i = p;
+                j = i+1;
+                k = j+1;
+                //salimos del bucle
+                break;
+            }
+        }
+        //comprobamos si no se ha utilizado ninguno de los vértices candidatos
+        if(!usado)
+        {
+            //pasamos al siguiente punto como extremo del segmento
+            k++;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el último punto se ha añadido
+    if(sal[(*nPtosSal)-1]!=(nPtos-1))
+    {
+        //añadimos al contador el último punto
+        (*nPtosSal)++;
+        //comprobamos si hay que reasignar memoria
+        if((*nPtosSal)>nElem)
+        {
+            //añadimos otro grupo de puntos
+            nElem += GEOC_DPEUCKER_BUFFER_PTOS;
+            //asignamos memoria para el vector de salida
+            sal = (size_t*)realloc(sal,nElem*sizeof(size_t));
+            //comprobamos los posibles errores
+            if(sal==NULL)
+            {
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+        }
+        //asignamos el último punto
+        sal[(*nPtosSal)-1] = nPtos-1;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el vector de salida tiene demasiada memoria asignada
+    if(nElem>(*nPtosSal))
+    {
+        //ajustamos el tamaño del vector de salida
+        sal = (size_t*)realloc(sal,(*nPtosSal)*sizeof(size_t));
+        //comprobamos los posibles errores
+        if(sal==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AligPolilRobIntersecOrig(const double* x,
+                              const double* y,
+                              const size_t nPtos,
+                              const size_t incX,
+                              const size_t incY,
+                              const size_t ptosAUsar,
+                              const size_t posIni,
+                              size_t* posFin)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //coordenadas de trabajo
+    double xA=0.0,yA=0.0,xB=0.0,yB=0.0,xC=0.0,yC=0.0,xD=0.0,yD=0.0;
+    //punto de parada para comprobar la intersección de segmentos
+    size_t parada=0;
+    //identificador de intersección
+    int inter=0;
+    //variables auxiliares
+    size_t aux=0;
+    double xAux=0.0,yAux=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contemplamos una posible salida rápida
+    if((*posFin)<=(posIni+1))
+    {
+        //salimos de la función
+        return;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el número de puntos que quedan hasta el final de los vectores
+    //de coordenadas desde la posición de fin de segmento (contándola)
+    aux = nPtos-(*posFin);
+    //calculamos el punto de parada para la intersección de segmentos
+    if((aux>ptosAUsar)&&(ptosAUsar!=0))
+    {
+        //paramos en un pnto tal que usemos ptosAUsar puntos
+        parada = *posFin+ptosAUsar-1;
+    }
+    else
+    {
+        //paramos en el penúltimo punto
+        parada = nPtos-2;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //las coordenadas del punto inicial del segmento base no cambian nunca
+    xA = x[posIni*incX];
+    yA = y[posIni*incY];
+    //recorremos los puntos candidatos hasta el anterior al punto base
+    for(i=(*posFin);i>posIni;i--)
+    {
+        //comprobamos si estamos ante el punto posterior al inicial
+        if(i==(posIni+1))
+        {
+            //terminamos, porque este punto es el siguiente al punto base en el
+            //listado original
+            *posFin = i;
+            //salimos del bucle
+            break;
+        }
+        else
+        {
+            //coordenadas de los puntos inicial y final del segmento base
+            xB = x[i*incX];
+            yB = y[i*incY];
+            //recorremos los puntos posteriores hasta el de parada
+            for(j=i;j<=parada;j++)
+            {
+                //coordenadas de los puntos inicial y final del siguiente
+                //segmento
+                xC = x[j*incX];
+                yC = y[j*incY];
+                xD = x[(j+1)*incX];
+                yD = y[(j+1)*incY];
+                //calculamos la intersección entre los segmentos
+                inter = IntersecSegmentos2D(xA,yA,xB,yB,xC,yC,xD,yD,&xAux,
+                                            &yAux);
+                //comprobamos si hay intersección entre los segmentos
+                if(inter!=GEOC_SEG_NO_INTERSEC)
+                {
+                    //salimos del bucle
+                    break;
+                }
+            }
+            //comprobamos si no ha habido ninguna intersección
+            if(inter==GEOC_SEG_NO_INTERSEC)
+            {
+                //indicamos el índice del vértice final
+                *posFin = i;
+                //salimos del bucle
+                break;
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AligPolilRobAutoIntersec(const double* x,
+                              const double* y,
+                              const size_t incX,
+                              const size_t incY,
+                              const size_t* posAlig,
+                              const size_t nPosAlig,
+                              const size_t segAUsar,
+                              const size_t posIni,
+                              size_t* posFin)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //variables de posición
+    size_t k=0,l=0,pos=0;
+    //coordenadas de trabajo
+    double xA=0.0,yA=0.0,xB=0.0,yB=0.0,xC=0.0,yC=0.0,xD=0.0,yD=0.0;
+    //número de segmentos calculados hasta ahora, excepto el último
+    size_t nSeg=0;
+    //identificador de intersección
+    int inter=0;
+    //variables auxiliares
+    double xAux=0.0,yAux=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contemplamos una posible salida rápida
+    if(((*posFin)<=(posIni+1))||(nPosAlig<2))
+    {
+        //salimos de la función
+        return;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el número de segmentos calculados hasta ahora, excepto el
+    //anterior al de trabajo
+    nSeg = nPosAlig-1;
+    //comprobamos si se usan todos los segmentos o sólo parte
+    if(segAUsar!=0)
+    {
+        //asignamos el número de segmentos a utilizar
+        nSeg = (nSeg>segAUsar) ? segAUsar : nSeg;
+    }
+    //las coordenadas del punto inicial del segmento base no cambian nunca
+    xA = x[posIni*incX];
+    yA = y[posIni*incY];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos los puntos candidatos hasta el anterior al punto base
+    for(i=(*posFin);i>posIni;i--)
+    {
+        //comprobamos si estamos ante el punto posterior al inicial
+        if(i==(posIni+1))
+        {
+            //terminamos, porque este punto es el siguiente al punto inicial
+            *posFin = i;
+            //salimos del bucle
+            break;
+        }
+        else
+        {
+            //coordenadas del punto final del segmento base
+            xB = x[i*incX];
+            yB = y[i*incY];
+            //recorremos el número de segmentos de trabajo
+            for(j=0;j<nSeg;j++)
+            {
+                //posición del punto inicial del siguiente segmento anterior
+                pos = nPosAlig-1-j;
+                //índices inicial y final del siguiente segmento anterior
+                k = posAlig[pos];
+                l = posAlig[pos-1];
+                //puntos inicial y final del siguiente segmento
+                xC = x[k*incX];
+                yC = y[k*incY];
+                xD = x[l*incX];
+                yD = y[l*incY];
+                //calculamos la intersección entre los segmentos
+                inter = IntersecSegmentos2D(xA,yA,xB,yB,xC,yC,xD,yD,&xAux,
+                                            &yAux);
+                //comprobamos si hay intersección entre los segmentos
+                if(inter!=GEOC_SEG_NO_INTERSEC)
+                {
+                    //salimos del bucle
+                    break;
+                }
+            }
+            //comprobamos si no ha habido ninguna intersección
+            if(inter==GEOC_SEG_NO_INTERSEC)
+            {
+                //indicamos el índice del vértice final
+                *posFin = i;
+                //salimos del bucle
+                break;
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/errores.c b/src/errores.c
new file mode 100755
index 0000000..4b7788a
--- /dev/null
+++ b/src/errores.c
@@ -0,0 +1,119 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup anespec errores eop fichero general geodesia geom geopot gshhs marea
+\ingroup matriz mmcc orden snx texto
+@{
+\file errores.c
+\brief Definición de funciones para el tratamiento de errores.
+
+En el momento de la compilación ha de seleccionarse el comportamiento de la
+función \ref GeocError. Para realizar la selección es necesario definir las
+variables para el preprocesador \em ESCRIBE_MENSAJE_ERROR si se quiere que la
+función imprima un mensaje de error y/o \em FIN_PROGRAMA_ERROR si se quiere que
+la función termine la ejecución del programa en curso. Si no se define ninguna
+variable, la función no ejecuta ninguna acción. En \p gcc, las variables para el
+preprocesador se pasan como \em -DXXX, donde \em XXX es la variable a
+introducir.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 09 de enero de 2011
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/errores.h"
+/******************************************************************************/
+/******************************************************************************/
+int GeocTipoError(void)
+{
+    //variable de salida
+    int valor=GEOC_TIPO_ERR_NADA;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //distinguimos los posibles casos según las variables del preprocesador
+#if defined(ESCRIBE_MENSAJE_ERROR) && defined(FIN_PROGRAMA_ERROR)
+    //mensaje de error y terminación del programa
+    valor = GEOC_TIPO_ERR_MENS_Y_EXIT;
+#elif defined(ESCRIBE_MENSAJE_ERROR)
+    //mensaje de error
+    valor = GEOC_TIPO_ERR_MENS;
+#elif defined(FIN_PROGRAMA_ERROR)
+    //terminación del programa
+    valor = GEOC_TIPO_ERR_EXIT;
+#endif
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return valor;
+}
+/******************************************************************************/
+/******************************************************************************/
+void GeocError(const char mensaje[],
+               const char funcion[])
+{
+    //hacemos una copia para que en la compilación no dé warning si sólo se
+    //termina la ejecución del programa o no se hace nada
+    mensaje = mensaje;
+    funcion = funcion;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //distinguimos los posibles casos según las variables del preprocesador
+#if defined(ESCRIBE_MENSAJE_ERROR) && defined(FIN_PROGRAMA_ERROR)
+    //imprimimos el nombre de la función y el mensaje
+    fprintf(stderr,"En la función '%s'\n",funcion);
+    fprintf(stderr,"%s\n",mensaje);
+    //indicamos que el programa finalizará
+    fprintf(stderr,"El programa finalizará mediante la llamada a la función "
+                   "'exit(EXIT_FAILURE)'\n");
+    //detenemos la ejecución del programa
+    exit(EXIT_FAILURE);
+#elif defined(ESCRIBE_MENSAJE_ERROR)
+    //imprimimos el nombre de la función y el mensaje
+    fprintf(stderr,"En la función '%s'\n",funcion);
+    fprintf(stderr,"%s\n",mensaje);
+    //salimos de la función
+    return;
+#elif defined(FIN_PROGRAMA_ERROR)
+    //indicamos que el programa finalizará
+    fprintf(stderr,"El programa finalizará mediante la llamada a la función "
+                   "'exit(EXIT_FAILURE)'\n");
+    //detenemos la ejecución del programa
+    exit(EXIT_FAILURE);
+#else
+    //salimos de la función
+    return;
+#endif
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/eucli.c b/src/eucli.c
new file mode 100755
index 0000000..fcd8cd7
--- /dev/null
+++ b/src/eucli.c
@@ -0,0 +1,238 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom interp
+@{
+\file eucli.c
+\brief Definición de funciones para la realización de cálculos de geometría
+       euclídea.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 27 de octubre de 2009
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/eucli.h"
+/******************************************************************************/
+/******************************************************************************/
+double Dist2D(const double x1,
+              const double y1,
+              const double x2,
+              const double y2)
+{
+    //calculamos y salimos de la función
+    return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
+}
+/******************************************************************************/
+/******************************************************************************/
+void Dist2DVC(const double x1,
+              const double y1,
+              const double x2,
+              const double y2,
+              const double varx1,
+              const double varx1y1,
+              const double vary1,
+              const double varx2,
+              const double varx2y2,
+              const double vary2,
+              double* dist,
+              double* varDist)
+{
+    //matrices auxiliares
+    double j[4],jvc[4];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos la distancia
+    *dist = Dist2D(x1,y1,x2,y2);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //rellenamos la matriz jacobiana
+    j[0] = -(x2-x1)/(*dist);
+    j[1] = -(y2-y1)/(*dist);
+    j[2] = -j[0];
+    j[3] = -j[1];
+    //producto de la matriz jacobiana por la matriz de varianza-covarianza
+    jvc[0] = j[0]*varx1+j[1]*varx1y1;
+    jvc[1] = j[0]*varx1y1+j[1]*vary1;
+    jvc[2] = j[2]*varx2+j[3]*varx2y2;
+    jvc[3] = j[2]*varx2y2+j[3]*vary2;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //realizamos la propagación de errores
+    *varDist = jvc[0]*j[0]+jvc[1]*j[1]+jvc[2]*j[2]+jvc[3]*j[3];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+double Dist3D(const double x1,
+              const double y1,
+              const double z1,
+              const double x2,
+              const double y2,
+              const double z2)
+{
+    //calculamos y salimos de la función
+    return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
+}
+/******************************************************************************/
+/******************************************************************************/
+void Dist3DVC(const double x1,
+              const double y1,
+              const double z1,
+              const double x2,
+              const double y2,
+              const double z2,
+              const double varx1,
+              const double varx1y1,
+              const double varx1z1,
+              const double vary1,
+              const double vary1z1,
+              const double varz1,
+              const double varx2,
+              const double varx2y2,
+              const double varx2z2,
+              const double vary2,
+              const double vary2z2,
+              const double varz2,
+              double* dist,
+              double* varDist)
+{
+    //matrices auxiliares
+    double j[6],jvc[6];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos la distancia
+    *dist = Dist3D(x1,y1,z1,x2,y2,z2);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //rellenamos la matriz jacobiana
+    j[0] = -(x2-x1)/(*dist);
+    j[1] = -(y2-y1)/(*dist);
+    j[2] = -(z2-z1)/(*dist);
+    j[3] = -j[0];
+    j[4] = -j[1];
+    j[5] = -j[2];
+    //producto de la matriz jacobiana por la matriz de varianza-covarianza
+    jvc[0] = j[0]*varx1+j[1]*varx1y1+j[2]*varx1z1;
+    jvc[1] = j[0]*varx1y1+j[1]*vary1+j[2]*vary1z1;
+    jvc[2] = j[0]*varx1z1+j[1]*vary1z1+j[2]*varz1;
+    jvc[3] = j[3]*varx2+j[4]*varx2y2+j[5]*varx2z2;
+    jvc[4] = j[3]*varx2y2+j[4]*vary2+j[5]*vary2z2;
+    jvc[5] = j[3]*varx2z2+j[4]*vary2z2+j[5]*varz2;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //realizamos la propagación de errores
+    *varDist = jvc[0]*j[0]+jvc[1]*j[1]+jvc[2]*j[2]+jvc[3]*j[3]+jvc[4]*j[4]+
+               jvc[5]*j[5];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+double AnguloVecPlano(const double x1,
+                      const double y1,
+                      const double x2,
+                      const double y2)
+{
+    //variables auxiliares
+    double num=0.0,den=0.0;
+    //variable de salida
+    double alfa=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el numerador de la fórmula que da el coseno del ángulo
+    num = x1*x2+y1*y2;
+    //calculamos el denominador de la fórmula que da el coseno del ángulo
+    den = sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2));
+    //calculamos el coseno del ángulo, teniendo en cuenta casos singulares
+    if(den==0.0)
+    {
+        //si el denominador es 0.0, el ángulo es 0.0 y su coseno 1.0
+        alfa = 1.0;
+    }
+    else
+    {
+        //no hay singularidad
+        alfa = num/den;
+    }
+    //calculamos el ángulo
+    alfa = acos(alfa);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return alfa;
+}
+/******************************************************************************/
+/******************************************************************************/
+double AlturaTriangulo(const double xVert,
+                       const double yVert,
+                       const double xBase1,
+                       const double yBase1,
+                       const double xBase2,
+                       const double yBase2)
+{
+    //ángulo entra la base en el punto 1 y el vértice
+    double alfa=0.0;
+    //longitud del punto 1 de la base al vértice
+    double lon=0.0;
+    //variables auxiliares
+    double dxv=0.0,dyv=0.0,dxb=0.0,dyb=0.0;
+    //variable de salida
+    double h=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos los incrementos de coordenadas auxiliares
+    dxv = xVert-xBase1;
+    dyv = yVert-yBase1;
+    dxb = xBase2-xBase1;
+    dyb = yBase2-yBase1;
+    //calculamos el ángulo entre la base y el segmento que une el punto inicial
+    //de ésta con el vértice
+    alfa = AnguloVecPlano(dxv,dyv,dxb,dyb);
+    //longitud del lado que une la base con el vértice 1 de la base
+    lon = sqrt(dxv*dxv+dyv*dyv);
+    //calculamos la altura
+    h = fabs(lon*sin(alfa));
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return h;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/fgeneral.c b/src/fgeneral.c
new file mode 100755
index 0000000..c048f42
--- /dev/null
+++ b/src/fgeneral.c
@@ -0,0 +1,880 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup eop general geom geopot matriz
+@{
+\file fgeneral.c
+\brief Definición de funciones de utilidad general.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 10 de octubre de 2009
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/fgeneral.h"
+/******************************************************************************/
+/******************************************************************************/
+int GeocParOmpFgeneral(char version[])
+{
+    //comprobamos si hay paralelización
+#if defined(_OPENMP)
+    //comprobamos si hay que extraer versión
+    if(version!=NULL)
+    {
+        //calculamos la versión
+        VersionOpenMP(_OPENMP,version);
+    }
+    //salimos de la función
+    return 1;
+#else
+    if(version!=NULL)
+    {
+        //utilizamos la variable version para que no dé warming al compilar
+        strcpy(version,"");
+    }
+    //salimos de la función
+    return 0;
+#endif
+}
+/******************************************************************************/
+/******************************************************************************/
+double PonAnguloDominio(const double angulo)
+{
+    //signo del ángulo de trabajo
+    double signo=0.0;
+    //2.0*pi
+    double dosPi=2.0*GEOC_CONST_PI;
+    //variable auxiliar
+    double aux=angulo;
+    //variable de salida
+    double sal=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //sólo trabajamos si el valor de entrada está fuera de los límites
+    if((angulo<=-dosPi)||(angulo>=dosPi))
+    {
+        //extraemos el signo del ángulo pasado
+        signo = GEOC_SIGNO(angulo);
+        //valor absoluto del ángulo pasado
+        aux = fabs(angulo);
+        //metemos el ángulo en dominio eliminando la cantidad que se pase de
+        //2.0*pi
+        sal = signo*(aux-floor(aux/dosPi)*dosPi);
+    }
+    else
+    {
+        //el valor de entrada no cambia
+        sal = angulo;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+void BuscaSegmento1DInc(const double valor,
+                        const double* lista,
+                        const size_t nDatos,
+                        const size_t incDatos,
+                        size_t* posInicio,
+                        size_t* posFin)
+{
+    //variable para recorrer bucles
+    size_t i=0;
+    //variable indicadora de búsqueda secuencial
+    int busca=0;
+    //variables para calcular posiciones
+    size_t pos1=0,pos2=0;
+    //posiciones en memoria
+    size_t posm=0,pos1m=0,pos2m=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //CONSIDERAMOS QUE LA LISTA CONTIENE ENTEROS EQUIESPACIADOS UNA UNIDAD
+    //posición del valor anterior al de trabajo
+    pos1 = (size_t)(floor(valor)-lista[0]);
+    //posición del valor posterior al de trabajo
+    pos2 = (size_t)(ceil(valor)-lista[0]);
+    //si pos1==pos2, valor puede ser un extremo de la lista
+    if(pos1==pos2)
+    {
+        if(pos1!=(nDatos-1))
+        {
+            //calculamos el punto final del segmento
+            pos2++;
+        }
+        else
+        {
+            //calculamos el punto inicial del segmento
+            pos1--;
+        }
+    }
+    //calculamos las posiciones en memoria
+    pos1m = pos1*incDatos;
+    pos2m = pos2*incDatos;
+    //comprobamos si el segmento detectado es válido
+    if((lista[pos1m]!=round(lista[pos1m]))||
+       (lista[pos2m]!=round(lista[pos2m]))||
+       ((lista[pos2m]-lista[pos1m])!=1.0)||
+       (valor<lista[pos1m])||(valor>lista[pos2m]))
+    {
+        //indicamos que se ha de hacer una búsqueda secuencial
+        busca = 1;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //LA LISTA CONTIENE REALES NO EQUIESPACIADOS
+    if(busca)
+    {
+        //recorremos todos los elementos de la lista
+        for(i=0;i<nDatos;i++)
+        {
+            //posición en memoria
+            posm = i*incDatos;
+            //comprobamos si estamos ante un límite
+            if(lista[posm]>=valor)
+            {
+                //comprobamos el tipo de límite
+                if(lista[posm]>valor)
+                {
+                    //extraemos las posiciones
+                    pos1 = i-1;
+                    pos2 = i;
+                }
+                else
+                {
+                    //comprobamos si estamos trabajando con el último elemento
+                    if(i==(nDatos-1))
+                    {
+                        //extraemos las posiciones
+                        pos1 = i-1;
+                        pos2 = i;
+                    }
+                    else
+                    {
+                        //extraemos las posiciones
+                        pos1 = i;
+                        pos2 = i+1;
+                    }
+                }
+                //salimos del bucle
+                break;
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos las variables de salida
+    *posInicio = pos1;
+    *posFin = pos2;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void BuscaSegmento1D(const double valor,
+                     const double* lista,
+                     const size_t nDatos,
+                     size_t* posInicio,
+                     size_t* posFin)
+{
+    //realizamos la búsqueda con incremento igual a 1
+    BuscaSegmento1DInc(valor,lista,nDatos,1,posInicio,posFin);
+}
+/******************************************************************************/
+/******************************************************************************/
+void BuscaPosNWEnMalla(const double xPto,
+                       const double yPto,
+                       const double xMin,
+                       const double xMax,
+                       const double yMin,
+                       const double yMax,
+                       const double pasoX,
+                       const double pasoY,
+                       size_t* fil,
+                       size_t* col)
+{
+    //dimensiones de la matriz
+    size_t f=0,c=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos las dimensiones de la matriz de trabajo
+    f = (size_t)(round((yMax-yMin)/pasoY)+1.0);
+    c = (size_t)(round((xMax-xMin)/pasoX)+1.0);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos la fila y comprobamos si es el extremo S
+    *fil = (size_t)(fabs(yPto-yMax)/pasoY);
+    if(*fil==(f-1))
+    {
+        //retrasamos una fila
+        (*fil)--;
+    }
+    //calculamos la columna y comprobamos si es el extremo E
+    *col = (size_t)((xPto-xMin)/pasoX);
+    if(*col==(c-1))
+    {
+        //retrasamos una columna
+        (*col)--;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+double Minimo(const double* lista,
+              const size_t nDatos,
+              const size_t incDatos)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //variable de salida, inicializada como el máximo valor para un double
+    double salida=DBL_MAX;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP, sólo si la versión es superior a la 3.0
+    //en versiones anteriores no existe la posibilidad de usar reduction(min:)
+#if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1)
+#pragma omp parallel for default(none) \
+ shared(lista) \
+ private(i,pos) \
+ reduction(min:salida)
+#endif
+    //recorremos el resto de elementos de la lista
+    for(i=0;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es menor que el considerado menor
+        if(lista[pos]<salida)
+        {
+            //asignamos el nuevo valor menor
+            salida = lista[pos];
+        }
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+double Maximo(const double* lista,
+              const size_t nDatos,
+              const size_t incDatos)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //variable de salida, inicializada como el mínimo valor para un double
+    double salida=DBL_MIN;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP, sólo si la versión es superior a la 3.0
+    //en versiones anteriores no existe la posibilidad de usar reduction(max:)
+#if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1)
+#pragma omp parallel for default(none) \
+ shared(lista) \
+ private(i,pos) \
+ reduction(max:salida)
+#endif
+    //recorremos el resto de elementos de la lista
+    for(i=0;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es mayor que el considerado mayor
+        if(lista[pos]>salida)
+        {
+            //asignamos el nuevo valor menor
+            salida = lista[pos];
+        }
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+double MinimoAbs(const double* lista,
+                 const size_t nDatos,
+                 const size_t incDatos)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //variable de salida, inicializada como el máximo valor para un double
+    double salida=DBL_MAX;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP, sólo si la versión es superior a la 3.0
+    //en versiones anteriores no existe la posibilidad de usar reduction(min:)
+#if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1)
+#pragma omp parallel for default(none) \
+ shared(lista) \
+ private(i,pos) \
+ reduction(min:salida)
+#endif
+    //recorremos el resto de elementos de la lista
+    for(i=0;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es menor que el considerado menor
+        if(fabs(lista[pos])<salida)
+        {
+            //asignamos el nuevo valor menor
+            salida = fabs(lista[pos]);
+        }
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+double MaximoAbs(const double* lista,
+                 const size_t nDatos,
+                 const size_t incDatos)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //variable de salida, inicializada como 0.0 (trabajamos en valor absoluto)
+    double salida=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP, sólo si la versión es superior a la 3.0
+    //en versiones anteriores no existe la posibilidad de usar reduction(max:)
+#if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1)
+#pragma omp parallel for default(none) \
+ shared(lista) \
+ private(i,pos) \
+ reduction(max:salida)
+#endif
+    //recorremos el resto de elementos de la lista
+    for(i=0;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es mayor que el considerado mayor
+        if(fabs(lista[pos])>salida)
+        {
+            //asignamos el nuevo valor menor
+            salida = fabs(lista[pos]);
+        }
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t MinimoSizeT(const size_t* lista,
+                   const size_t nDatos,
+                   const size_t incDatos)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //variable de salida, inicializada como el máximo valor para un size_t
+    size_t salida=SIZE_MAX;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP, sólo si la versión es superior a la 3.0
+    //en versiones anteriores no existe la posibilidad de usar reduction(min:)
+#if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1)
+#pragma omp parallel for default(none) \
+ shared(lista) \
+ private(i,pos) \
+ reduction(min:salida)
+#endif
+    //recorremos el resto de elementos de la lista
+    for(i=0;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es menor que el considerado menor
+        if(lista[pos]<salida)
+        {
+            //asignamos el nuevo valor menor
+            salida = lista[pos];
+        }
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t MaximoSizeT(const size_t* lista,
+                   const size_t nDatos,
+                   const size_t incDatos)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //variable de salida, inicializada como 0 (size_t es sólo positivo)
+    size_t salida=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP, sólo si la versión es superior a la 3.0
+    //en versiones anteriores no existe la posibilidad de usar reduction(max:)
+#if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1)
+#pragma omp parallel for default(none) \
+ shared(lista) \
+ private(i,pos) \
+ reduction(max:salida)
+#endif
+    //recorremos el resto de elementos de la lista
+    for(i=0;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es mayor que el considerado mayor
+        if(lista[pos]>salida)
+        {
+            //asignamos el nuevo valor menor
+            salida = lista[pos];
+        }
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+void MinMax(const double* lista,
+            const size_t nDatos,
+            const size_t incDatos,
+            size_t* posMin,
+            size_t* posMax)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //consideramos que el primer elemento es el mayor y el menor
+    *posMin = 0;
+    *posMax = 0;
+    //recorremos el resto de elementos de la lista
+    for(i=1;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es menor que el considerado menor
+        if(lista[pos]<lista[(*posMin)*incDatos])
+        {
+            //asignamos la nueva posición
+            *posMin = i;
+        }
+        //comprobamos si el elemento actual es mayor que el considerado mayor
+        if(lista[pos]>lista[(*posMax)*incDatos])
+        {
+            //asignamos la nueva posición
+            *posMax = i;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void MinMaxAbs(const double* lista,
+               const size_t nDatos,
+               const size_t incDatos,
+               size_t* posMin,
+               size_t* posMax)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //consideramos que el primer elemento es el mayor y el menor
+    *posMin = 0;
+    *posMax = 0;
+    //recorremos el resto de elementos de la lista
+    for(i=1;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es menor que el considerado menor
+        if(fabs(lista[pos])<fabs(lista[(*posMin)*incDatos]))
+        {
+            //asignamos la nueva posición
+            *posMin = i;
+        }
+        //comprobamos si el elemento actual es mayor que el considerado mayor
+        if(fabs(lista[pos])>fabs(lista[(*posMax)*incDatos]))
+        {
+            //asignamos la nueva posición
+            *posMax = i;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void MinMaxSizeT(const size_t* lista,
+                 const size_t nDatos,
+                 const size_t incDatos,
+                 size_t* posMin,
+                 size_t* posMax)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //consideramos que el primer elemento es el mayor y el menor
+    *posMin = 0;
+    *posMax = 0;
+    //recorremos el resto de elementos de la lista
+    for(i=1;i<nDatos;i++)
+    {
+        //posición del elemento a comprobar
+        pos = i*incDatos;
+        //comprobamos si el elemento actual es menor que el considerado menor
+        if(lista[pos]<lista[(*posMin)*incDatos])
+        {
+            //asignamos la nueva posición
+            *posMin = i;
+        }
+        //comprobamos si el elemento actual es mayor que el considerado mayor
+        if(lista[pos]>lista[(*posMax)*incDatos])
+        {
+            //asignamos la nueva posición
+            *posMax = i;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+double** AsigMemMatrizC(const size_t fil,
+                        const size_t col)
+{
+    //índices para recorrer bucles
+    size_t i=0;
+    //matriz de salida
+    double** matriz=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para el array principal
+    matriz = (double**)malloc(fil*sizeof(double*));
+    //comprobamos los errores
+    if(matriz==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos toda la memoria al primer puntero
+    matriz[0] = (double*)malloc(fil*col*sizeof(double));
+    //comprobamos los errores
+    if(matriz[0]==NULL)
+    {
+        //liberamos la memoria previamente asignada
+        free(matriz);
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //recorremos el resto de filas
+    for(i=1;i<fil;i++)
+    {
+        //vamos asignando las direcciones de inicio de cada fila
+        matriz[i] = &matriz[0][i*col];
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return matriz;
+}
+/******************************************************************************/
+/******************************************************************************/
+void LibMemMatrizC(double** matriz)
+{
+    //sólo trabajamos si hay memoria asignada
+    if(matriz!=NULL)
+    {
+        //sólo trabajamos si hay memoria asignada
+        if(matriz[0]!=NULL)
+        {
+            //liberamos la memoria de los datos
+            free(matriz[0]);
+        }
+        //liberamos la memoria del array principal
+        free(matriz);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t* PosRepeEnVector(const double* datos,
+                        const size_t nDatos,
+                        const size_t incDatos,
+                        size_t* nRepe)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //número de repeticiones encontradas
+    size_t numRep=0;
+    //datos de las posiciones de trabajo
+    double dato=0.0,datoTrab=0.0;
+    //variable de salida
+    size_t* pos=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para el vector de salida
+    pos = (size_t*)malloc(nDatos*sizeof(double));
+    //comprobamos los posibles errores
+    if(pos==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la primera posición, extraemos el dato e inicializamos el
+    //contador de repeticiones
+    pos[0] = 0;
+    dato = datos[0];
+    numRep = 1;
+    //recorremos el resto de elementos del vector
+    for(i=1;i<nDatos;i++)
+    {
+        //extraemos el dato de trabajo
+        datoTrab = datos[i*incDatos];
+        //lo comparamos con el dato de referencia
+        if(datoTrab!=dato)
+        {
+            //asignamos la nueva posición
+            pos[numRep] = i;
+            //aumentamos el contador de repeticiones
+            numRep++;
+            //convertimos el nuevo dato en dato de referencia
+            dato = datoTrab;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ajustamos la memoria al número de posiciones repetidas encontradas
+    pos = (size_t*)realloc(pos,numRep*sizeof(double));
+    //comprobamos los posibles errores
+    if(pos==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //indicamos el número de repeticiones
+    *nRepe = numRep;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return pos;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t* NumElemRepeEnVector(const size_t* pos,
+                            const size_t nPos,
+                            const size_t nElemVecOrig)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de salida
+    size_t* num=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para el vector de salida
+    num = (size_t*)malloc(nPos*sizeof(double));
+    //comprobamos los posibles errores
+    if(num==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos el vector de posiciones desde el segundo elemento
+    for(i=1;i<nPos;i++)
+    {
+        //vamos calculando los elementos repetidos
+        num[i-1] = pos[i]-pos[i-1];
+    }
+    //comprobamos si la última posición corresponde al último elemento del
+    //vector original
+    if(pos[nPos-1]==(nElemVecOrig-1))
+    {
+        //el último número es 1
+        num[nPos-1] = 1;
+    }
+    else
+    {
+        //tenemos en cuente que los elementos son el mismo hasta el final
+        num[nPos-1] = nElemVecOrig-pos[nPos-1];
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return num;
+}
+/******************************************************************************/
+/******************************************************************************/
+void EscalaYTrasladaVector(double* vector,
+                           const size_t nElem,
+                           const size_t inc,
+                           const double escala,
+                           const double traslada)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //distinguimos entre incremento igual a 1 o mayor
+    if(inc==1)
+    {
+        //recorremos los elementos del vector
+        for(i=0;i<nElem;i++)
+        {
+            //primero factor de escala y luego traslación
+            vector[i] = vector[i]*escala+traslada;
+        }
+    }
+    else
+    {
+        //recorremos los elementos del vector
+        for(i=0;i<nElem;i++)
+        {
+            //posición en el vector de trabajo
+            pos = i*inc;
+            //primero factor de escala y luego traslación
+            vector[pos] = vector[pos]*escala+traslada;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void TrasladaYEscalaVector(double* vector,
+                           const size_t nElem,
+                           const size_t inc,
+                           const double escala,
+                           const double traslada)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //distinguimos entre incremento igual a 1 o mayor
+    if(inc==1)
+    {
+        //recorremos los elementos del vector
+        for(i=0;i<nElem;i++)
+        {
+            //primero traslación y luego factor de escala
+            vector[i] = (vector[i]+traslada)*escala;
+        }
+    }
+    else
+    {
+        //recorremos los elementos del vector
+        for(i=0;i<nElem;i++)
+        {
+            //posición en el vector de trabajo
+            pos = i*inc;
+            //primero traslación y luego factor de escala
+            vector[pos] = (vector[pos]+traslada)*escala;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/geocnan.c b/src/geocnan.c
new file mode 100755
index 0000000..2a2aca5
--- /dev/null
+++ b/src/geocnan.c
@@ -0,0 +1,184 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geocnan geom matriz gshhs
+@{
+\file geocnan.c
+\brief Definición de funciones para el trabajo con constantes Not-a-Number.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 26 de mayo de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2010-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/geocnan.h"
+/******************************************************************************/
+/******************************************************************************/
+double GeocNan(void)
+{
+    //devolvemos el valor de NaN
+    //le calculamos el valor absoluto porque, en algunos sistemas, al imprimir
+    //un valor GEOC_NAN normal, éste sale con un signo negativo delante
+    //aclaración a 22 de septiembre de 2011: parecía que con lo del fabs()
+    //estaba solucionado el asunto del signo negativo, pero no es así
+    //la impresión con signo negativo parece que depende de los flags de
+    //optimización al compilar y de los propios compiladores
+    //no obstante, se mantiene el fabs()
+    return fabs(GEOC_NAN);
+}
+/******************************************************************************/
+/******************************************************************************/
+int EsGeocNan(const double valor)
+{
+    //comparamos y salimos de la función
+    return valor!=valor;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t* PosGeocNanEnVector(const double* datos,
+                           const size_t nDatos,
+                           const size_t incDatos,
+                           size_t* nNan)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //vector de salida
+    size_t* salida=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos a 0 el número de NaN encontrados
+    *nNan = 0;
+    //comprobamos una posible salida rápida
+    if(nDatos==0)
+    {
+        //salimos de la función
+        return salida;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos los elementos de los vectores
+    for(i=0;i<nDatos;i++)
+    {
+        //comprobamos si el elemento del vector es NaN
+        if(EsGeocNan(datos[i*incDatos]))
+        {
+            //aumentamos el contador de NaN encontrados
+            (*nNan)++;
+            //reasignamos memoria a la salida
+            salida = (size_t*)realloc(salida,(*nNan)*sizeof(size_t));
+            //comprobamos los posibles errores
+            if(salida==NULL)
+            {
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //indicamos la posición del valor NaN
+            salida[(*nNan)-1] = i;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t LonFormatoNumSimple(const char formato[])
+{
+    //cadena auxiliar para la impresión
+    char cadena[GEOC_NAN_LON_FORM_NUM_SIMPLE+1];
+    //longitud de la cadena imprimida
+    size_t lon=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //imprimimos en la cadena auxiliar un valor numérico
+    sprintf(cadena,formato,1);
+    //calculamos la longitud de la cadena imprimida
+    lon = strlen(cadena);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return lon;
+}
+/******************************************************************************/
+/******************************************************************************/
+void FormatoNumFormatoTexto(const char formatoNum[],
+                            char formatoTexto[])
+{
+    //número de carácteres de los resultados impresos con el formato numérico
+    size_t lon=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el número de carácteres de los resultados impresos con el
+    //formato numérico
+    lon = LonFormatoNumSimple(formatoNum);
+    //creamos la cadena de formato para imprimir texto
+    sprintf(formatoTexto,"%s%zu%s","%",lon,"s");
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void ImprimeGeocNanTexto(FILE* idFich,
+                         const size_t nNan,
+                         const char formato[],
+                         const int retCarro)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos el número de elementos a imprimir
+    for(i=0;i<nNan;i++)
+    {
+        //imprimimos
+        fprintf(idFich,formato,GEOC_NAN_TXT);
+    }
+    //comprobamos si hay que añadir salto de línea
+    if(retCarro)
+    {
+        fprintf(idFich,"\n");
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/geocomp.c b/src/geocomp.c
new file mode 100644
index 0000000..a004e7a
--- /dev/null
+++ b/src/geocomp.c
@@ -0,0 +1,129 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup anespec general geocomp geodesia geom geopot gravim mmcc
+@{
+\file geocomp.c
+\brief Definición de funciones para la obtención de información de la
+       implementación de OpenMP usada.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 25 de agosto de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/geocomp.h"
+/******************************************************************************/
+/******************************************************************************/
+void VersionOpenMP(const int macro_OPENMP,
+                   char version[])
+{
+    //vamos comprobando los valores de la macro
+    if(macro_OPENMP==GEOC_OMP_F_1_0)
+    {
+        //versión 1.0
+        strcpy(version,GEOC_OMP_V_1_0);
+    }
+    else if(macro_OPENMP==GEOC_OMP_F_2_0)
+    {
+        //versión 2.0
+        strcpy(version,GEOC_OMP_V_2_0);
+    }
+    else if(macro_OPENMP==GEOC_OMP_F_2_5)
+    {
+        //versión 2.5
+        strcpy(version,GEOC_OMP_V_2_5);
+    }
+    else if(macro_OPENMP==GEOC_OMP_F_3_0)
+    {
+        //versión 3.0
+        strcpy(version,GEOC_OMP_V_3_0);
+    }
+    else if(macro_OPENMP==GEOC_OMP_F_3_1)
+    {
+        //versión 3.1
+        strcpy(version,GEOC_OMP_V_3_1);
+    }
+    else
+    {
+        //versión desconocida
+        strcpy(version,GEOC_OMP_V_DESC);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int FechaVersionOpenMP(const char version[])
+{
+    //variable de salida
+    int fecha=GEOC_OMP_F_DESC;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //vamos comprobando los valores de la versión
+    if(!strcmp(version,GEOC_OMP_V_1_0))
+    {
+        //versión 1.0
+        fecha = GEOC_OMP_F_1_0;
+    }
+    else if(!strcmp(version,GEOC_OMP_V_2_0))
+    {
+        //versión 2.0
+        fecha = GEOC_OMP_F_2_0;
+    }
+    else if(!strcmp(version,GEOC_OMP_V_2_5))
+    {
+        //versión 2.5
+        fecha = GEOC_OMP_F_2_5;
+    }
+    else if(!strcmp(version,GEOC_OMP_V_3_0))
+    {
+        //versión 3.0
+        fecha = GEOC_OMP_F_3_0;
+    }
+    else if(!strcmp(version,GEOC_OMP_V_3_1))
+    {
+        //versión 3.1
+        fecha = GEOC_OMP_F_3_1;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return fecha;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/greiner.c b/src/greiner.c
new file mode 100755
index 0000000..cbe682c
--- /dev/null
+++ b/src/greiner.c
@@ -0,0 +1,1840 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file greiner.c
+\brief Definición de funciones para el recorte de polígonos mediante el
+       algoritmo de Greiner-Hormann
+       (http://davis.wpi.edu/~matt/courses/clipping/).
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 14 de mayo de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/greiner.h"
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* CreaVertPoliClip(const double x,
+                               const double y,
+                               vertPoliClip* anterior,
+                               vertPoliClip* siguiente,
+                               vertPoliClip* vecino,
+                               const char ini,
+                               const char interseccion,
+                               const char entrada,
+                               const char visitado,
+                               const double alfa)
+{
+    //variable de salida (nuevo vértice)
+    vertPoliClip* nuevoVert=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para el nuevo vértice
+    nuevoVert = (vertPoliClip*)malloc(sizeof(vertPoliClip));
+    //comprobamos los posibles errores
+    if(nuevoVert==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos los vértices anterior y posterior
+    nuevoVert->anterior = anterior;
+    nuevoVert->siguiente = siguiente;
+    //si anterior es un vértice bueno
+    if(anterior!=NULL)
+    {
+        //lo apuntamos al vértice creado
+        nuevoVert->anterior->siguiente = nuevoVert;
+    }
+    //si siguiente es un vértice bueno
+    if(siguiente!=NULL)
+    {
+        //indicamos que el vértice creado es el anterior
+        nuevoVert->siguiente->anterior = nuevoVert;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos el resto de campos
+    nuevoVert->x = x;
+    nuevoVert->y = y;
+    nuevoVert->xP = x;
+    nuevoVert->yP = y;
+    nuevoVert->vecino = vecino;
+    nuevoVert->ini = ini;
+    nuevoVert->interseccion = interseccion;
+    nuevoVert->entrada = entrada;
+    nuevoVert->visitado = visitado;
+    nuevoVert->alfa = alfa;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return nuevoVert;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* CreaPoliClip(const double* x,
+                           const double* y,
+                           const size_t nCoor,
+                           const size_t incX,
+                           const size_t incY)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variables auxiliares de posición
+    size_t posIni=0,posFin=0;
+    //otra variable auxiliar
+    int hayVert=0;
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    //variable de salida
+    vertPoliClip* poli=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //buscamos el primer punto que sea distinto de NaN
+    for(i=0;i<nCoor;i++)
+    {
+        //comprobamos si el elemento es distinto de NaN
+        if((!EsGeocNan(x[i*incX]))&&(!EsGeocNan(y[i*incY])))
+        {
+            //indicamos que sí hay vértices de trabajo
+            hayVert = 1;
+            //guardamos la posición de este elemento
+            posIni = i;
+            //salimos del bucle
+            break;
+        }
+    }
+    //si no hay ningún vértice distinto de NaN
+    if(!hayVert)
+    {
+        //salimos de la función
+        return poli;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el primer elemento
+    poli = CreaVertPoliClip(x[posIni*incX],y[posIni*incY],NULL,NULL,NULL,1,0,0,
+                            0,0.0);
+    //comprobamos los posibles errores
+    if(poli==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //asignamos el elemento creado a la variable auxiliar
+    aux = poli;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable posFin
+    posFin = posIni;
+    //recorremos los puntos de trabajo
+    for(i=(posIni+1);i<nCoor;i++)
+    {
+        //comprobamos si el elemento es distinto de NaN
+        if((!EsGeocNan(x[i*incX]))&&(!EsGeocNan(y[i*incY])))
+        {
+            //actualizamos la variable que almacena la posición del último
+            //vértice válido
+            posFin = i;
+            //vamos añadiendo vértices al final
+            aux = CreaVertPoliClip(x[i*incX],y[i*incY],aux,NULL,NULL,0,0,0,0,
+                                   0.0);
+            //comprobamos los posibles errores
+            if(aux==NULL)
+            {
+                //liberamos la memoria asignada hasta ahora
+                LibMemPoliClip(poli);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el último vértice no está repetido
+    if((x[posIni*incX]!=x[posFin*incX])||(y[posIni*incY]!=y[posFin*incY]))
+    {
+        //repetimos el primer vértice al final
+        aux = CreaVertPoliClip(x[posIni*incX],y[posIni*incY],aux,NULL,NULL,0,0,
+                               0,0,0.0);
+        //comprobamos los posibles errores
+        if(aux==NULL)
+        {
+            //liberamos la memoria asignada hasta ahora
+            LibMemPoliClip(poli);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return poli;
+}
+/******************************************************************************/
+/******************************************************************************/
+void LibMemPoliClip(vertPoliClip* poli)
+{
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //trabajamos mientras quede memoria
+    while(poli!=NULL)
+    {
+        //apuntamos con la estructura auxiliar hacia la memoria a liberar
+        aux = poli;
+        //apuntamos con la estructura principal al siguiente vértice
+        poli = poli->siguiente;
+        //liberamos la memoria
+        free(aux);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* ReiniciaPoliClip(vertPoliClip* poli)
+{
+    //estructura que apunta al espacio en memoria a liberar
+    vertPoliClip* borra=NULL;
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    //estructura de salida
+    vertPoliClip* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar
+    aux = poli;
+    //comprobamos una posible salida rápida
+    if(aux==NULL)
+    {
+        //salimos de la función
+        return NULL;
+    }
+    //buscamos para la estructura de salida el primer vértice que no sea una
+    //intersección
+    while(aux!=NULL)
+    {
+        //comprobamos si estamos ante un vértice bueno
+        if(aux->interseccion==0)
+        {
+            //asignamos la variable de salida
+            sal = aux;
+            //salimos del bucle
+            break;
+        }
+        //siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //volvemos a inicializar la variable auxiliar
+    aux = poli;
+    //mientras la variable de trabajo no apunte a NULL
+    while(aux!=NULL)
+    {
+        //comprobamos si estamos ante un vértice a borrar
+        if(aux->interseccion)
+        {
+            //lo almacenamos en la estructura de borrado
+            borra = aux;
+            //actualizamos el puntero de vértice siguiente
+            if(aux->anterior!=NULL)
+            {
+                //cuando el vértice a borrar no es el primero de la lista
+                aux->anterior->siguiente = aux->siguiente;
+            }
+            else if(aux->siguiente!=NULL)
+            {
+                //cuando el vértice a borrar es el primero de la lista
+                aux->siguiente->anterior = NULL;
+            }
+            //actualizamos el puntero de vértice anterior
+            if(aux->siguiente!=NULL)
+            {
+                //cuando el vértice a borrar no es el último de la lista
+                aux->siguiente->anterior = aux->anterior;
+            }
+            else if(aux->anterior!=NULL)
+            {
+                //cuando el vértice a borrar es el último de la lista
+                aux->anterior->siguiente = NULL;
+            }
+            //apuntamos al siguiente elemento
+            aux = aux->siguiente;
+            //liberamos la memoria
+            free(borra);
+        }
+        else
+        {
+            //reinicializamos el resto de miembros, menos las coordenadas
+            //originales y el identificador de primer elemento
+            aux->xP = aux->x;
+            aux->yP = aux->y;
+            aux->vecino = NULL;
+            aux->interseccion = 0;
+            aux->entrada = 0;
+            aux->visitado = 0;
+            aux->alfa = 0.0;
+            //siguiente elemento
+            aux = aux->siguiente;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* ReiniciaVerticesPoliClip(vertPoliClip* poli)
+{
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura de auxiliar con la dirección de entrada
+    aux = poli;
+    //mientras no lleguemos al final
+    while(aux!=NULL)
+    {
+        //vamos poniendo a 0 el campo 'visitado'
+        aux->visitado = 0;
+        //vamos poniendo a 0 el campo 'entrada'
+        aux->entrada = 0;
+        //nos posicionamos en el siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return poli;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* SiguienteVertOrigPoliClip(vertPoliClip* vert)
+{
+    //variable de salida, que inicializamos con la dirección de entrada
+    vertPoliClip* sal=vert;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //si estamos ante un vértice original, pasamos al siguiente
+    if((sal!=NULL)&&(sal->interseccion==0))
+    {
+        //apuntamos al siguiente vértice
+        sal = sal->siguiente;
+    }
+    //vamos rechazando intersecciones (el bucle se para cuando llegamos al final
+    //o a un vértice que no es intersección)
+    while((sal!=NULL)&&(sal->interseccion!=0))
+    {
+        //pasamos al siguiente vértice
+        sal = sal->siguiente;
+    }
+    //si hemos llegado a un vértice que no es original, apuntamos a NULL
+    if((sal!=NULL)&&(sal->interseccion!=0))
+    {
+        //asignamos NULL
+        sal = NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* SiguienteIntersecNoVisitadaPoliClip(vertPoliClip* vert)
+{
+    //variable de salida, que inicializamos con la dirección de entrada
+    vertPoliClip* sal=vert;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //si estamos ante una intersección no visitada o ante el vértice original
+    //del polígono, pasamos al siguiente vértice
+    if((sal!=NULL)&&
+       (((sal->interseccion!=0)&&(sal->visitado==0))||(sal->ini!=0)))
+    {
+        //apuntamos al siguiente vértice
+        sal = sal->siguiente;
+    }
+    //vamos rechazando vértices originales e intersecciones visitadas: el bucle
+    //se para cuando llegamos al final (si la lista no es circular), cuando
+    //volvamos al principio (si la lista es circular) o cuando lleguemos a una
+    //intersección no visitada
+    while(((sal!=NULL)&&(sal->ini==0))&&
+          ((sal->interseccion==0)||
+           ((sal->interseccion!=0)&&(sal->visitado!=0))))
+    {
+        //pasamos al siguiente vértice
+        sal = sal->siguiente;
+    }
+    //si hemos llegado a un vértice que no es una intersección no visitada o es
+    //de nuevo el punto inicial (lista circular), apuntamos a NULL
+    if((sal!=NULL)&&
+       (((sal->interseccion!=0)&&(sal->visitado!=0))||(sal->ini!=0)))
+    {
+        //asignamos NULL
+        sal = NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* UltimoVertPoliClip(vertPoliClip* poli)
+{
+    //variable de salida, que inicializamos con la dirección de entrada
+    vertPoliClip* sal=poli;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //sólo trabajamos si la entrada es distinta de NULL
+    if(sal!=NULL)
+    {
+        //mientras el siguiente vértice sea distinto de NULL
+        while(sal->siguiente!=NULL)
+        {
+            //avanzamos un vértice
+            sal = sal->siguiente;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+void InsertaVertPoliClip(vertPoliClip* ins,
+                         vertPoliClip* extremoIni,
+                         vertPoliClip* extremoFin)
+{
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el vértice auxiliar como el extremo inicial pasado
+    aux = extremoIni;
+    //mientras no lleguemos al extremo final y el punto a insertar esté más
+    //lejos del origen que el punto de trabajo
+    while((aux!=extremoFin)&&((aux->alfa)<=(ins->alfa)))
+    {
+        //avanzamos al siguiente vértice
+        aux = aux->siguiente;
+    }
+    //insertamos el punto y ordenamos los punteros de vértices anterior y
+    //posterior
+    ins->siguiente = aux;
+    ins->anterior = aux->anterior;
+    ins->anterior->siguiente = ins;
+    ins->siguiente->anterior = ins;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPoliClip* CierraPoliClip(vertPoliClip* poli)
+{
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    //variable de salida: último vértice de la lista original
+    vertPoliClip* ultimo=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si se ha pasado NULL
+    if(poli==NULL)
+    {
+        //salimos de la función
+        return NULL;
+    }
+    //buscamos el último vértice de la lista original
+    ultimo = UltimoVertPoliClip(poli);
+    //almacenamos el penúltimo vértice en la estructura auxiliar
+    aux = ultimo->anterior;
+    //apuntamos el penúltimo vértice al primero
+    aux->siguiente = poli;
+    //le decimos al primer vértice cuál es el anterior
+    aux->siguiente->anterior = aux;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return ultimo;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AbrePoliClip(vertPoliClip* poli,
+                  vertPoliClip* ultimo)
+{
+    //estructuras auxiliares
+    vertPoliClip* aux=poli;
+    vertPoliClip* ult=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //buscamos el vértice inicial
+    while((aux!=NULL)&&(aux->ini==0))
+    {
+        //pasamos al siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //último vértice
+    ult = aux->anterior;
+    //le decimos al falso último vértice cuál es el último verdadero
+    ult->siguiente = ultimo;
+    //ajustamos los parámetros del nuevo último vértice
+    ultimo->anterior = ult;
+    ultimo->siguiente = NULL;
+    //le decimos al primer vértice que el anterior es NULL
+    aux->anterior = NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoliClip(const double x,
+                  const double y,
+                  vertPoliClip* poli)
+{
+    //estructuras auxiliares
+    vertPoliClip* aux=NULL;
+    vertPoliClip* aux1=NULL;
+    //coordenadas auxiliares
+    double x1=0.0,y1=0.0,x2=0.0,y2=0.0;
+    //variable de salida
+    int c=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar con la dirección de entrada
+    aux = poli;
+    //comprobamos si no es un vértice original
+    if(aux->interseccion!=0)
+    {
+        //nos posicionamos en el siguiente vértice original
+        aux = SiguienteVertOrigPoliClip(aux);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //entramos en un bucle infinito
+    while(1)
+    {
+        //nos posicionamos en el siguiente vértice original
+        aux1 = SiguienteVertOrigPoliClip(aux);
+        //sólo continuamos si el siguiente vértice no es NULL
+        if(aux1!=NULL)
+        {
+            //extraemos las coordenadas de trabajo
+            x1 = aux->xP;
+            y1 = aux->yP;
+            x2 = aux1->xP;
+            y2 = aux1->yP;
+            //actalizamos el vértice inicial de trabajo para la siguiente vuelta
+            aux = aux1;
+            //calculamos
+            if(((y1>y)!=(y2>y))&&(x<(x2-x1)*(y-y1)/(y2-y1)+x1))
+            {
+                c = !c;
+            }
+        }
+        else
+        {
+            //salimos del bucle
+            break;
+        }
+    }
+    //asignamos el elemento de salida
+    if(c)
+    {
+        //el punto está dentro del polígono
+        c = GEOC_PTO_DENTRO_POLIG;
+    }
+    else
+    {
+        //el punto está fuera del polígono
+        c = GEOC_PTO_FUERA_POLIG;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return c;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoliClipVertice(const double x,
+                         const double y,
+                         vertPoliClip* poli)
+{
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    //variable de salida, que inicializamos fuera del polígono
+    int pos=GEOC_PTO_FUERA_POLIG;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar con la dirección de entrada
+    aux = poli;
+    //comprobamos si no es un vértice original
+    if(aux->interseccion!=0)
+    {
+        //nos posicionamos en el siguiente vértice original
+        aux = SiguienteVertOrigPoliClip(aux);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el punto es un vértice
+    while(aux!=NULL)
+    {
+        //comprobamos si las coordenadas coinciden
+        if((aux->xP==x)&&(aux->yP==y))
+        {
+            //indicamos que el punto es un vértice
+            pos = GEOC_PTO_VERTICE_POLIG;
+            //salimos del bucle
+            break;
+        }
+        //nos posicionamos en el siguiente vértice original
+        aux = SiguienteVertOrigPoliClip(aux);
+    }
+    //sólo continuamos si el punto no es un vértice
+    if(pos!=GEOC_PTO_VERTICE_POLIG)
+    {
+        //calculamos la posición sin tener en cuenta el borde
+        pos = PtoEnPoliClip(x,y,poli);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return pos;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t NumeroVertOrigPoliClip(vertPoliClip* poli)
+{
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    //variable de salida
+    size_t num=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar con la dirección de entrada
+    aux = poli;
+    //comprobamos si estamos ante un vértice original
+    if(aux->interseccion!=0)
+    {
+        //si no es un vértice original, nos posicionamos en el siguiente que sí
+        //lo sea
+        aux = SiguienteVertOrigPoliClip(aux);
+    }
+    //mientras no lleguemos al final
+    while(aux!=NULL)
+    {
+        //aumentamos el contador de vértices originales
+        num++;
+        //nos posicionamos en el siguiente vértice original
+        aux = SiguienteVertOrigPoliClip(aux);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return num;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t NumeroVertPoliClip(vertPoliClip* poli)
+{
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    //variable de salida
+    size_t num=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar con la dirección de entrada
+    aux = poli;
+    //mientras no lleguemos al final
+    while(aux!=NULL)
+    {
+        //aumentamos el contador de vértices
+        num++;
+        //nos posicionamos en el siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return num;
+}
+/******************************************************************************/
+/******************************************************************************/
+double CantPerturbMin(const double x,
+                      const double factor)
+{
+    //valor absoluto del argumento de entrada
+    double xAbs=fabs(x);
+    //variable auxiliar
+    double aux=0.0;
+    //variable de salida, que inicializamos como el épsilon para el tipo de dato
+    double sal=fabs(DBL_EPSILON);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //mientras la variable auxiliar sea igual a la de antrada (la primera vuelta
+    //del bucle se ejecuta siempre)
+    do
+    {
+        //escalamos la variable de salida
+        sal *= factor;
+        //sumamos el nuevo valor a la coordenada de entrada
+        //esta suma es necesario realizarla aquí, en lugar de en la propia
+        //comparación del while, para obligar al resultado a almacenarse en una
+        //variable y evitar errores porque las variables intermedias de la
+        //comparación puede que se almacenen en registros de más precisión que
+        //el tipo de dato
+        aux = xAbs+sal;
+    }while(aux==xAbs);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+double PerturbaPuntoMin(const double x,
+                        const double factor)
+{
+    //variable para almacenar un número seudoaleatorio
+    int aleat=0;
+    //cantidad perturbadora
+    double perturb=0.0;
+    //signo para multiplicar por la cantidad perturbadora
+    double signo=0.0;
+    //variable de salida
+    double sal=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //plantamos la semilla para la función rand()
+    srand((unsigned int)time(NULL));
+    //generamos el número seudoaleatorio
+    aleat = rand();
+    //calculamos el signo para la multiplicación, basándonos en la paridad del
+    //número seudoaleatorio generado: si es par vale 1 y si es impar -1
+    signo = (aleat%2) ? -1.0 : 1.0;
+    //calculamos la cantidad perturbadora
+    perturb = CantPerturbMin(x,factor);
+    //perturbamos la coordenada
+    sal = x+signo*perturb;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+int Paso1Greiner(vertPoliClip* poliBas,
+                 vertPoliClip* poliRec,
+                 const double facPer,
+                 size_t* nIntersec,
+                 size_t* nPerturb)
+{
+    //estructuras auxiliares que apuntan a los polígonos pasados
+    vertPoliClip* auxA=NULL;
+    vertPoliClip* auxC=NULL;
+    //estructuras auxiliares para trabajar con el siguiente vértice
+    vertPoliClip* auxB=NULL;
+    vertPoliClip* auxD=NULL;
+    //vértices de intersección a insertar
+    vertPoliClip* insBas=NULL;
+    vertPoliClip* insRec=NULL;
+    //coordenadas de la intersección de dos segmentos
+    double xI=0.0,yI=0.0;
+    //longitudes de segmentos y parámetros alfa
+    double lonAB=0.0,lonCD=0.0,alfaAB=0.0,alfaCD=0.0;
+    //código de intersección de segmentos
+    int intersec=0;
+    //variable de salida
+    int salida=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el número de intersecciones a 0
+    *nIntersec = 0;
+    //inicializamos el número de puntos perturbados a 0
+    *nPerturb = 0;
+    //EL PRIMER PASO DEL ALGORITMO DE GREINER-HORMANN ES EL CÁLCULO DE TODOS LOS
+    //PUNTOS DE INTERSECCIÓN ENTRE LOS POLÍGONOS
+    //recorremos los vértices del polígono base
+    for(auxA=poliBas;auxA->siguiente!=NULL;auxA=auxA->siguiente)
+    {
+        //sólo trabajamos si el vértice es original
+        if(auxA->interseccion==0)
+        {
+            //recorremos los vértices del polígono de recorte
+            for(auxC=poliRec;auxC->siguiente!=NULL;auxC=auxC->siguiente)
+            {
+                //sólo trabajamos si el vértice es original
+                if(auxC->interseccion==0)
+                {
+                    //siguiente vértice de los segmentos
+                    auxB = SiguienteVertOrigPoliClip(auxA);
+                    auxD = SiguienteVertOrigPoliClip(auxC);
+                    //calculamos la intersección de los segmentos
+                    intersec = IntersecSegmentos2D(auxA->xP,auxA->yP,auxB->xP,
+                                                   auxB->yP,auxC->xP,auxC->yP,
+                                                   auxD->xP,auxD->yP,&xI,&yI);
+                    //perturbamos las coordenadas de los extremos de los
+                    //segmentos mientras haya una intersección no limpia
+                    while((intersec!=GEOC_SEG_NO_INTERSEC)&&
+                          (intersec!=GEOC_SEG_INTERSEC))
+                    {
+                        //distinguimos entre intersecciones donde sólo se toca
+                        //un extremo e intersecciones colineales donde se
+                        //comparte más de un punto
+                        if((intersec==GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN)||
+                           (intersec==GEOC_SEG_INTERSEC_EXTREMO_COLIN))
+                        {
+                            if((xI==auxC->xP)&&(yI==auxC->yP))
+                            {
+                                //perturbamos el extremo C
+                                auxC->xP = PerturbaPuntoMin(auxC->x,facPer);
+                                auxC->yP = PerturbaPuntoMin(auxC->y,facPer);
+                                //aumentamos el contador de puntos perturbados
+                                (*nPerturb)++;
+                            }
+                            else if((xI==auxD->xP)&&(yI==auxD->yP))
+                            {
+                                //perturbamos el extremo D
+                                auxD->xP = PerturbaPuntoMin(auxD->x,facPer);
+                                auxD->yP = PerturbaPuntoMin(auxD->y,facPer);
+                                //aumentamos el contador de puntos perturbados
+                                (*nPerturb)++;
+                            }
+                            else
+                            {
+                                //si el punto de contacto es un extremo de AB y
+                                //los segmentos no son paralelos, perturbamos
+                                //todo el segmento CD
+                                auxC->xP = PerturbaPuntoMin(auxC->x,facPer);
+                                auxC->yP = PerturbaPuntoMin(auxC->y,facPer);
+                                auxD->xP = PerturbaPuntoMin(auxD->x,facPer);
+                                auxD->yP = PerturbaPuntoMin(auxD->y,facPer);
+                                //aumentamos el contador de puntos perturbados
+                                (*nPerturb) += 2;
+                            }
+                        }
+                        else if((intersec==GEOC_SEG_INTERSEC_MISMO_SEG)||
+                                (intersec==GEOC_SEG_INTERSEC_COLIN))
+                        {
+                            //perturbamos todo el segmento CD
+                            auxC->xP = PerturbaPuntoMin(auxC->x,facPer);
+                            auxC->yP = PerturbaPuntoMin(auxC->y,facPer);
+                            auxD->xP = PerturbaPuntoMin(auxD->x,facPer);
+                            auxD->yP = PerturbaPuntoMin(auxD->y,facPer);
+                            //aumentamos el contador de puntos perturbados
+                            (*nPerturb) += 2;
+                        }
+                        //volvemos a calcular la intersección de los segmentos
+                        intersec = IntersecSegmentos2D(auxA->xP,auxA->yP,
+                                                       auxB->xP,auxB->yP,
+                                                       auxC->xP,auxC->yP,
+                                                       auxD->xP,auxD->yP,
+                                                       &xI,&yI);
+                    }
+                    //comprobamos si los segmentos se cortan limpiamente
+                    if(intersec==GEOC_SEG_INTERSEC)
+                    {
+                        //aumentamos el contador de intersecciones
+                        (*nIntersec)++;
+                        //calculamos las longitudes de los segmentos
+                        lonAB = Dist2D(auxA->xP,auxA->yP,auxB->xP,auxB->yP);
+                        lonCD = Dist2D(auxC->xP,auxC->yP,auxD->xP,auxD->yP);
+                        //calculamos los parámetros alfa
+                        alfaAB = Dist2D(auxA->xP,auxA->yP,xI,yI)/lonAB;
+                        alfaCD = Dist2D(auxC->xP,auxC->yP,xI,yI)/lonCD;
+                        //creamos los nuevos vértices a insertar
+                        insBas = CreaVertPoliClip(xI,yI,NULL,NULL,NULL,0,1,0,0,
+                                                  alfaAB);
+                        insRec = CreaVertPoliClip(xI,yI,NULL,NULL,NULL,0,1,0,0,
+                                                  alfaCD);
+                        //comprobamos los posibles errores
+                        if((insBas==NULL)||(insRec==NULL))
+                        {
+                            //liberamos la memoria previamente asignada
+                            free(insBas);
+                            free(insRec);
+                            //mensaje de error
+                            GEOC_ERROR("Error de asignación de memoria");
+                            //asignamos el código de error
+                            salida = GEOC_ERR_ASIG_MEMORIA;
+                            //salimos de la función
+                            return salida;
+                        }
+                        //enlazamos los vértices mediante el campo 'vecino'
+                        insBas->vecino = insRec;
+                        insRec->vecino = insBas;
+                        //los insertamos en los polígonos
+                        InsertaVertPoliClip(insBas,auxA,auxB);
+                        InsertaVertPoliClip(insRec,auxC,auxD);
+                    }
+                }
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+void Paso2Greiner(vertPoliClip* poliBas,
+                  vertPoliClip* poliRec,
+                  const enum GEOC_OP_BOOL_POLIG op)
+{
+    //estructuras auxiliares que apuntan a los polígonos pasados
+    vertPoliClip* auxA=NULL;
+    vertPoliClip* auxC=NULL;
+    //identificador de si una intersección es de entrada o salida
+    char entrada=0;
+    //variables auxiliares
+    char entA=0,entC=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos los valores iniciales a los identificadores de intersección
+    switch(op)
+    {
+        //distinguimos los tipos de operación
+        case GeocOpBoolInter:
+            //intersección
+            entA = 1;
+            entC = 1;
+            break;
+        case GeocOpBoolUnion:
+            //unión
+            entA = 0;
+            entC = 0;
+            break;
+        case GeocOpBoolAB:
+            //A-B
+            entA = 0;
+            entC = 1;
+            break;
+        case GeocOpBoolBA:
+            //B-A
+            entA = 1;
+            entC = 0;
+            break;
+        default:
+            //por defecto, intersección
+            entA = 1;
+            entC = 1;
+            break;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //EL SEGUNDO PASO DEL ALGORITMO DE GREINER-HORMANN ES LA IDENTIFICACIÓN DE
+    //INTERSECCIONES COMO ENTRADA-SALIDA
+    //comprobamos si el primer punto del polígono base está fuera del polígono
+    //de recorte
+    if(PtoEnPoliClipVertice(poliBas->xP,poliBas->yP,poliRec))
+    {
+        //si el punto está fuera, la siguiente intersección es de entrada
+        entrada = !entA;
+    }
+    else
+    {
+        entrada = entA;
+    }
+    //recorremos los vértices del polígono de recorte
+    for(auxA=poliBas;auxA->siguiente!=NULL;auxA=auxA->siguiente)
+    {
+        //sólo trabajamos si el vértice es intersección
+        if(auxA->interseccion!=0)
+        {
+            //indicamos la dirección
+            auxA->entrada = entrada;
+            //actualizamos la variable de entrada para la siguiente vuelta
+            entrada = !entrada;
+        }
+    }
+    //comprobamos si el primer punto del polígono de recorte está fuera del
+    //polígono base
+    if(PtoEnPoliClipVertice(poliRec->xP,poliRec->yP,poliBas))
+    {
+        //si el punto está fuera, la siguiente intersección es de entrada
+        entrada = !entC;
+    }
+    else
+    {
+        entrada = entC;
+    }
+    //recorremos los vértices del polígono base
+    for(auxC=poliRec;auxC->siguiente!=NULL;auxC=auxC->siguiente)
+    {
+        //sólo trabajamos si el vértice es intersección
+        if(auxC->interseccion!=0)
+        {
+            //indicamos la dirección
+            auxC->entrada = entrada;
+            //actualizamos la variable de entrada para la siguiente vuelta
+            entrada = !entrada;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+polig* Paso3Greiner(vertPoliClip* poliBas,
+                    vertPoliClip* poliRec)
+{
+    //vértices colgados al cerrar los polígonos
+    vertPoliClip* ultBas=NULL;
+    vertPoliClip* ultRec=NULL;
+    //estructura auxiliar
+    vertPoliClip* aux=NULL;
+    //vectores de coordenadas de los vértices del resultado
+    double* x=NULL;
+    double* y=NULL;
+    //número de elementos de los vectores x e y
+    size_t nPtos=0;
+    //número de elementos para los que ha sido asignada memoria
+    size_t nElem=0;
+    //variable de estado
+    int estado=GEOC_ERR_NO_ERROR;
+    //polígono de salida
+    polig* resultado=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //cerramos los polígonos, convirtiéndolos en listas circulares
+    ultBas = CierraPoliClip(poliBas);
+    ultRec = CierraPoliClip(poliRec);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //mientras queden intersecciones sin visitar
+    while((aux = SiguienteIntersecNoVisitadaPoliClip(poliBas))!=NULL)
+    {
+        //aumentamos el contador de elementos para los vectores x e y en 2
+        //unidades: una para el marcador de inicio de polígono y la otra para
+        //las coordenadas del primer vértice
+        nPtos+=2;
+        //comprobamos si hay que reasignar memoria a los vectores de coordenadas
+        if(nPtos>nElem)
+        {
+            //actualizamos el número de elementos de los vectores de puntos
+            nElem += GEOC_GREINER_BUFFER_PTOS;
+            //reasignamos memoria para los vectores
+            x = (double*)realloc(x,nElem*sizeof(double));
+            y = (double*)realloc(y,nElem*sizeof(double));
+            //comprobamos si ha ocurrido algún error
+            if((x==NULL)||(y==NULL))
+            {
+                //liberamos la posible memoria asignada
+                free(x);
+                free(y);
+                //reabrimos los polígonos
+                AbrePoliClip(poliBas,ultBas);
+                AbrePoliClip(poliRec,ultRec);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+        }
+        //asignamos el marcador NaN como identificador de comienzo de polígono
+        x[nPtos-2] = GeocNan();
+        y[nPtos-2] = GeocNan();
+        //asignamos las coordenadas del punto de intersección
+        x[nPtos-1] = aux->xP;
+        y[nPtos-1] = aux->yP;
+        //EN ESTE NIVEL SIEMPRE ESTAMOS ANTE UN PUNTO DE INTERSECCIÓN
+        //mientras el punto no haya sido visitado con anterioridad
+        do
+        {
+            //lo marcamos como visitado
+            aux->visitado = 1;
+            aux->vecino->visitado = 1;
+            //comprobamos si el punto es de entrada o no
+            if(aux->entrada!=0)
+            {
+                //mientras no encontremos otra intersección
+                do
+                {
+                    //caminamos en la lista hacia adelante
+                    aux = aux->siguiente;
+                    //aumentamos el contador de elementos para x e y
+                    nPtos++;
+                    //comprobamos si hay que reasignar memoria a los vectores de
+                    //coordenadas
+                    if(nPtos>nElem)
+                    {
+                        //actualizamos el número de elementos de los vectores de
+                        //puntos
+                        nElem += GEOC_GREINER_BUFFER_PTOS;
+                        //reasignamos memoria para los vectores
+                        x = (double*)realloc(x,nElem*sizeof(double));
+                        y = (double*)realloc(y,nElem*sizeof(double));
+                        //comprobamos si ha ocurrido algún error
+                        if((x==NULL)||(y==NULL))
+                        {
+                            //liberamos la posible memoria asignada
+                            free(x);
+                            free(y);
+                            //reabrimos los polígonos
+                            AbrePoliClip(poliBas,ultBas);
+                            AbrePoliClip(poliRec,ultRec);
+                            //mensaje de error
+                            GEOC_ERROR("Error de asignación de memoria");
+                            //salimos de la función
+                            return NULL;
+                        }
+                    }
+                    //asignamos las coordenadas del punto de intersección
+                    x[nPtos-1] = aux->xP;
+                    y[nPtos-1] = aux->yP;
+                }
+                while(aux->interseccion==0); //mientras no sea intersección
+            }
+            else
+            {
+                ////mientras no encontremos otra intersección
+                do
+                {
+                    //caminamos hacia atrás
+                    aux = aux->anterior;
+                    //aumentamos el contador de elementos para x e y
+                    nPtos++;
+                    //comprobamos si hay que reasignar memoria a los vectores de
+                    //coordenadas
+                    if(nPtos>nElem)
+                    {
+                        //actualizamos el número de elementos de los vectores de
+                        //puntos
+                        nElem += GEOC_GREINER_BUFFER_PTOS;
+                        //reasignamos memoria para los vectores
+                        x = (double*)realloc(x,nElem*sizeof(double));
+                        y = (double*)realloc(y,nElem*sizeof(double));
+                        //comprobamos si ha ocurrido algún error
+                        if((x==NULL)||(y==NULL))
+                        {
+                            //liberamos la posible memoria asignada
+                            free(x);
+                            free(y);
+                            //reabrimos los polígonos
+                            AbrePoliClip(poliBas,ultBas);
+                            AbrePoliClip(poliRec,ultRec);
+                            //mensaje de error
+                            GEOC_ERROR("Error de asignación de memoria");
+                            //salimos de la función
+                            return NULL;
+                        }
+                    }
+                    //asignamos las coordenadas del punto de intersección
+                    x[nPtos-1] = aux->xP;
+                    y[nPtos-1] = aux->yP;
+                }
+                while(aux->interseccion==0); //mientras no sea intersección
+            }
+            //saltamos al otro polígono
+            aux = aux->vecino;
+        }while(aux->visitado==0); //mientras el punto no haya sido visitado
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos la estructura de salida
+    resultado = CreaPolig(x,y,nPtos,1,1,&estado);
+    //comprobamos los posibles errores
+    if(resultado==NULL)
+    {
+        //liberamos la memoria asignada
+        free(x);
+        free(y);
+        //reabrimos los polígonos
+        AbrePoliClip(poliBas,ultBas);
+        AbrePoliClip(poliRec,ultRec);
+        //comprobamos el error
+        if(estado==GEOC_ERR_ASIG_MEMORIA)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+        }
+        else
+        {
+            //mensaje de error
+            GEOC_ERROR("Error en la llamada a 'CreaPolig()'\nEste error no "
+                       "puede producirse aquí porque los NaN deben estar "
+                       "bien puestos");
+        }
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //reabrimos los polígonos
+    AbrePoliClip(poliBas,ultBas);
+    AbrePoliClip(poliRec,ultRec);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //liberamos la memoria asignada
+    free(x);
+    free(y);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return resultado;
+}
+/******************************************************************************/
+/******************************************************************************/
+polig* PoliBoolGreiner(vertPoliClip* poliBas,
+                       vertPoliClip* poliRec,
+                       const enum GEOC_OP_BOOL_POLIG op,
+                       const double facPer,
+                       size_t* nIntersec,
+                       size_t* nPerturb)
+{
+    //factor de perturbación
+    double factor=0.0;
+    //variables de posición
+    int posBas=0,posRec=0;
+    //identificador de error
+    int idError=GEOC_ERR_NO_ERROR;
+    //polígono auxiliar
+    polig* ba=NULL;
+    //polígono de salida
+    polig* resultado=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si se ha pasado factor de perturbación
+    if(facPer<=1.0)
+    {
+        //utilizamos el valor por defecto
+        factor = GEOC_GREINER_FAC_EPS_PERTURB;
+    }
+    else
+    {
+        //utilizamos el valor pasado
+        factor = facPer;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //PRIMER PASO DEL ALGORITMO DE GREINER-HORMANN: CÁLCULO DE TODOS LOS PUNTOS
+    //DE INTERSECCIÓN ENTRE LOS POLÍGONOS
+    //calculamos los puntos de intersección
+    idError = Paso1Greiner(poliBas,poliRec,factor,nIntersec,nPerturb);
+    //comprobamos los posibles errores
+    if(idError==GEOC_ERR_ASIG_MEMORIA)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria en la llamada a "
+                   "'Paso1Greiner'");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si no hay intersecciones
+    if(!(*nIntersec))
+    {
+        //calculo la situación relativa entre los polígonos
+        posBas = PtoEnPoliClipVertice(poliBas->xP,poliBas->yP,poliRec);
+        posRec = PtoEnPoliClipVertice(poliRec->xP,poliRec->yP,poliBas);
+        //comprobamos las posibles situaciones relativas entre los polígonos que
+        //pueden producir cero intersecciones
+        if((posBas==GEOC_PTO_DENTRO_POLIG)||(posBas==GEOC_PTO_VERTICE_POLIG))
+        {
+            //EL POLÍGONO BASE ESTÁ DENTRO DEL POLÍGONO DE RECORTE
+            //distinguimos las operaciones (por defecto, intersección)
+            if(op==GeocOpBoolUnion)
+            {
+                //el resultado es el polígono de recorte
+                resultado = CreaPoligPoliClip(poliRec,0);
+            }
+            else if(op==GeocOpBoolAB)
+            {
+                //el resultado es un polígono vacío
+                resultado = CreaPoligPoliClip(NULL,0);
+            }
+            else if((op==GeocOpBoolBA)||(op==GeocOpBoolXor))
+            {
+                //el resultado son los dos polígonos
+                //polígono base
+                resultado = CreaPoligPoliClip(poliBas,0);
+                //añadimos el polígono de recorte
+                AnyadePoligClipPolig(resultado,poliRec,0);
+            }
+            else
+            {
+                //el resultado es el polígono base
+                resultado = CreaPoligPoliClip(poliBas,0);
+            }
+        }
+        else if((posRec==GEOC_PTO_DENTRO_POLIG)||
+                (posRec==GEOC_PTO_VERTICE_POLIG))
+        {
+            //EL POLÍGONO DE RECORTE ESTÁ DENTRO DEL POLÍGONO BASE
+            //distinguimos las operaciones (por defecto, intersección)
+            if(op==GeocOpBoolUnion)
+            {
+                //el resultado es el polígono base
+                resultado = CreaPoligPoliClip(poliBas,0);
+            }
+            else if((op==GeocOpBoolAB)||(op==GeocOpBoolXor))
+            {
+                //el resultado son los dos polígonos
+                //polígono base
+                resultado = CreaPoligPoliClip(poliBas,0);
+                //añadimos el polígono de recorte
+                AnyadePoligClipPolig(resultado,poliRec,0);
+            }
+            else if(op==GeocOpBoolBA)
+            {
+                //el resultado es un polígono vacío
+                resultado = CreaPoligPoliClip(NULL,0);
+            }
+            else
+            {
+                //el resultado es el polígono de recorte
+                resultado = CreaPoligPoliClip(poliRec,0);
+            }
+        }
+        else
+        {
+            //NINGÚN POLÍGONO ESTÁ DENTRO DEL OTRO
+            //distinguimos las operaciones (por defecto, intersección)
+            if((op==GeocOpBoolUnion)||(op==GeocOpBoolXor))
+            {
+                //el resultado son los dos polígonos
+                //polígono base
+                resultado = CreaPoligPoliClip(poliBas,0);
+                //añadimos el polígono de recorte
+                AnyadePoligClipPolig(resultado,poliRec,0);
+            }
+            else if(op==GeocOpBoolAB)
+            {
+                //el resultado es el polígono base
+                resultado = CreaPoligPoliClip(poliBas,0);
+            }
+            else if(op==GeocOpBoolBA)
+            {
+                //el resultado es el polígono de recorte
+                resultado = CreaPoligPoliClip(poliRec,0);
+            }
+            else
+            {
+                //el resultado es un polígono vacío
+                resultado = CreaPoligPoliClip(NULL,0);
+            }
+        }
+        //comprobamos los posibles errores
+        if(resultado==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //salimos de la función
+        return resultado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //distinguimos entre XOR y el resto de operaciones
+    if(op!=GeocOpBoolXor)
+    {
+        //SEGUNDO PASO DEL ALGORITMO DE GREINER-HORMANN: IDENTIFICACIÓN DE
+        //INTERSECCIONES COMO ENTRADA-SALIDA
+        //marcamos los puntos como entrada o salida
+        Paso2Greiner(poliBas,poliRec,op);
+        //TERCER PASO DEL ALGORITMO DE GREINER-HORMANN: EXTRACCIÓN DE LOS POLÍGONOS
+        //RESULTADO DE LA OPERACIÓN
+        //extraemos los polígonos
+        resultado = Paso3Greiner(poliBas,poliRec);
+        //comprobamos los posibles errores
+        if(resultado==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria en la llamada a "
+                       "'Paso3Greiner'");
+            //salimos de la función
+            return NULL;
+        }
+    }
+    else
+    {
+        //LA OPERCIÓN XOR LA HACEMOS COMO LA UNIÓN DE LA OPERACIÓN A-B CON B-A
+        //marcamos los puntos como entrada o salida para la operación A-B
+        Paso2Greiner(poliBas,poliRec,GeocOpBoolAB);
+        //extraemos los polígonos
+        resultado = Paso3Greiner(poliBas,poliRec);
+        //comprobamos los posibles errores
+        if(resultado==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria en la llamada a "
+                       "'Paso3Greiner'");
+            //salimos de la función
+            return NULL;
+        }
+        //reinicializamos los polígonos, pero manteniendo las intersecciones
+        poliBas = ReiniciaVerticesPoliClip(poliBas);
+        poliRec = ReiniciaVerticesPoliClip(poliRec);
+        //marcamos los puntos como entrada o salida para la operación B-A
+        Paso2Greiner(poliBas,poliRec,GeocOpBoolBA);
+        //extraemos los polígonos
+        ba = Paso3Greiner(poliBas,poliRec);
+        //comprobamos los posibles errores
+        if(ba==NULL)
+        {
+            //liberamos la memoria asignada
+            LibMemPolig(resultado);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria en la llamada a "
+                       "'Paso3Greiner'");
+            //salimos de la función
+            return NULL;
+        }
+        //añadimos el resultado de la operación B-A al anterior de A-B
+        idError = AnyadePoligPolig(resultado,ba);
+        //comprobamos los posibles errores
+        if(idError==GEOC_ERR_ASIG_MEMORIA)
+        {
+            //liberamos la memoria asignada
+            LibMemPolig(resultado);
+            LibMemPolig(ba);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria en la llamada a "
+                       "'AnyadePoligPolig' para la operación XOR");
+            //salimos de la función
+            return NULL;
+        }
+        //liberamos la memoria asociada a la estructura auxiliar ba
+        LibMemPolig(ba);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return resultado;
+}
+/******************************************************************************/
+/******************************************************************************/
+polig* PoliBoolGreinerMult(const polig* poliBas,
+                           const polig* poliRec,
+                           const enum GEOC_OP_BOOL_POLIG op,
+                           const double facPer,
+                           size_t* nIntersec,
+                           size_t* nPerturb)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //variable de posición
+    size_t pos=0;
+    //número de intersecciones y de puntos perturbados auxiliar
+    size_t nInt=0,nPer=0;
+    //posición de un rectángulo con respecto a otro
+    int pr=0;
+    //variables de error
+    int estado1=GEOC_ERR_NO_ERROR,estado2=GEOC_ERR_NO_ERROR;
+    //listas de trabajo
+    vertPoliClip* poligBas=NULL;
+    vertPoliClip* poligRec=NULL;
+    //polígono auxiliar
+    polig* poligAux=NULL;
+    //variable de salida
+    polig* resultado=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el número total de intersecciones y de puntos perturbados
+    *nIntersec = 0;
+    *nPerturb = 0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable de salida
+    resultado = IniciaPoligVacio();
+    //comprobamos los posibles errores
+    if(resultado==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos los polígonos base
+    for(i=0;i<poliBas->nPolig;i++)
+    {
+        //dirección de inicio de los vértices del polígono base
+        pos = poliBas->posIni[i];
+        //creamos el polígono base de trabajo
+        poligBas = CreaPoliClip(&(poliBas->x[pos]),&(poliBas->y[pos]),
+                                poliBas->nVert[i],1,1);
+        //comprobamos los posibles errores
+        if(poligBas==NULL)
+        {
+            //liberamos la memoria asignada hasta ahora
+            LibMemPolig(resultado);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //recorremos los polígonos de recorte
+        for(j=0;j<poliRec->nPolig;j++)
+        {
+            //comprobamos si los polígonos tienen definidos sus límites
+            if((poliBas->hayLim)&&(poliRec->hayLim))
+            {
+                //comprobamos si los restángulos que encierran a los polígonos
+                //son disjuntos o no
+                pr = RectDisjuntos(poliBas->xMin[i],poliBas->xMax[i],
+                                   poliBas->yMin[i],poliBas->yMax[i],
+                                   poliRec->xMin[j],poliRec->xMax[j],
+                                   poliRec->yMin[j],poliRec->yMax[j]);
+                //comprobamos los casos particulares si los rectángulos son
+                //disjuntos
+                if(pr&&(op==GeocOpBoolInter))
+                {
+                    //EN CASO DE INTERSECCIÓN, NO SE AÑADE NADA
+                    //vamos a la siguiente vuelta del bucle
+                    continue;
+                }
+                else if(pr&&((op==GeocOpBoolUnion)||(op==GeocOpBoolXor)))
+                {
+                    //EN CASO DE UNIÓN O UNIÓN EXCLUSIVA, SE AÑADEN LOS DOS
+                    //POLÍGONOS
+                    //añadimos el polígono base
+                    estado1 = AnyadeDatosPolig(resultado,&(poliBas->x[pos]),
+                                               &(poliBas->y[pos]),
+                                               poliBas->nVert[i],1,1);
+                    //añadimos el polígono de recorte
+                    pos = poliRec->posIni[j];
+                    estado2 = AnyadeDatosPolig(resultado,&(poliRec->x[pos]),
+                                               &(poliRec->y[pos]),
+                                               poliRec->nVert[j],1,1);
+                    //comprobamos los posibles errores, que sólo pueden ser de
+                    //asignación de memoria
+                    if((estado1!=GEOC_ERR_NO_ERROR)||
+                       (estado2!=GEOC_ERR_NO_ERROR))
+                    {
+                        //liberamos la posible memoria asignada hasta ahora
+                        LibMemPoliClip(poligBas);
+                        LibMemPolig(resultado);
+                        //lanzamos el mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                    //vamos a la siguiente vuelta del bucle
+                    continue;
+                }
+                else if(pr&&(op==GeocOpBoolAB))
+                {
+                    //EN CASO DE OPERACIÓN A-B, SE AÑADE EL POLÍGONO BASE
+                    //añadimos el polígono base
+                    estado1 = AnyadeDatosPolig(resultado,&(poliBas->x[pos]),
+                                               &(poliBas->y[pos]),
+                                               poliBas->nVert[i],1,1);
+                    //comprobamos los posibles errores, que sólo pueden ser de
+                    //asignación de memoria
+                    if(estado1!=GEOC_ERR_NO_ERROR)
+                    {
+                        //liberamos la posible memoria asignada hasta ahora
+                        LibMemPoliClip(poligBas);
+                        LibMemPolig(resultado);
+                        //lanzamos el mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                    //vamos a la siguiente vuelta del bucle
+                    continue;
+                }
+                else if(pr&&(op==GeocOpBoolBA))
+                {
+                    //EN CASO DE OPERACIÓN B-A, SE AÑADE EL POLÍGONO DE RECORTE
+                    //añadimos el polígono de recorte
+                    pos = poliRec->posIni[j];
+                    estado1 = AnyadeDatosPolig(resultado,&(poliRec->x[pos]),
+                                               &(poliRec->y[pos]),
+                                               poliRec->nVert[j],1,1);
+                    //comprobamos los posibles errores, que sólo pueden ser de
+                    //asignación de memoria
+                    if(estado1!=GEOC_ERR_NO_ERROR)
+                    {
+                        //liberamos la posible memoria asignada hasta ahora
+                        LibMemPoliClip(poligBas);
+                        LibMemPolig(resultado);
+                        //lanzamos el mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                    //vamos a la siguiente vuelta del bucle
+                    continue;
+                }
+            }
+            //dirección de inicio de los vértices del polígono de recorte
+            pos = poliRec->posIni[j];
+            //creamos el polígono de recorte de trabajo
+            poligRec = CreaPoliClip(&(poliRec->x[pos]),&(poliRec->y[pos]),
+                                    poliRec->nVert[j],1,1);
+            //comprobamos los posibles errores
+            if(poligRec==NULL)
+            {
+                //liberamos la memoria asignada hasta ahora
+                LibMemPoliClip(poligBas);
+                LibMemPolig(resultado);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //recortamos
+            poligAux = PoliBoolGreiner(poligBas,poligRec,op,facPer,&nInt,&nPer);
+            //comprobamos los posibles errores
+            if(poligAux==NULL)
+            {
+                //liberamos la posible memoria asignada hasta ahora
+                LibMemPoliClip(poligBas);
+                LibMemPoliClip(poligRec);
+                LibMemPolig(resultado);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //sumamos el número de intersecciones y de puntos perturbados
+            (*nIntersec) += nInt;
+            (*nPerturb) += nPer;
+            //añadimos los polígonos recortados a la variable de salida
+            if(AnyadePoligPolig(resultado,poligAux)==GEOC_ERR_ASIG_MEMORIA)
+            {
+                //liberamos la posible memoria asignada hasta ahora
+                LibMemPoliClip(poligBas);
+                LibMemPoliClip(poligRec);
+                LibMemPolig(poligAux);
+                LibMemPolig(resultado);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //liberamos la memoria asignada al polígono de esta vuelta del bucle
+            LibMemPoliClip(poligRec);
+            //liberamos la memoria asignada al polígono auxiliar
+            LibMemPolig(poligAux);
+            //reinicializamos el polígono base
+            poligBas = ReiniciaPoliClip(poligBas);
+        }
+        //liberamos la memoria asignada al polígono de esta vuelta del bucle
+        LibMemPoliClip(poligBas);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return resultado;
+}
+/******************************************************************************/
+/******************************************************************************/
+polig* CreaPoligPoliClip(vertPoliClip* poli,
+                         const int coorOrig)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //número de elementos
+    size_t nVert=0,nElem=0;
+    //estructura auxiliar
+    vertPoliClip* aux=poli;
+    //variable de salida
+    polig* result=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos la estructura vacía
+    result = IniciaPoligVacio();
+    //comprobamos los posibles errores
+    if(result==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contamos todos los vértices del polígono
+    nVert = NumeroVertPoliClip(poli);
+    //contemplamos una posible salida rápida
+    if(nVert==0)
+    {
+        //devolvemos la estructura vacía
+        return result;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //número de elementos de los vectores de coordenadas
+    nElem = nVert+2;
+    //asignamos memoria para los vectores de coordenadas de la estructura
+    result->x = (double*)malloc(nElem*sizeof(double));
+    result->y = (double*)malloc(nElem*sizeof(double));
+    //asignamos memoria para los vectores de posición
+    result->posIni = (size_t*)malloc(sizeof(size_t));
+    result->nVert = (size_t*)malloc(sizeof(size_t));
+    //comprobamos los posibles errores de asignación de memoria
+    if((result->x==NULL)||(result->y==NULL)||(result->posIni==NULL)||
+       (result->nVert==NULL))
+    {
+        //liberamos la posible memoria asignada
+        LibMemPolig(result);
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos el número de elementos de los vectores de coordenadas y de
+    //polígonos
+    result->nElem = nElem;
+    result->nPolig = 1;
+    //asignamos la posición de inicio y el número de vértices
+    result->posIni[0] = 1;
+    result->nVert[0] = nVert;
+    //asignamos los separadores de polígono al principio y al final
+    result->x[0] = GeocNan();
+    result->y[0] = GeocNan();
+    result->x[nElem-1] = GeocNan();
+    result->y[nElem-1] = GeocNan();
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos los vértices del polígono
+    for(i=1;i<=nVert;i++)
+    {
+        //distinguimos el tipo de coordenadas a copiar
+        if(coorOrig)
+        {
+            //coordenadas originales
+            result->x[i] = aux->x;
+            result->y[i] = aux->y;
+        }
+        else
+        {
+            //coordenadas perturbadas
+            result->x[i] = aux->xP;
+            result->y[i] = aux->yP;
+        }
+        //siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return result;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AnyadePoligClipPolig(polig* poli,
+                         vertPoliClip* anyade,
+                         const int coorOrig)
+{
+    //número de elementos a añadir
+    size_t nVert=0;
+    //polígono auxiliar
+    polig* aux=NULL;
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contamos todos los vértices del polígono a añadir
+    nVert = NumeroVertPoliClip(anyade);
+    //contemplamos una posible salida rápida
+    if(nVert==0)
+    {
+        //devolvemos la estructura vacía
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos un nuevo polígono con los datos a añadir
+    aux = CreaPoligPoliClip(anyade,coorOrig);
+    //comprobamos los posibles errores
+    if(aux==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //añadimos la nueva estructura
+    estado = AnyadePoligPolig(poli,aux);
+    //comprobamos los posibles errores
+    if(estado!=GEOC_ERR_NO_ERROR)
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(aux);
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //liberamos la memoria utilizada
+    LibMemPolig(aux);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/calctopo.h b/src/libgeoc/calctopo.h
new file mode 100644
index 0000000..899cc8e
--- /dev/null
+++ b/src/libgeoc/calctopo.h
@@ -0,0 +1,81 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geodesia geom
+@{
+\file calctopo.h
+\brief Declaración de funciones para cálculos de topografía.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 05 de julio de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _CALCTOPO_H_
+#define _CALCTOPO_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<math.h>
+#include"libgeoc/constantes.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula el acimut topográfico entre dos puntos.
+\param[in] x1 Coordenada X del primer punto.
+\param[in] y1 Coordenada y del primer punto.
+\param[in] x2 Coordenada X del segundo punto.
+\param[in] y2 Coordenada y del segundo punto.
+\return Acimut del primer al segundo punto, en radianes.
+\date 05 de julio de 2011: Creación de la función.
+\todo Esta función todavía no ha sido probada.
+*/
+double AcimutTopografico(const double x1,
+                         const double y1,
+                         const double x2,
+                         const double y2);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/compilador.h b/src/libgeoc/compilador.h
new file mode 100755
index 0000000..bdd9684
--- /dev/null
+++ b/src/libgeoc/compilador.h
@@ -0,0 +1,96 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup general geopot
+@{
+\file compilador.h
+\brief Declaración de funciones para la detección de compiladores.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 28 de abril de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _COMPILADOR_H_
+#define _COMPILADOR_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdio.h>
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si el compilador utilizado para compilar este fichero es de la
+       familia GCC.
+\param[out] noGnu Identificador de que estamos ante un compilador que no es de
+            la familia GCC, diga lo que diga la variable devuelta por la función
+            (ver nota al final de la documentación). Este argumento sólo es
+            utilizado si en la entrada su valor es distinto de \p NULL. Dos
+            posibles valores de salida:
+            - 0: El compilador \b *ES* de la familia GCC.
+            - Distinto de 0: El compilador \b *NO* \b *ES* de la familia GCC.
+\return Dos posibilidades:
+        - 0: El compilador no pertenece a la familia GCC.
+        - Distinto de 0: El compilador sí pertenece a la familia GCC (para una
+          validez total de este valor hay que tener en cuenta el argumento
+          \em noGnu).
+\note Esta función realiza la comprobación mediante el chequeo de la existencia
+      de la constante simbólica \p __GNUC__. Este hecho hace que la detección
+      del compilador se lleve a cabo durante la compilación del fichero que
+      contiene a esta función, por lo que  hay que tener en cuenta si ésta es
+      llamada desde una función contenida en otro fichero que no fue compilado
+      con un compilador de la familia GCC.
+\note Algunos compiladores, como el Intel C/C++ Compiler (\p icc), definen por
+      defecto la macro \p __GNUC__, por lo que la detección puede ser errónea.
+      Para estos casos ha de tenerse en cuenta el argumento \em noGnu.
+\note En las versiones más recientes de \p icc, el argumento \p -no-gcc suprime
+      la definición de \p __GNUC__.
+\date 11 de octubre de 2009: Creación de la función.
+*/
+int EsCompiladorGNU(int* noGnu);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/constantes.h b/src/libgeoc/constantes.h
new file mode 100755
index 0000000..294f5a6
--- /dev/null
+++ b/src/libgeoc/constantes.h
@@ -0,0 +1,264 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup anespec astro eop general geodesia geom gravim marea
+@{
+\file constantes.h
+\brief Definición de constantes generales.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 02 de marzo de 2009
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _CONSTANTES_H_
+#define _CONSTANTES_H_
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\typedef geoc_char
+\brief Nombre del tipo \p char para almacenar números en \p libgeoc.
+
+       Se declara este tipo para dotar de portabilidad a la biblioteca, debido a
+       que en algunas implementaciones de C la declaración \p char a secas
+       corresponde a un tipo \p unsigned \p char en lugar de a un \p signed
+       \p char, que es el que necesita \p libgeoc cuando almacena un número en
+       un \p char. En la implementación de \p gcc para PowerPC, por ejemplo, el
+       tipo por defecto de un \p char es \p unsigned \p char, lo que hace que se
+       produzcan errores al intentar almacenar números negativos.
+\date 02 de marzo de 2009: Creación del tipo.
+*/
+typedef signed char geoc_char;
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_PI
+\brief Constante \em PI. Tomada del fichero \p gsl_math.h, de la biblioteca GSL.
+\date 02 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_PI (3.14159265358979323846264338328)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_E
+\brief Constante \em e (base de los logaritmos naturales). Tomada del fichero
+       \p gsl_math.h, de la biblioteca GSL.
+\date 03 de octubre de 2010: Creación de la constante.
+*/
+#define GEOC_CONST_E (2.71828182845904523536028747135)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_GR
+\brief Paso de grados centesimales a radianes.
+*/
+#define GEOC_CONST_GR ((GEOC_CONST_PI)/200.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_RG
+\brief Paso de radianes a grados centesimales.
+\date 02 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_RG (1.0/(GEOC_CONST_GR))
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_DR
+\brief Paso de grados sexagesimales en formato decimal a radianes.
+\date 02 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_DR ((GEOC_CONST_PI)/180.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_RD
+\brief Paso de radianes a grados sexagesimales en formato decimal.
+\date 02 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_RD (1.0/(GEOC_CONST_DR))
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_SIMUGAL
+\brief Paso de atracción gravitatoria en el SI (m/s^2) a microgales.
+\date 05 de noviembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_SIMUGAL (1.0e8)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_MJD
+\brief Constante a sustraer a una fecha juliana (en días) para convertirla en
+       fecha juliana modificada (MJD).
+\date 04 de octubre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_MJD (2400000.5)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_J2000
+\brief Constante a sustraer a una fecha juliana (en días) para convertirla en
+       fecha juliana referida a J2000.
+\date 01 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_J2000 (2451545.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_JISGPS
+\brief Fecha juliana del día de inicio de las semanas GPS: 6 de enero de 1980,
+       00:00:00 horas.
+\date 02 de marzo de 2010: Creación de la constante.
+*/
+#define GEOC_CONST_JISGPS (2444244.5)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_MIN_HORA
+\brief Número de minutos que contiene una hora.
+\date 19 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_MIN_HORA (60.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_SEG_HORA
+\brief Número de segundos que contiene una hora.
+\date 01 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_SEG_HORA (3600.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_SEG_MIN
+\brief Número de segundos que contiene un minuto
+\date 19 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_SEG_MIN (60.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_SEG_DIA
+\brief Número de segundos que contiene un día.
+\date 24 de octubre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_SEG_DIA (86400.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_HORAS_DIA
+\brief Número de horas que contiene un día.
+\date 01 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_HORAS_DIA (24.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_DIAS_SIGLO_JUL
+\brief Número de días que contiene un siglo juliano.
+\date 01 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_DIAS_SIGLO_JUL (36525.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_DIAS_SEMANA
+\brief Número de días que contiene una semana.
+\date 02 de marzo de 2010: Creación de la constante.
+*/
+#define GEOC_CONST_DIAS_SEMANA (7.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_DIAS_ANYO_NORM
+\brief Número de días que contiene un año normal.
+\date 02 de marzo de 2010: Creación de la constante.
+*/
+#define GEOC_CONST_DIAS_ANYO_NORM (365.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_DIAS_ANYO_BIS
+\brief Número de días que contiene un año bisiesto.
+\date 02 de marzo de 2010: Creación de la constante.
+*/
+#define GEOC_CONST_DIAS_ANYO_BIS ((GEOC_CONST_DIAS_ANYO_NORM)+1.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_CPD_RH
+\brief Paso de ciclos por día a radianes por hora.
+\date 20 de diciembre de 2009: Creación de la constante.
+ */
+#define GEOC_CONST_CPD_RH (2.0*(GEOC_CONST_PI)/(GEOC_CONST_HORAS_DIA))
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_RH_CPD
+\brief Paso de radianes por hora a ciclos por día.
+\date 20 de diciembre de 2009: Creación de la constante.
+ */
+#define GEOC_CONST_RH_CPD (1.0/(GEOC_CONST_CPD_RH))
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_G
+\brief Constante de gravitación universal, en m^3/(kg*s^2).
+\date 04 de noviembre de 2009: Creación de la constante.
+*/
+#define GEOC_CONST_G (6.67428e-11)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_CONST_VRT
+\brief Velocidad de rotación de la Tierra, en radianes/s.
+\date 21 de enero de 2011: Creación de la constante.
+*/
+#define GEOC_CONST_VRT (7.292115e-5)
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/dpeucker.h b/src/libgeoc/dpeucker.h
new file mode 100644
index 0000000..b4fe38a
--- /dev/null
+++ b/src/libgeoc/dpeucker.h
@@ -0,0 +1,261 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom
+@{
+\file dpeucker.h
+\brief Declaración de funciones para el aligerado de polilíneas basadas en el
+       algoritmo de Douglas-Peucker.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 04 de julio de 2011
+\section Licencia Licencia
+Copyright (c) 2009-2010, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _DPEUCKER_H_
+#define _DPEUCKER_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdlib.h>
+#include<math.h>
+#include"libgeoc/calctopo.h"
+#include"libgeoc/constantes.h"
+#include"libgeoc/eucli.h"
+#include"libgeoc/fgeneral.h"
+#include"libgeoc/segmento.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_DPEUCKER_BUFFER_PTOS
+\brief Número de puntos para ir asignando memoria en bloques para el vector de
+       salida en la funcion \ref AligeraPolilinea.
+\date 06 de julio de 2011: Creación de la constante.
+*/
+#define GEOC_DPEUCKER_BUFFER_PTOS 100
+/******************************************************************************/
+/******************************************************************************/
+/** \enum GEOC_DPEUCKER_ROBUSTO
+\brief Aplicación o no del algoritmo robusto de aligerado de polilíneas.
+\date 10 de julio de 2011: Creación del tipo.
+*/
+enum GEOC_DPEUCKER_ROBUSTO
+{
+    /** \brief \b *NO* se realiza aligerado robusto. */
+    GeocDPeuckerRobNo=111,
+    /** \brief \b *SÍ* se realiza aligerado robusto. */
+    GeocDPeuckerRobSi=112,
+    /** \brief Aligerado semi robusto con \ref AligPolilRobIntersecOrig. */
+    GeocDPeuckerRobOrig=113,
+    /** \brief Aligerado semi robusto con \ref AligPolilRobAutoIntersec. */
+    GeocDPeuckerRobAuto=114
+};
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Elimina vértices de una polilínea mediante un algoritmo inspirado en el
+       de Douglas-Peucker.
+
+       Este algoritmo, comenzando por el primer punto de la polilínea, va
+       uniendo puntos en segmentos de tal forma que se eliminan todos aquellos
+       puntos que queden a una distancia perpendicular menor o igual a \em tol
+       del segmento de trabajo. Así aplicado, pueden ocurrir casos singulares en
+       los que la polilínea aligerada tenga casos de auto intersección entre sus
+       lados resultantes. Para evitar esto, se puede aplicar la versión robusta
+       del algoritmo.
+\param[in] x Vector que contiene las coordenadas X de los vértices de la
+           polilínea de trabajo.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de la
+           polilínea de trabajo.
+\param[in] nPtos Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] tol Tolerancia para eliminar vértices, en las mismas unidades que las
+           coordenadas de los vértices.
+\param[in] robusto Identificador para realizar o no un aligerado robusto. Ha de
+           ser un elemento del tipo enumerado #GEOC_DPEUCKER_ROBUSTO. Varias
+           posibilidades:
+           - #GeocDPeuckerRobNo: No se aplica el algoritmo robusto.
+           - #GeocDPeuckerRobSi: Se aplica el algoritmo robusto completo, que
+             garantiza la no ocurrencia de auto intersecciones en la polilínea
+             resultante. Internamente, primero se aplica el tratamiento robusto
+             de la opción #GeocDPeuckerRobOrig y luego el de la opción
+             #GeocDPeuckerRobAuto.
+           - #GeocDPeuckerRobOrig: Se aplica un algoritmo semi robusto que
+             consiste en garantizar que los segmentos de la polilínea aligerada
+             que se van creando no intersectarán con ninguno de los segmentos
+             que forman los vértices que quedan por procesar de la polilínea
+             original. En casos muy especiales, este algoritmo puede seguir
+             dando lugar a auto intersecciones.
+           - #GeocDPeuckerRobAuto: Se aplica un algoritmo semi robusto que
+             consiste en garantizar que los segmentos de la polilínea aligerada
+             que se van creando no intersectarán con ninguno de los segmentos de
+             la polilínea aligerada creados con anterioridad. En casos muy
+             especiales, este algoritmo puede seguir dando lugar a auto
+             intersecciones.
+\param[in] nPtosRobusto Número de puntos de la polilínea original a utilizar en
+           el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o
+           #GeocDPeuckerRobOrig. Si se pasa el valor 0, se utilizan todos los
+           puntos hasta el final de la polilínea original.
+\param[in] nSegRobusto Número de segmentos de la polilínea aligerada a utilizar
+           en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi
+           o #GeocDPeuckerRobAuto. Si se pasa el valor 0, se utilizan todos los
+           segmentos hasta el inicio de la polilínea aligerada.
+\param[out] nPtosSal Número de puntos de la polilínea aligerada.
+\return Vector de \em nPtosSal elementos que contiene los índices en los
+        vectores \em x e \em y de los vértices que formarán la polilínea
+        aligerada. Si ocurre algún error de asignación de memoria se devuelve el
+        valor \p NULL.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con el valor pasado en \em nPtos.
+\note Esta función asume que \em nPtos es mayor que 0. En caso contrario,
+      devuelve \p NULL.
+\date 07 de julio de 2011: Creación de la función.
+\date 10 de julio de 2011: Cambio del tipo del argumento \em robusto al tipo
+      enumerado #GEOC_DPEUCKER_ROBUSTO.
+\todo Esta función todavía no está probada.
+*/
+size_t* AligeraPolilinea(const double* x,
+                         const double* y,
+                         const size_t nPtos,
+                         const size_t incX,
+                         const size_t incY,
+                         const double tol,
+                         const enum GEOC_DPEUCKER_ROBUSTO robusto,
+                         const size_t nPtosRobusto,
+                         const size_t nSegRobusto,
+                         size_t* nPtosSal);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aproximación robusta al aligerado de líneas consistente en evitar que los
+       segmentos creados intersecten con los de la polilínea original a partir
+       del punto de trabajo actual.
+\param[in] x Vector que contiene las coordenadas X de los vértices de la
+           polilínea de trabajo.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de la
+           polilínea de trabajo.
+\param[in] nPtos Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] ptosAUsar Número de puntos a utilizar de la polilínea original. Si se
+           pasa el valor 0 se utilizan todos los puntos que quedan desde el
+           punto de trabajo hasta el final.
+\param[in] posIni Posición inicial del segmento a chequear.
+\param[in,out] posFin Posición final del segmento a chequear. Al término de la
+               ejecución de la función almacena la posición del punto que hace
+               que el segmento de la polilínea aligerada no intersecte con
+               ninguno de los que quedan de la polilínea original.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con el valor pasado en \em nPtos.
+\note Esta función no comprueba si los índices pasados en los argumentos
+      \em posIni y \em posFin son congruentes con el tamaño de los vectores
+      pasado en \em nPtos.
+\note Esta función no comprueba internamente si la variable \em ptosAUsar es
+      congruente con el valor pasado en \em nPtos.
+\date 07 de julio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void AligPolilRobIntersecOrig(const double* x,
+                              const double* y,
+                              const size_t nPtos,
+                              const size_t incX,
+                              const size_t incY,
+                              const size_t ptosAUsar,
+                              const size_t posIni,
+                              size_t* posFin);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aproximación robusta al aligerado de líneas consistente en evitar que los
+       segmentos creados intersecten con los anteriores de la polilínea
+       aligerada.
+\param[in] x Vector que contiene las coordenadas X de los vértices de la
+           polilínea de trabajo.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de la
+           polilínea de trabajo.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] posAlig Vector de posiciones de \em x e \em y utilizadas en la
+           polilínea aligerada.
+\param[in] nPosAlig Número de elementos de \em posAlig menos el último punto
+           añadido. Esto se hace así para evitar chequear el segmento
+           inmediatamente anterior, que siempre tiene un punto en común (su
+           extremo final) con el de trabajo.
+\param[in] segAUsar Número de segmentos a utilizar de la polilínea aligerada. Si
+           se pasa el valor 0 se utilizan todos los segmentos anteriores.
+\param[in] posIni Posición inicial del segmento a chequear.
+\param[in,out] posFin Posición final del segmento a chequear. Al término de la
+               ejecución de la función almacena la posición del punto que hace
+               que el segmento de la polilínea aligerada no intersecte con
+               ninguno de los anteriormente calculados.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con el valor pasado en \em nPtos.
+\note Esta función no comprueba si los índices pasados en los argumentos
+      \em posIni y \em posFin son congruentes con el tamaño de los vectores
+      pasado en \em nPtos.
+\note Esta función trabaja internamente con el valor absoluto del argumento
+      \em tamRect.
+\date 05 de julio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void AligPolilRobAutoIntersec(const double* x,
+                              const double* y,
+                              const size_t incX,
+                              const size_t incY,
+                              const size_t* posAlig,
+                              const size_t nPosAlig,
+                              const size_t segAUsar,
+                              const size_t posIni,
+                              size_t* posFin);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/errores.h b/src/libgeoc/errores.h
new file mode 100755
index 0000000..3b91f08
--- /dev/null
+++ b/src/libgeoc/errores.h
@@ -0,0 +1,1058 @@
+/* -*- coding: utf-8 -*- */
+/**
+\defgroup errores Módulo ERRORES
+\ingroup anespec eop fichero geodesia geom general geopot gshhs marea matriz
+\ingroup mmcc orden snx texto
+\brief En este módulo se reúnen los ficheros necesarios para realizar el
+       tratamiento de errores que puedan ocurrir en la biblioteca.
+@{
+\file errores.h
+\brief Declaración de funciones y constantes para el tratamiento de errores.
+
+En el momento de la compilación ha de seleccionarse el comportamiento de la
+función \ref GeocError. Para realizar la selección es necesario definir las
+variables para el preprocesador \em ESCRIBE_MENSAJE_ERROR si se quiere que la
+función imprima un mensaje de error y/o \em FIN_PROGRAMA_ERROR si se quiere que
+la función termine la ejecución del programa en curso. Si no se define ninguna
+variable, la función no ejecuta ninguna acción. En \p gcc, las variables para el
+preprocesador se pasan como \em -DXXX, donde \em XXX es la variable a
+introducir.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 06 de marzo de 2009
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include<stdio.h>
+#include<stdlib.h>
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _ERRORES_H_
+#define _ERRORES_H_
+/******************************************************************************/
+/******************************************************************************/
+//GENERAL
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_PLINEA
+\brief Palabra \em Línea para ser utilizada en el mensaje que imprime la macro
+       #GEOC_ERROR. Esta constante se define porque el preprocesador del
+       compilador \p pgcc no soporta letras con tilde escritas directamente en
+       las órdenes a ejecutar por las macros.
+\date 10 de enero de 2011: Creación de la constante.
+*/
+#define GEOC_PLINEA "Línea"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_TIPO_ERR_NADA
+\brief Indicador de que la función \ref GeocError no hace nada.
+\date 09 de enero de 2011: Creación de la constante.
+*/
+#define GEOC_TIPO_ERR_NADA 0
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_TIPO_ERR_MENS_Y_EXIT
+\brief Indicador de que la función \ref GeocError imprime un mensaje descriptivo
+       en la salida de error \em stderr y termina la ejecución del programa en
+       curso.
+\date 09 de enero de 2011: Creación de la constante.
+*/
+#define GEOC_TIPO_ERR_MENS_Y_EXIT 1
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_TIPO_ERR_MENS
+\brief Indicador de que la función \ref GeocError imprime un mensaje descriptivo
+       en la salida de error \em stderr y no termina la ejecución del programa
+       en curso.
+\date 09 de enero de 2011: Creación de la constante.
+*/
+#define GEOC_TIPO_ERR_MENS 2
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_TIPO_ERR_EXIT
+\brief Indicador de que la función \ref GeocError termina la ejecución del
+       programa en curso.
+\date 09 de enero de 2011: Creación de la constante.
+*/
+#define GEOC_TIPO_ERR_EXIT 3
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Indica el tipo de acción que realiza la función \ref GeocError.
+\return Cuatro posibles valores:
+        - #GEOC_TIPO_ERR_NADA: La función \ref GeocError no hace nada.
+        - #GEOC_TIPO_ERR_MENS_Y_EXIT: La función \ref GeocError imprime un
+          mensaje descriptivo en la salida de error \em stderr y termina la
+          ejecución del programa en curso.
+        - #GEOC_TIPO_ERR_MENS: La función \ref GeocError imprime un mensaje
+          descriptivo en la salida de error \em stderr y no detiene la ejecución
+          del programa en curso.
+        - #GEOC_TIPO_ERR_EXIT: La función \ref GeocError detiene la ejecución
+          del programa en curso.
+\date 09 de enero de 2011: Creación de la función.
+*/
+int GeocTipoError(void);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Imprime un mensaje en la salida de error \em stderr y/o sale del programa
+       en ejecución.
+\param[in] mensaje Cadena de texto a imprimir.
+\param[in] funcion Nombre de la función desde donde se ha invocado a esta
+           función.
+\note Si este fichero se compila con las variables para el preprocesador
+      \em ESCRIBE_MENSAJE_ERROR y \em FIN_PROGRAMA_ERROR, esta función imprime
+      el mensaje de error y termina la ejecución del programa en curso mediante
+      la llamada a la función \em exit(EXIT_FAILURE), de la biblioteca estándar
+      de C.
+\note Si este fichero se compila con la variable para el preprocesador
+      \em ESCRIBE_MENSAJE_ERROR, esta función imprime el mensaje de error.
+\note Si este fichero se compila con la variable para el preprocesador
+      \em FIN_PROGRAMA_ERROR, esta función termina la ejecución del programa en
+      curso mediante la llamada a la función \em exit(EXIT_FAILURE), de la
+      biblioteca estándar de C.
+\note Si este fichero se compila sin variables para el preprocesador, esta
+      función no hace nada.
+\date 10 de enero de 2011: Creación de la función.
+*/
+void GeocError(const char mensaje[],
+               const char funcion[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERROR
+\brief Macro para imprimir un mensaje en la salida de error \em stderr y/o sale
+       del programa en ejecución.
+\param[in] mensaje Cadena de texto a imprimir.
+\note Esta macro llama internamente a la función \ref GeocError.
+\note Esta macro pasa como argumento \em funcion a \ref GeocError la variable
+      del preprocesador \em __func__, de C99.
+\date 10 de enero de 2011: Creación de la macro.
+*/
+#define GEOC_ERROR(mensaje) \
+{ \
+    if(GeocTipoError()!=GEOC_TIPO_ERR_NADA) \
+    { \
+        fprintf(stderr,"\n\n"); \
+        fprintf(stderr,"********************\n********************\n"); \
+        fprintf(stderr,GEOC_PLINEA" %d del fichero '%s'\n",__LINE__,__FILE__); \
+        GeocError(mensaje,(const char*)__func__); \
+        fprintf(stderr,"********************\n********************\n\n"); \
+    } \
+    else \
+    { \
+        GeocError(mensaje,(const char*)__func__); \
+    } \
+}
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//GENERAL
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_NO_ERROR
+\brief Indicador de que no ha ocurrido ningun error.
+\date 06 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_NO_ERROR 0
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_LECTURA_FICHERO
+\brief Indicador de que ha ocurrido un error en la lectura de un fichero.
+\date 06 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_LECTURA_FICHERO 1001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_ESCRITURA_FICHERO
+\brief Indicador de que ha ocurrido un error en escritura de un fichero.
+\date 20 de agosto de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_ESCRITURA_FICHERO 1002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_QUEDAN_DATOS_EN_FICHERO
+\brief Indicador de que quedan datos por leer en un fichero.
+\date 06 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_QUEDAN_DATOS_EN_FICHERO 1003
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_NO_QUEDAN_DATOS_EN_FICHERO
+\brief Indicador de que no quedan datos por leer en un fichero.
+\date 25 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_NO_QUEDAN_DATOS_EN_FICHERO 1004
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_NO_HAY_DATOS_EN_FICHERO
+\brief Indicador de que no hay datos a leer en un fichero.
+\date 02 de diciembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_NO_HAY_DATOS_EN_FICHERO 1005
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_LINEA_LARGA_EN_FICHERO
+\brief Indicador de que una línea de un fichero es demasiado larga.
+\date 23 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_LINEA_LARGA_EN_FICHERO 1006
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_LINEA_CORTA_EN_FICHERO
+\brief Indicador de que una línea de un fichero es demasiado corta.
+\date 23 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_LINEA_CORTA_EN_FICHERO 1007
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_ARG_ENTRADA_INCORRECTO
+\brief Indicador de que un argumento de entrada de una función es incorrecto.
+\date 06 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_ARG_ENTRADA_INCORRECTO 1008
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_ASIG_MEMORIA
+\brief Indicador de que ha ocurrido un error en la asignación de memoria.
+\date 06 de marzo de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_ASIG_MEMORIA 1009
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_FUERA_DOMINIO
+\brief Indicador de que ha ocurrido un error porque un dato está fuera de
+       dominio.
+\date 04 de octubre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_FUERA_DOMINIO 1010
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_FUERA_DOMINIO_MAYOR
+\brief Indicador de que ha ocurrido un error porque un dato está fuera de
+       dominio. En este caso, el dato se sale del dominio por arriba (porque es
+       demasiado grande).
+\date 26 de octubre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_FUERA_DOMINIO_MAYOR 1011
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_FUERA_DOMINIO_MENOR
+\brief Indicador de que ha ocurrido un error porque un dato está fuera de
+       dominio. En este caso, el dato se sale del dominio por abajo (porque es
+       demasiado pequeño).
+\date 26 de octubre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_FUERA_DOMINIO_MENOR 1012
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_INTERP
+\brief Indicador de que ha ocurrido un error en una interpolación.
+\date 15 de mayo de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_INTERP 1013
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_INTERP_NO_DATO
+\brief Indicador de que no hay datos para realizar una interpolación.
+\date 30 de mayo de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_INTERP_NO_DATO 1014
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_DIV_ENTRE_CERO
+\brief Indicador de que se ha realizado una división entre cero.
+\date 26 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_DIV_ENTRE_CERO 1015
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_DIM_MATRIZ
+\brief Indicador de dimensiones de una matriz erróneas.
+\date 02 de diciembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_DIM_MATRIZ 1016
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_MATRIZ_SINGULAR
+\brief Indicador de matriz singular.
+\date 12 de marzo de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_MATRIZ_SINGULAR 1017
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//EOP
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_EOP_ERRORES
+\brief Indicador de que ha ocurrido un error porque una estructura eop no
+       contiene información de errores.
+\date 04 de octubre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_EOP_ERRORES 2001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_EOP_DOS_PUNTOS
+\brief Indicador de que ha ocurrido un error porque en una interpolación
+       cuadrática sólo hay dos puntos disponibles.
+\date 12 de octubre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_EOP_DOS_PUNTOS 2002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_EOP_NO_DATOS
+\brief Indicador de que una estructura eop no contiene datos.
+\date 19 de junio de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_EOP_NO_DATOS 2003
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//SINEX
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_LINEA_ILEGAL
+\brief Indicador de que una línea de un fichero SINEX no comienza por una de las
+       cadenas permitidas (#GEOC_SNX_CAD_COMENTARIO, #GEOC_SNX_CAD_INI_CABECERA,
+       #GEOC_SNX_CAD_INI_BLOQUE, #GEOC_SNX_CAD_FIN_BLOQUE o
+       #GEOC_SNX_CAD_INI_DATOS).
+\date 28 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_LINEA_ILEGAL 3001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_LINEA_LARGA
+\brief Indicador de que una línea de un fichero SINEX es demasiado larga (más de
+       #GEOC_SNX_LON_MAX_LIN_FICH carácteres).
+\date 28 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_LINEA_LARGA 3002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_LINEA_CORTA
+\brief Indicador de que una línea de un fichero SINEX es demasiado corta.
+\date 29 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_LINEA_CORTA 3003
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_NO_BLOQUES
+\brief Indicador de que en un fichero SINEX no hay bloques válidos.
+\date 28 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_NO_BLOQUES 3004
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_ID_BLOQUE_DISTINTO
+\brief Indicador de que en un fichero SINEX los identificadores de bloque tras
+       las marcas de inicio y fin son distintos.
+\date 28 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_ID_BLOQUE_DISTINTO 3005
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BLOQUE_NO_INICIO
+\brief Indicador de que en un fichero SINEX un bloque no tiene identificador de
+       inicio.
+\date 28 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BLOQUE_NO_INICIO 3006
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BLOQUE_NO_FIN
+\brief Indicador de que en un fichero SINEX un bloque no tiene identificador de
+       fin.
+\date 28 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BLOQUE_NO_FIN 3007
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_NO_FIN_FICH
+\brief Indicador de que un fichero SINEX no tiene indicador de fin de fichero.
+\date 28 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_NO_FIN_FICH 3008
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_NO_ID_CABECERA
+\brief Indicador de que un fichero SINEX no tiene indicador cabecera.
+\date 29 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_NO_ID_CABECERA 3009
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_FORMATO_CABECERA
+\brief Indicador de que un fichero SINEX tiene una cabecera que no respeta el
+       formato.
+\date 29 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_FORMATO_CABECERA 3010
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_CODFICH_INC
+\brief Indicador de que un fichero SINEX tiene un indicador de código de tipo de
+       fichero incorrecto.
+\date 05 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_CODFICH_INC 3011
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_TIPODOC_INC
+\brief Indicador de que un fichero SINEX tiene un indicador de tipo de documento
+       incorrecto.
+\date 05 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_TIPODOC_INC 3012
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_VERS_INC
+\brief Indicador de que un fichero SINEX tiene un indicador de versión
+       incorrecto.
+\date 30 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_VERS_INC 3013
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_FECHA_INC
+\brief Indicador de que una fecha es incorrecta en un fichero SINEX.
+\date 30 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_FECHA_INC 3014
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_CODOBS_INC
+\brief Indicador de que el código de observación es incorrecto en un fichero
+       SINEX.
+\date 30 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_CODOBS_INC 3015
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_CODCONSTR_INC
+\brief Indicador de que el código de constreñimiento es incorrecto en un fichero
+       SINEX.
+\date 30 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_CODCONSTR_INC 3016
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_SOLCONT_INC
+\brief Indicador de que un código de solución contenida en un fichero SINEX es
+       incorrecto.
+\date 31 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_SOLCONT_INC 3017
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_NSOLCONT_INC
+\brief Indicador de que un código de solución contenida en un fichero SINEX es
+       incorrecto.
+\date 31 de diciembre de 2009: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_NSOLCONT_INC 3018
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_FORM_LINEA_INC
+\brief Indicador de que una línea de un fichero SINEX tiene un formato
+       incorrecto.
+\date 01 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_FORM_LINEA_INC 3019
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BFR_TIPOINF_INC
+\brief Indicador de que el código de tipo de información de un bloque
+       FILE/REFERENCE de un fichero SINEX es incorrecto.
+\date 01 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BFR_TIPOINF_INC 3020
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BND_CODNUT_INC
+\brief Indicador de que el código de modelo de nutación de un bloque
+       NUTATION/DATA de un fichero SINEX es incorrecto.
+\date 03 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BND_CODNUT_INC 3021
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BPD_CODPREC_INC
+\brief Indicador de que el código de modelo de precesión de un bloque
+       PRECESSION/DATA de un fichero SINEX es incorrecto.
+\date 03 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BPD_CODPREC_INC 3022
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSII_GRADLATSEX_INC
+\brief Indicador de que un valor de grados sexagesimales de latitud de un bloque
+       SITE/ID de un fichero SINEX es incorrecto.
+\date 15 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSII_GRADLATSEX_INC 3023
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSII_GRADLONSEX_INC
+\brief Indicador de que un valor de grados sexagesimales de longitud de un bloque
+       SITE/ID de un fichero SINEX es incorrecto.
+\date 15 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSII_GRADLONSEX_INC 3024
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSII_MINSEX_INC
+\brief Indicador de que un valor de minutos sexagesimales de un bloque SITE/ID
+       de un fichero SINEX es incorrecto.
+\date 15 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSII_MINSEX_INC 3025
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSII_SEGSEX_INC
+\brief Indicador de que un valor de segundos sexagesimales de un bloque SITE/ID
+       de un fichero SINEX es incorrecto.
+\date 15 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSII_SEGSEX_INC 3026
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSE_CODSREX_INC
+\brief Indicador de que un código del sistema de referencia utilizado para
+       definir la excentricidad de una antena de un bloque SITE/ECCENTRICITY de
+       un fichero SINEX es incorrecto.
+\date 23 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSE_CODSREX_INC 3027
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_CODGNSS_INC
+\brief Indicador de que un código de constelación GNSS utilizado en un fichero
+       SINEX es incorrecto.
+\date 28 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_CODGNSS_INC 3028
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSAP_CODFREC_INC
+\brief Indicador de que un código frecuencia de satélite GNSS de un bloque
+       SATELLITE/PHASE_CENTER de un fichero SINEX es incorrecto.
+\date 28 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSAP_CODFREC_INC 3029
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSAP_TIPOPCV_INC
+\brief Indicador de que un código indicador de tipo de variación del centro de
+       fase de un bloque SATELLITE/PHASE_CENTER de un fichero SINEX es
+       incorrecto.
+\date 28 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSAP_TIPOPCV_INC 3030
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSAP_MODAPPCV_INC
+\brief Indicador de que un código indicador de modelo de aplicación de las
+       variaciones del centro de fase de un bloque SATELLITE/PHASE_CENTER de un
+       fichero SINEX es incorrecto.
+\date 28 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSAP_MODAPPCV_INC 3031
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_BSOES_IDPARAM_INC
+\brief Indicador de que un identificador de parámetro estadístico de un bloque
+       SOLUTION/STATISTICS de un fichero SINEX es incorrecto.
+\date 28 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_BSOES_IDPARAM_INC 3032
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_IDUNID_INC
+\brief Indicador de que un identificador de unidades utilizado en un fichero
+       SINEX es incorrecto.
+\date 29 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_IDUNID_INC 3033
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_TIPPAR_INC
+\brief Indicador de que un identificador de tipo de parámetro utilizado en un
+       fichero SINEX es incorrecto.
+\date 29 de enero de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_TIPPAR_INC 3034
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_PTRIAN_INC
+\brief Indicador de que un identificador de parte triangular de una matriz
+       simétrica utilizado en un fichero SINEX es incorrecto.
+\date 17 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_PTRIAN_INC 3035
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_TIPOMAT_INC
+\brief Indicador de que un identificador de tipo de matriz utilizado en un
+       fichero SINEX es incorrecto.
+\date 17 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_TIPOMAT_INC 3036
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_SNX_POSMAT_INC
+\brief Indicador de que una posición en una matriz almacenada en un fichero
+       SINEX es incorrecta.
+\date 17 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_SNX_POSMAT_INC 3037
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//GTS
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GTS_VERT_FHULL
+\brief Indicador de que un vértice de una nube de puntos está fuera del
+       \em convex \em hull que la engloba.
+\date 09 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GTS_VERT_FHULL 4001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GTS_VERT_FSUP
+\brief Indicador de que un vértice está fuera de una superficie.
+\date 22 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GTS_VERT_FSUP 4002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GTS_VERT_DUPL
+\brief Indicador de que un vértice de una nube de puntos está duplicado.
+\date 09 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GTS_VERT_DUPL 4003
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GTS_CONF_CONSTR
+\brief Indicador de que ha habido un conflicto con un constreñimiento en un
+       proceso de triangulación.
+\date 09 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GTS_CONF_CONSTR 4004
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//PMAREA
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_PMAREA_NO_HAY_BLOQUE
+\brief Indicador de que no existe un bloque buscado en un fichero.
+\date 24 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_PMAREA_NO_HAY_BLOQUE 5001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_PMAREA_LIN_FICH_INC
+\brief Indicador de que una línea de fichero de parámetros de marea es
+       incorrecta.
+\date 25 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_PMAREA_LIN_FICH_INC 5002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_PMAREA_DEF_BLOQUE_INC
+\brief Indicador de que una definición de bloque de parámetros de marea en un
+       fichero es incorrecta.
+\date 25 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_PMAREA_DEF_BLOQUE_INC 5003
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_PMAREA_LIM_FDOM
+\brief Indicador de que alguno de los límites de la malla está fuera de dominio.
+\date 25 de abril de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_PMAREA_LIM_FDOM 5004
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//GEOPOT
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GEOPOT_GRADO_ORDEN_MAL
+\brief Indicador de que los grados y/u órdenes pasados a una función no son
+       correctos.
+\date 25 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GEOPOT_GRADO_ORDEN_MAL 6001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GEOPOT_GRACE_LINFO_NO
+\brief Indicador de que no hay línea (o la que hay no es la primera) de
+       información general de un fichero de un desarrollo del potencial de la
+       Tierra en armónicos esféricos en formato de GRACE.
+\date 16 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GEOPOT_GRACE_LINFO_NO 6002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GEOPOT_GRACE_LINFO_REPE
+\brief Indicador de que la línea de información general de un fichero de un
+       desarrollo del potencial de la Tierra en armónicos esféricos en formato
+       de GRACE está repetida.
+\date 16 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GEOPOT_GRACE_LINFO_REPE 6003
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GEOPOT_GRACE_CAB_INCOMP
+\brief Indicador de cabecera incompleta en un fichero de un desarrollo del
+       potencial de la Tierra en armónicos esféricos en formato de GRACE está
+       repetida.
+\date 17 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GEOPOT_GRACE_CAB_INCOMP 6004
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GEOPOT_GRACE_MEZCLA_TIPO_COEF
+\brief Indicador de que en un fichero de un desarrollo del potencial de la
+       Tierra en armónicos esféricos en formato de GRACE hay definiciones de
+       coeficientes de distintas versiones.
+\date 23 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GEOPOT_GRACE_MEZCLA_TIPO_COEF 6005
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GEOPOT_GRACE_NLINEAS_DATOS_MAL
+\brief Indicador de que en un fichero de un desarrollo del potencial de la
+       Tierra en armónicos esféricos en formato de GRACE no coinciden el número
+       de líneas de datos leídas en dos pasadas distintas sobre el fichero.
+\date 24 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_GEOPOT_GRACE_NLINEAS_DATOS_MAL 6006
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//NUMLOVE
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_NUMLOVE_NO_HAY_BLOQUE
+\brief Indicador de que no existe un bloque buscado en un fichero.
+\date 29 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_NUMLOVE_NO_HAY_BLOQUE 7001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_NUMLOVE_DEF_BLOQUE_INC
+\brief Indicador de que una línea de fichero de números de Love es incorrecta.
+\date 29 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_NUMLOVE_DEF_BLOQUE_INC 7002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_NUMLOVE_LIN_FICH_INC
+\brief Indicador de que una definición de bloque de números de Love en un
+       fichero es incorrecta.
+\date 29 de noviembre de 2010: Creación de la constante.
+*/
+#define GEOC_ERR_NUMLOVE_LIN_FICH_INC 7003
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//GSHHS
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GSHHS_VERS_ANTIGUA
+\brief Indicador de que la versión de un fichero de GSHHS es antigua.
+\date 16 de abril de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_GSHHS_VERS_ANTIGUA 8001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_GSHHS_CREA_POLI
+\brief Indicador de que ha ocurrido un error de tipo
+       #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG o
+       #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG al crear una estructura \ref polig o
+       \ref polil
+\date 19 de junio de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_GSHHS_CREA_POLI 8002
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//POLIG
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG
+\brief Indicador de que dos vectores de coordenadas no contienen el mismo número
+       de polígonos.
+\date 27 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG 9001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG
+\brief Indicador de que dos vectores de coordenadas no contienen los mismos
+       polígonos.
+\date 27 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG 9002
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//POLIL
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL
+\brief Indicador de que dos vectores de coordenadas no contienen el mismo número
+       de polilíneas.
+\date 03 de junio de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL 10001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL
+\brief Indicador de que dos vectores de coordenadas no contienen las mismas
+       polilíneas.
+\date 03 de junio de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL 10002
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+//PROYEC
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_PROYEC_INI_PROJ
+\brief Indicador de que ha ocurrido un error en la inicialización de una
+       proyección de PROJ.4.
+\date 31 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_PROYEC_INI_PROJ 11001
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_PROYEC_NO_INV_PROJ
+\brief Indicador de que una proyección cartográfica de PROJ.4 no tiene paso
+       inverso.
+\date 31 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_PROYEC_NO_INV_PROJ 11002
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ERR_PROYEC_PROJ_ERROR
+\brief Indicador de que ha ocurrido un error al proyectar un punto con PROJ.4.
+\date 31 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_ERR_PROYEC_PROJ_ERROR 11003
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/eucli.h b/src/libgeoc/eucli.h
new file mode 100755
index 0000000..1ee7d7c
--- /dev/null
+++ b/src/libgeoc/eucli.h
@@ -0,0 +1,237 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom interp
+@{
+\file eucli.h
+\brief Declaración de funciones para la realización de cálculos de geometría
+       euclídea.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 27 de octubre de 2009
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _EUCLI_H_
+#define _EUCLI_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<math.h>
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la distancia euclídea entre dos puntos en el plano.
+\param[in] x1 Coordenada X del punto inicial.
+\param[in] y1 Coordenada Y del punto inicial.
+\param[in] x2 Coordenada X del punto final.
+\param[in] y2 Coordenada Y del punto final.
+\return Distancia euclídea entre los dos puntos.
+\note Esta función asume que todas las coordenadas vienen dadas en las mismas
+      unidades.
+\date 27 de octubre de 2009: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+double Dist2D(const double x1,
+              const double y1,
+              const double x2,
+              const double y2);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la distancia euclídea entre dos puntos en el plano y realiza la
+       propagación de errores correspondiente.
+\param[in] x1 Coordenada X del punto inicial.
+\param[in] y1 Coordenada Y del punto inicial.
+\param[in] x2 Coordenada X del punto final.
+\param[in] y2 Coordenada Y del punto final.
+\param[in] varx1 Varianza de la coordenada X del punto inicial.
+\param[in] varx1y1 Covarianza entre las coordenadas X e Y del punto inicial.
+\param[in] vary1 Varianza de la coordenada Y del punto inicial.
+\param[in] varx2 Varianza de la coordenada X del punto final.
+\param[in] varx2y2 Covarianza entre las coordenadas X e Y del punto final.
+\param[in] vary2 Varianza de la coordenada Y del punto final.
+\param[out] dist Distancia euclídea entre los dos puntos.
+\param[out] varDist Varianza de la distancia calculada.
+\note Esta función asume que todas las coordenadas vienen dadas en las mismas
+      unidades.
+\note Las unidades de las matrices de varianza-covarianza han de ser congruentes
+      con las de las coordenadas pasadas.
+\date 27 de octubre de 2009: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void Dist2DVC(const double x1,
+              const double y1,
+              const double x2,
+              const double y2,
+              const double varx1,
+              const double varx1y1,
+              const double vary1,
+              const double varx2,
+              const double varx2y2,
+              const double vary2,
+              double* dist,
+              double* varDist);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la distancia euclídea entre dos puntos en el espacio.
+\param[in] x1 Coordenada X del punto inicial.
+\param[in] y1 Coordenada Y del punto inicial.
+\param[in] z1 Coordenada Z del punto inicial.
+\param[in] x2 Coordenada X del punto final.
+\param[in] y2 Coordenada Y del punto final.
+\param[in] z2 Coordenada Z del punto final.
+\return Distancia euclídea entre los dos puntos.
+\note Esta función asume que todas las coordenadas vienen dadas en las mismas
+      unidades.
+\date 27 de octubre de 2009: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+double Dist3D(const double x1,
+              const double y1,
+              const double z1,
+              const double x2,
+              const double y2,
+              const double z2);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la distancia euclídea entre dos puntos en el espacio y realiza la
+       propagación de errores correspondiente.
+\param[in] x1 Coordenada X del punto inicial.
+\param[in] y1 Coordenada Y del punto inicial.
+\param[in] z1 Coordenada Z del punto inicial.
+\param[in] x2 Coordenada X del punto final.
+\param[in] y2 Coordenada Y del punto final.
+\param[in] z2 Coordenada Z del punto final.
+\param[in] varx1 Varianza de la coordenada X del punto inicial.
+\param[in] varx1y1 Covarianza entre las coordenadas X e Y del punto inicial.
+\param[in] varx1z1 Covarianza entre las coordenadas X y Z del punto inicial.
+\param[in] vary1 Varianza de la coordenada Y del punto inicial.
+\param[in] vary1z1 Covarianza entre las coordenadas Y y Z del punto inicial.
+\param[in] varz1 Varianza de la coordenada Z del punto inicial.
+\param[in] varx2 Varianza de la coordenada X del punto final.
+\param[in] varx2y2 Covarianza entre las coordenadas X e Y del punto final.
+\param[in] varx2z2 Covarianza entre las coordenadas X y Z del punto final.
+\param[in] vary2 Varianza de la coordenada Y del punto final.
+\param[in] vary2z2 Covarianza entre las coordenadas Y y Z del punto final.
+\param[in] varz2 Varianza de la coordenada Z del punto final.
+\param[out] dist Distancia euclídea entre los dos puntos.
+\param[out] varDist Varianza de la distancia calculada.
+\note Esta función asume que todas las coordenadas vienen dadas en las mismas
+      unidades.
+\note Las unidades de las matrices de varianza-covarianza han de ser congruentes
+      con las de las coordenadas pasadas.
+\date 27 de octubre de 2009: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void Dist3DVC(const double x1,
+              const double y1,
+              const double z1,
+              const double x2,
+              const double y2,
+              const double z2,
+              const double varx1,
+              const double varx1y1,
+              const double varx1z1,
+              const double vary1,
+              const double vary1z1,
+              const double varz1,
+              const double varx2,
+              const double varx2y2,
+              const double varx2z2,
+              const double vary2,
+              const double vary2z2,
+              const double varz2,
+              double* dist,
+              double* varDist);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula el ángulo formado por dos vectores en el plano.
+\param[in] x1 Coordenada X del primer vector.
+\param[in] y1 Coordenada Y del primer vector.
+\param[in] x2 Coordenada X del segundo vector.
+\param[in] y2 Coordenada Y del segundo vector.
+\return Ángulo formado por los dos vectores, en radianes.
+\note Esta función asume que todas las coordenadas vienen dadas en las mismas
+      unidades.
+\date 04 de julio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+double AnguloVecPlano(const double x1,
+                      const double y1,
+                      const double x2,
+                      const double y2);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la altura de un triángulo a partir de las coordenadas de sus
+       vértices.
+\param[in] xVert Coordenada X del vértice a partir del cual se calculará la
+           altura.
+\param[in] yVert Coordenada Y del vértice a partir del cual se calculará la
+           altura.
+\param[in] xBase1 Coordenada X del primer punto de la base del triángulo.
+\param[in] yBase1 Coordenada Y del primer punto de la base del triángulo.
+\param[in] xBase2 Coordenada X del segundo punto de la base del triángulo.
+\param[in] yBase2 Coordenada Y del segundo punto de la base del triángulo.
+\return Altura del triángulo, dada como la longitud del segmento que, partiendo
+        del vértice pasado, corta en ángulo recto a la base.
+\note Esta función asume que todas las coordenadas vienen dadas en las mismas
+      unidades.
+\date 04 de julio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+double AlturaTriangulo(const double xVert,
+                       const double yVert,
+                       const double xBase1,
+                       const double yBase1,
+                       const double xBase2,
+                       const double yBase2);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/fgeneral.h b/src/libgeoc/fgeneral.h
new file mode 100755
index 0000000..2dc3832
--- /dev/null
+++ b/src/libgeoc/fgeneral.h
@@ -0,0 +1,646 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup eop general geom geopot matriz
+@{
+\file fgeneral.h
+\brief Declaración de macros y funciones de utilidad general.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 25 de septiembre de 2009
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _FGENERAL_H_
+#define _FGENERAL_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdlib.h>
+#include<stdint.h>
+#include<float.h>
+#include<math.h>
+#include"libgeoc/constantes.h"
+#include"libgeoc/errores.h"
+#include"libgeoc/geocomp.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_SIGNO
+\brief Macro para determinar el signo de un escalar.
+\param[in] a Un número.
+\return Signo del dato de entrada. Dos posibilidades:
+        - -1.0: El dato pasado es negativo.
+        - 1.0: El dato pasado es positivo o 0.0.
+\date 10 de junio de 2011: Creación de la macro.
+*/
+#define GEOC_SIGNO(a) ((a)>=0.0 ? 1.0 : -1.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_MAX
+\brief Macro para seleccionar el valor máximo entre dos escalares.
+\param[in] a Un número.
+\param[in] b Otro número.
+\return El mayor de los dos argumentos de entrada.
+\date 25 de septiembre de 2009: Creación de la macro.
+*/
+#define GEOC_MAX(a,b) ((a)>(b) ? (a) : (b))
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_MIN
+\brief Macro para seleccionar el valor mínimo entre dos escalares.
+\param[in] a Un número.
+\param[in] b Otro número.
+\return El menor de los dos argumentos de entrada.
+\date 25 de septiembre de 2009: Creación de la macro.
+*/
+#define GEOC_MIN(a,b) ((a)<(b) ? (a) : (b))
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_PARI
+\brief Macro para comprobar si un número de tipo entero es par.
+\param[in] a Un número.
+\return Dos posibilidades:
+        - 0: El número es impar.
+        - 1: El número es par.
+\note Esta macro usa el operador \b % de C para calcular el resto de la división
+      del número pasado entre 2, por lo que el argumento de entrada ha de ser de
+      tipo entero: \p char, \p short, \p int, \p long o \p long \p long (con los
+      identificadores \p signed o \p undigned).
+\date 15 de marzo de 2011: Creación de la macro.
+*/
+#define GEOC_PARI(a) ((a)%2 ? 0 : 1)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ES_CERO
+\brief Macro para comprobar si un número puede considerarse cero con una cierta
+       tolerancia.
+\param[in] num Número a comprobar.
+\param[in] tol Tolerancia. Ha de ser un número \b POSITIVO.
+\return Dos posibilidades:
+        - 0: \em num es distinto de 0, tal que \f$num<=-tol\f$ o \f$num>=tol\f$.
+        - 1: \em num es 0, tal que \f$ -tol < num < tol\f$.
+\note Para que esta macro funcione correctamente, \em tol ha de ser un número
+      \b POSITIVO.
+\date 13 de marzo de 2010: Creación de la macro.
+\todo Esta macro todavía no está probada.
+*/
+#define GEOC_ES_CERO(num,tol) (((num)>(-(tol)))&&((num)<(tol)) ? 1 : 0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_DBL
+\brief Macro para realizar una conversión explícita a tipo de dato \p double.
+\param[in] a Un número.
+\return Órdenes para la conversión explícita del dato pasado a \p double.
+\date 19 de junio de 2011: Creación de la macro.
+*/
+#define GEOC_DBL(a) ((double)(a))
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Indica si hay alguna función compilada en paralelo con OpenMP en el
+       fichero \ref fgeneral.c.
+\param[out] version Cadena identificadora de la versión de OpenMP utilizada.
+            Este argumento sólo se utiliza si su valor de entrada es distinto de
+            \p NULL y si hay alguna función compilada con OpenMP.
+\return Dos posibles valores:
+        - 0: No hay ninguna función compilada en paralelo con OpenMP.
+        - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP.
+\note Esta función asume que el argumento \em version tiene suficiente memoria
+      asignada (si es distinto de \p NULL).
+\date 22 de agosto de 2011: Creación de la función.
+\date 25 de agosto de 2011: Adición del argumento de entrada \em version.
+*/
+int GeocParOmpFgeneral(char version[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Mete un ángulo en el dominio \f$]-2*\pi,2*\pi[\f$.
+\param[in] angulo Valor angular, en radianes.
+\return Valor angular de entrada, en el dominio \f$]-2*\pi,2*\pi[\f$, en
+        radianes.
+\note Esta función elimina todas las vueltas completas a la circunferencia que
+      hacen que el posible valor de entrada esté fuera de los límites del
+      dominio de salida.
+\date 10 de junio de 2011: Creación de la función.
+*/
+double PonAnguloDominio(const double angulo);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca en una lista de coordenadas de una polilínea en una dimensión las
+       posiciones de inicio y fin del segmento que encierra a un punto dado.
+\param[in] valor Coordenada del punto de trabajo, contenido en el segmento a
+           buscar.
+\param[in] lista Lista con las coordenadas de la polilínea.
+\param[in] nDatos Número de elementos de la lista de coordenadas pasadas.
+\param[in] incDatos Posiciones de separación entre cada elemento de \em lista.
+           Ha de ser un número positivo.
+\param[out] posInicio Posición en \em lista de la coordenada inicial del
+            segmento buscado.
+\param[out] posFin Posición en \em lista de la coordenada final del segmento
+            buscado.
+\note Para convertir las posiciones devueltas por la función en las posiciones
+      reales del array en memoria, han de ser multiplicadas por el valor
+      \em incDatos.
+\note En las siguientes notas, cuando se habla de la longitud o el número de
+      elementos de \em lista quiere decir el número de datos de trabajo, no
+      todas las posiciones almacenadas en memoria.
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con el valor \em nDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 2.
+\note Esta función supone que los elementos almacenados en \em lista están
+      ordenados de menor a mayor.
+\note Esta función supone que \em lista[0] <= \em valor >= \em lista[nDatos-1].
+\note Si algún elemento de \em lista es igual a \em valor, su posición será el
+      punto de inicio del segmento calculado, excepto si el elemento de
+      \em lista es el último, en cuyo caso será el punto final.
+\date 06 de diciembre de 2010: Creación de la función.
+*/
+void BuscaSegmento1DInc(const double valor,
+                        const double* lista,
+                        const size_t nDatos,
+                        const size_t incDatos,
+                        size_t* posInicio,
+                        size_t* posFin);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca en una lista de coordenadas de una polilínea en una dimensión las
+       posiciones de inicio y fin del segmento que encierra a un punto dado.
+\param[in] valor Coordenada del punto de trabajo, contenido en el segmento a
+           buscar.
+\param[in] lista Lista con las coordenadas de la polilínea.
+\param[in] nDatos Número de elementos de la lista de coordenadas pasadas.
+\param[out] posInicio Posición en \em lista de la coordenada inicial del
+            segmento buscado.
+\param[out] posFin Posición en \em lista de la coordenada final del segmento
+            buscado.
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con el valor \em nDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 2.
+\note Esta función supone que los elementos almacenados en \em lista están
+      ordenados de menor a mayor.
+\note Esta función supone que \em lista[0] <= \em valor >= \em lista[nDatos-1].
+\note Si algún elemento de \em lista es igual a \em valor, su posición será el
+      punto de inicio del segmento calculado, excepto si el elemento de
+      \em lista es el último, en cuyo caso será el punto final.
+\date 11 de octubre de 2009: Creación de la función.
+*/
+void BuscaSegmento1D(const double valor,
+                     const double* lista,
+                     const size_t nDatos,
+                     size_t* posInicio,
+                     size_t* posFin);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca las posiciones fila y columna del elemento de una matriz
+       correspondiente a la esquina NW del cuadrado que encierra a un punto
+       dado.
+\param[in] xPto Coordenada X del punto de trabajo.
+\param[in] yPto Coordenada Y del punto de trabajo.
+\param[in] xMin Coordenada X mínima (esquina W) de los puntos almacenados en la
+           matriz.
+\param[in] xMax Coordenada X máxima (esquina E) de los puntos almacenados en la
+           matriz.
+\param[in] yMin Coordenada Y mínima (esquina S) de los puntos almacenados en la
+           matriz.
+\param[in] yMax Coordenada Y máxima (esquina N) de los puntos almacenados en la
+           matriz.
+\param[in] pasoX Paso de malla (valor absoluto) en la dirección X.
+\param[in] pasoY Paso de malla (valor absoluto) en la dirección Y.
+\param[out] fil Fila del elemento NW del cuadrado que encierra al punto de
+            trabajo.
+\param[out] col Columna del elemento NW del cuadrado que encierra al punto de
+            trabajo.
+\note Esta función no comprueba internamente si las coordenadas del punto de
+      trabajo son congruentes con los límites de la matriz.
+\note Esta función asume que los pasos de malla son congruentes con los límites
+      de la malla (supone que el cálculo del número de nodos es un número
+      entero o del tipo X.9... o X.0...).
+\note Esta función asume que \em xMin < \em xMax y que \em yMin < \em yMax.
+\note Esta función asume que \em pasoX y \em pasoY han sido introducidos en
+      valor absoluto.
+\date 15 de mayo de 2010: Creación de la función.
+\date 25 de septiembre de 2011: Corrección de error que hacía que se calculase
+      una fila de más en determinados casos.
+\todo Esta función no está probada.
+*/
+void BuscaPosNWEnMalla(const double xPto,
+                       const double yPto,
+                       const double xMin,
+                       const double xMax,
+                       const double yMin,
+                       const double yMax,
+                       const double pasoX,
+                       const double pasoY,
+                       size_t* fil,
+                       size_t* col);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el elemento de mínimo valor en una lista de tipo \p double.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\return Elemento de mínimo valor.
+\note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o
+      superior (se detecta automáticamente en la compilación).
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\date 22 de agosto de 2011: Creación de la función.
+\todo Esta función todavía no está probada con OpenMP.
+*/
+double Minimo(const double* lista,
+              const size_t nDatos,
+              const size_t incDatos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el elemento de máximo valor en una lista de tipo \p double.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\return Elemento de máximo valor.
+\note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o
+      superior (se detecta automáticamente en la compilación).
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\date 22 de agosto de 2011: Creación de la función.
+\todo Esta función todavía no está probada con OpenMP.
+*/
+double Maximo(const double* lista,
+              const size_t nDatos,
+              const size_t incDatos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el elemento de mínimo valor absoluto en una lista de tipo
+       \p double.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\return Elemento de mínimo valor absoluto.
+\note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o
+      superior (se detecta automáticamente en la compilación).
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\date 22 de agosto de 2011: Creación de la función.
+\todo Esta función todavía no está probada con OpenMP.
+*/
+double MinimoAbs(const double* lista,
+                 const size_t nDatos,
+                 const size_t incDatos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el elemento de máximo valor absoluto en una lista de tipo
+       \p double.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\return Elemento de máximo valor absoluto.
+\note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o
+      superior (se detecta automáticamente en la compilación).
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\date 22 de agosto de 2011: Creación de la función.
+\todo Esta función todavía no está probada con OpenMP.
+*/
+double MaximoAbs(const double* lista,
+                 const size_t nDatos,
+                 const size_t incDatos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el elemento de mínimo valor en una lista de tipo \p size_t.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\return Elemento de mínimo valor.
+\note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o
+      superior (se detecta automáticamente en la compilación).
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\date 24 de agosto de 2011: Creación de la función.
+\todo Esta función todavía no está probada con OpenMP.
+*/
+size_t MinimoSizeT(const size_t* lista,
+                   const size_t nDatos,
+                   const size_t incDatos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el elemento de máximo valor en una lista de tipo \p size_t.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\return Elemento de máximo valor.
+\note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o
+      superior (se detecta automáticamente en la compilación).
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\date 24 de agosto de 2011: Creación de la función.
+\todo Esta función todavía no está probada con OpenMP.
+*/
+size_t MaximoSizeT(const size_t* lista,
+                   const size_t nDatos,
+                   const size_t incDatos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca las posiciones que ocupan en una lista de tipo \p double los
+       elementos de menor y mayor valor.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\param[out] posMin Posición en \em lista del elemento de menor valor.
+\param[out] posMax Posición en \em lista del elemento de mayor valor.
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\note Si hay varios elementos en la lista que se corresponden con el valor menor
+      o mayor, la posición devuelta es la correspondiente al primer elemento a
+      partir del inicio.
+\note Las posiciones devueltas lo son atendiendo al parámetro \em nDatos, por lo
+      que para obtener las posiciones reales del elemento en memoria han de ser
+      multiplicadas por el valor \em incDatos.
+\date 27 de octubre de 2009: Creación de la función.
+\date 29 de mayo de 2011: Adición del argumento de entrada \em incDatos.
+*/
+void MinMax(const double* lista,
+            const size_t nDatos,
+            const size_t incDatos,
+            size_t* posMin,
+            size_t* posMax);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca las posiciones que ocupan en una lista los elementos de menor y
+       mayor valor absoluto.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\param[out] posMin Posición en \em lista del elemento de menor valor absoluto.
+\param[out] posMax Posición en \em lista del elemento de mayor valor absoluto.
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\note Si hay varios elementos en la lista que se corresponden con el valor menor
+      o mayor, la posición devuelta es la correspondiente al primer elemento a
+      partir del inicio.
+\note Las posiciones devueltas lo son atendiendo al parámetro \em nDatos, por lo
+      que para obtener las posiciones reales del elemento en memoria han de ser
+      multiplicadas por el valor \em incDatos.
+\date 27 de octubre de 2009: Creación de la función.
+\date 29 de mayo de 2011: Adición del argumento de entrada \em incDatos.
+*/
+void MinMaxAbs(const double* lista,
+               const size_t nDatos,
+               const size_t incDatos,
+               size_t* posMin,
+               size_t* posMax);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca las posiciones que ocupan en una lista de tipo \p size_t los
+       elementos de menor y mayor valor.
+\param[in] lista Lista de valores.
+\param[in] nDatos Número de elementos de la lista de valores.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em lista. Este argumento siempre ha de ser un número positivo.
+\param[out] posMin Posición en \em lista del elemento de menor valor.
+\param[out] posMax Posición en \em lista del elemento de mayor valor.
+\note Esta función no comprueba internamente si la longitud de \em lista es
+      congruente con los valores de \em nDatos e \em incDatos.
+\note Esta función supone que \em lista contiene un número de elementos >= 1.
+\note Si hay varios elementos en la lista que se corresponden con el valor menor
+      o mayor, la posición devuelta es la correspondiente al primer elemento a
+      partir del inicio.
+\note Las posiciones devueltas lo son atendiendo al parámetro \em nDatos, por lo
+      que para obtener las posiciones reales del elemento en memoria han de ser
+      multiplicadas por el valor \em incDatos.
+\date 08 de enero de 2010: Creación de la función.
+\date 29 de mayo de 2011: Adición del argumento de entrada \em incDatos.
+*/
+void MinMaxSizeT(const size_t* lista,
+                 const size_t nDatos,
+                 const size_t incDatos,
+                 size_t* posMin,
+                 size_t* posMax);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Asigna memoria para una matriz bidimensional en estilo C.
+\param[in] fil Número de filas de la matriz.
+\param[in] col Número de columnas de la matriz.
+\return Puntero a la matriz creada. Si ocurre algún error de asignación de
+        memoria, se devuelve NULL.
+\note La memoria asignada no se inicializa a ningún valor.
+\note Los datos se almacenan en ROW MAJOR ORDER de forma contigua en memoria.
+\note Esta función no controla si alguna de las dimensiones pasadas es 0.
+\date 14 de enero de 2010: Creación de la función.
+\date 02 de diciembre de 2010: Reprogramación de la función para que los datos
+      se almacenen en memoria de forma contigua.
+*/
+double** AsigMemMatrizC(const size_t fil,
+                        const size_t col);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Libera memoria de una matriz bidimensional en estilo C.
+\param[in] matriz Puntero al espacio de memoria a liberar.
+\date 14 de enero de 2010: Creación de la función.
+\date 27 de febrero de 2010: Corregido bug que hacía que la función diese error
+      si se le pasaba un puntero a NULL.
+*/
+void LibMemMatrizC(double** matriz);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula las posiciones de comienzo de elementos repetidos en un vector.
+
+       - Para un vector de datos [1,2,2,3,4,4] se devuelve el vector de
+         posiciones [0,1,3,4].
+       - Para un vector de datos [1,2,2,3,4] se devuelve el vector de posiciones
+         [0,1,3,4].
+       - Para un vector de datos [1,1,1,1,1] se devuelve el vector de posiciones
+         [0].
+       - Para un vector de datos [1] se devuelve el vector de posiciones [0].
+\param[in] datos Vector de datos.
+\param[in] nDatos Número de elementos de \em datos. No puede ser 0.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em datos. Este argumento siempre ha de ser un número positivo.
+\param[out] nRepe Número de elementos del vector de posiciones de comienzo de
+            elementos repetidos devuelto por la función.
+\return Vector, de \em nRepe elementos, que almacena las posiciones de comienzo
+        de elementos repetidos en el vector \em datos. Las posiciones devueltas
+        no tienen en cuenta el argumento \em incDatos, luego no son posiciones
+        en el array realmente almacenado en memoria. Los índices comienzan en 0.
+        Si ocurre un error de asignación de memoria se devuelve \p NULL.
+\note Esta función no comprueba internamente el vector pasado contiene
+      suficiente memoria.
+\note Esta función no comprueba internamente si las dimensiones del vector
+      pasado son congruentes con el espacio almacenado en memoria.
+\note Esta función no comprueba internamente si el argumento \em nDatos es
+      igual a 0.
+\note Para calcular con los valores de salida las posiciones reales en el vector
+      \em datos es necesario tener en cuenta el argumento \em incDatos.
+\date 02 de febrero de 2011: Creación de la función.
+*/
+size_t* PosRepeEnVector(const double* datos,
+                        const size_t nDatos,
+                        const size_t incDatos,
+                        size_t* nRepe);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula el número de elementos repetidos en un vector a partir de la
+       salida de la función \ref PosRepeEnVector.
+
+       - Para un vector de datos [1,2,2,3,4,4], donde la función
+         \ref PosRepeEnVector devuelve el vector de posiciones [0,1,3,4], esta
+         función devuelve el vector [1,2,1,2].
+       - Para un vector de datos [1,2,2,3,4], donde la función
+         \ref PosRepeEnVector devuelve el vector de posiciones [0,1,3,4], esta
+         función devuelve el vector [1,2,1,1].
+       - Para un vector de datos [1,1,1,1,1], donde la función
+         \ref PosRepeEnVector devuelve el vector de posiciones [0], esta función
+         devuelve el vector [5].
+       - Para un vector de datos [1], donde la función
+         \ref PosRepeEnVector devuelve el vector de posiciones [0], esta función
+         devuelve el vector [1].
+\param[in] pos Vector de posiciones devuelto por la función
+           \ref PosRepeEnVector.
+\param[in] nPos Número de elementos de \em pos. No puede ser 0.
+\param[in] nElemVecOrig Número de elementos del vector de datos original.
+\return Vector, de \em nPos elementos, que almacena el número de elementos
+        repetidos a partir de cada posición (incluida ésta) almacenada en el
+        vector \em pos. Si ocurre un error de asignación de memoria se devuelve
+        \p NULL.
+\note Esta función no comprueba internamente el vector pasado contiene
+      suficiente memoria.
+\note Esta función no comprueba internamente si las dimensiones del vector
+      pasado son congruentes con el espacio almacenado en memoria.
+\note Esta función no comprueba internamente si el argumento \em nPos es igual a
+      0.
+\date 02 de febrero de 2011: Creación de la función.
+*/
+size_t* NumElemRepeEnVector(const size_t* pos,
+                            const size_t nPos,
+                            const size_t nElemVecOrig);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica un factor de escala y una traslación (en este orden) a los
+       elementos de un vector.
+\param[in,out] vector Vector de datos. Al término de la ejecución de la función,
+               se ha aplicado un factor de escala y una traslación (en este
+               orden) a los elementos del vector.
+\param[in] nElem Número de elementos de \em vector.
+\param[in] inc Posiciones de separación entre los elementos del vector
+           \em vector. Este argumento siempre ha de ser un número positivo.
+\param[in] escala Factor de escala a aplicar.
+\param[in] traslada Traslación a aplicar.
+\note Primero se aplica el factor de escala y luego la traslación.
+\note Esta función asume que el vector de entrada \em vector tiene memoria
+      asignada.
+\date 18 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void EscalaYTrasladaVector(double* vector,
+                           const size_t nElem,
+                           const size_t inc,
+                           const double escala,
+                           const double traslada);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica una traslación y un factor de escala (en este orden) a los
+       elementos de un vector.
+\param[in,out] vector Vector de datos. Al término de la ejecución de la función,
+               se ha aplicado una traslación y un factor de escala (en este
+               orden) a los elementos del vector.
+\param[in] nElem Número de elementos de \em vector.
+\param[in] inc Posiciones de separación entre los elementos del vector
+           \em vector. Este argumento siempre ha de ser un número positivo.
+\param[in] escala Factor de escala a aplicar.
+\param[in] traslada Traslación a aplicar.
+\note Primero se aplica la traslación y luego el factor de escala.
+\note Esta función asume que el vector de entrada \em vector tiene memoria
+      asignada.
+\date 18 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void TrasladaYEscalaVector(double* vector,
+                           const size_t nElem,
+                           const size_t inc,
+                           const double escala,
+                           const double traslada);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/general.h b/src/libgeoc/general.h
new file mode 100755
index 0000000..c7d5f0f
--- /dev/null
+++ b/src/libgeoc/general.h
@@ -0,0 +1,61 @@
+/* -*- coding: utf-8 -*- */
+/**
+\defgroup general Módulo GENERAL
+\brief En este módulo se reúnen constantes, macros y funciones de utilidad
+       general.
+@{
+\file general.h
+\brief Inclusión de archivos de cabecera para la utilización de la biblioteca
+       GENERAL.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 16 de febrero de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _GENERAL_H_
+#define _GENERAL_H_
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/compilador.h"
+#include"libgeoc/constantes.h"
+#include"libgeoc/fgeneral.h"
+#include"libgeoc/ventorno.h"
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/geocnan.h b/src/libgeoc/geocnan.h
new file mode 100755
index 0000000..c55c1ef
--- /dev/null
+++ b/src/libgeoc/geocnan.h
@@ -0,0 +1,233 @@
+/* -*- coding: utf-8 -*- */
+/**
+\defgroup geocnan Módulo GEOCNAN
+\ingroup geom matriz gshhs
+\brief En este módulo se reúnen constantes y funciones para el trabajo con
+       valores Not-a-Number.
+@{
+\file geocnan.h
+\brief Declaración de constantes y funciones para el trabajo con valores
+       Not-a-Number.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 26 de mayo de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2010-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _GEOCNAN_H_
+#define _GEOCNAN_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include<math.h>
+#include"libgeoc/errores.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_NAN
+\brief Constante \em Not-a-Number (\em NaN). Se define como \em 0.0/0.0.
+\date 21 de diciembre de 2010: Creación de la constante.
+*/
+#define GEOC_NAN (0.0/0.0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_NAN_TXT
+\brief Constante \em Not-a-Number (\em NaN), como cadena de texto.
+\date 22 de septiembre de 2011: Creación de la constante.
+*/
+#define GEOC_NAN_TXT "NaN"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_NAN_LON_FORM_NUM_SIMPLE
+\brief Longitud de una cadena de texto auxiliar para el cálculo de la longitud
+       de una cadena de formato numérico simple.
+\date 22 de septiembre de 2011: Creación de la constante.
+*/
+#define GEOC_NAN_LON_FORM_NUM_SIMPLE 100
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Devuelve el número que representa el valor \em Not-a-Number (\em NaN),
+       que se define como el resultado de la evaluación de la operación
+       \em 0.0/0.0.
+\return Valor NaN.
+\note Esta función devuelve el valor almacenado en la constante #GEOC_NAN.
+\date 21 de diciembre de 2010: Creación de la función.
+\date 24 de mayo de 2011: Ahora la función devuelve el valor absoluto de
+      #GEOC_NAN, calculado con la función <tt>fabs()</tt> de C estándar. Se ha
+      hecho así porque, a veces, al imprimir un valor normal de #GEOC_NAN, éste
+      aparecía con un signo negativo delante.
+\date 22 de septiembre de 2011: Lo del <tt>fabs()</tt> no funciona. Parece que
+      los problemas en la impresión dependen del compilador y los flags de
+      optimización utilizados. No obstante, se mantiene el uso de la función
+      <tt>fabs()</tt> en el código.
+\todo Esta función todavía no está probada.
+*/
+double GeocNan(void);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un número es \em Not-a-Number (\em NaN).
+\param[in] valor Un número.
+\return Dos posibilidades:
+        - 0: El número pasado no es NaN.
+        - Distinto de 0: El número pasado sí es NaN.
+\note Esta función ha sido adaptada de LAPACK 3.2.1, disnan.f,
+      (http://www.netlib.org/lapack).
+\date 21 de diciembre de 2010: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+int EsGeocNan(const double valor);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca valores #GEOC_NAN es un vector de datos.
+\param[in] datos Vector de trabajo.
+\param[in] nDatos Número de elementos que contiene el vector \em datos.
+\param[in] incDatos Posiciones de separación entre los elementos del vector
+           \em datos. Este argumento siempre ha de ser un número positivo.
+\param[out] nNan Número de valores #GEOC_NAN encontrados, que es el número de
+            elementos del vector de salida.
+\return Varias posibilidades:
+        - Si todo ha ido bien, vector que contiene las posiciones en el vector
+          original donde se almacena el valor #GEOC_NAN.
+        - NULL: Pueden haber ocurrido dos cosas:
+          - Si \em nNan vale 0, en los datos de entrada no hay ningún valor
+            #GEOC_NAN.
+          - Si \em nNan es mayor que 0, ha ocurrido un error interno de
+            asignación de memoria.
+\note Esta función no comprueba si el número de elementos del vector \em datos
+      es congruente con los valores pasados en \em nDatos e \em incDatos.
+\note Las posiciones de los elementos #GEOC_NAN encontradas se refieren al
+      número de elementos \em nDatos del vector de trabajo. Para encontrar la
+      posición real en memoria es necesario tener en cuenta la variable
+      \em incDatos.
+\date 26 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+size_t* PosGeocNanEnVector(const double* datos,
+                           const size_t nDatos,
+                           const size_t incDatos,
+                           size_t* nNan);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula el número de carácteres que ocupa un valor numérico imprimido con
+       determinado formato.
+\param[in] formato Cadena de formato para imprimir \b *UN \b ÚNICO* valor
+           numérico (de cualquier tipo).
+\return Número de carácteres que ocupa un valor numérico imprimido según el
+        formato pasado.
+\note Esta función no comprueba internamente si la cadena de formato es
+      correcta.
+\note \em formato no puede dar lugar a un texto impreso de más de
+      #GEOC_NAN_LON_FORM_NUM_SIMPLE carácteres.
+\date 22 de septiembre de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+size_t LonFormatoNumSimple(const char formato[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Convierte una cadena de formato para imprimir un \b *ÚNICO* número en una
+       cadena para imprimir texto con el mismo ancho que el que tendría de haber
+       sido imprimida como número.
+\param[in] formatoNum Cadena de formato para imprimir \b *UN \b ÚNICO* valor
+           numérico (de cualquier tipo).
+\param[out] formatoTexto Cadena de texto que almacenará la cadena de formato
+            para la impresión en modo texto.
+\note Esta función no comprueba internamente si la cadena de formato numérico es
+      correcta.
+\note \em formatoNum no puede dar lugar a un texto impreso de más de
+      #GEOC_NAN_LON_FORM_NUM_SIMPLE carácteres.
+\note Esta función asume que \em formatoTexto tiene espacio suficiente para
+      almacenar la cadena de salida.
+\note Si \em formatoNum contiene al final carácteres de retorno de carro y salto
+      de línea, estos no son tenidos en cuenta en la creación de la cadena de
+      salida (no son tenidos en cuenta en el sentido de que no se añaden al
+      formato de salida, pero el espacio que ocupan sí se computa).
+\date 22 de septiembre de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void FormatoNumFormatoTexto(const char formatoNum[],
+                            char formatoTexto[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Imprime valores Not-a-Number en modo texto (#GEOC_NAN_TXT) es un fichero.
+\param[in] idFich Identificador del fichero de trabajo, abierto para escribir.
+\param[in] nNan Número de veces que se ha de imprimir el valor #GEOC_NAN_TXT,
+           una a continuación de otra.
+\param[in] formato Cadena de formato para la impresión de cada valor
+           #GEOC_NAN_TXT.
+\param[in] retCarro Identificador para añadir un retorno de carro y cambio de
+           línea al final de la impresión de datos, independientemente del valor
+           pasado en el argumento \em formato. Dos posibilidades:
+           - 0: No se imprime retorno de carro y cambio de línea al final.
+           - Distinto de 0: Sí se imprime retorno de carro y cambio de línea al
+             final.
+\note Esta función no comprueba internamente si el fichero de entrada está
+      abierto correctamente.
+\note Esta función no comprueba internamente si la cadena de formato es
+      correcta.
+\note Si se ha indicado que se imprima salto de línea y retorno de carro al
+      final, este se imprime aunque \em nNan valga 0.
+\date 22 de septiembre de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+void ImprimeGeocNanTexto(FILE* idFich,
+                         const size_t nNan,
+                         const char formato[],
+                         const int retCarro);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/geocomp.h b/src/libgeoc/geocomp.h
new file mode 100644
index 0000000..79768ba
--- /dev/null
+++ b/src/libgeoc/geocomp.h
@@ -0,0 +1,208 @@
+/* -*- coding: utf-8 -*- */
+/**
+\defgroup geocomp Módulo GEOC-OMP
+\ingroup anespec general geodesia geom geopot gravim mmcc
+\brief En este módulo se reúnen constantes y funciones para la obtención de
+       información de la implementación de OpenMP usada.
+@{
+\file geocomp.h
+\brief Declaración de macros y funciones para la obtención de información de la
+       implementación de OpenMP usada.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 25 de agosto de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _GEOCOMP_H_
+#define _GEOCOMP_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<string.h>
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_F_1_0
+\brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 1.0 de
+       OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_F_1_0 (199810)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_F_2_0
+\brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 2.0 de
+       OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_F_2_0 (200203)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_F_2_5
+\brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 2.5 de
+       OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_F_2_5 (200505)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_F_3_0
+\brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 3.0 de
+       OpenMP.
+\date 22 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_F_3_0 (200805)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_F_3_1
+\brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 3.1 de
+       OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_F_3_1 (201107)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_V_1_0
+\brief Cadena de texto identificadora de la versión 1.0 de OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_V_1_0 "1.0"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_V_2_0
+\brief Cadena de texto identificadora de la versión 2.0 de OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_V_2_0 "2.0"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_V_2_5
+\brief Cadena de texto identificadora de la versión 2.5 de OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_V_2_5 "2.5"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_V_3_0
+\brief Cadena de texto identificadora de la versión 3.0 de OpenMP.
+\date 22 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_V_3_0 "3.0"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_V_3_1
+\brief Cadena de texto identificadora de la versión 3.1 de OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_V_3_1 "3.1"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_F_DESC
+\brief Fecha de versión de OpenMP desconocida.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_F_DESC (0)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_V_DESC
+\brief Versión de OpenMP correspondiente a un valor desconocido de la macro
+       \p _OPENMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_V_DESC "0.0"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_OMP_LON_CAD_VERS
+\brief Longitud de la cadena de texto que almacena la versión de OpenMP.
+\date 25 de agosto de 2011: Creación de la constante.
+*/
+#define GEOC_OMP_LON_CAD_VERS (10)
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la versión de OpenMP a partir del valor de la macro \p _OPENMP.
+\param[in] macro_OPENMP Valor de la macro \p _OPENMP.
+\param[out] version Versión de OpenMP correspondiente al valor de la macro. Si
+            el argumento \em macro_OPENMP almacena un valor desconocido, se
+            devuelve #GEOC_OMP_V_DESC.
+\note Esta función asume que \em version tiene asignada suficiente memoria: como
+      mínimo, espacio para una cadena de #GEOC_OMP_LON_CAD_VERS carácteres.
+\date 25 de agosto de 2011: Creación de la función.
+*/
+void VersionOpenMP(const int macro_OPENMP,
+                   char version[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la fecha (el valor de la macro \p _OPENMP) de una versión de
+       OpenMP dada.
+\param[in] version Cadena de versión de OpenMP, tal como es calculada por la
+           función \ref VersionOpenMP.
+\return Fecha, en el formato YYYYMM, correspondiente a la versión. Este valor
+        debería coincidir con la macro \p _OPENMP de la implementación de OpenMP
+        usada.
+\note En caso de pasar una cadena de versión errónea o desconocida, la función
+      devuelve #GEOC_OMP_F_DESC.
+\date 25 de agosto de 2011: Creación de la función.
+*/
+int FechaVersionOpenMP(const char version[]);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/geom.h b/src/libgeoc/geom.h
new file mode 100755
index 0000000..134cb7b
--- /dev/null
+++ b/src/libgeoc/geom.h
@@ -0,0 +1,64 @@
+/* -*- coding: utf-8 -*- */
+/**
+\defgroup geom Módulo GEOMETRIA
+\brief En este módulo se reúnen las funciones necesarias para el tratamiento de
+       problemas de geometría.
+@{
+\file geom.h
+\brief Inclusión de ficheros de cabecera para el trabajo con la biblioteca
+       GEOMETRIA.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 26 de diciembre de 2009
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _GEOM_H_
+#define _GEOM_H_
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/dpeucker.h"
+#include"libgeoc/eucli.h"
+#include"libgeoc/greiner.h"
+#include"libgeoc/polig.h"
+#include"libgeoc/polil.h"
+#include"libgeoc/ptopol.h"
+#include"libgeoc/recpolil.h"
+#include"libgeoc/segmento.h"
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/greiner.h b/src/libgeoc/greiner.h
new file mode 100755
index 0000000..37fe416
--- /dev/null
+++ b/src/libgeoc/greiner.h
@@ -0,0 +1,827 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file greiner.h
+\brief Definición de estructuras y declaración de funciones para el recorte de
+       polígonos mediante el algoritmo de Greiner-Hormann
+       (http://davis.wpi.edu/~matt/courses/clipping/).
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 14 de mayo de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _GREINER_H_
+#define _GREINER_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdlib.h>
+#include<math.h>
+#include<float.h>
+#include<time.h>
+#include"libgeoc/errores.h"
+#include"libgeoc/eucli.h"
+#include"libgeoc/geocnan.h"
+#include"libgeoc/polig.h"
+#include"libgeoc/ptopol.h"
+#include"libgeoc/segmento.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_GREINER_FAC_EPS_PERTURB
+\brief Factor de escala para el cálculo de la cantidad mínima de perturbación
+       para un valor. Esta variable se usa en la función \ref CantPerturbMin.
+
+       A base de hacer pruebas he visto que es desaconsejable un valor por
+       debajo de 10.0.
+\date 22 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_GREINER_FAC_EPS_PERTURB 10.0
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_GREINER_BUFFER_PTOS
+\brief Número de puntos para ir asignando memoria en bloques para los polígonos
+       de salida en la funcion \ref Paso3Greiner. Ha de ser un número mayor o
+       igual a 2.
+\date 23 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_GREINER_BUFFER_PTOS 100
+/******************************************************************************/
+/******************************************************************************/
+/** \enum GEOC_OP_BOOL_POLIG
+\brief Operación booleana entre polígonos.
+\date 21 de mayo de 2011: Creación del tipo.
+*/
+enum GEOC_OP_BOOL_POLIG
+{
+    /** \brief Intersección entre polígonos. */
+    GeocOpBoolInter=111,
+    /** \brief Unión de polígonos. */
+    GeocOpBoolUnion=112,
+    /** \brief Unión exclusiva de polígonos. */
+    GeocOpBoolXor=113,
+    /** \brief Operación A-B. */
+    GeocOpBoolAB=114,
+    /** \brief Operación B-A. */
+    GeocOpBoolBA=115
+};
+/******************************************************************************/
+/******************************************************************************/
+/** \struct _vertPoliClip
+\brief Estructura de definición de un vértice de un polígono usado en
+       operaciones de recorte. El polígono se almacena en memoria como una lista
+       doblemente enlazada de vértices.
+\date 14 de mayo de 2011: Creación de la estructura.
+*/
+typedef struct _vertPoliClip
+{
+    /** \brief Coordenada X del vértice. */
+    double x;
+    /** \brief Coordenada Y del vértice. */
+    double y;
+    /** \brief Coordenada X perturbada del vértice. */
+    double xP;
+    /** \brief Coordenada Y perturbada del vértice. */
+    double yP;
+    /** \brief Vértice anterior. */
+    struct _vertPoliClip* anterior;
+    /** \brief Vértice siguiente. */
+    struct _vertPoliClip* siguiente;
+    /**
+    \brief Enlace al mismo nodo, perteneciente a otro polígono.
+
+           Los puntos de intersección pertenecen tanto al polígono de recorte
+           como al recortado.
+    */
+    struct _vertPoliClip* vecino;
+    /**
+    \brief Indicador de primer punto de polígono.
+
+           Dos posibilidades:
+           - 0: No es el primer punto del polígono.
+           - Distinto de 0: Sí es el primer punto del polígono.
+    */
+    char ini;
+    /**
+    \brief Indicador de punto de intersección.
+
+           Dos posibilidades:
+           - 0: No es un punto de intersección.
+           - Distinto de 0: Sí es un punto de intersección.
+    */
+    char interseccion;
+    /**
+    \brief Indicador de punto de entrada al interior del otro polígono.
+
+           Dos posibilidades:
+           - 0: No es un punto de entrada, es de salida.
+           - Distinto de 0: Sí es un punto de entrada.
+    */
+    char entrada;
+    /**
+    \brief Indicador de punto visitado.
+
+           Dos posibilidades:
+           - 0: No ha sido visitado.
+           - Distinto de 0: Sí ha sido visitado.
+    */
+    char visitado;
+    /** \brief Distancia, en tanto por uno, de un nodo de intersección con
+               respecto al primer vértice del segmento que lo contiene. */
+    double alfa;
+}vertPoliClip;
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea un vértice de tipo \ref _vertPoliClip y lo inserta entre otros dos.
+\param[in] x Coordenada X del vértice.
+\param[in] y Coordenada Y del vértice.
+\param[in] anterior Vértice anterior (puede ser \p NULL).
+\param[in] siguiente Vértice siguiente (puede ser \p NULL).
+\param[in] vecino Campo _vertPoliClip::vecino (puede ser \p NULL).
+\param[in] ini Campo _vertPoliClip::ini.
+\param[in] interseccion Campo _vertPoliClip::interseccion.
+\param[in] entrada Campo _vertPoliClip::entrada.
+\param[in] visitado Campo _vertPoliClip::visitado.
+\param[in] alfa Campo _vertPoliClip::alfa.
+\return Puntero al nuevo vértice creado. Si se devuelve \p NULL, ha ocurrido un
+        error de asignación de memoria.
+\date 18 de mayo de 2011: Creación de la función.
+\date 21 de mayo de 2011: Eliminación del algumento \em siguientePoli y adición
+      del argumento \em ini.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* CreaVertPoliClip(const double x,
+                               const double y,
+                               vertPoliClip* anterior,
+                               vertPoliClip* siguiente,
+                               vertPoliClip* vecino,
+                               const char ini,
+                               const char interseccion,
+                               const char entrada,
+                               const char visitado,
+                               const double alfa);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea un polígono, como una lista doblemente enlazada de elementos
+       \ref _vertPoliClip.
+\param[in] x Vector de coordenadas X de los nodos del polígono.
+\param[in] y Vector de coordenadas Y de los nodos del polígono.
+\param[in] nCoor Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\return Puntero al primer vértice de la lista. Si se devuelve \p NULL, ha
+        ocurrido un error de asignación de memoria.
+\note Esta función asume que el argumento \em nCoor es mayor que 0.
+\note En la lista de salida que representa al polígono, el primer vértice
+      siempre se repite al final. Si en los vectores \em x e \em y el último
+      elemento no es igual que el primero, igualmente se crea en la lista de
+      salida.
+\note Si en los vectores de coordenadas \em x e \em y hay valores #GEOC_NAN,
+      éstos no se tienen en cuenta a la hora de la creación de la estructura de
+      salida.
+\note Que los vectores de coordenadas \em x e \em y admitan vértices con
+      coordenadas (#GEOC_NAN,#GEOC_NAN) no quiere decir que éstos sean
+      separadores de múltiples polígonos. \em x e \em y \b *SÓLO* deben
+      almacenar un único polígono.
+\date 18 de mayo de 2011: Creación de la función.
+\date 24 de mayo de 2011: Adición del soporte de coordenadas
+      (#GEOC_NAN,#GEOC_NAN) en los vectores de entrada.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* CreaPoliClip(const double* x,
+                           const double* y,
+                           const size_t nCoor,
+                           const size_t incX,
+                           const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Libera la memoria asignada a un polígono almacenado como una lista
+       doblemente enlazada de elementos \ref _vertPoliClip.
+\param[in] poli Puntero al primer elemento del polígono.
+\note Esta función no comprueba si hay vértices del polígono anteriores al
+      vértice de entrada, por lo que si se quiere liberar toda la memoria
+      asignada a un polígono, el vértice pasado ha de ser el primero de la
+      lista.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 18 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void LibMemPoliClip(vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Elimina los vértices no originales de un polígono almacenado como una
+       lista doblemente enlazada de elementos \ref _vertPoliClip.
+\param[in] poli Puntero al primer elemento del polígono.
+\return Puntero al primer elemento del polígono original. Si se devuelve
+        \p NULL, ninguno de los vértices pertenecía al polígono original.
+\note Esta función asume que el primero y el último vértices originales del
+      polígono pasado tienen las mismas coordenadas.
+\note Los vértices eliminados por esta función son todos aquéllos cuyo campo
+      _vertPoliClip::interseccion sea distinto de 0.
+\note Aunque se supone que el primer vértice de un polígono siempre es un
+      vértice original, si no lo es, la variable de entrada queda modificada.
+      Por tanto, siempre es recomendable capturar la variable de salida, que
+      garantiza la posición del primer elemento.
+\note Las coordenadas de todos los vértices originales vuelven a ser la de
+      inicio, es decir, los campos _vertPoliClip::xP e _vertPoliClip::yP se
+      sobreescriben con los valores almacenados en _vertPoliClip::x e
+      _vertPoliClip::y.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 18 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* ReiniciaPoliClip(vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Reinicia los vértices de un polígono almacenado como una lista doblemente
+       enlazada de elementos \ref _vertPoliClip para poder volver a calcular
+       otra operación booleana sin tener que recalcular las intersecciones.
+
+       Esta función devuelve todos los campos _vertPoliClip::visitado a 0 y los
+       campos _vertPoliClip::entrada a 0.
+\param[in] poli Puntero al primer elemento del polígono.
+\return Puntero al primer elemento del polígono original. Si se devuelve
+        \p NULL, quiere decir qie el argumento de entrada valía \p NULL.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 30 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* ReiniciaVerticesPoliClip(vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el siguiente vértice original en un polígono.
+\param[in] vert Puntero al vértice a partir del cual se ha de buscar.
+\return Puntero al siguiente vértice original en el polígono. Si se devuelve
+        \p NULL, se ha llegado al final.
+\note Esta función asume que el primero y el último vértices originales del
+      polígono pasado tienen las mismas coordenadas.
+\note Los vértices no originales son todos aquéllos cuyo campo
+      _vertPoliClip::interseccion es distinto de 0.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 19 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* SiguienteVertOrigPoliClip(vertPoliClip* vert);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el siguiente vértice que sea una intersección no visitada en un
+       polígono.
+\param[in] vert Puntero al vértice a partir del cual se ha de buscar.
+\return Puntero al siguiente vértice que sea una intersección no visitada en el
+        polígono. Si se devuelve \p NULL, se ha llegado al final.
+\note Esta función asume que el primero y el último vértices originales del
+      polígono pasado tienen las mismas coordenadas.
+\note Los vértices intersección no visitados son todos aquéllos cuyo campo
+      _vertPoliClip::visitado es 0.
+\note Esta función asume que el vértice inicial del polígono, aquél cuyo campo
+      _vertPoliClip::ini vale 1, es un vértice original.
+\note Esta función puede trabajar con listas circulares y no circulares.
+\date 21 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* SiguienteIntersecNoVisitadaPoliClip(vertPoliClip* vert);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el último vértice de un polígono almacenado como una lista
+       doblemente enlazada de vértives \ref _vertPoliClip.
+\param[in] poli Puntero al primer elemento del polígono.
+\return Puntero al último vértice del polígono, que es aquél cuyo campo
+        _vertPoliClip::siguiente apunta a \p NULL. Si se devuelve \p NULL,
+        significa que el argumento pasado en \em poli vale \p NULL.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 21 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* UltimoVertPoliClip(vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Inserta un vértice de tipo \ref _vertPoliClip entre otros dos, atendiendo
+       al campo _vertPoliClip::alfa.
+\param[in] ins Vértice a insertar.
+\param[in] extremoIni Extremo inicial del segmento donde se insertará \em ins.
+\param[in] extremoFin Extremo final del segmento donde se insertará \em ins.
+\note Esta función asume que todos los elementos pasados tienen memoria
+      asignada.
+\note Si entre \em extremoIni y \em extremoFin hay más vértices, \em ins se
+      insertará de tal modo que los campos _vertPoliClip::alfa queden ordenados
+      de menor a mayor.
+\note Si el campo _vertPoliClip::alfa de \em ins tiene el mismo valor que el
+      de \em extremoIni, \em ins se insertará justo a continuación de
+      \em extremoIni.
+\note Si el campo _vertPoliClip::alfa de \em ins tiene el mismo valor que el
+      de \em extremoFin, \em ins se insertará justo antes de \em extremoIni.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 19 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void InsertaVertPoliClip(vertPoliClip* ins,
+                         vertPoliClip* extremoIni,
+                         vertPoliClip* extremoFin);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Convierte una lista doblemente enlazada de elementos \ref _vertPoliClip
+       en una lista doblemente enlazada circular.
+\param[in,out] poli Vértice inicial del polígono, almacenado como lista
+               doblemente enlazada, pero no cerrada. Al término de la ejecución
+               de la función la lista se ha cerrado, por medio de un enlace del
+               penúltimo elemento (el último es el primero repetido) con el
+               primero.
+\return Puntero al último elemento del polígono original que, al ser el primer
+        elemento repetido, queda almacenado en memoria pero no neferenciado por
+        el polígono. Si el valor devuelto es \p NULL quiere decir que el
+        argumento de entrada era \p NULL.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 21 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPoliClip* CierraPoliClip(vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Convierte una lista doblemente enlazada circular de elementos
+       \ref _vertPoliClip en una lista doblemente enlazada simple.
+\param[in,out] poli Vértice inicial del polígono, almacenado como lista
+               doblemente enlazada circular. Al término de la ejecución de la
+               función la lista ha recuperado su condición de doblemente
+               enlazada sin cerrar.
+\param[in] ultimo Puntero al último elemento de la lista doblemente enlazada
+           original. Este argumento ha de ser el valor devuelto por la
+           función \ref CierraPoliClip.
+\note Esta función asume que los elementos pasados tienen memoria asignada.
+\note Esta función sólo trabaja con listas circulares.
+\date 21 de mayo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void AbrePoliClip(vertPoliClip* poli,
+                  vertPoliClip* ultimo);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en un polígono de un número
+       arbitrario de lados. Esta función puede no dar resultados correctos para
+       puntos en los bordes y/o los vértices del polígono.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] poli Polígono, almacenado como una lista doblemente enlazada de
+           elementos \ref _vertPoliClip. Sólo se tienen en cuenta los vértices
+           originales del polígono, que son todos aquéllos cuyo campo
+           _vertPoliClip::interseccion es distinto de 0.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono.
+\note El código de esta función ha sido adaptado de la función
+      \ref PtoEnPoligono.
+\note Esta función no comprueba si la variable \em poli es un polígono
+      correctamente almacenado.
+\note Esta función no detecta el caso de que el punto de trabajo esté en el
+      borde o en un vértice del polígono. En este caso, el test puede dar el
+      punto dentro o fuera, indistintamente (el chequeo del mismo punto con el
+      mismo polígono siempre dará el mismo resultado).
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 19 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int PtoEnPoliClip(const double x,
+                  const double y,
+                  vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en un polígono de un número
+       arbitrario de lados. Esta función puede no dar resultados correctos para
+       puntos en los bordes del polígono.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] poli Polígono, almacenado como una lista doblemente enlazada de
+           elementos \ref _vertPoliClip. Sólo se tienen en cuenta los vértices
+           originales del polígono, que son todos aquéllos cuyo campo
+           _vertPoliClip::interseccion es distinto de 0.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del polígono.
+\note El código de esta función ha sido adaptado de la función
+      \ref PtoEnPoligonoVertice.
+\note Esta función no comprueba si la variable \em poli es un polígono
+      correctamente almacenado.
+\note Esta función utiliza en uno de sus pasos la función \ref PtoEnPoliClip y
+      se comporta igual que ella en el caso de puntos en el borde.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 19 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int PtoEnPoliClipVertice(const double x,
+                         const double y,
+                         vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Cuenta el número de vértices originales que hay en un polígono almacenado
+       como una lista doblemente enlazada de elementos \ref _vertPoliClip.
+\param[in] poli Polígono, almacenado como una lista doblemente enlazada de
+           elementos \ref _vertPoliClip. Sólo se tienen en cuenta los vértices
+           originales del polígono, que son todos aquéllos cuyo campo
+           _vertPoliClip::interseccion es distinto de 0.
+\return Número de vértices originales almacenados. El último vértice, que es
+        igual al primero, también se cuenta.
+\note Esta función no comprueba si la variable \em poli es un polígono
+      correctamente almacenado.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 19 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+size_t NumeroVertOrigPoliClip(vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Cuenta el número total de vértices que hay en un polígono almacenado como
+       una lista doblemente enlazada de elementos \ref _vertPoliClip.
+\param[in] poli Polígono, almacenado como una lista doblemente enlazada de
+           elementos \ref _vertPoliClip. Se tienen en cuenta todos los vértices.
+\return Número total de vértices almacenados. El último vértice, que debe ser
+        igual al primero, también se cuenta.
+\note Esta función no comprueba si la variable \em poli es un polígono
+      correctamente almacenado.
+\note Esta función \b *NO* trabaja con listas circulares.
+\date 19 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+size_t NumeroVertPoliClip(vertPoliClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la cantidad mínima a añadir a un número para que el valor de la
+       suma sea distinto del número original.
+\param[in] x Número a perturbar.
+\param[in] factor Factor para ir multiplicando el valor a añadir a \em x
+           mientras no sea suficiente para producir una perturbación detectable.
+           Un buen valor para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB.
+\return Cantidad mínima a añadir a \em x para que el valor de la suma sea
+        distinto de \em x.
+\note Esta función no comprueba internamente si \em factor es menor o igual que
+      1, lo que daría lugar a que la función entrase en un bucle infinito.
+\note Como valor inicial de la cantidad a añadir se toma el producto de
+      \em factor por la constante \p DBL_EPSILON, perteneciente al fichero
+      \p float.h de C estándar.
+\date 22 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+double CantPerturbMin(const double x,
+                      const double factor);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Modifica un número la cantidad mínima para que sea distinto del número
+       original.
+\param[in] x Número a perturbar.
+\param[in] factor Factor para el cálculo de la cantidad perturbadora mínima. Ver
+           la documentación de la función \ref CantPerturbMin para obtener más
+           detalles. Un buen valor para este argumento es
+           #GEOC_GREINER_FAC_EPS_PERTURB.
+\return Número perturbado.
+\note La perturbación de \em x se realiza de la siguiente manera:
+      - Se calcula la cantidad mínima perturbadora \p perturb con la función
+        \ref CantPerturbMin.
+      - Se calcula un número seudoaleatorio con la función de C estándar
+        <tt>rand()</tt> (el generador de números seudoaleatorios se inicializa
+        con la orden <tt>srand((unsigned int)time(NULL));</tt>).
+      - Se comprueba la paridad del número seudoaleatorio generado para obtener
+        la variable \p signo, de tal forma que:
+        - Si el número seudoaleatorio es par: \p signo vale 1.0.
+        - Si el número seudoaleatorio es impar: \p signo vale -1.0.
+      - Se perturba \em x como <tt>xPerturb=x+signo*perturb</tt>.
+\date 22 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+double PerturbaPuntoMin(const double x,
+                        const double factor);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Realiza el paso número 1 del algoritmo de Greiner-Hormann, que consiste
+       en el cálculo de los puntos de intersección entre los dos polígonos de
+       trabajo.
+\param[in,out] poliBas Polígono base, representado como una lista doblemente
+               enlazada de elementos \ref _vertPoliClip. Al término de la
+               ejecución de la función se le han añadido los puntos de
+               intersección.
+\param[in,out] poliRec Polígono de recorte, representado como una lista
+               doblemente enlazada de elementos \ref _vertPoliClip. Al término
+               de la ejecución de la función se le han añadido los puntos de
+               intersección.
+\param[in] facPer Factor para el posible cálculo de la perturbación de las
+           coordenadas de algunos vértices. Este valor es usado internamente por
+           la función \ref PerturbaPuntoMin (ver su documentación). Un buen
+           valor para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB.
+\param[out] nIntersec Número de intersecciones calculadas.
+\param[out] nPerturb Número de puntos perturbados en el proceso.
+\return Variable de estado. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si las variables \em poliBas y \em poliRec son
+      polígonos correctamente almacenados.
+\note En el caso de tener que perturbar algún vértice, sólo se modifican los de
+      \em poliRec, dejando las coordenadas del polígono base inalteradas.
+\date 22 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int Paso1Greiner(vertPoliClip* poliBas,
+                 vertPoliClip* poliRec,
+                 const double facPer,
+                 size_t* nIntersec,
+                 size_t* nPerturb);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Realiza el paso número 2 del algoritmo de Greiner-Hormann, que consiste
+       en la asignación de los puntos de intersección como entrada o salida.
+\param[in,out] poliBas Polígono base, representado como una lista doblemente
+               enlazada de elementos \ref _vertPoliClip. Al término de la
+               ejecución de la función los puntos de intersección han sido
+               marcados como entrada o salida.
+\param[in,out] poliRec Polígono de recorte, representado como una lista
+               doblemente enlazada de elementos \ref _vertPoliClip. Al término
+               de la ejecución de la función los puntos de intersección han sido
+               marcados como entrada o salida.
+\param[in] op Identificador de la operación a realizar. Ha de ser un elemento
+           del tipo enumerado #GEOC_OP_BOOL_POLIG, excepto la unión exclusiva
+           \p xor. En el caso de indicar la operación de unión exclusiva \p xor,
+           se realiza una intersección y \b *NO* se avisa del argumento
+           incorrecto.
+\note Esta función no comprueba si las variables \em poliBas y \em poliRec son
+      polígonos correctamente almacenados.
+\date 22 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+void Paso2Greiner(vertPoliClip* poliBas,
+                  vertPoliClip* poliRec,
+                  const enum GEOC_OP_BOOL_POLIG op);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Realiza el paso número 3 del algoritmo de Greiner-Hormann, que consiste
+       en la generación de los polígonos resultado.
+\param[in,out] poliBas Polígono base, representado como una lista doblemente
+               enlazada de elementos \ref _vertPoliClip, tal y como sale de la
+               función \ref Paso2Greiner. Al término de la ejecución de la
+               función los puntos visitados han sido marcados en el campo
+               _vertPoliClip::visitado.
+\param[in,out] poliRec Polígono de recorte, representado como una lista
+               doblemente enlazada de elementos \ref _vertPoliClip, tal y como
+               sale de la función \ref Paso2Greiner. Al término de la ejecución
+               de la función los puntos visitados han sido marcados en el campo
+               _vertPoliClip::visitado.
+\return Estructura \ref polig con los polígonos resultado de la operación. Si se
+        devuelve \p NULL ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si las variables \em poliBas y \em poliRec son
+      polígonos correctamente almacenados.
+\date 22 de mayo de 2011: Creación de la función.
+\date 29 de mayo de 2011: Cambio de la variable de salida por la estructura
+      \ref polig.
+\todo Esta función no está probada.
+*/
+polig* Paso3Greiner(vertPoliClip* poliBas,
+                    vertPoliClip* poliRec);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Realiza una operación booleana entre dos polígonos mediante el algoritmo
+       de Greiner-Hormann.
+\param[in,out] poliBas Polígono base, representado como una lista doblemente
+               enlazada de elementos \ref _vertPoliClip. Al término de la
+               ejecución de la función se han añadido los puntos de intersección
+               con \em poliRec.
+\param[in,out] poliRec Polígono de recorte, representado como una lista
+               doblemente enlazada de elementos \ref _vertPoliClip. Al término
+               de la ejecución de la función se han añadido los puntos de
+               intersección con \em poliRec.
+\param[in] op Identificador de la operación a realizar. Ha de ser un elemento
+           del tipo enumerado #GEOC_OP_BOOL_POLIG. Varias posibilidades:
+           - #GeocOpBoolInter: Realiza la intersección entre \em poliBas y
+             \em poliRec.
+           - #GeocOpBoolUnion: Realiza la unión entre \em poliBas y \em poliRec.
+           - #GeocOpBoolXor: Realiza la unión exclusiva entre \em poliBas y
+             \em poliRec.
+           - #GeocOpBoolAB: Realiza la sustracción \em poliBas-poliRec.
+           - #GeocOpBoolBA: Realiza la sustracción \em poliRec-poliBas.
+\param[in] facPer Factor para el posible cálculo de la perturbación de las
+           coordenadas de algunos vértices. Este valor es usado internamente por
+           la función \ref Paso1Greiner (ver su documentación). Un buen valor
+           para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB.
+\param[out] nIntersec Número de intersecciones calculadas.
+\param[out] nPerturb Número de puntos perturbados en el proceso.
+\return Estructura \ref polig con los polígonos resultado de la operación. Si se
+        devuelve \p NULL ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si las variables \em poliBas y \em poliRec son
+      polígonos correctamente almacenados.
+\note Esta función no comprueba internamente si \em op pertenece al tipo
+      enumerado #GEOC_OP_BOOL_POLIG. Si se introduce un valor no perteneciente
+      al tipo, se realiza la operación #GeocOpBoolInter.
+\note En el caso de tener que perturbar algún vértice, sólo se modifican los de
+      \em poliRec, dejando las coordenadas de \em poliBase inalteradas.
+\note Si \em facPer es menor o igual que 1, se sustituye internamente su valor
+      por #GEOC_GREINER_FAC_EPS_PERTURB (ver documentación de la función
+      \ref CantPerturbMin).
+\note Esta función realiza la unión exclusiva #GeocOpBoolXor mediante la unión
+      de las operaciones individuales #GeocOpBoolAB y #GeocOpBoolBA. Esta última
+      unión simplemente es el almacenamiento en la estructura de salida de los
+      resultados de #GeocOpBoolAB y #GeocOpBoolBA. En ningún momento se realiza
+      la operación booleana #GeocOpBoolUnion entre los resultados de
+      #GeocOpBoolAB y #GeocOpBoolBA.
+\date 22 de mayo de 2011: Creación de la función.
+\date 29 de mayo de 2011: Cambio de la variable de salida por la estructura
+      \ref polig.
+\date 30 de mayo de 2011: Adición de la capacidad de calcular la operación unión
+      exclusiva \p xor.
+\todo Esta función no está probada.
+*/
+polig* PoliBoolGreiner(vertPoliClip* poliBas,
+                       vertPoliClip* poliRec,
+                       const enum GEOC_OP_BOOL_POLIG op,
+                       const double facPer,
+                       size_t* nIntersec,
+                       size_t* nPerturb);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Realiza una operación booleana entre múltiples polígonos mediante el
+       algoritmo de Greiner-Hormann.
+\param[in] poliBas Estructura \ref polig que almacena los polígonos base.
+\param[in] poliRec Estructura \ref polig que almacena los polígonos de recorte.
+\param[in] op Identificador de la operación a realizar. Ha de ser un elemento
+           del tipo enumerado #GEOC_OP_BOOL_POLIG. Varias posibilidades:
+           - #GeocOpBoolInter: Realiza la intersección entre los polígonos
+             almacenados en \em poliBas y los almacenados en \em poliRec.
+           - #GeocOpBoolUnion: Realiza la unión entre los polígonos almacenados
+             en \em poliBas y los almacenados en \em poliRec.
+           - #GeocOpBoolXor: Realiza la unión exclusiva entre los polígonoa
+             almacenados en \em poliBas y los almacenados en \em poliRec.
+           - #GeocOpBoolAB: Realiza la sustracción entre todos los polígonos
+             \em poliBas-poliRec.
+           - #GeocOpBoolBA: Realiza la sustracción entre todos los polígonos
+             \em poliRec-poliBas.
+\param[in] facPer Factor para el posible cálculo de la perturbación de las
+           coordenadas de algunos vértices. Este valor es usado internamente por
+           la función \ref Paso1Greiner (ver su documentación). Un buen valor
+           para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB.
+\param[out] nIntersec Número total de intersecciones calculadas entre todas los
+            polígonos.
+\param[out] nPerturb Número total de puntos perturbados en el proceso.
+\return Estructura \ref polig con los polígonos resultado de las operaciones. Si
+        se devuelve \p NULL ha ocurrido un error de asignación de memoria.
+\note Esta función realiza la operación \em op con todas las combinaciones
+      posibles de polígonos. Es decir, se recorren todos los polígonos
+      almacenados en \em poliBas y con cada uno de ellos se realiza la operación
+      \em op con cada polígono almacenado en \em poliRec.
+\note Esta función no comprueba si las variables \em poliBas y \em poliRec son
+      polígonos correctamente almacenados.
+\note Esta función no comprueba internamente si \em op pertenece al tipo
+      enumerado #GEOC_OP_BOOL_POLIG. Si se introduce un valor no perteneciente
+      al tipo, se realiza la operación #GeocOpBoolInter.
+\note En el caso de tener que perturbar algún vértice, sólo se modifican los
+      correspondientes a \em poliRec, dejando las coordenadas de los polígonos
+      de \em poliBase inalteradas.
+\note Si \em facPer es menor o igual que 1, se sustituye internamente su valor
+      por #GEOC_GREINER_FAC_EPS_PERTURB (ver documentación de la función
+      \ref CantPerturbMin).
+\note Esta función realiza la unión exclusiva #GeocOpBoolXor mediante la unión
+      de las operaciones individuales #GeocOpBoolAB y #GeocOpBoolBA. Esta última
+      unión simplemente es el almacenamiento en la estructura de salida de los
+      resultados de #GeocOpBoolAB y #GeocOpBoolBA. En ningún momento se realiza
+      la operación booleana #GeocOpBoolUnion entre los resultados de
+      #GeocOpBoolAB y #GeocOpBoolBA.
+\date 07 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+polig* PoliBoolGreinerMult(const polig* poliBas,
+                           const polig* poliRec,
+                           const enum GEOC_OP_BOOL_POLIG op,
+                           const double facPer,
+                           size_t* nIntersec,
+                           size_t* nPerturb);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea una estructura \ref polig a partir de todos los vértices de un
+       polígono almacenado como una lista doblemente enlazada de elementos
+       \ref _vertPoliClip.
+\param[in] poli Polígono de trabajo, representado como una lista doblemente
+                enlazada de elementos \ref _vertPoliClip. El puntero pasado ha
+                de apuntar al primer elemento del polígono (no se controla
+                internamente).
+\param[in] coorOrig Identificador para copiar las coordenadas originales o
+           perturbadas. Dos posibilidades:
+           - 0: Se copiarán las coordenadas perturbadas _vertPoliClip::xP e
+             _vertPoliClip::yP.
+           - Distinto de 0: Se copiarán las coordenadas originales
+             _vertPoliClip::x e _vertPoliClip::y.
+\return Estructura \ref polig que representa el polígono. Si se devuelve \p NULL
+        ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si la variable \em poli es un polígono
+      correctamente almacenado.
+\note Esta función \b *NO* trabaja con listas circulares.
+\note Esta función realiza una copia en memoria de las coordenadas de los
+      vértices de la estructura \em poli a la estructura de salida.
+\date 29 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+polig* CreaPoligPoliClip(vertPoliClip* poli,
+                         const int coorOrig);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Añade los vértices de un polígono almacenado como una lista doblemente
+       enlazada de elementos \ref _vertPoliClip a una estructura \ref polig
+       previamente creada.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se han añadido los
+               polígonos de la estructura \em anyade.
+\param[in] anyade Polígono a añadir, representado como una lista doblemente
+                  enlazada de elementos \ref _vertPoliClip. El puntero pasado ha
+                  de apuntar al primer elemento del polígono (no se controla
+                  internamente).
+\param[in] coorOrig Identificador para copiar las coordenadas originales o
+           perturbadas. Dos posibilidades:
+           - 0: Se copiarán las coordenadas perturbadas _vertPoliClip::xP e
+             _vertPoliClip::yP.
+           - Distinto de 0: Se copiarán las coordenadas originales
+             _vertPoliClip::x e _vertPoliClip::y.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si la variable \em poli es un polígono
+      correctamente almacenado.
+\note Esta función no comprueba si la variable \em anyade es un polígono
+      correctamente almacenado.
+\note Esta función \b *NO* trabaja con listas circulares.
+\note Esta función realiza una copia en memoria de las coordenadas de los
+      vértices de la estructura \em poli a la estructura de salida.
+\note Esta función crea internamente una estructura \ref polig para luego
+      añadirla a \em poli con la función \ref AnyadePoligPolig.
+\date 29 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int AnyadePoligClipPolig(polig* poli,
+                         vertPoliClip* anyade,
+                         const int coorOrig);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/polig.h b/src/libgeoc/polig.h
new file mode 100755
index 0000000..0588800
--- /dev/null
+++ b/src/libgeoc/polig.h
@@ -0,0 +1,1101 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file polig.h
+\brief Definición de estructuras y declaración de funciones para el trabajo con
+       polígonos.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 20 de abril de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _POLIG_H_
+#define _POLIG_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdio.h>
+#include<stdlib.h>
+#include<math.h>
+#include"libgeoc/dpeucker.h"
+#include"libgeoc/errores.h"
+#include"libgeoc/fgeneral.h"
+#include"libgeoc/geocnan.h"
+#include"libgeoc/geocomp.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** \struct polig
+\brief Estructura contenedora de los vértices que definen el contorno de uno o
+       varios polígono.
+\date 20 de abril de 2011: Creación de la estructura.
+\date 26 de mayo de 2011: Reorganización total de la estructura.
+\date 28 de mayo de 2011: Adición de los campos polig::hayArea, polig::area,
+      polig::hayLim, polig::xMin, polig::xMax, polig::yMin e polig::yMax.
+*/
+typedef struct
+{
+    /** \brief Número de elementos de los vectores de coordenadas. */
+    size_t nElem;
+    /**
+    \brief Vector de polig::nElem elementos, que almacena las coordenadas X de
+           los vértices del polígono (o los polígonos), así como los separadores
+           entre polígonos. La primera coordenada de cada polígono se repite al
+           final.
+    */
+    double* x;
+    /**
+    \brief Vector de polig::nElem elementos, que almacena las coordenadas Y de
+           los vértices del polígono (o los polígonos), así como los separadores
+           entre polígonos. La primera coordenada de cada polígono se repite al
+           final.
+    */
+    double* y;
+    /** \brief Número de polígonos almacenados. */
+    size_t nPolig;
+    /**
+    \brief Vector de polig::nPolig elementos, que almacena las posiciones en los
+           vectores \em x e \em y de inicio de cada polígono almacenado.
+    */
+    size_t* posIni;
+    /**
+    \brief Vector de polig::nPolig elementos, que almacena el número de vértices
+           de cada polígono almacenado. El último vértice de cada polígono, que
+           es el primero repetido, también entra en la cuenta.
+    */
+    size_t* nVert;
+    /**
+    \brief Identificador de si la estructura contiene información acerca de los
+           límites del rectángulo que encierra a cada polígono almacenado.
+
+           Dos posibilidades:
+           - 0: La estructura no contiene información de los límites.
+           - Distinto de 0: La estructura sí contiene información de los
+                            límites.
+    */
+    int hayLim;
+    /**
+    \brief Vector de polig::nPolig elementos, que almacena la coordenada X
+           mínima de cada polígono almacenado. Este campo sólo contiene
+           información si el campo polig::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* xMin;
+    /**
+    \brief Vector de polig::nPolig elementos, que almacena la coordenada X
+           máxima de cada polígono almacenado. Este campo sólo contiene
+           información si el campo polig::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* xMax;
+    /**
+    \brief Vector de polig::nPolig elementos, que almacena la coordenada Y
+           mínima de cada polígono almacenado. Este campo sólo contiene
+           información si el campo polig::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* yMin;
+    /**
+    \brief Vector de polig::nPolig elementos, que almacena la coordenada Y
+           máxima de cada polígono almacenado. Este campo sólo contiene
+           información si el campo polig::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* yMax;
+    /**
+    \brief Identificador de si la estructura contiene información acerca de la
+           superficie de los polígonos almacenados.
+
+           Dos posibilidades:
+           - 0: La estructura no contiene información de superficie.
+           - Distinto de 0: La estructura sí contiene información de superficie.
+    */
+    int hayArea;
+    /**
+    \brief Vector de polig::nPolig elementos, que almacena la superficie de cada
+           polígono almacenado. Este campo sólo contiene información si el campo
+           polig::hayArea es distinto de 0; si no, es igual a \p NULL. La
+           superficie almacenada sólo es correcta si el polígono es simple, esto
+           es, si sus lados no se cortan entre ellos mismos.
+
+           El área de los polígono puede ser negativa o positiva, de tal forma
+           que:
+           - Si es negativa: Los vértices de polígono están ordenados en el
+             sentido de las agujas del reloj.
+           - Si es positiva: Los vértices de polígono están ordenados en sentido
+             contrario al de las agujas del reloj.
+    */
+    double* area;
+}polig;
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Indica si hay alguna función compilada en paralelo con OpenMP en el
+       fichero \ref polig.c.
+\param[out] version Cadena identificadora de la versión de OpenMP utilizada.
+            Este argumento sólo se utiliza si su valor de entrada es distinto de
+            \p NULL y si hay alguna función compilada con OpenMP.
+\return Dos posibles valores:
+        - 0: No hay ninguna función compilada en paralelo con OpenMP.
+        - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP.
+\note Esta función asume que el argumento \em version tiene suficiente memoria
+      asignada (si es distinto de \p NULL).
+\date 27 de mayo de 2011: Creación de la función.
+\date 25 de agosto de 2011: Adición del argumento de entrada \em version.
+*/
+int GeocParOmpPolig(char version[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea una estructura \ref polig vacía.
+\return Estructura \ref polig vacía. Los campos escalares se inicializan con el
+        valor 0 y los vectoriales con \p NULL. Si se devuelve \p NULL ha
+        ocurrido un error de asignación de memoria.
+\date 26 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+polig* IniciaPoligVacio(void);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Función auxiliar para la rutina de creación de una estructura \ref polig
+       a partir de dos vectores que contienen las coordenadas de los vértices.
+
+       Esta función calcula el número máximo de elementos que almacenarán los
+       vectores de coordenadas de una estructura \ref polig y el número de
+       polígonos almacenados en los vectores de trabajo.
+\param[in] nElem Número de elementos de los vectores de coordenadas originales.
+\param[in] posNanX Vector que almacena las posiciones de los elementos #GEOC_NAN
+           en el vector \em x de coordenadas originales.
+\param[in] posNanY Vector que almacena las posiciones de los elementos #GEOC_NAN
+           en el vector \em y de coordenadas originales.
+\param[in] nNanX Número de elementos del vector \em posNanX.
+\param[in] nNanY Número de elementos del vector \em posNanY.
+\param[out] nElemMax Número máximo de elementos que contendrán los vectores de
+            coordenadas de los elementos de la estructura.
+\param[out] nPolig Número de polígonos almacenados en los vectores \em x e
+            \em y de coordenadas originales.
+\return Variable de error. Tres posibilidades:
+        - #GEOC_ERR_NO_ERROR: Si todo ha ido bien.
+        - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Si los vectores \em x e \em y
+          de coordenadas originales almacenan un número distinto de polígonos,
+          es decir, \em nNanX es distinto que \em nNanY.
+        - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Si algunos polígonos almacenados
+          en \em x e \em y son distintos, es decir, las posiciones almacenadas
+          en \em posNanX son distintas de las almacenadas en \em posNanY.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em posNanX y \em posNanY es congruente con los valores pasados en
+      \em nNanX y \em nNanY.
+\date 26 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+int AuxCreaPolig1(const size_t nElem,
+                  const size_t* posNanX,
+                  const size_t* posNanY,
+                  const size_t nNanX,
+                  const size_t nNanY,
+                  size_t* nElemMax,
+                  size_t* nPolig);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Función auxiliar para la rutina de creación de una estructura \ref polig
+       a partir de dos vectores que contienen las coordenadas de los vértices.
+
+       Esta función copia una serie de datos de dos vectores en otros dos.
+\param[in] x Vector que contiene las coordenadas X de los vértices a copiar.
+\param[in] y Vector que contiene las coordenadas Y de los vértices a copiar.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[out] xSal Vector para almacenar los elementos copiados del vector \em x.
+            Ha de tener la suficiente memoria asignada para copiar \em nElem
+            elementos más un posible elemento adicional, que es el primer
+            elemento de \em x, si éste no se repite al final.
+\param[out] ySal Vector para almacenar los elementos copiados del vector \em y.
+            Ha de tener la suficiente memoria asignada para copiar \em nElem
+            elementos más un posible elemento adicional, que es el primer
+            elemento de \em y, si éste no se repite al final.
+\param[out] nCopias Número de elementos copiados en los vectores \em xSal e
+            \em ySal, incluido el primer punto repetido al final, si se copia.
+\note Esta función no comprueba si el número de elementos de los vectores \em x,
+      \em y, \em xSal e \em ySal es congruente con los valores pasados en
+      \em nElem, \em incX e \em incY.
+\date 26 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void AuxCreaPolig2(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   double* xSal,
+                   double* ySal,
+                   size_t* nCopias);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Función auxiliar para las rutinas de creación de estructuras \ref polig
+       a partir de dos vectores que contienen las coordenadas de los vértices.
+
+       Esta función crea los polígonos en el formato de almacenamiento de
+       \ref polig a partir de los vectores de entrada.
+\param[in] x Vector que contiene las coordenadas X de los vértices de trabajo.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de trabajo.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] posNan Vector que almacena las posiciones de los elementos #GEOC_NAN
+           en los vectores \em x e \em y.
+\param[in] nNan Número de elementos del vector \em posNan.
+\param[out] xSal Vector para almacenar las coordenadas X de los vértices de los
+            polígonos creados.
+\param[out] ySal Vector para almacenar las coordenadas Y de los vértices de los
+            polígonos creados.
+\param[out] posIni Vector para almacenar las posiciones de inicio de los
+            polígonos creados.
+\param[out] nVert Vector para almacenar el número de vértices de los polígonos
+            creados.
+\param[out] nPtos Número de posiciones con información almacenada en los
+            vectores \em xSal e \em ySal.
+\param[out] nPolig Número de posiciones con información almacenada en los
+            vectores \em posIni y \em nVert.
+\note Esta función no comprueba si el número de elementos de los vectores \em x,
+      \em y y \em posNan es congruente con los valores pasados en \em nElem,
+      \em incX, \em incY y \em nNan.
+\note Esta función asume que los vectores \em xSal, \em ySal, \em posIni y
+      \em nVert tienen asignada suficiente memoria.
+\date 29 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void AuxCreaPolig3(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   const size_t* posNan,
+                   const size_t nNan,
+                   double* xSal,
+                   double* ySal,
+                   size_t* posIni,
+                   size_t* nVert,
+                   size_t* nPtos,
+                   size_t* nPolig);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea una estructura \ref polig a partir de dos vectores que contienen las
+       coordenadas de los vértices de uno o varios polígonos.
+\param[in] x Vector que contiene las coordenadas X de los vértices del polígono
+           o polígonos de trabajo. Si hay varios polígonos, han de estar
+           separados por un valor #GEOC_NAN.
+\param[in] y Vector que contiene las coordenadas Y de los vértices del polígono
+           o polígonos de trabajo. Si hay varios polígonos, han de estar
+           separados por un valor #GEOC_NAN.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[out] idError Identificador de error. Varias posibilidades:
+            - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+            - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de
+              memoria.
+            - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Los vectores \em x e \em y
+              contienen un número distinto de polígonos. No contienen el mismo
+              número de identificadores #GEOC_NAN.
+            - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Los vectores \em x e \em y
+              contienen distintos polígonos. Los marcadores #GEOC_NAN no están
+              colocados en las mismas posiciones.
+\return Estructura \ref polig con los polígonos pasados. Si ocurre algún error,
+        se devuelve \p NULL y el motivo del fallo se codifica en la variable
+        \em idError.
+\note Esta función está paralelizada con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con los valores pasados de \em nElem, \em incX e
+      \em incY.
+\note Si los vectores \em x e \em y almacenan varios polígonos, éstos se separan
+      mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición y/o la
+      última es opcional.
+\note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en
+      \em x e \em y.
+\note Para los polígonos, es opcional repetir las coordenadas del primer vértice
+      al final del listado del resto de vértices.
+\note Esta función no calcula los límites de los polígonos ni su área, por lo
+      que los campos polig::hayLim y polig::hayArea se inicializan a 0 y los
+      campos polig::xMin, polig::xMax, polig::yMin, polig::yMax y polig::area se
+      inicializan a \p NULL.
+\date 26 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+polig* CreaPolig(const double* x,
+                 const double* y,
+                 const size_t nElem,
+                 const size_t incX,
+                 const size_t incY,
+                 int* idError);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Enlaza el contenido de una estructura \ref polig a otra.
+\param[in] poliEnt Estructura \ref polig de entrada, que almacena los datos a
+           enlazar.
+\param[out] poliSal Estructura \ref polig, cuyos campos serán enlazados a los de
+            la estructura \em poliEnt. Esta estructura ha de estar, como mínimo,
+            inicializada. Al término de la ejecución de la función, las
+            estructuras \em poliEnt y \em poliSal comparten el mismo espacio de
+            memoria en sus argumentos vectoriales.
+\note Esta función asume que la estructura de entrada \em poligEnt tiene memoria
+      asignada.
+\note Esta función asume que la estructura de salida \em poligSal está, como
+      mínimo, inicializada.
+\note Esta función libera la posible memoria asignada a los campos de
+      \em poliSal antes de realizar el enlace.
+\date 19 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void EnlazaCamposPolig(polig* poliEnt,
+                       polig* poliSal);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Copia el contenido de una estructura \ref polig en otra.
+\param[in] poli Estructura \ref polig de entrada, que almacena los datos a
+           copiar.
+\param[out] idError Identificador de error. Varias posibilidades:
+            - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+            - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de
+              memoria.
+            - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Los campos polig::x e
+              polig::y del polígono de entrada contienen un número distinto de
+              polígonos. No contienen el mismo número de identificadores
+              #GEOC_NAN.
+            - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Los campos polig::x e
+              polig::y del polígono de entrada contienen distintos polígonos.
+              Los marcadores #GEOC_NAN no están colocados en las mismas
+              posiciones.
+\return Polígono con los datos contenidos en \em poli copiados. Si ocurre algún
+        error se devuelve \p NULL y la causa se almacena en el argumento
+        \em idError.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\date 09 de julio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+polig* CopiaPolig(const polig* poli,
+                  int* idError);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Añade el contenido de una estructura \ref polig a otra.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se han añadido los
+               polígonos de la estructura \em anyade.
+\param[in] anyade Estructura cuyo contenido será añadido a \em poli.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función asume que la estructura de entrada \ref polig tiene memoria
+      asignada.
+\note En caso de error de asignación de memoria, la memoria de las estructuras
+      de entrada no se libera.
+\note Si la estructura \em poli guarda información de superficie y límites de
+      los polígonos almacenados, esta información se calcula también para los
+      nuevos datos (en realidad, si la estructura \em anyade ya los tiene
+      calculados, simplemente se copian).
+\date 29 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+int AnyadePoligPolig(polig* poli,
+                     const polig* anyade);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Añade al contenido de una estructura \ref polig un conjunto de polígonos
+       definidos a partir de un listado con las coordenadas de sus vértices, de
+       la misma forma que el utilizado en la función \ref CreaPolig.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se han añadido los
+               polígonos pasados en \em x e \em y.
+\param[in] x Vector que contiene las coordenadas X de los vértices del polígono
+           o polígonos a añadir. Si hay varios polígonos, han de estar separados
+           por un valor #GEOC_NAN.
+\param[in] y Vector que contiene las coordenadas Y de los vértices del polígono
+           o polígonos a añadir. Si hay varios polígonos, han de estar separados
+           por un valor #GEOC_NAN.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+        - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Los vectores \em x e \em y
+           contienen un número distinto de polígonos. No contienen el mismo
+           número de identificadores #GEOC_NAN.
+        - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Los vectores \em x e \em y
+           contienen distintos polígonos. Los marcadores #GEOC_NAN no están
+           colocados en las mismas posiciones.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\note En caso de error de asignación de memoria, la memoria de la estructura y
+      los vectores de entrada no se libera.
+\note Si la estructura \em poli guarda información de superficie y límites de
+      los polígonos almacenados, esta información se calcula también para los
+      nuevos datos.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con los valores pasados de \em nElem, \em incX e
+      \em incY.
+\note Si los vectores \em x e \em y almacenan varios polígonos, éstos se separan
+      mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición y/o la
+      última es opcional.
+\note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en
+      \em x e \em y.
+\note Para los polígonos, es opcional repetir las coordenadas del primer vértice
+      al final del listado del resto de vértices.
+\note Esta función crea internamente una estructura \ref polig para luego
+      añadirla a \em poli con la función \ref AnyadePoligPolig.
+\date 29 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+int AnyadeDatosPolig(polig* poli,
+                     const double* x,
+                     const double* y,
+                     const size_t nElem,
+                     const size_t incX,
+                     const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Libera la memoria asignada a una estructura \ref polig.
+\param[in] datos Estructura \ref polig.
+\date 20 de abril de 2011: Creación de la estructura.
+\date 26 de mayo de 2011: Reescritura de la función para el trabajo con la nueva
+      versión de la estructura.
+\note Esta función todavía no está probada.
+*/
+void LibMemPolig(polig* datos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula los límites de todos los polígonos almacenados en una estructura
+       \ref polig.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se han añadido los
+               límites de los polígonos almacenados.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función está paralelizada con OpenMP.
+\note Esta función asume que la estructura de entrada \ref polig tiene memoria
+      asignada.
+\note En caso de error de asignación de memoria, la memoria de la estructura de
+      entrada no se libera.
+\date 29 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+int CalcLimitesPolig(polig* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula los límites de un polígono a partir de las coordenadas de sus
+       vértices.
+\param[in] x Vector que contiene las coordenadas X de los vértices del polígono
+           de trabajo.
+\param[in] y Vector que contiene las coordenadas Y de los vértices del polígono
+           de trabajo.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[out] xMin Coordenada X mímina del polígono.
+\param[out] xMax Coordenada X máxima del polígono.
+\param[out] yMin Coordenada Y mímina del polígono.
+\param[out] yMax Coordenada Y máxima del polígono.
+\note Esta función está paralelizada con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con los valores pasados de \em nElem, \em incX e
+      \em incY.
+\date 29 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void LimitesPoligono(const double* x,
+                     const double* y,
+                     const size_t nElem,
+                     const size_t incX,
+                     const size_t incY,
+                     double* xMin,
+                     double* xMax,
+                     double* yMin,
+                     double* yMax);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula los límites de una serie de polígonos a partir de las coordenadas
+       de sus vértices, almacenadas en vectores en el formato de la estructura
+       \ref polig.
+\param[in] x Vector que contiene las coordenadas X de los vértices del polígono
+           de trabajo, tal y como se almacenan en una estructura \ref polig.
+\param[in] y Vector que contiene las coordenadas Y de los vértices del polígono
+           de trabajo, tal y como se almacenan en una estructura \ref polig.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] posIni Vector de \em nPolig elementos, que almacena las posiciones de
+           inicio de los polígonos de trabajo.
+\param[in] nVert Vector de \em nPolig elementos, que almacena el número de
+           vértices de los polígonos de trabajo.
+\param[in] nPolig Número de polígonos de trabajo.
+\param[in] restaPosIni Número de posiciones a restar a los valores almacenados
+           en \em posIni, de tal forma que los índices de los vértices se
+           refieran al inicio pasado mediante los punteros \em x e \em y.
+\param[out] xMin Vector de \em nPolig elementos para almacenar las coordenadas
+            X mínimas calculadas de los polígonos.
+\param[out] xMax Vector de \em nPolig elementos para almacenar las coordenadas
+            X máximas calculadas de los polígonos.
+\param[out] yMin Vector de \em nPolig elementos para almacenar las coordenadas
+            Y mínimas calculadas de los polígonos.
+\param[out] yMax Vector de \em nPolig elementos para almacenar las coordenadas
+            Y máximas calculadas de los polígonos.
+\note Esta función está paralelizada con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores \em x,
+      \em y, \em posIni, \em nVert, \em xMin, \em xMax, \em yMin e \em yMax es
+      congruente con los valores pasados de \em incX, \em incY, \em nPolig y
+      \em restaPoliIni.
+\note Esta función no comprueba si las coordenadas almacenadas en los vectores
+      \em x e \em y están en el formato de la estructura \ref polig.
+\date 29 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void LimitesPoligonosPolig(const double* x,
+                           const double* y,
+                           const size_t incX,
+                           const size_t incY,
+                           const size_t* posIni,
+                           const size_t* nVert,
+                           const size_t nPolig,
+                           const size_t restaPosIni,
+                           double* xMin,
+                           double* xMax,
+                           double* yMin,
+                           double* yMax);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula el área de todos los polígonos almacenados en una estructura
+       \ref polig.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se han añadido las
+               superficies de los polígonos almacenados.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función asume que la estructura de entrada \ref polig tiene memoria
+      asignada.
+\note En caso de error de asignación de memoria, la memoria de la estructura de
+      entrada no se libera.
+\date 29 de mayo de 2011: Creación de la función.
+\date 01 de agosto de 2011: Corregido error que hacía que se calculasen mal las
+      superficies debido a un incorrecto uso del argumento \em restaPosIni de la
+      función \ref AreaPoligonosSimplesPolig.
+\note Esta función todavía no está probada.
+*/
+int CalcAreaPolig(polig* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula el área de un polígono simple (sin intersecciones consigo mismo)
+       a partir de las coordenadas de sus vértices.
+\param[in] x Vector que contiene las coordenadas X de los vértices del polígono
+           de trabajo. Las coordenadas del primer punto pueden repetirse o no al
+           final, indistintamente.
+\param[in] y Vector que contiene las coordenadas Y de los vértices del polígono
+           de trabajo. Las coordenadas del primer punto pueden repetirse o no al
+           final, indistintamente.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\return Superficie del polígono de trabajo. Dos posibilidades:
+        - Número negativo: Los vértices del polígono están ordenados en el
+          sentido de las agujas del reloj.
+        - Número positivo: Los vértices del polígono están ordenados en el
+          sentido contrario al de las agujas del reloj.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con los valores pasados de \em nElem, \em incX e
+      \em incY.
+\note El algoritmo implementado es el correspondiente a la ecuación 21.4.20 del
+      Numerical Recipes, tercera edición, página 1127. Este algoritmo trabaja
+      con vectores de coordenadas en los que el primer punto no se repite al
+      final. Esta función comprueba internamente si el primer punto se repite al
+      final de los vectores pasados y actua en consecuencia para proporcionar un
+      resultado correcto.
+\date 29 de mayo de 2011: Creación de la función.
+\date 23 de junio de 2011: Adición de la capacidad de trabajar con vectores de
+      coordenadas en los que se repite el primer punto al final.
+\note Esta función todavía no está probada.
+*/
+double AreaPoligonoSimple(const double* x,
+                          const double* y,
+                          const size_t nElem,
+                          const size_t incX,
+                          const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula el área de una serie de polígonos simples (sin intersecciones
+       consigo mismo) a partir de las coordenadas de sus vértices, almacenadas
+       en vectores en el formato de la estructura \ref polig.
+\param[in] x Vector que contiene las coordenadas X de los vértices del polígono
+           de trabajo, tal y como se almacenan en una estructura \ref polig.
+\param[in] y Vector que contiene las coordenadas Y de los vértices del polígono
+           de trabajo, tal y como se almacenan en una estructura \ref polig.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] posIni Vector de \em nPolig elementos, que almacena las posiciones de
+           inicio de los polígonos de trabajo.
+\param[in] nVert Vector de \em nPolig elementos, que almacena el número de
+           vértices de los polígonos de trabajo.
+\param[in] nPolig Número de polígonos de trabajo.
+\param[in] restaPosIni Número de posiciones a restar a los valores almacenados
+           en \em posIni, de tal forma que los índices de los vértices se
+           refieran al inicio pasado mediante los punteros \em x e \em y.
+\param[out] area Vector de \em nPolig elementos para almacenar las superficies
+            calculadas de los polígonos. Los valores pueden ser positivos o
+            negativos:
+            - Número negativo: Los vértices del polígono están ordenados en el
+              sentido de las agujas del reloj.
+            - Número positivo: Los vértices del polígono están ordenados en el
+              sentido contrario al de las agujas del reloj.
+\note Esta función está paralelizada con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores \em x,
+      \em y, \em posIni, \em nVert y \em area es congruente con los valores
+      pasados de \em incX, \em incY, \em nPolig y \em restaPoliIni.
+\note Esta función no comprueba si las coordenadas almacenadas en los vectores
+      \em x e \em y están en el formato de la estructura \ref polig.
+\date 29 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void AreaPoligonosSimplesPolig(const double* x,
+                               const double* y,
+                               const size_t incX,
+                               const size_t incY,
+                               const size_t* posIni,
+                               const size_t* nVert,
+                               const size_t nPolig,
+                               const size_t restaPosIni,
+                               double* area);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica un factor de escala y una traslación (en este orden) a las
+       coordenadas de todos los polígonos almacenados en una estructura
+       \ref polig.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se ha aplicado un
+               factor de escala y una traslación (en este orden) a las
+               coordenadas de todos los polígonos almacenados y, si se indica, a
+               los límites y las superficies.
+\param[in] escalaX Factor de escala a aplicar a las coordenadas X.
+\param[in] escalaY Factor de escala a aplicar a las coordenadas Y.
+\param[in] trasladaX Traslación a aplicar a las coordenadas X.
+\param[in] trasladaY Traslación a aplicar a las coordenadas Y.
+\param[in] aplicaLim Identificador para aplicar o no los factores de escala y
+           las traslaciones a los límites de los polígonos (sólo si están
+           previemente calculados). Dos posibilidades:
+           - 0: No se aplican los factores de escala ni las traslaciones a los
+             límites.
+           - Distinto de 0: Sí se aplican los factores de escala y las
+             traslaciones a los límites, si estos están calculados en la
+             estructura de entrada.
+\param[in] aplicaArea Identificador para aplicar o no los factores de escala
+           (que se aplican como un único factor \em escalaX*escalaY) a las áreas
+           de los polígonos (sólo si están previemente calculadas). Dos
+           posibilidades:
+           - 0: No se aplican los factores a las áreas.
+           - Distinto de 0: Sí se aplican los factores a las áreas, si estas
+             están calculadas en la estructura de entrada.
+\note Esta función está paralelizada con OpenMP.
+\note Primero se aplican los factores de escala y luego las traslaciones.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\note A las áreas sólo se aplican los factores de escala, ya que son invariantes
+      ante traslaciones.
+\note A las áreas, los factores de escala se aplican como uno solo, igual a
+      \em escalaX*escalaY, para que éstas queden correctamente expresadas en las
+      nuevas unidades a las que da lugar el escalado.
+\date 02 de junio de 2011: Creación de la función.
+\date 18 de junio de 2011: Distinción entre factores de escala y traslaciones
+      para las coordenadas X e Y.
+\note Esta función todavía no está probada.
+*/
+void EscalaYTrasladaPolig(polig* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim,
+                          const int aplicaArea);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica una traslación y un factor de escala (en este orden) a las
+       coordenadas de todos los polígonos almacenados en una estructura
+       \ref polig.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se ha aplicado una
+               traslación y un factor de escala (en este orden) a las
+               coordenadas de todos los polígonos almacenados y, si se indica, a
+               los límites y las superficies.
+\param[in] escalaX Factor de escala a aplicar a las coordenadas X.
+\param[in] escalaY Factor de escala a aplicar a las coordenadas Y.
+\param[in] trasladaX Traslación a aplicar a las coordenadas X.
+\param[in] trasladaY Traslación a aplicar a las coordenadas Y.
+\param[in] aplicaLim Identificador para aplicar o no las traslaciones y los
+           factores de escala a los límites de los polígonos (sólo si están
+           previemente calculados). Dos posibilidades:
+           - 0: No se aplican las traslaciones ni los factores de escala a los
+             límites.
+           - Distinto de 0: Sí se aplican las traslaciones y los factores de
+             escala a los límites, si estos están calculados en la estructura de
+             entrada.
+\param[in] aplicaArea Identificador para aplicar o no los factores de escala
+           (que se aplican como un único factor \em escalaX*escalaY) a las áreas
+           de los polígonos (sólo si están previemente calculadas). Dos
+           posibilidades:
+           - 0: No se aplican los factores a las áreas.
+           - Distinto de 0: Sí se aplican los factores a las áreas, si estas
+             están calculadas en la estructura de entrada.
+\note Esta función está paralelizada con OpenMP.
+\note Primero se aplican las traslaciones y luego los factores de escala.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\note A las áreas sólo se aplican los factores de escala, ya que son invariantes
+      ante traslaciones.
+\note A las áreas, los factores de escala se aplican como uno solo, igual a
+      \em escalaX*escalaY, para que éstas queden correctamente expresadas en las
+      nuevas unidades a las que da lugar el escalado.
+\date 02 de junio de 2011: Creación de la función.
+\date 18 de junio de 2011: Distinción entre factores de escala y traslaciones
+      para las coordenadas X e Y.
+\note Esta función todavía no está probada.
+*/
+void TrasladaYEscalaPolig(polig* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim,
+                          const int aplicaArea);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica un factor de escala y una traslación (el orden de aplicación se ha
+       de seleccionar) a las coordenadas de todos los polígonos almacenados en
+       una estructura \ref polig.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, se ha aplicado un
+               factor de escala y una traslación (orden a seleccionar) a las
+               coordenadas de todos los polígonos almacenados y, si se indica, a
+               los límites y las superficies.
+\param[in] escalaX Factor de escala a aplicar a las coordenadas X.
+\param[in] escalaY Factor de escala a aplicar a las coordenadas Y.
+\param[in] trasladaX Traslación a aplicar a las coordenadas X.
+\param[in] trasladaY Traslación a aplicar a las coordenadas Y.
+\param[in] orden Orden de aplicación de los factores de escala y traslación. Dos
+           posibilidades:
+           - 0: Primero se aplican los factores de escala y luego las
+             traslaciones \f$x'=f\cdot x+t\f$.
+           - Distinto de 0: Primero se aplican las traslaciones y luego los
+             factores de escala \f$x'=(x+t)\cdot f\f$.
+\param[in] aplicaLim Identificador para aplicar o no los factores de escala y
+           las traslaciones a los límites de los polígonos (sólo si están
+           previemente calculados). Dos posibilidades:
+           - 0: No se aplican los factores de escala ni las traslaciones a los
+             límites.
+           - Distinto de 0: Sí se aplican los factores de escala y las
+             traslaciones a los límites, si estos están calculados en la
+             estructura de entrada.
+\param[in] aplicaArea Identificador para aplicar o no los factores de escala
+           (que se aplican como un único factor \em escalaX*escalaY) a las áreas
+           de los polígonos (sólo si están previemente calculadas). Dos
+           posibilidades:
+           - 0: No se aplican los factores a las áreas.
+           - Distinto de 0: Sí se aplican los factores a las áreas, si estas
+             están calculadas en la estructura de entrada.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\note A las áreas sólo se aplican los factores de escala, ya que son invariantes
+      ante traslaciones.
+\note A las áreas, los factores de escala se aplican como uno solo, igual a
+      \em escalaX*escalaY, para que éstas queden correctamente expresadas en las
+      nuevas unidades a las que da lugar el escalado.
+\date 02 de junio de 2011: Creación de la función.
+\date 18 de junio de 2011: Distinción entre factores de escala y traslaciones
+      para las coordenadas X e Y.
+\note Esta función todavía no está probada.
+*/
+void MuevePolig(polig* poli,
+                const double escalaX,
+                const double escalaY,
+                const double trasladaX,
+                const double trasladaY,
+                const int orden,
+                const int aplicaLim,
+                const int aplicaArea);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Elimina vértices de los polígonos almacenados en una estructura
+       \ref polig mediante un algoritmo inspirado en el de Douglas-Peucker. Se
+       usa internamente la función \ref AligeraPolilinea.
+\param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos.
+               Al término de la ejecución de la función, almacena el resultado
+               de la aplicación a cada polígono del algoritmo de aligerado de
+               vértices implementado en la función \ref AligeraPolilinea.
+\param[in] tol Tolerancia para eliminar vértices, en las mismas unidades que las
+           coordenadas de los vértices. Ver la ayuda de la función
+           \ref AligeraPolilinea.
+\param[in] robusto Identificador para realizar o no un aligerado robusto. Ha de
+           ser un elemento del tipo enumerado #GEOC_DPEUCKER_ROBUSTO. Varias
+           posibilidades:
+           - #GeocDPeuckerRobNo: No se aplica el algoritmo robusto.
+           - #GeocDPeuckerRobSi: Se aplica el algoritmo robusto completo, que
+             garantiza la no ocurrencia de auto intersecciones en el polígono
+             resultante. Internamente, primero se aplica el tratamiento robusto
+             de la opción #GeocDPeuckerRobOrig y luego el de la opción
+             #GeocDPeuckerRobAuto.
+           - #GeocDPeuckerRobOrig: Se aplica un algoritmo semi robusto que
+             consiste en garantizar que los segmentos del polígono aligerado que
+             se van creando no intersectarán con ninguno de los segmentos que
+             forman los vértices que quedan por procesar del polígono original.
+             En casos muy especiales, este algoritmo puede seguir dando lugar a
+             auto intersecciones.
+           - #GeocDPeuckerRobAuto: Se aplica un algoritmo semi robusto que
+             consiste en garantizar que los segmentos del polígono aligerado que
+             se van creando no intersectarán con ninguno de los segmentos del
+             polígono aligerado creados con anterioridad. En casos muy
+             especiales, este algoritmo puede seguir dando lugar a auto
+             intersecciones.
+\param[in] nPtosRobusto Número de puntos del polígono original a utilizar en el
+           caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o
+           #GeocDPeuckerRobOrig. Si se pasa el valor 0, se utilizan todos los
+           puntos hasta el final del polígono original.
+\param[in] nSegRobusto Número de segmentos del polígono aligerado a utilizar en
+           el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o
+           #GeocDPeuckerRobAuto. Si se pasa el valor 0, se utilizan todos los
+           segmentos hasta el inicio del polígono aligerado.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función asume que \em poli está, como mínimo, inicializado.
+\note Si \em poli tiene límites y/o áreas calculadas en la entrada, también los
+      tendrá en la salida.
+\note Un polígono aligerado sólo será válido si después de aplicarle la función
+      \ref AligeraPolilinea mantiene un mínimo de 3 puntos no alineados por lo
+      que, al término de la ejecución de esta función, el resultado puede ser
+      una estructura \ref polig vacía.
+\date 09 de julio de 2011: Creación de la función.
+\date 10 de julio de 2011: Cambio del tipo del argumento \em robusto al tipo
+      enumerado #GEOC_DPEUCKER_ROBUSTO.
+\date 31 de julio de 2011: Corregido error con índices a la hora de guardar los
+      resultados y comprobación de que los polígonos de salida no estén
+      compuestos por tres puntos alineados.
+\todo Esta función todavía no está probada.
+*/
+int AligeraPolig(polig* poli,
+                 const double tol,
+                 const enum GEOC_DPEUCKER_ROBUSTO robusto,
+                 const size_t nPtosRobusto,
+                 const size_t nSegRobusto);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Imprime una línea de cabecera para un polígono almacenado en una
+       estructura \ref polig.
+\param[in] poli Estructura \ref polig.
+\param[in] indice Índice del polígono de trabajo en la estructura.
+\param[in] iniCab Cadena de texto con la que comenzará la cabecera.
+\param[in] impLim Identificador para imprimir o no los límites de coordenadas
+           del polígono de trabajo. Dos posibles valores:
+           - 0: No se imprimen.
+           - Distinto de 0: Sí se imprimen.
+\param[in] formCoor Cadena de carácteres indicadora del formato para escribir
+           las coordenadas de los límites. Este argumento sólo se usa
+           internamente si se ha indicado la impresión de límites.
+\param[in] impArea Identificador para imprimir o no la superficie del polígono
+           de trabajo. Dos posibles valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] formArea Cadena de carácteres indicadora del formato para escribir el
+           valor de la superficie. Este argumento sólo se usa internamente si se
+           ha indicado la impresión de la superficie del polígono.
+\param[in] factorX Factor para multiplicar las coordenadas X de los vértices
+           antes de imprimirlas.
+\param[in] factorY Factor para multiplicar las coordenadas Y de los vértices
+           antes de imprimirlas.
+\param[in] repitePrimerPunto Identificador para tener o no en cuenta el primer
+           vértice del polígono repetido al final del listado de coordenadas
+           para el cálculo del número de vértices del polígono. Dos posibles
+           valores:
+           - 0: No se repite, luego no se tiene en cuenta.
+           - Distinto de 0: Sí se repite, luego sí se tiene en cuenta.
+\param[in] idFich Identificador de fichero abierto para escribir.
+\note Esta función está paralelizada con OpenMP.
+\note La cabecera completa tiene el siguiente formato:
+      <tt>iniCab númVert área xMín xMáx yMín yMáx</tt>.
+\note Si la estructura no tiene información de límites y/o áreas y se indica que
+      se impriman, los valores se calculan internamente.
+\note Esta función asume que \em poli es una estructura \ref polig correctamente
+      almacenada.
+\note Esta función no comprueba si la estructura pasada tiene memoria asignada.
+\note Esta función no comprueba internamente la validez de los argumentos de
+      formato.
+\note Esta función no comprueba internamente si el identificador pasado
+      corresponde a un fichero abierto para escribir.
+\date 18 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void ImprimeCabeceraPoligFichero(const polig* poli,
+                                 const size_t indice,
+                                 const char iniCab[],
+                                 const int impLim,
+                                 const char formCoor[],
+                                 const int impArea,
+                                 const char formArea[],
+                                 const double factorX,
+                                 const double factorY,
+                                 const int repitePrimerPunto,
+                                 FILE* idFich);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Imprime una estructura \ref polig en un fichero.
+\param[in] poli Estructura \ref polig.
+\param[in] factorX Factor para multiplicar las coordenadas X de los vértices
+           antes de imprimirlas.
+\param[in] factorY Factor para multiplicar las coordenadas Y de los vértices
+           antes de imprimirlas.
+\param[in] repitePrimerPunto Identificador para repetir o no el primer vértice
+           del polígono al final del listado de coordenadas. Dos posibles
+           valores:
+           - 0: No se repite.
+           - Distinto de 0: Sí se repite.
+\param[in] iniNan Identificador para imprimir o no la marca de separación de
+           polígonos (\p NaN) delante del primer polígono. Dos posibles valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] finNan Identificador para imprimir o no la marca de separación de
+           polígonos (\p NaN) detrás del último polígono. Dos posibles valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] formCoor Cadena de carácteres indicadora del formato de cada
+           coordenada a imprimir.
+\param[in] impCabecera Identificador para imprimir o no una cabecera con
+           información general por cada polígono. Dos posibles valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] iniCab Cadena de texto con la que comenzará la cabecera.
+\param[in] impLim Identificador para imprimir o no en la cabecera los límites de
+           coordenadas de los polígonos de trabajo. Dos posibles valores:
+           - 0: No se imprimen.
+           - Distinto de 0: Sí se imprimen.
+\param[in] impArea Identificador para imprimir o no en la cabecera la superficie
+           de los polígonos de trabajo. Dos posibles valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] formArea Cadena de carácteres indicadora del formato para escribir el
+           valor de la superficie. Este argumento sólo se usa internamente si se
+           ha indicado la impresión de la superficie de los polígonos.
+\param[in] idFich Identificador de fichero abierto para escribir.
+\note La cabecera completa tiene el siguiente formato:
+      <tt>iniCab númVert área xMín xMáx yMín yMáx</tt>.
+\note Si la estructura no tiene información de límites y/o áreas y se indica que
+      se impriman, los valores se calculan internamente.
+\note Esta función asume que \em poli es una estructura \ref polig correctamente
+      almacenada.
+\note Esta función no comprueba si la estructura pasada tiene memoria asignada.
+\note Esta función no comprueba internamente la validez de los argumentos de
+      formato.
+\note Esta función no comprueba internamente si el identificador pasado
+      corresponde a un fichero abierto para escribir.
+\date 26 de mayo de 2011: Creación de la función.
+\date 30 de mayo de 2011: Adición del argumento de entrada \em factor.
+\date 18 de junio de 2011: Adición de la capacidad de escritura de una cabecera
+      y del uso de factores de escala independientes para las coordenadas X e Y.
+\date 22 de septiembre de 2011: Corregido bug que hacía que, dependiendo del
+      compilador y/o los flags de optimización en la compilación, se imprimiesen
+      mal (con un signo menos delante) los valores Not-a-Number.
+\note Esta función todavía no está probada.
+*/
+void ImprimePoligFichero(const polig* poli,
+                         const double factorX,
+                         const double factorY,
+                         const int repitePrimerPunto,
+                         const int iniNan,
+                         const int finNan,
+                         const char formCoor[],
+                         const int impCabecera,
+                         const char iniCab[],
+                         const int impLim,
+                         const int impArea,
+                         const char formArea[],
+                         FILE* idFich);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/polil.h b/src/libgeoc/polil.h
new file mode 100755
index 0000000..174ffae
--- /dev/null
+++ b/src/libgeoc/polil.h
@@ -0,0 +1,799 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file polil.h
+\brief Definición de estructuras y declaración de funciones para el trabajo con
+       polilíneas.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 03 de junio de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _POLIL_H_
+#define _POLIL_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdio.h>
+#include<stdlib.h>
+#include"libgeoc/dpeucker.h"
+#include"libgeoc/errores.h"
+#include"libgeoc/fgeneral.h"
+#include"libgeoc/geocnan.h"
+#include"libgeoc/geocomp.h"
+#include"libgeoc/polig.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** \struct polil
+\brief Estructura contenedora de los vértices que definen el contorno de una o
+       varias polilíneas.
+\date 03 de junio de 2011: Creación de la estructura.
+*/
+typedef struct
+{
+    /** \brief Número de elementos de los vectores de coordenadas. */
+    size_t nElem;
+    /**
+    \brief Vector de polil::nElem elementos, que almacena las coordenadas X de
+           los vértices de la polilínea (o las polilíneas), así como los
+           separadores entre polilíneas. La primera coordenada de cada polilínea
+           se repite al final.
+    */
+    double* x;
+    /**
+    \brief Vector de polil::nElem elementos, que almacena las coordenadas Y de
+           los vértices de la polilínea (o las polilíneas), así como los
+           separadores entre polilíneas. La primera coordenada de cada polilínea
+           se repite al final.
+    */
+    double* y;
+    /** \brief Número de polilíneas almacenadas. */
+    size_t nPolil;
+    /**
+    \brief Vector de polil::nPolig elementos, que almacena las posiciones en los
+           vectores \em x e \em y de inicio de cada polilínea almacenada.
+    */
+    size_t* posIni;
+    /**
+    \brief Vector de polil::nPolig elementos, que almacena el número de vértices
+           de cada polilínea almacenada.
+    */
+    size_t* nVert;
+    /**
+    \brief Identificador de si la estructura contiene información acerca de los
+           límites del rectángulo que encierra a cada polilínea almacenada.
+
+           Dos posibilidades:
+           - 0: La estructura no contiene información de los límites.
+           - Distinto de 0: La estructura sí contiene información de los
+                            límites.
+    */
+    int hayLim;
+    /**
+    \brief Vector de polil::nPolig elementos, que almacena la coordenada X
+           mínima de cada polilínea almacenada. Este campo sólo contiene
+           información si el campo polil::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* xMin;
+    /**
+    \brief Vector de polil::nPolig elementos, que almacena la coordenada X
+           máxima de cada polilínea almacenada. Este campo sólo contiene
+           información si el campo polil::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* xMax;
+    /**
+    \brief Vector de polil::nPolig elementos, que almacena la coordenada Y
+           mínima de cada polilínea almacenada. Este campo sólo contiene
+           información si el campo polil::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* yMin;
+    /**
+    \brief Vector de polil::nPolig elementos, que almacena la coordenada Y
+           máxima de cada polilínea almacenada. Este campo sólo contiene
+           información si el campo polil::hayLim es distinto de 0; si no, es
+           igual a \p NULL.
+    */
+    double* yMax;
+}polil;
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Indica si hay alguna función compilada en paralelo con OpenMP en el
+       fichero \ref polil.c.
+\param[out] version Cadena identificadora de la versión de OpenMP utilizada.
+            Este argumento sólo se utiliza si su valor de entrada es distinto de
+            \p NULL y si hay alguna función compilada con OpenMP.
+\return Dos posibles valores:
+        - 0: No hay ninguna función compilada en paralelo con OpenMP.
+        - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP.
+\note Esta función asume que el argumento \em version tiene suficiente memoria
+      asignada (si es distinto de \p NULL).
+\date 03 de junio de 2011: Creación de la función.
+\date 25 de agosto de 2011: Adición del argumento de entrada \em version.
+*/
+int GeocParOmpPolil(char version[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea una estructura \ref polil vacía.
+\return Estructura \ref polil vacía. Los campos escalares se inicializan con el
+        valor 0 y los vectoriales con \p NULL. Si se devuelve \p NULL ha
+        ocurrido un error de asignación de memoria.
+\date 26 de mayo de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+polil* IniciaPolilVacia(void);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Función auxiliar para la rutina de creación de una estructura \ref polil
+       a partir de dos vectores que contienen las coordenadas de los vértices.
+
+       Esta función calcula el número máximo de elementos que almacenarán los
+       vectores de coordenadas de una estructura \ref polil y el número de
+       polilíneas almacenadas en los vectores de trabajo.
+\param[in] nElem Número de elementos de los vectores de coordenadas originales.
+\param[in] posNanX Vector que almacena las posiciones de los elementos #GEOC_NAN
+           en el vector \em x de coordenadas originales.
+\param[in] posNanY Vector que almacena las posiciones de los elementos #GEOC_NAN
+           en el vector \em y de coordenadas originales.
+\param[in] nNanX Número de elementos del vector \em posNanX.
+\param[in] nNanY Número de elementos del vector \em posNanY.
+\param[out] nElemMax Número máximo de elementos que contendrán los vectores de
+            coordenadas de los elementos de la estructura.
+\param[out] nPolil Número de polilíneas almacenadas en los vectores \em x e
+            \em y de coordenadas originales.
+\return Variable de error. Tres posibilidades:
+        - #GEOC_ERR_NO_ERROR: Si todo ha ido bien.
+        - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Si los vectores \em x e \em y
+          de coordenadas originales almacenan un número distinto de polilíneas,
+          es decir, \em nNanX es distinto que \em nNanY.
+        - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Si algunas polilíneas almacenadas
+          en \em x e \em y son distintas, es decir, las posiciones almacenadas
+          en \em posNanX son distintas de las almacenadas en \em posNanY.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em posNanX y \em posNanY es congruente con los valores pasados en
+      \em nNanX y \em nNanY.
+\date 03 de junio de 2011: Creación de la función.
+\date 13 de junio de 2011: Corrección de error que hacía que el argumento
+      \em nElemMax que calculase mal si los argumentos \em nNanX y/o \em nNanY
+      valían 0.
+\note Esta función todavía no está probada.
+*/
+int AuxCreaPolil1(const size_t nElem,
+                  const size_t* posNanX,
+                  const size_t* posNanY,
+                  const size_t nNanX,
+                  const size_t nNanY,
+                  size_t* nElemMax,
+                  size_t* nPolil);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Función auxiliar para la rutina de creación de una estructura \ref polil
+       a partir de dos vectores que contienen las coordenadas de los vértices.
+
+       Esta función copia una serie de datos de dos vectores en otros dos.
+\param[in] x Vector que contiene las coordenadas X de los vértices a copiar.
+\param[in] y Vector que contiene las coordenadas Y de los vértices a copiar.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[out] xSal Vector de \em nElem elementos para almacenar los elementos
+            copiados del vector \em x.
+\param[out] ySal Vector de \em nElem elementos para almacenar los elementos
+            copiados del vector \em y.
+\note Esta función no comprueba si el número de elementos de los vectores \em x,
+      \em y, \em xSal e \em ySal es congruente con los valores pasados en
+      \em nElem, \em incX e \em incY.
+\date 03 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void AuxCreaPolil2(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   double* xSal,
+                   double* ySal);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Función auxiliar para las rutinas de creación de estructuras \ref polil
+       a partir de dos vectores que contienen las coordenadas de los vértices.
+
+       Esta función crea las polilíneas en el formato de almacenamiento de
+       \ref polil a partir de los vectores de entrada.
+\param[in] x Vector que contiene las coordenadas X de los vértices de trabajo.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de trabajo.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] posNan Vector que almacena las posiciones de los elementos #GEOC_NAN
+           en los vectores \em x e \em y.
+\param[in] nNan Número de elementos del vector \em posNan.
+\param[out] xSal Vector para almacenar las coordenadas X de los vértices de las
+            polilíneas creadas.
+\param[out] ySal Vector para almacenar las coordenadas Y de los vértices de las
+            polilíneas creadas.
+\param[out] posIni Vector para almacenar las posiciones de inicio de las
+            polilíneas creadas.
+\param[out] nVert Vector para almacenar el número de vértices de las polilíneas
+            creadas.
+\param[out] nPtos Número de posiciones con información almacenada en los
+            vectores \em xSal e \em ySal.
+\param[out] nPolil Número de posiciones con información almacenada en los
+            vectores \em posIni y \em nVert.
+\note Esta función no comprueba si el número de elementos de los vectores \em x,
+      \em y y \em posNan es congruente con los valores pasados en \em nElem,
+      \em incX, \em incY y \em nNan.
+\note Esta función asume que los vectores \em xSal, \em ySal, \em posIni y
+      \em nVert tienen asignada suficiente memoria.
+\date 03 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void AuxCreaPolil3(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   const size_t* posNan,
+                   const size_t nNan,
+                   double* xSal,
+                   double* ySal,
+                   size_t* posIni,
+                   size_t* nVert,
+                   size_t* nPtos,
+                   size_t* nPolil);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea una estructura \ref polil a partir de dos vectores que contienen las
+       coordenadas de los vértices de una o varias polilíneas.
+\param[in] x Vector que contiene las coordenadas X de los vértices de la
+           polilínea o polilíneas de trabajo. Si hay varias polilíneas, han de
+           estar separados por un valor #GEOC_NAN.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de la
+           polilínea o polilíneas de trabajo. Si hay varias polilíneas, han de
+           estar separados por un valor #GEOC_NAN.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[out] idError Identificador de error. Varias posibilidades:
+            - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+            - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de
+              memoria.
+            - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Los vectores \em x e \em y
+              contienen un número distinto de polilíneas. No contienen el mismo
+              número de identificadores #GEOC_NAN.
+            - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Los vectores \em x e \em y
+              contienen distintas polilíneas. Los marcadores #GEOC_NAN no están
+              colocados en las mismas posiciones.
+\return Estructura \ref polil con las polilíneas pasadas. Si ocurre algún error,
+        se devuelve \p NULL y el motivo del fallo se codifica en la variable
+        \em idError.
+\note Esta función está paralelizada con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con los valores pasados de \em nElem, \em incX e
+      \em incY.
+\note Si los vectores \em x e \em y almacenan varias polilíneas, éstas se
+      separan mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición
+      y/o la última es opcional.
+\note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en
+      \em x e \em y.
+\note Esta función no calcula los límites de las polilíneas, por lo que el
+      campo polil::hayLim se inicializa a 0 y los campos polil::xMin,
+      polil::xMax, polil::yMin y polil::yMax se inicializan a \p NULL.
+\date 03 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+polil* CreaPolil(const double* x,
+                 const double* y,
+                 const size_t nElem,
+                 const size_t incX,
+                 const size_t incY,
+                 int* idError);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Enlaza el contenido de una estructura \ref polil a otra.
+\param[in] poliEnt Estructura \ref polil de entrada, que almacena los datos a
+           enlazar.
+\param[out] poliSal Estructura \ref polil, cuyos campos serán enlazados a los de
+            la estructura \em poliEnt. Esta estructura ha de estar, como mínimo,
+            inicializada. Al término de la ejecución de la función, las
+            estructuras \em poliEnt y \em poliSal comparten el mismo espacio de
+            memoria en sus argumentos vectoriales.
+\note Esta función asume que la estructura de entrada \em poligEnt tiene memoria
+      asignada.
+\note Esta función asume que la estructura de salida \em poligSal está, como
+      mínimo, inicializada.
+\note Esta función libera la posible memoria asignada a los campos de
+      \em poliSal antes de realizar el enlace.
+\date 19 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void EnlazaCamposPolil(polil* poliEnt,
+                       polil* poliSal);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Copia el contenido de una estructura \ref polil en otra.
+\param[in] poli Estructura \ref polil de entrada, que almacena los datos a
+           copiar.
+\param[out] idError Identificador de error. Varias posibilidades:
+            - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+            - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de
+              memoria.
+            - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Los campos polil::x e
+              polil::y de la polilínea de entrada contienenun número distinto de
+              polilíneas. No contienen el mismo número de identificadores
+              #GEOC_NAN.
+            - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Los campos polig::x e
+              polig::y de la polilínea de entrada contienen distintas
+              polilíneas. Los marcadores #GEOC_NAN no están colocados en las
+              mismas posiciones.
+\return Polilínea con los datos contenidos en \em poli copiados. Si ocurre algún
+        error se devuelve \p NULL y la causa se almacena en el argumento
+        \em idError.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\date 09 de julio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+polil* CopiaPolil(const polil* poli,
+                  int* idError);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Añade el contenido de una estructura \ref polil a otra.
+\param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas.
+               Al término de la ejecución de la función, se han añadido las
+               polilíneas de la estructura \em anyade.
+\param[in] anyade Estructura cuyo contenido será añadido a \em poli.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función asume que la estructura de entrada \ref polil tiene memoria
+      asignada.
+\note En caso de error de asignación de memoria, la memoria de las estructuras
+      de entrada no se libera.
+\note Si la estructura \em poli guarda información de límites de las polilíneas
+      almacenadas, esta información se calcula también para los nuevos datos (en
+      realidad, si la estructura \em anyade ya los tiene calculados, simplemente
+      se copian).
+\date 03 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+int AnyadePolilPolil(polil* poli,
+                     const polil* anyade);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Añade al contenido de una estructura \ref polil un conjunto de polilíneas
+       definidas a partir de un listado con las coordenadas de sus vértices, de
+       la misma forma que el utilizado en la función \ref CreaPolil.
+\param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas.
+               Al término de la ejecución de la función, se han añadido las
+               polilíneas pasados en \em x e \em y.
+\param[in] x Vector que contiene las coordenadas X de los vértices de la
+           polilínea o polilíneas a añadir. Si hay varias polilíneas, han de
+           estar separadas por un valor #GEOC_NAN.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de la
+           polilínea o polilíneas a añadir. Si hay varias polilíneas, han de
+           estar separadas por un valor #GEOC_NAN.
+\param[in] nElem Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+        - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Los vectores \em x e \em y
+           contienen un número distinto de polilíneas. No contienen el mismo
+           número de identificadores #GEOC_NAN.
+        - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Los vectores \em x e \em y
+           contienen distintas polilíneas. Los marcadores #GEOC_NAN no están
+           colocados en las mismas posiciones.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\note En caso de error de asignación de memoria, la memoria de la estructura y
+      los vectores de entrada no se libera.
+\note Si la estructura \em poli guarda información de límites de las polilíneas
+      almacenadas, esta información se calcula también para los nuevos datos.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con los valores pasados de \em nElem, \em incX e
+      \em incY.
+\note Si los vectores \em x e \em y almacenan varias polilíneas, éstas se
+      separan mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición
+      y/o la última es opcional.
+\note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en
+      \em x e \em y.
+\note Esta función crea internamente una estructura \ref polil para luego
+      añadirla a \em poli con la función \ref AnyadePolilPolil.
+\date 03 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+int AnyadeDatosPolil(polil* poli,
+                     const double* x,
+                     const double* y,
+                     const size_t nElem,
+                     const size_t incX,
+                     const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Libera la memoria asignada a una estructura \ref polil.
+\param[in] datos Estructura \ref polil.
+\date 03 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void LibMemPolil(polil* datos);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula los límites de todas las polilíneas almacenados en una estructura
+       \ref polil.
+\param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas.
+               Al término de la ejecución de la función, se han añadido los
+               límites de las polilíneas almacenadas.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función está paralelizada con OpenMP.
+\note Esta función asume que la estructura de entrada \ref polil tiene memoria
+      asignada.
+\note En caso de error de asignación de memoria, la memoria de la estructura de
+      entrada no se libera.
+\date 03 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+int CalcLimitesPolil(polil* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica un factor de escala y una traslación (en este orden) a las
+       coordenadas de todas las polilíneas almacenadas en una estructura
+       \ref polil.
+\param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas.
+               Al término de la ejecución de la función, se ha aplicado un
+               factor de escala y una traslación (en este orden) a las
+               coordenadas de todas las polilíneas almacenadas y, si se indica,
+               a los límites.
+\param[in] escalaX Factor de escala a aplicar a las coordenadas X.
+\param[in] escalaY Factor de escala a aplicar a las coordenadas Y.
+\param[in] trasladaX Traslación a aplicar a las coordenadas X.
+\param[in] trasladaY Traslación a aplicar a las coordenadas Y.
+\param[in] aplicaLim Identificador para aplicar o no los factores de escala y
+           las traslaciones a los límites de las polilíneas (sólo si están
+           previemente calculados). Dos posibilidades:
+           - 0: No se aplican los factores de escala ni las traslaciones a los
+             límites.
+           - Distinto de 0: Sí se aplican los factores de escala y las
+             traslaciones a los límites, si estos están calculados en la
+             estructura de entrada.
+\note Esta función está paralelizada con OpenMP.
+\note Primero se aplican los factores de escala y luego las traslaciones.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\date 03 de junio de 2011: Creación de la función.
+\date 18 de junio de 2011: Distinción entre factores de escala y traslaciones
+      para las coordenadas X e Y.
+\note Esta función todavía no está probada.
+*/
+void EscalaYTrasladaPolil(polil* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica una traslación y un factor de escala (en este orden) a las
+       coordenadas de todas las polilíneas almacenadss en una estructura
+       \ref polil.
+\param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas.
+               Al término de la ejecución de la función, se ha aplicado una
+               traslación y un factor de escala (en este orden) a las
+               coordenadas de todas las polilíneas almacenadas y, si se indica,
+               a los límites.
+\param[in] escalaX Factor de escala a aplicar a las coordenadas X.
+\param[in] escalaY Factor de escala a aplicar a las coordenadas Y.
+\param[in] trasladaX Traslación a aplicar a las coordenadas X.
+\param[in] trasladaY Traslación a aplicar a las coordenadas Y.
+\param[in] aplicaLim Identificador para aplicar o no las traslaciones y los
+           factores de escala a los límites de las polilíneas (sólo si están
+           previemente calculados). Dos posibilidades:
+           - 0: No se aplican las traslaciones ni los factores de escala a los
+             límites.
+           - Distinto de 0: Sí se aplican las traslaciones y los factores de
+             escala a los límites, si estos están calculados en la estructura de
+             entrada.
+\note Esta función está paralelizada con OpenMP.
+\note Primero se aplican las traslaciones y luego los factores de escala.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\date 03 de junio de 2011: Creación de la función.
+\date 18 de junio de 2011: Distinción entre factores de escala y traslaciones
+      para las coordenadas X e Y.
+\note Esta función todavía no está probada.
+*/
+void TrasladaYEscalaPolil(polil* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Aplica un factor de escala y una traslación (el orden de aplicación se ha
+       de seleccionar) a las coordenadas de todas las polilíneas almacenadas en
+       una estructura \ref polil.
+\param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas.
+               Al término de la ejecución de la función, se ha aplicado un
+               factor de escala y una traslación (orden a seleccionar) a las
+               coordenadas de todas las polilíneas almacenadas y, si se indica,
+               a los límites.
+\param[in] escalaX Factor de escala a aplicar a las coordenadas X.
+\param[in] escalaY Factor de escala a aplicar a las coordenadas Y.
+\param[in] trasladaX Traslación a aplicar a las coordenadas X.
+\param[in] trasladaY Traslación a aplicar a las coordenadas Y.
+\param[in] orden Orden de aplicación de los factores de escala y traslación. Dos
+           posibilidades:
+           - 0: Primero se aplican los factores de escala y luego las
+             traslaciones \f$x'=f\cdot x+t\f$.
+           - Distinto de 0: Primero se aplican las traslaciones y luego los
+             factores de escala \f$x'=(x+t)\cdot f\f$.
+\param[in] aplicaLim Identificador para aplicar o no los factores de escala y
+           las traslaciones a los límites de las polilíneas (sólo si están
+           previemente calculados). Dos posibilidades:
+           - 0: No se aplican los factores de escala ni las traslaciones a los
+             límites.
+           - Distinto de 0: Sí se aplican los factores de escala y las
+             traslaciones a los límites, si estos están calculados en la
+             estructura de entrada.
+\note Esta función asume que la estructura de entrada \em poli tiene memoria
+      asignada.
+\date 03 de junio de 2011: Creación de la función.
+\date 18 de junio de 2011: Distinción entre factores de escala y traslaciones
+      para las coordenadas X e Y.
+\note Esta función todavía no está probada.
+*/
+void MuevePolil(polil* poli,
+                const double escalaX,
+                const double escalaY,
+                const double trasladaX,
+                const double trasladaY,
+                const int orden,
+                const int aplicaLim);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Elimina vértices de las polilíneas almacenadas en una estructura
+       \ref polil mediante un algoritmo inspirado en el de Douglas-Peucker. Se
+       usa internamente la función \ref AligeraPolilinea.
+\param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas.
+               Al término de la ejecución de la función, almacena el resultado
+               de la aplicación a cada polilínea del algoritmo de aligerado de
+               vértices implementado en la función \ref AligeraPolilinea.
+\param[in] tol Tolerancia para eliminar vértices, en las mismas unidades que las
+           coordenadas de los vértices. Ver la ayuda de la función
+           \ref AligeraPolilinea.
+\param[in] robusto Identificador para realizar o no un aligerado robusto. Ha de
+           ser un elemento del tipo enumerado #GEOC_DPEUCKER_ROBUSTO. Varias
+           posibilidades:
+           - #GeocDPeuckerRobNo: No se aplica el algoritmo robusto.
+           - #GeocDPeuckerRobSi: Se aplica el algoritmo robusto completo, que
+             garantiza la no ocurrencia de auto intersecciones en la polilínea
+             resultante. Internamente, primero se aplica el tratamiento robusto
+             de la opción #GeocDPeuckerRobOrig y luego el de la opción
+             #GeocDPeuckerRobAuto.
+           - #GeocDPeuckerRobOrig: Se aplica un algoritmo semi robusto que
+             consiste en garantizar que los segmentos de la polilínea aligerada
+             que se van creando no intersectarán con ninguno de los segmentos
+             que forman los vértices que quedan por procesar de la polilínea
+             original. En casos muy especiales, este algoritmo puede seguir
+             dando lugar a auto intersecciones.
+           - #GeocDPeuckerRobAuto: Se aplica un algoritmo semi robusto que
+             consiste en garantizar que los segmentos de la polilínea aligerada
+             que se van creando no intersectarán con ninguno de los segmentos de
+             la polilínea aligerada creados con anterioridad. En casos muy
+             especiales, este algoritmo puede seguir dando lugar a auto
+             intersecciones.
+\param[in] nPtosRobusto Número de puntos de la polilínea original a utilizar en
+           el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o
+           #GeocDPeuckerRobOrig. Si se pasa el valor 0, se utilizan todos los
+           puntos hasta el final de la polilínea original.
+\param[in] nSegRobusto Número de segmentos de la polilínea aligerada a utilizar
+           en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi
+           o #GeocDPeuckerRobAuto. Si se pasa el valor 0, se utilizan todos los
+           segmentos hasta el inicio de la polilínea aligerada.
+\return Variable de error. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función asume que \em poli está, como mínimo, inicializada.
+\note Si \em poli tiene límites calculados en la entrada, también los tendrá en
+      la salida.
+\note Una polilínea aligerada sólo será válida si después de aplicarle la
+      función \ref AligeraPolilinea mantiene un mínimo de 2 puntos que no sean
+      el mismo (esto sólo puede ocurrir si se pasa un polígono -los vértices de
+      inicio y final coinciden- y sólo quedan al final los extremos). Al término
+      de la ejecución de esta función, el resultado puede ser una estructura
+      \ref polil vacía.
+\date 09 de julio de 2011: Creación de la función.
+\date 10 de julio de 2011: Cambio del tipo del argumento \em robusto al tipo
+      enumerado #GEOC_DPEUCKER_ROBUSTO.
+\date 31 de julio de 2011: Corregido error con índices a la hora de guardar los
+      resultados y modificación para no tomar como válidas las polilíneas que se
+      quedan en sólo dos vértices que sean el mismo.
+\todo Esta función todavía no está probada.
+*/
+int AligeraPolil(polil* poli,
+                 const double tol,
+                 const enum GEOC_DPEUCKER_ROBUSTO robusto,
+                 const size_t nPtosRobusto,
+                 const size_t nSegRobusto);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Imprime una línea de cabecera para una polilínea almacenada en una
+       estructura \ref polil.
+\param[in] poli Estructura \ref polil.
+\param[in] indice Índice de la polilínea de trabajo en la estructura.
+\param[in] iniCab Cadena de texto con la que comenzará la cabecera.
+\param[in] impLim Identificador para imprimir o no los límites de coordenadas
+           de la polilínea de trabajo. Dos posibles valores:
+           - 0: No se imprimen.
+           - Distinto de 0: Sí se imprimen.
+\param[in] formCoor Cadena de carácteres indicadora del formato para escribir
+           las coordenadas de los límites. Este argumento sólo se usa
+           internamente si se ha indicado la impresión de límites.
+\param[in] factorX Factor para multiplicar las coordenadas X de los vértices
+           antes de imprimirlas.
+\param[in] factorY Factor para multiplicar las coordenadas Y de los vértices
+           antes de imprimirlas.
+\param[in] idFich Identificador de fichero abierto para escribir.
+\note Esta función está paralelizada con OpenMP.
+\note La cabecera completa tiene el siguiente formato:
+      <tt>iniCab númVert xMín xMáx yMín yMáx</tt>.
+\note Si la estructura no tiene información de límites y se indica que se
+      impriman, los valores se calculan internamente.
+\note Esta función asume que \em poli es una estructura \ref polil correctamente
+      almacenada.
+\note Esta función no comprueba si la estructura pasada tiene memoria asignada.
+\note Esta función no comprueba internamente la validez de los argumentos de
+      formato.
+\note Esta función no comprueba internamente si el identificador pasado
+      corresponde a un fichero abierto para escribir.
+\date 18 de junio de 2011: Creación de la función.
+\note Esta función todavía no está probada.
+*/
+void ImprimeCabeceraPolilFichero(const polil* poli,
+                                 const size_t indice,
+                                 const char iniCab[],
+                                 const int impLim,
+                                 const char formCoor[],
+                                 const double factorX,
+                                 const double factorY,
+                                 FILE* idFich);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Imprime una estructura \ref polil en un fichero.
+\param[in] poli Estructura \ref polil.
+\param[in] factorX Factor para multiplicar las coordenadas X de los vértices
+           antes de imprimirlas.
+\param[in] factorY Factor para multiplicar las coordenadas Y de los vértices
+           antes de imprimirlas.
+\param[in] iniNan Identificador para imprimir o no la marca de separación de
+           polilíneas (\p NaN) delante de la primera polilínea. Dos posibles
+           valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] finNan Identificador para imprimir o no la marca de separación de
+           polilíneas (\p NaN) delante de la última polilínea. Dos posibles
+           valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] formCoor Cadena de carácteres indicadora del formato de cada
+           coordenada a imprimir.
+\param[in] impCabecera Identificador para imprimir o no una cabecera con
+           información general por cada polilínea. Dos posibles valores:
+           - 0: No se imprime.
+           - Distinto de 0: Sí se imprime.
+\param[in] iniCab Cadena de texto con la que comenzará la cabecera.
+\param[in] impLim Identificador para imprimir o no en la cabecera los límites de
+           coordenadas de las polilíneas de trabajo. Dos posibles valores:
+           - 0: No se imprimen.
+           - Distinto de 0: Sí se imprimen.
+\param[in] idFich Identificador de fichero abierto para escribir.
+\note La cabecera completa tiene el siguiente formato:
+      <tt>iniCab númVert xMín xMáx yMín yMáx</tt>.
+\note Si la estructura no tiene información de límites y se indica que se
+      impriman, los valores se calculan internamente.
+\note Esta función asume que \em poli es una estructura \ref polil correctamente
+      almacenada.
+\note Esta función no comprueba si la estructura pasada tiene memoria asignada.
+\note Esta función no comprueba internamente la validez de los argumentos de
+      formato.
+\note Esta función no comprueba internamente si el identificador pasado
+      corresponde a un fichero abierto para escribir.
+\date 03 de junio de 2011: Creación de la función.
+\date 18 de junio de 2011: Adición de la capacidad de escritura de una cabecera
+      y del uso de factores de escala independientes para las coordenadas X e Y.
+\date 22 de septiembre de 2011: Corregido bug que hacía que, dependiendo del
+      compilador y/o los flags de optimización en la compilación, se imprimiesen
+      mal (con un signo menos delante) los valores Not-a-Number.
+\note Esta función todavía no está probada.
+*/
+void ImprimePolilFichero(const polil* poli,
+                         const double factorX,
+                         const double factorY,
+                         const int iniNan,
+                         const int finNan,
+                         const char formCoor[],
+                         const int impCabecera,
+                         const char iniCab[],
+                         const int impLim,
+                         FILE* idFich);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/ptopol.h b/src/libgeoc/ptopol.h
new file mode 100755
index 0000000..6f82b3a
--- /dev/null
+++ b/src/libgeoc/ptopol.h
@@ -0,0 +1,947 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file ptopol.h
+\brief Declaración de funciones para la realización de chequeos de inclusión de
+       puntos en polígonos.
+
+En el momento de la compilación ha de seleccionarse el tipo de dato que se
+utilizará en los cálculos intermedios de las funciones
+\ref PtoEnPoligonoVerticeBorde y \ref PtoEnPoligonoVerticeBordeDouble. Si los
+puntos de trabajo están muy alejados de los polígonos pueden darse casos de
+resultados erróneos. Sería conveniente que los cálculos internedios se hiciesen
+en variables de 64 bits, pero el tipo <tt>long int</tt> suele ser de 4 bytes en
+procesadores de 32 bits. Para seleccionar este tipo como <tt>long long int</tt>,
+lo que en procesadores de 32 bits equivale a una variable de 64 bits, es
+necesario definir la variable para el preprocesador \em PTOPOL_BORDE_LONG_64. En
+procesadores de 64 bits no es necesario (aunque puede utilizarse), ya que el
+tipo <tt>long int</tt> tiene una longitud de 64 bits. Si no se define la
+variable, se usará un tipo <tt>long int</tt> para los cálculos intermedios. En
+\p gcc, las variables para el preprocesador se pasan como \em -DXXX, donde
+\em XXX es la variable a introducir. El uso del tipo <tt>long long int</tt> en
+procesadores de 32 bits puede hacer que las funciones se ejecuten hasta 10 veces
+más lentamente que si se utiliza el tipo <tt>long int</tt>. Con cálculos
+internos de 32 bits las coordenadas de los vértices del polígono no han de estar
+más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos
+de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas
+3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al
+centímetro. Con esto podríamos chequear un punto en un polo con respecto a un
+polígono en el ecuador en coordenadas UTM expresadas en centímetros.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 05 de abril de 2010
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _PTOPOL_H_
+#define _PTOPOL_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdlib.h>
+#include<math.h>
+#include"libgeoc/errores.h"
+#include"libgeoc/geocnan.h"
+#include"libgeoc/geocomp.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_PTO_FUERA_POLIG
+\brief Identificador de punto fuera de un polígono.
+\date 12 de abril de 2011: Creación de la constante.
+*/
+#define GEOC_PTO_FUERA_POLIG 0
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_PTO_DENTRO_POLIG
+\brief Identificador de punto dentro de un polígono.
+\date 12 de abril de 2011: Creación de la constante.
+*/
+#define GEOC_PTO_DENTRO_POLIG 1
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_PTO_VERTICE_POLIG
+\brief Identificador de punto que es un vértice de un polígono.
+\date 12 de abril de 2011: Creación de la constante.
+*/
+#define GEOC_PTO_VERTICE_POLIG 2
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_PTO_BORDE_POLIG
+\brief Identificador de punto que está en el borde de un polígono.
+\date 12 de abril de 2011: Creación de la constante.
+*/
+#define GEOC_PTO_BORDE_POLIG 3
+/******************************************************************************/
+/******************************************************************************/
+/**
+\typedef ptopol_long
+\brief Nombre del tipo <tt>long int</tt> o <tt>long long int</tt> para utilizar
+       en los cálculos intermedios de las funciones
+       \ref PtoEnPoligonoVerticeBorde y \ref PtoEnPoligonoVerticeBordeDouble. Si
+       los puntos de trabajo están muy alejados de los polígonos pueden darse
+       casos de resultados erróneos. Sería conveniente que los cálculos
+       internedios se hiciesen en variables de 64 bits, pero el tipo
+       <tt>long int</tt> suele ser de 4 bytes en procesadores de 32 bits.
+       Mediante la variable del preprocesador PTOPOL_BORDE_LONG_64 indicamos que
+       este tipo sea <tt>long long int</tt>, lo que en procesadores de 32 bits
+       equivale a una variable de 64 bits.
+\note Este tipo de dato sólo es para uso interno en el fichero \ref ptopol.c. No
+      se recomienda su uso fuera de él, ya que habría que tener el cuenta la
+      variable del preprocesador cada vez que se incluyera este fichero
+      (\ref ptopol.h) en un programa u otro fichero.
+\date 19 de abril de 2011: Creación del tipo.
+*/
+#if defined(PTOPOL_BORDE_LONG_64)
+typedef long long int ptopol_long;
+#else
+typedef long int ptopol_long;
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Indica si hay alguna función compilada en paralelo con OpenMP en el
+       fichero \ref ptopol.c.
+\return Dos posibles valores:
+        - 0: No hay ninguna función compilada en paralelo con OpenMP.
+        - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP.
+\note Esta función asume que el argumento \em version tiene suficiente memoria
+      asignada (si es distinto de \p NULL).
+\date 13 de abril de 2011: Creación de la función.
+\date 25 de agosto de 2011: Adición del argumento de entrada \em version.
+*/
+int GeocParOmpPtopol(char version[]);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Indica si se está utilizando el tipo <tt>log long int</tt> para la
+       realización de cálculos intermedios en las funciones de chequeo de puntos
+       en polígonos que son capaces de detectar si un punto está en el borde.
+\return Dos posibles valores:
+        - 0: No se está utilizando <tt>log long int</tt>.
+        - Distinto de 0: Sí se está utilizando <tt>log long int</tt>.
+\date 19 de abril de 2011: Creación de la función.
+*/
+int GeocLongLongIntPtopol(void);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en un rectángulo.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] xMin Coordenada X mínima del rectángulo.
+\param[in] xMax Coordenada X máxima del rectángulo.
+\param[in] yMin Coordenada Y mínima del rectángulo.
+\param[in] yMax Coordenada Y máxima del rectángulo.
+\return Varias posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera del rectángulo.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del rectángulo.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del rectángulo.
+        - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera del
+          rectángulo, pero no es un vértice.
+\note Esta función asume que \em xMin<xMax e \em yMin<yMax.
+\date 05 de abril de 2010: Creación de la función.
+\date 12 de abril de 2011: Las variables de salida son ahora constantes
+      simbólicas.
+\todo Esta función no está probada.
+*/
+int PtoEnRectangulo(const double x,
+                    const double y,
+                    const double xMin,
+                    const double xMax,
+                    const double yMin,
+                    const double yMax);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un rectángulo 1 está contenido íntegramente en otro 2.
+\param[in] borde Identificador para indicar si los bordes se tienen en cuenta o
+           no. Dos posibilidades:
+           - 0: Lo bordes \b *NO* se tienen en cuenta. Es decir, si algún borde
+             de un rectángulo coincide con el de otro, el resultado es que el
+             rectángulo 1 no está contenido en 2.
+           - Distinto de 0: Lo bordes \b *SÍ* se tienen en cuenta. Es decir, el
+             que un borde del rectángulo 1 coincida con otro del rectángulo 2 no
+             impide que 1 esté contenido en 2.
+\param[in] xMin1 Coordenada X mínima del rectángulo 1.
+\param[in] xMax1 Coordenada X máxima del rectángulo 1.
+\param[in] yMin1 Coordenada Y mínima del rectángulo 1.
+\param[in] yMax1 Coordenada Y máxima del rectángulo 1.
+\param[in] xMin2 Coordenada X mínima del rectángulo 2.
+\param[in] xMax2 Coordenada X máxima del rectángulo 2.
+\param[in] yMin2 Coordenada Y mínima del rectángulo 2.
+\param[in] yMax2 Coordenada Y máxima del rectángulo 2.
+\return Dos posibilidades:
+        - 0: El rectángulo 1 no está contenido íntegramente en el rectángulo 2.
+        - Distinto de 0: El rectángulo 1 está contenido íntegramente en el
+          rectángulo 2.
+\note Esta función asume que \em xMin1<xMax1, \em yMin1<yMax1, \em xMin2<xMax2 e
+      \em yMin2<yMax2.
+\date 20 de junio de 2010: Creación de la función.
+\todo Esta función no está probada.
+*/
+int RectanguloEnRectangulo(const int borde,
+                           const double xMin1,
+                           const double xMax1,
+                           const double yMin1,
+                           const double yMax1,
+                           const double xMin2,
+                           const double xMax2,
+                           const double yMin2,
+                           const double yMax2);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si dos rectángulos son disjuntos.
+\param[in] xMin1 Coordenada X mínima del rectángulo 1.
+\param[in] xMax1 Coordenada X máxima del rectángulo 1.
+\param[in] yMin1 Coordenada Y mínima del rectángulo 1.
+\param[in] yMax1 Coordenada Y máxima del rectángulo 1.
+\param[in] xMin2 Coordenada X mínima del rectángulo 2.
+\param[in] xMax2 Coordenada X máxima del rectángulo 2.
+\param[in] yMin2 Coordenada Y mínima del rectángulo 2.
+\param[in] yMax2 Coordenada Y máxima del rectángulo 2.
+\return Dos posibilidades:
+        - 0: Los rectángulos no son disjuntos, es decir, tienen alguna parte
+             común (se cortan o se tocan) o uno está completamente contenido en
+             el otro.
+        - Distinto de 0: Los rectángulos son disjuntos.
+\note Esta función asume que \em xMin1<xMax1, \em yMin1<yMax1, \em xMin2<xMax2 e
+      \em yMin2<yMax2.
+\date 13 de junio de 2010: Creación de la función.
+\todo Esta función no está probada.
+*/
+int RectDisjuntos(const double xMin1,
+                  const double xMax1,
+                  const double yMin1,
+                  const double yMax1,
+                  const double xMin2,
+                  const double xMax2,
+                  const double yMin2,
+                  const double yMax2);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en un polígono de un número
+       arbitrario de lados. Esta función puede no dar resultados correctos para
+       puntos en los bordes y/o los vértices del polígono.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices del
+           polígono. Puede contener varios polígonos.
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices del
+           polígono. Puede contener varios polígonos.
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono.
+\note El código de esta función ha sido tomado de
+      http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html y
+      se han hecho pequeñas modificaciones para permitir el trabajo con vectores
+      que contengan elementos separados entre sí por varias posiciones.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note Esta función no detecta el caso de que el punto de trabajo esté en el
+      borde o en un vértice del polígono. En este caso, el test puede dar el
+      punto dentro o fuera, indistintamente (el chequeo del mismo punto con el
+      mismo polígono siempre dará el mismo resultado).
+\note La estructura de los vectores de coordenadas puede contener uno o varios
+      polígonos, de la siguiente manera:
+      -# Los vectores de vértices pasados puedes contener elementos aislados
+         (varios polígonos) y/o agujeros en los elementos. En los vectores de
+         entrada se han de separar los polígonos y los agujeros mediante un
+         vértice de coordenadas NaN=(#GEOC_NAN, #GEOC_NAN), de la siguiente
+         forma:
+         -# Primero, se incluye un vértice NaN.
+         -# A continuación, se incluyen las coordenadas de los vértices del
+            primer elemento, repitiendo el primer vértice después del último.
+         -# Se incluye otro vértice NaN.
+         -# Se incluye otro elemento, repitiendo el primer vértice después del
+            último.
+         -# Se repiten los dos pasos anteriores por cada elemento o agujero.
+         -# Se incluye un vértice NaN al final.
+      -# Por ejemplo, dados tres elementos aislados de vértices A1, A2, A3, B1,
+         B2, B3 y C1, C2, C3, y dos agujeros de vértices H1, H2, H3 e I1, I2,
+         I3, los vértices serán listados en los vectores de coordenadas como:
+         - NaN,A1,A2,A2,A1,NaN,B1,B2,B3,B1,NaN,C1,C2,C3,C1,NaN,H1,H2,H3,H1,NaN,
+           I1,I2,I3,I1,NaN.
+      -# Los vértices de cada elemento y/o agujero pueden ser listados en
+         sentido dextrógiro o levógiro.
+      -# Si el polígono es único y no tiene agujeros es opcional repetir el
+         primer vértice después del último e iniciar y terminar el listado de
+         coordenadas con el vértice NaN. Pero si se inicia y termina el listado
+         con vértices NaN, ha de repetirse el primer vértice del polígono.
+\date 05 de abril de 2010: Creación de la función.
+\date 10 de abril de 2011: Adición de los argumentos de entrada \em incX e
+      \em incY.
+\date 12 de abril de 2011: Las variables de salida son ahora constantes
+      simbólicas.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligono(const double x,
+                  const double y,
+                  const double* coorX,
+                  const double* coorY,
+                  const size_t N,
+                  const size_t incX,
+                  const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido o es un vértice de un polígono de un
+       número arbitrario de lados. Esta función puede no dar resultados
+       correctos para puntos en los bordes del polígono.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices del
+           polígono. Sólo puede contener un polígono.
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices del
+           polígono. Sólo puede contener un polígono.
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del polígono.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note Esta función utiliza en uno de sus pasos la función \ref PtoEnPoligono y
+      se comporta igual que ella en el caso de puntos en el borde.
+\note La estructura de los vectores de coordenadas es idéntica a la de la
+      función \ref PtoEnPoligono.
+\date 09 de abril de 2010: Creación de la función.
+\date 10 de abril de 2011: Adición de los argumentos de entrada \em incX e
+      \em incY.
+\date 12 de abril de 2011: Las variables de salida son ahora constantes
+      simbólicas.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligonoVertice(const double x,
+                         const double y,
+                         const double* coorX,
+                         const double* coorY,
+                         const size_t N,
+                         const size_t incX,
+                         const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en un polígono de un número
+       arbitrario de lados. Esta función trata correctamente los puntos situados
+       en los bordes y/o los vértices del polígono, pero sólo trabaja con datos
+       de tipo entero.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices del
+           polígono. Sólo puede contener un polígono.
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices del
+           polígono. Sólo puede contener un polígono.
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\return Varias posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del polígono.
+        - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera del polígono,
+          pero no es un vértice.
+\note El código de esta función ha sido tomado del texto Joseph O'Rourke (2001),
+      Computational geometry in C, 2a edición, Cambridge University Press,
+      página 244.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note El polígono ha de ser único, sin huecos. Es opcional repetir las
+      coordenadas del primer punto al final del listado.
+\note Los vértices del polígono pueden listarse en sentido dextrógiro o
+      levógiro.
+\note <b>Esta función puede dar resultados incorrectos para puntos muy alejados
+      de los polígonos de trabajo. Para intentar mitigar este efecto, puede
+      seleccionarse mediante una variable del preprocesador la precisión de
+      algunas variables intermedias. Para más información se recomienda leer el
+      encabezado de este fichero.</b>
+\note Con cálculos internos de 32 bits las coordenadas de los vértices del
+      polígono no han de estar más lejos de las de los puntos de trabajo de unas
+      40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar
+      alejados de los puntos de trabajo unas 3000000000 unidades, lo que
+      corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto
+      podríamos chequear un punto en un polo con respecto a un polígono en el
+      ecuador en coordenadas UTM expresadas en centímetros.
+\date 06 de abril de 2010: Creación de la función.
+\date 10 de abril de 2011: Adición de los argumentos de entrada \em incX e
+      \em incY.
+\date 12 de abril de 2011: Las variables de salida son ahora constantes
+      simbólicas.
+\date 18 de abril de 2011: Reescritura de la función, siguiendo la página 244
+      del libro de O'Rourke. La versión anterior la había adaptado del código de
+      la web de O'Rourke, y lo había hecho mal.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligonoVerticeBorde(const long x,
+                              const long y,
+                              const long* coorX,
+                              const long* coorY,
+                              const size_t N,
+                              const size_t incX,
+                              const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en un polígono de un número
+       arbitrario de lados. Esta función trata correctamente los puntos situados
+       en los bordes y/o los vértices del polígono. Trabaja con datos de tipo
+       real, que convierte a enteros (por redondeo o truncamiento) intermamente,
+       mediante la aplicación de un factor de escala.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices del
+           polígono. Sólo puede contener un polígono.
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices del
+           polígono. Sólo puede contener un polígono.
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\param[in] factor Factor de multiplicación para aplicar a las coordenadas del
+           punto de trabajo y de los vértices del polígono, con el fin de
+           aumentar su resolución antes de convertirlas en valores de tipo
+           entero (\p long \p int). El uso de factores muy grandes puede
+           provocar resultados erróneos. Ver la nota al final de la
+           documentación de esta función.
+\param[in] redondeo Identificador de redondeo o truncamiento en la conversión
+           interna de variables de tipo \p double en variables de tipo
+           \p long \p int. Dos posibilidades:
+           - 0: La conversión se hace por truncamiento.
+           - Distinto de 0: La conversión se hace por redondeo.
+\return Varias posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del polígono.
+        - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera del polígono,
+          pero no es un vértice.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note El polígono ha de ser único, sin huecos. Es opcional repetir las
+      coordenadas del primer punto al final del listado.
+\note Los vértices del polígono pueden listarse en sentido dextrógiro o
+      levógiro.
+\note El código de esta función es el mismo que el de la función
+      \ref PtoEnPoligonoVerticeBorde, salvo que convierte internamente varias
+      variables intermedias de tipo \p double a tipo \p long \p int, que es el
+      tipo de datos necesario para detectar correctamente si un punto pertenece
+      al borde de un polígono.
+\note Las variables se redondean internamente con la orden
+      <tt>(long)(round(factor*variable))</tt>, y se truncan con la orden
+      <tt>(long)(factor*variable)</tt>.
+\note <b>Esta función puede dar resultados incorrectos para puntos muy alejados
+      de los polígonos de trabajo. Para intentar mitigar este efecto, puede
+      seleccionarse mediante una variable del preprocesador la precisión de
+      algunas variables intermedias. Para más información se recomienda leer el
+      encabezado de este fichero.</b>
+\note Con cálculos internos de 32 bits las coordenadas de los vértices del
+      polígono no han de estar más lejos de las de los puntos de trabajo de unas
+      40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar
+      alejados de los puntos de trabajo unas 3000000000 unidades, lo que
+      corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto
+      podríamos chequear un punto en un polo con respecto a un polígono en el
+      ecuador en coordenadas UTM expresadas en centímetros. En este caso nos
+      referimos a las coordenadas una vez aplicado el factor de escala
+      \em factor.
+\date 10 de abril de 2011: Creación de la función.
+\date 11 de abril de 2011: Adición del argumento de entrada \em redondeo.
+\date 12 de abril de 2011: Las variables de salida son ahora constantes
+      simbólicas.
+\date 18 de abril de 2011: Reescritura de la función, siguiendo la página 244
+      del libro de O'Rourke. La versión anterior la había adaptado del código de
+      la web de O'Rourke, y lo había hecho mal.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligonoVerticeBordeDouble(const double x,
+                                    const double y,
+                                    const double* coorX,
+                                    const double* coorY,
+                                    const size_t N,
+                                    const size_t incX,
+                                    const size_t incY,
+                                    const double factor,
+                                    const int redondeo);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca valores #GEOC_NAN es uno o dos vectores de datos. Esta función
+       está pensada para el chequeo en paralelo de la inclusión de puntos en
+       polígonos.
+\param[in] x Vector que contiene las coordenadas X de los vértices de una serie
+           de polígonos, tal y como entraría en la definición de múltiples
+           elementos (pero sin huecos) para la función \ref PtoEnPoligono. La
+           marca de separación entre polígonos ha de ser #GEOC_NAN.
+\param[in] y Vector que contiene las coordenadas Y de los vértices de una serie
+           de polígonos, tal y como entraría en la definición de múltiples
+           elementos (pero sin huecos) para la función \ref PtoEnPoligono. La
+           marca de separación entre polígonos ha de ser #GEOC_NAN. Este
+           argumento puede valer NULL, en cuyo caso sólo se trabajará con el
+           vector \em x.
+\param[in] N Número de elementos que contienen los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\param[out] nNan Número de valores #GEOC_NAN encontrados, que es el número de
+            elementos del vector de salida.
+\return Varias posibilidades:
+        - Si todo ha ido bien, vector que contiene las posiciones en el vector o
+          vectores originales donde se almacena el valor #GEOC_NAN. Si se
+          trabaja con los vectores \em x e \em y, la posición sólo se extrae si
+          ambos vectores contienen #GEOC_NAN para una misma posición.
+        - NULL: Pueden haber ocurrido dos cosas:
+          - Si \em nNan vale 0, en los datos de entrada no hay ningún valor
+            #GEOC_NAN.
+          - Si \em nNan es mayor que 0, ha ocurrido un error interno de
+            asignación de memoria.
+\note Esta función no comprueba si el número de elementos de los vectores \em x
+      e \em y es congruente con los valores pasados en \em N, \em incX e
+      \em incY.
+\note Las posiciones de los elementos #GEOC_NAN encontradas se refieren al
+      número de elementos \em N de los vectores de trabajo. Para encontrar la
+      posición real en memoria es necesario tener en cuenta las variables
+      \em incX e \em incY.
+\date 13 de abril de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+size_t* BuscaGeocNanEnVectores(const double* x,
+                               const double* y,
+                               const size_t N,
+                               const size_t incX,
+                               const size_t incY,
+                               size_t* nNan);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Extrae los parámetros de inicio y número de elementos de un polígono en
+       una lista de polígonos separados por un indicador. Esta función está
+       pensada para el chequeo en paralelo de la inclusión de puntos en
+       polígonos.
+\param[in] posInd Vector que contiene las posiciones de los indicadores en el
+           vector original. Este argumento es el vector que devuelve la función
+           \ref BuscaGeocNanEnVectores.
+\param[in] indPosInd Índice en el vector de posiciones de indicadores del
+           indicador que da comienzo al polígono de trabajo.
+\param[in] incX Posiciones de separación entre los elementos del vector original
+           que almacena las coordenadas X del listado de polígonos. Este
+           argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector original
+           que almacena las coordenadas Y del listado de polígonos. Este
+           argumento siempre ha de ser un número positivo.
+\param[out] iniX Posición de inicio de la coordenada X del polígono de trabajo
+            en el vector original que almacena las coordenadas X del listado de
+            polígonos. Para encontrar la posición real en memoria es necesario
+            tener en cuenta la variable \em incX.
+\param[out] iniY Posición de inicio de la coordenada Y del polígono de trabajo
+            en el vector original que almacena las coordenadas Y del listado de
+            polígonos. Para encontrar la posición real en memoria es necesario
+            tener en cuenta la variable \em incY.
+\param[out] nElem Número de elementos que conforman el polígono de trabajo.
+\note Esta función no comprueba si el vector \em posInd contiene datos.
+\note Esta función asume que el vector \em posInd contiene un número \b *PAR* de
+      datos.
+\note Esta función asume que el argumento \em indPosInd no es la última posición
+      del vector \em posInd.
+\date 13 de abril de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+void DatosPoliIndividualEnVecInd(const size_t* posInd,
+                                 const size_t indPosInd,
+                                 const size_t incX,
+                                 const size_t incY,
+                                 size_t* iniX,
+                                 size_t* iniY,
+                                 size_t* nElem);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en una serie de polígonos
+       individuales de un número arbitrario de lados. Esta función puede no dar
+       resultados correctos para puntos en los bordes y/o los vértices del
+       polígono.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y
+           \em coorY de los elementos #GEOC_NAN, que separan los polígonos
+           individuales. Este vector es la salida de la función
+           \ref BuscaGeocNanEnVectores.
+\param[in] nNan Número de elementos del vector \em posNan.
+\param[out] poli Número del polígono en que está incluido el punto de trabajo.
+            Si hay varios polígonos que contienen al punto de trabajo no se
+            puede asegurar cuál de ellos será el indicado en este argumento.
+            Este argumento sólo tiene sentido si el valor retornado por la
+            función es distinto de #GEOC_PTO_FUERA_POLIG.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos
+          listados.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono
+          de entre los listados.
+\note Esta función se puede ejecutar en paralelo con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note Esta función no comprueba si el número de elementos del vector \em posNan
+      es congruente con el valor pasado en \em nNan.
+\note Esta función no detecta el caso de que el punto de trabajo esté en el
+      borde o en un vértice del polígono. En este caso, el test puede dar el
+      punto dentro o fuera, indistintamente (el chequeo del mismo punto con el
+      mismo polígono siempre dará el mismo resultado).
+\note La estructura de los vectores de coordenadas es la misma que la de la
+      función \ref PtoEnPoligono. Las marcas de comienzo y final de los
+      listados, así como las de separación entre polígonos han de ser valores
+      #GEOC_NAN.
+\note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los
+      elementos primero y último han de ser #GEOC_NAN.
+\note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados
+      como polígonos individuales.
+\date 14 de abril de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligonoInd(const double x,
+                     const double y,
+                     const double* coorX,
+                     const double* coorY,
+                     const size_t N,
+                     const size_t incX,
+                     const size_t incY,
+                     const size_t* posNan,
+                     const size_t nNan,
+                     size_t* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en una serie de polígonos
+       individuales de un número arbitrario de lados. Esta función puede no dar
+       resultados correctos para puntos en los bordes del polígono.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y
+           \em coorY de los elementos #GEOC_NAN, que separan los polígonos
+           individuales. Este vector es la salida de la función
+           \ref BuscaGeocNanEnVectores.
+\param[in] nNan Número de elementos del vector \em posNan.
+\param[out] poli Número del polígono en que está incluido el punto de trabajo.
+            Si hay varios polígonos que contienen al punto de trabajo no se
+            puede asegurar cuál de ellos será el indicado en este argumento.
+            Este argumento sólo tiene sentido si el valor retornado por la
+            función es distinto de #GEOC_PTO_FUERA_POLIG.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos
+          listados.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono
+          de entre los listados.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice de, al menos, un
+          polígono de entre los listados.
+\note Esta función se puede ejecutar en paralelo con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note Esta función no comprueba si el número de elementos del vector \em posNan
+      es congruente con el valor pasado en \em nNan.
+\note Esta función no detecta el caso de que el punto de trabajo esté en el
+      borde del polígono. En este caso, el test puede dar el punto dentro o
+      fuera, indistintamente (el chequeo del mismo punto con el mismo polígono
+      siempre dará el mismo resultado).
+\note La estructura de los vectores de coordenadas es la misma que la de la
+      función \ref PtoEnPoligono. Las marcas de comienzo y final de los
+      listados, así como las de separación entre polígonos han de ser valores
+      #GEOC_NAN.
+\note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los
+      elementos primero y último han de ser #GEOC_NAN.
+\note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados
+      como polígonos individuales.
+\date 14 de abril de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligonoVerticeInd(const double x,
+                            const double y,
+                            const double* coorX,
+                            const double* coorY,
+                            const size_t N,
+                            const size_t incX,
+                            const size_t incY,
+                            const size_t* posNan,
+                            const size_t nNan,
+                            size_t* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en una serie de polígonos
+       individuales de un número arbitrario de lados. Esta función trata
+       correctamente los puntos situados en los bordes y/o los vértices del
+       polígono, pero sólo trabaja con datos de tipo entero.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y
+           \em coorY de los elementos #GEOC_NAN, que separan los polígonos
+           individuales. Este vector es la salida de la función
+           \ref BuscaGeocNanEnVectores.
+\param[in] nNan Número de elementos del vector \em posNan.
+\param[out] poli Número del polígono en que está incluido el punto de trabajo.
+            Si hay varios polígonos que contienen al punto de trabajo no se
+            puede asegurar cuál de ellos será el indicado en este argumento.
+            Este argumento sólo tiene sentido si el valor retornado por la
+            función es distinto de #GEOC_PTO_FUERA_POLIG.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos
+          listados.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono
+          de entre los listados.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice de, al menos, un
+          polígono de entre los listados.
+        - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera de, al menos,
+          un polígono de entre los listados, pero no es un vértice.
+\note Esta función se puede ejecutar en paralelo con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note Esta función no comprueba si el número de elementos del vector \em posNan
+      es congruente con el valor pasado en \em nNan.
+\note La estructura de los vectores de coordenadas es la misma que la de la
+      función \ref PtoEnPoligono. Las marcas de comienzo y final de los
+      listados, así como las de separación entre polígonos han de ser valores
+      #GEOC_NAN.
+\note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los
+      elementos primero y último han de ser #GEOC_NAN.
+\note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados
+      como polígonos individuales.
+\note <b>Esta función puede dar resultados incorrectos para puntos muy alejados
+      de los polígonos de trabajo. Para intentar mitigar este efecto, puede
+      seleccionarse mediante una variable del preprocesador la precisión de
+      algunas variables intermedias. Para más información se recomienda leer el
+      encabezado de este fichero.</b>
+\note Con cálculos internos de 32 bits las coordenadas de los vértices del
+      polígono no han de estar más lejos de las de los puntos de trabajo de unas
+      40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar
+      alejados de los puntos de trabajo unas 3000000000 unidades, lo que
+      corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto
+      podríamos chequear un punto en un polo con respecto a un polígono en el
+      ecuador en coordenadas UTM expresadas en centímetros.
+\date 14 de abril de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligonoVerticeBordeInd(const long x,
+                                 const long y,
+                                 const long* coorX,
+                                 const long* coorY,
+                                 const size_t N,
+                                 const size_t incX,
+                                 const size_t incY,
+                                 const size_t* posNan,
+                                 const size_t nNan,
+                                 size_t* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está contenido en una serie de polígonos
+       individuales de un número arbitrario de lados. Esta función trata
+       correctamente los puntos situados en los bordes y/o los vértices del
+       polígono. Trabaja con datos de tipo real, que convierte a enteros (por
+       redondeo o truncamiento) intermamente, mediante a aplicación de un factor
+       de escala.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] coorX Vector que contiene las coordenadas X de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] coorY Vector que contiene las coordenadas Y de los vértices de los
+           elementos. Puede contener varios polígonos, pero no huecos (si los
+           hay, serán tratados como otros polígonos).
+\param[in] N Número de elementos que contienen los vectores \em coorX y
+           \em coorY.
+\param[in] incX Posiciones de separación entre los elementos del vector
+           \em coorX. Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector
+           \em coorY. Este argumento siempre ha de ser un número positivo.
+\param[in] factor Factor de multiplicación para aplicar a las coordenadas del
+           punto de trabajo y de los vértices de los polígonos, con el fin de
+           aumentar su resolución antes de convertirlas en valores de tipo
+           entero (\p long \p int). El uso de factores muy grandes puede
+           provocar resultados erróneos. Ver la nota al final de la
+           documentación de esta función.
+\param[in] redondeo Identificador de redondeo o truncamiento en la conversión
+           interna de variables de tipo \p double en variables de tipo
+           \p long \p int. Dos posibilidades:
+           - 0: La conversión se hace por truncamiento.
+           - Distinto de 0: La conversión se hace por redondeo.
+\param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y
+           \em coorY de los elementos #GEOC_NAN, que separan los polígonos
+           individuales. Este vector es la salida de la función
+           \ref BuscaGeocNanEnVectores.
+\param[in] nNan Número de elementos del vector \em posNan.
+\param[out] poli Número del polígono en que está incluido el punto de trabajo.
+            Si hay varios polígonos que contienen al punto de trabajo no se
+            puede asegurar cuál de ellos será el indicado en este argumento.
+            Este argumento sólo tiene sentido si el valor retornado por la
+            función es distinto de #GEOC_PTO_FUERA_POLIG.
+\return Dos posibilidades:
+        - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos
+          listados.
+        - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono
+          de entre los listados.
+        - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice de, al menos, un
+          polígono de entre los listados.
+        - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera de, al menos,
+          un polígono de entre los listados, pero no es un vértice.
+\note Esta función se puede ejecutar en paralelo con OpenMP.
+\note Esta función no comprueba si el número de elementos de los vectores
+      \em coorX y \em coorY es congruente con los valores pasados en \em N,
+      \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual
+      a 3, que es el número mínimo de vértices que ha de tener un polígono.
+\note Esta función no comprueba si el número de elementos del vector \em posNan
+      es congruente con el valor pasado en \em nNan.
+\note Las variables se redondean internamente con la orden
+      <tt>(long)(round(factor*variable))</tt>, y se truncan con la orden
+      <tt>(long)(factor*variable)</tt>.
+\note La estructura de los vectores de coordenadas es la misma que la de la
+      función \ref PtoEnPoligono. Las marcas de comienzo y final de los
+      listados, así como las de separación entre polígonos han de ser valores
+      #GEOC_NAN.
+\note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los
+      elementos primero y último han de ser #GEOC_NAN.
+\note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados
+      como polígonos individuales.
+\note <b>Esta función puede dar resultados incorrectos para puntos muy alejados
+      de los polígonos de trabajo. Para intentar mitigar este efecto, puede
+      seleccionarse mediante una variable del preprocesador la precisión de
+      algunas variables intermedias. Para más información se recomienda leer el
+      encabezado de este fichero.</b>
+\note Con cálculos internos de 32 bits las coordenadas de los vértices del
+      polígono no han de estar más lejos de las de los puntos de trabajo de unas
+      40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar
+      alejados de los puntos de trabajo unas 3000000000 unidades, lo que
+      corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto
+      podríamos chequear un punto en un polo con respecto a un polígono en el
+      ecuador en coordenadas UTM expresadas en centímetros. En este caso nos
+      referimos a las coordenadas una vez aplicado el factor de escala
+      \em factor.
+\date 14 de abril de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int PtoEnPoligonoVerticeBordeDoubleInd(const double x,
+                                       const double y,
+                                       const double* coorX,
+                                       const double* coorY,
+                                       const size_t N,
+                                       const size_t incX,
+                                       const size_t incY,
+                                       const double factor,
+                                       const int redondeo,
+                                       const size_t* posNan,
+                                       const size_t nNan,
+                                       size_t* poli);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/recpolil.h b/src/libgeoc/recpolil.h
new file mode 100755
index 0000000..6957b92
--- /dev/null
+++ b/src/libgeoc/recpolil.h
@@ -0,0 +1,439 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file recpolil.h
+\brief Definición de estructuras y declaración de funciones para el recorte de
+       polilíneas por medio de polígonos.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 04 de junio de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _RECPOLIL_H_
+#define _RECPOLIL_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdlib.h>
+#include<math.h>
+#include"libgeoc/errores.h"
+#include"libgeoc/eucli.h"
+#include"libgeoc/geocnan.h"
+#include"libgeoc/greiner.h"
+#include"libgeoc/polig.h"
+#include"libgeoc/polil.h"
+#include"libgeoc/ptopol.h"
+#include"libgeoc/segmento.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_RECPOLIL_BUFFER_PTOS
+\brief Número de puntos para ir asignando memoria en bloques para las polilíneas
+       de salida en la funcion \ref Paso2Recpolil. Ha de ser un número mayor o
+       igual a 2.
+\date 04 de junio de 2011: Creación de la constante.
+*/
+#define GEOC_RECPOLIL_BUFFER_PTOS 100
+/******************************************************************************/
+/******************************************************************************/
+/** \enum GEOC_OP_BOOL_POLIL
+\brief Operación booleana entre polilínea y polígono.
+\date 04 de junio de 2011: Creación del tipo.
+*/
+enum GEOC_OP_BOOL_POLIL
+{
+    /** \brief Polilínea interior al polígono. */
+    GeocOpBoolDentro=111,
+    /** \brief Polilínea exterior al polígono. */
+    GeocOpBoolFuera=112
+};
+/******************************************************************************/
+/******************************************************************************/
+/** \struct _vertPolilClip
+\brief Estructura de definición de un vértice de una polilínea usada en
+       operaciones de recorte. La polilínea se almacena en memoria como una
+       lista doblemente enlazada de vértices.
+\date 04 de junio de 2011: Creación de la estructura.
+*/
+typedef struct _vertPolilClip
+{
+    /** \brief Coordenada X del vértice. */
+    double x;
+    /** \brief Coordenada Y del vértice. */
+    double y;
+    /** \brief Vértice anterior. */
+    struct _vertPolilClip* anterior;
+    /** \brief Vértice siguiente. */
+    struct _vertPolilClip* siguiente;
+    /**
+    \brief Indicador de punto de la polilínea original.
+
+           Dos posibilidades:
+           - 0: No es un punto de la polilínea original.
+           - Distinto de 0: Sí es un punto de la polilínea original.
+    */
+    char orig;
+    /**
+    \brief Posición del vértice con respecto al polígono de recorte.
+
+           Tres posibilidades:
+           - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono.
+           - #GEOC_PTO_BORDE_POLIG: El punto está en el borde o en un vértice
+             del polígono.
+           - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono.
+    */
+    char pos;
+    /** \brief Distancia, en tanto por uno, de un nodo de intersección con
+               respecto al primer vértice del segmento que lo contiene. */
+    double alfa;
+}vertPolilClip;
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea un vértice de tipo \ref _vertPolilClip y lo inserta entre otros dos.
+\param[in] x Coordenada X del vértice.
+\param[in] y Coordenada Y del vértice.
+\param[in] anterior Vértice anterior (puede ser \p NULL).
+\param[in] siguiente Vértice siguiente (puede ser \p NULL).
+\param[in] orig Campo _vertPolilClip::orig.
+\param[in] pos Campo _vertPolilClip::pos.
+\param[in] alfa Campo _vertPolilClip::alfa.
+\return Puntero al nuevo vértice creado. Si se devuelve \p NULL, ha ocurrido un
+        error de asignación de memoria.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPolilClip* CreaVertPolilClip(const double x,
+                                 const double y,
+                                 vertPolilClip* anterior,
+                                 vertPolilClip* siguiente,
+                                 const char orig,
+                                 const char pos,
+                                 const double alfa);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea una polilínea, como una lista doblemente enlazada de elementos
+       \ref _vertPolilClip.
+\param[in] x Vector de coordenadas X de los nodos de la polilínea.
+\param[in] y Vector de coordenadas Y de los nodos de la polilínea.
+\param[in] nCoor Número de elementos de los vectores \em x e \em y.
+\param[in] incX Posiciones de separación entre los elementos del vector \em x.
+           Este argumento siempre ha de ser un número positivo.
+\param[in] incY Posiciones de separación entre los elementos del vector \em y.
+           Este argumento siempre ha de ser un número positivo.
+\return Puntero al primer vértice de la lista. Si se devuelve \p NULL, ha
+        ocurrido un error de asignación de memoria.
+\note Esta función asume que el argumento \em nCoor es mayor que 0.
+\note Si en los vectores de coordenadas \em x e \em y hay valores #GEOC_NAN,
+      éstos no se tienen en cuenta a la hora de la creación de la estructura de
+      salida.
+\note Que los vectores de coordenadas \em x e \em y admitan vértices con
+      coordenadas (#GEOC_NAN,#GEOC_NAN) no quiere decir que éstos sean
+      separadores de múltiples polilíneas. \em x e \em y \b *SÓLO* deben
+      almacenar una única polilínea.
+\note Esta función asigna el valor 0 a todos los campos _vertPolilClip::pos de
+      los elementos creados.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPolilClip* CreaPolilClip(const double* x,
+                             const double* y,
+                             const size_t nCoor,
+                             const size_t incX,
+                             const size_t incY);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Libera la memoria asignada a una polilínea almacenada como una lista
+       doblemente enlazada de elementos \ref _vertPolilClip.
+\param[in] poli Puntero al primer elemento de la polilínea.
+\note Esta función no comprueba si hay vértices de la polilínea anteriores al
+      vértice de entrada, por lo que si se quiere liberar toda la memoria
+      asignada a una polilínea, el vértice pasado ha de ser el primero de la
+      lista.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void LibMemPolilClip(vertPolilClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Elimina los vértices no originales de una polilínea almacenada como una
+       lista doblemente enlazada de elementos \ref _vertPolilClip.
+\param[in] poli Puntero al primer elemento de la polilínea.
+\return Puntero al primer elemento de la polilínea original. Si se devuelve
+        \p NULL, ninguno de los vértices pertenecía a la polilínea original.
+\note Los vértices eliminados por esta función son todos aquéllos cuyo campo
+      _vertPolilClip::orig sea igual a 0.
+\note Aunque se supone que el primer vértice de una polilínea siempre es un
+      vértice original, si no lo es, la variable de entrada queda modificada.
+      Por tanto, siempre es recomendable capturar la variable de salida, que
+      garantiza la posición del primer elemento.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPolilClip* ReiniciaPolilClip(vertPolilClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Busca el siguiente vértice original en una polilínea.
+\param[in] vert Puntero al vértice a partir del cual se ha de buscar.
+\return Puntero al siguiente vértice original en la polilínea. Si se devuelve
+        \p NULL, se ha llegado al final.
+\note Los vértices no originales son todos aquéllos cuyo campo
+      _vertPolilClip::orig es distinto de 0.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+vertPolilClip* SiguienteVertOrigPolilClip(vertPolilClip* vert);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Inserta un vértice de tipo \ref _vertPolilClip entre otros dos,
+       atendiendo al campo _vertPolilClip::alfa.
+\param[in] ins Vértice a insertar.
+\param[in] extremoIni Extremo inicial del segmento donde se insertará \em ins.
+\param[in] extremoFin Extremo final del segmento donde se insertará \em ins.
+\note Esta función asume que todos los elementos pasados tienen memoria
+      asignada.
+\note Si entre \em extremoIni y \em extremoFin hay más vértices, \em ins se
+      insertará de tal modo que los campos _vertPolilClip::alfa queden ordenados
+      de menor a mayor.
+\note Si el campo _vertPolilClip::alfa de \em ins tiene el mismo valor que el
+      de \em extremoIni, \em ins se insertará justo a continuación de
+      \em extremoIni.
+\note Si el campo _vertPolilClip::alfa de \em ins tiene el mismo valor que el
+      de \em extremoFin, \em ins se insertará justo antes de \em extremoIni.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+void InsertaVertPolilClip(vertPolilClip* ins,
+                          vertPolilClip* extremoIni,
+                          vertPolilClip* extremoFin);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Cuenta el número de vértices originales que hay en una polilínea
+       almacenada como una lista doblemente enlazada de elementos
+       \ref _vertPolilClip.
+\param[in] poli Polilínea, almacenado como una lista doblemente enlazada de
+           elementos \ref _vertPolilClip. Sólo se tienen en cuenta los vértices
+           originales de la polilínea, que son todos aquéllos cuyo campo
+           _vertPolilClip::orig es distinto de 0.
+\return Número de vértices originales almacenados.
+\note Esta función no comprueba si la variable \em poli es una polilínea
+      correctamente almacenada.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+size_t NumeroVertOrigPolilClip(vertPolilClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Cuenta el número total de vértices que hay en una polilínea almacenada
+       como una lista doblemente enlazada de elementos \ref _vertPolilClip.
+\param[in] poli Polilínea, almacenado como una lista doblemente enlazada de
+           elementos \ref _vertPolilClip. Se tienen en cuenta todos los
+           vértices.
+\return Número total de vértices almacenados.
+\note Esta función no comprueba si la variable \em poli es una polilínea
+      correctamente almacenada.
+\date 04 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+size_t NumeroVertPolilClip(vertPolilClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Realiza el paso número 1 del algoritmo de recorte de polilíneas, que
+       consiste en el cálculo de los puntos de intersección de la polilínea de
+       trabajo con el polígono de recorte.
+
+       Este paso está inspirado en el primer paso del algoritmo de
+       Greiner-Hormann.
+\param[in,out] poli Polilínea de trabajo, representada como una lista doblemente
+               enlazada de elementos \ref _vertPolilClip. Al término de la
+               ejecución de la función se le han añadido los puntos de
+               intersección con el polígono de recorte y se han asignado los
+               valores correctos al campo _vertPolilClip::pos de cada vértice.
+\param[in] poliRec Polígono de recorte, representado como una lista doblemente
+           enlazada de elementos \ref _vertPoliClip.
+\param[out] nIntersec Número de intersecciones (intersecciones propiamente
+            dichas y puntos en el borde del polígono) calculadas.
+\return Variable de estado. Dos posibilidades:
+        - #GEOC_ERR_NO_ERROR: Todo ha ido bien.
+        - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si las variables \em polil y \em poliRec son
+      estructuras correctamente almacenadas.
+\note El polígono \em poliRec puede provenir de una operación booleana previa
+      entre polígonos, ya que sólo se recorrerán sus vértices originales, que
+      serán aquéllos cuyo campo _vertPoliClip::interseccion valga 0.
+\date 06 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int Paso1Recpolil(vertPolilClip* poli,
+                  vertPoliClip* poliRec,
+                  size_t* nIntersec);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Realiza el paso número 2 del algoritmo de recorte de polilíneas, que
+       consiste en la generación de lss polilíneas resultado.
+\param[in] poli Polilínea a recortar, representada como una lista doblemente
+                enlazada de elementos \ref _vertPolilClip, tal y como sale de la
+                función \ref Paso1Recpolil.
+\param[in] op Identificador de la operación a realizar. Ha de ser un elemento
+           del tipo enumerado #GEOC_OP_BOOL_POLIL.
+\return Estructura \ref polil con las polilíneas resultado de la operación. Si
+        se devuelve \p NULL ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si la variable \em polil es una polilínea
+      correctamente almacenada.
+\date 06 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+polil* Paso2Recpolil(vertPolilClip* poli,
+                     const enum GEOC_OP_BOOL_POLIL op);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Recorta una polilínea según un polígono de recorte.
+\param[in,out] poli Polilínea de trabajo, representada como una lista doblemente
+               enlazada de elementos \ref _vertPolilClip. Al término de la
+               ejecución de la función se le han añadido los puntos de
+               intersección con el polígono de recorte y se han asignado los
+               valores correctos al campo _vertPolilClip::pos de cada vértice.
+\param[in] poliRec Polígono de recorte, representado como una lista doblemente
+           enlazada de elementos \ref _vertPoliClip.
+\param[in] op Identificador de la operación a realizar. Ha de ser un elemento
+           del tipo enumerado #GEOC_OP_BOOL_POLIL. Varias posibilidades:
+           - #GeocOpBoolDentro: Calcula la porción de \em poli que está dentro
+             \em poliRec.
+           - #GeocOpBoolFuera: Calcula la porción de \em poli que está fuera
+             \em poliRec.
+\param[out] nIntersec Número de intersecciones calculadas.
+\return Estructura \ref polil con las polilíneas resultado de la operación. Si
+        se devuelve \p NULL ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si las variables \em poli y \em poliRec son
+      estructuras correctamente almacenadas.
+\note Esta función no comprueba internamente si \em op pertenece al tipo
+      enumerado #GEOC_OP_BOOL_POLIL. Si se introduce un valor no perteneciente
+      al tipo, se realiza la operación #GeocOpBoolDentro.
+\note Esta función asume que los puntos de borde pertenecen al interior del
+      polígono de recorte.
+\note Esta función asume que los puntos de borde sólo pertenecen al exterior del
+      polígono de recorte cuando son principio o final de polilínea recortada.
+\date 06 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+polil* RecortaPolil(vertPolilClip* poli,
+                    vertPoliClip* poliRec,
+                    const enum GEOC_OP_BOOL_POLIL op,
+                    size_t* nIntersec);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Recorta múltiples polilíneas según múltiples polígonos de recorte.
+\param[in] poli Estructura \ref polil que almacena las polilíneas de trabajo.
+\param[in] poliRec Estructura \ref polig que almacena los polígonos de recorte.
+\param[in] op Identificador de la operación a realizar. Ha de ser un elemento
+           del tipo enumerado #GEOC_OP_BOOL_POLIL. Varias posibilidades:
+           - #GeocOpBoolDentro: Calcula la porción de las polilíneas almacenadas
+             en \em poli que están dentro de los polígonos almacenados en
+             \em poliRec.
+           - #GeocOpBoolFuera: Calcula la porción de las polilíneas almacenadas
+             en \em poli que están fuera de los polígonos almacenados en
+             \em poliRec.
+\param[out] nIntersec Número total de intersecciones calculadas entre todas las
+            polilíneas con todos los polígonos.
+\return Estructura \ref polil con las polilíneas resultado de las operaciones.
+        Si se devuelve \p NULL ha ocurrido un error de asignación de memoria.
+\note Esta función realiza la operación \em op con todas las combinaciones
+      posibles de polilíneas y polígonos. Es decir, se recorren todas las
+      polilíneas y con cada una de ellas se realiza la operación \em op con cada
+      polígono almacenado en \em poliRec.
+\note Esta función no comprueba si las variables \em poli y \em poliRec son
+      estructuras correctamente almacenadas.
+\note Esta función no comprueba internamente si \em op pertenece al tipo
+      enumerado #GEOC_OP_BOOL_POLIL. Si se introduce un valor no perteneciente
+      al tipo, se realiza la operación #GeocOpBoolDentro.
+\note Esta función asume que los puntos de borde pertenecen al interior de los
+      polígonos de recorte.
+\note Esta función asume que los puntos de borde sólo pertenecen al exterior de
+      los polígonos de recorte cuando son principio o final de polilínea
+      recortada.
+\date 06 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+polil* RecortaPolilMult(const polil* poli,
+                        const polig* poliRec,
+                        const enum GEOC_OP_BOOL_POLIL op,
+                        size_t* nIntersec);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Crea una estructura \ref polil a partir de todos los vértices de una
+       polilínea almacenada como una lista doblemente enlazada de elementos
+       \ref _vertPolilClip.
+\param[in] poli Polilínea de trabajo, representada como una lista doblemente
+                enlazada de elementos \ref _vertPolilClip. El puntero pasado ha
+                de apuntar al primer elemento de la polilínea (no se controla
+                internamente).
+\return Estructura \ref polil que representa la polilínea. Si se devuelve
+        \p NULL ha ocurrido un error de asignación de memoria.
+\note Esta función no comprueba si la variable \em poli es una polilínea
+      correctamente almacenada.
+\note Esta función realiza una copia en memoria de las coordenadas de los
+      vértices de la estructura \em poli a la estructura de salida.
+\date 06 de junio de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+polil* CreaPolilPolilClip(vertPolilClip* poli);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/segmento.h b/src/libgeoc/segmento.h
new file mode 100755
index 0000000..3b3ef04
--- /dev/null
+++ b/src/libgeoc/segmento.h
@@ -0,0 +1,299 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom
+@{
+\file segmento.h
+\brief Declaración de funciones para la realización de cálculos con segmentos.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 22 de abril de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _SEGMENTO_H_
+#define _SEGMENTO_H_
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/fgeneral.h"
+#include"libgeoc/ptopol.h"
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_SEG_NO_INTERSEC
+\brief Identificador de que dos segmentos no se cortan.
+\date 14 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_SEG_NO_INTERSEC 0
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_SEG_INTERSEC
+\brief Identificador de que dos segmentos se cortan en un punto, pero no son
+       colineales.
+\date 14 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_SEG_INTERSEC 1
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN
+\brief Identificador de que dos segmentos se cortan en un punto, el cual es un
+       extremo que está encima del otro segmento, pero no son colineales.
+\date 14 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN 2
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_SEG_INTERSEC_EXTREMO_COLIN
+\brief Identificador de que dos segmentos tienen un punto común y son
+       colineales.
+\date 14 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_SEG_INTERSEC_EXTREMO_COLIN 3
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_SEG_INTERSEC_MISMO_SEG
+\brief Identificador de que dos segmentos tienen todos sus puntos extremos en
+       común.
+\date 21 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_SEG_INTERSEC_MISMO_SEG 4
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_SEG_INTERSEC_COLIN
+\brief Identificador de que dos segmentos tienen más de un punto en común.
+\date 14 de mayo de 2011: Creación de la constante.
+*/
+#define GEOC_SEG_INTERSEC_COLIN 5
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la posición relativa de un punto con respecto a una recta en el
+       plano.
+\param[in] x Coordenada X del punto de trabajo.
+\param[in] y Coordenada Y del punto de trabajo.
+\param[in] xIni Coordenada X del punto inicial del segmento que define la recta.
+\param[in] yIni Coordenada Y del punto inicial del segmento que define la recta.
+\param[in] xFin Coordenada X del punto final del segmento que define la recta.
+\param[in] yFin Coordenada Y del punto final del segmento que define la recta.
+\return Varias posibilidades:
+        - Menor que 0: El punto está a la derecha de la recta.
+        - 0: El punto pertenece a la recta.
+        - Mayor que 0: El punto está a la izquierda de la recta.
+\note Para la definición de derecha e izquierda, se considera que el sentido de
+      la recta es aquél que se define del punto de inicio al punto final del
+      segmento de trabajo.
+\note El resultado de esta función no es robusto, es decir, puede dar resultados
+      incorrectos debido a errores de redondeo (salvo que todas las coordenadas
+      pasadas sean números enteros).
+\note El código de esta función ha sido tomado de la función orient2dfast(), de
+      http://www.cs.cmu.edu/afs/cs/project/quake/public/code/predicates.c
+\date 20 de abril de 2010: Creación de la función.
+\date 14 de mayo de 2011: Cambio de nombre a la función.
+*/
+double PosPtoRecta2D(const double x,
+                     const double y,
+                     const double xIni,
+                     const double yIni,
+                     const double xFin,
+                     const double yFin);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si tres puntos (A, B, C) del plano son colineales.
+\param[in] xA Coordenada X del punto A.
+\param[in] yA Coordenada Y del punto A.
+\param[in] xB Coordenada X del punto B.
+\param[in] yB Coordenada Y del punto B.
+\param[in] xC Coordenada X del punto C.
+\param[in] yC Coordenada Y del punto C.
+\return Dos posibilidades:
+        - 0: Los puntos no son colineales.
+        - Distinto de 0: Los puntos son colineales.
+\note Esta función utiliza internamente la función \ref PtoComunSegmParalelos2D,
+      que no es robusta. En consecuencia, los resultados de esta función tampoco
+      lo son.
+\note Estafunción sirve de apoyo para \ref PtoComunSegmParalelos2D.
+\date 14 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int TresPuntosColineales2D(const double xA,
+                           const double yA,
+                           const double xB,
+                           const double yB,
+                           const double xC,
+                           const double yC);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si un punto está situado entre dos puntos (pero no es igual a
+       ninguno de ellos) en el plano. Se asume que los tres puntos con
+       colineales.
+\param[in] x Coordenada X del punto a comprobar.
+\param[in] y Coordenada Y del punto a comprobar.
+\param[in] xA Coordenada X del primer punto del segmento.
+\param[in] yA Coordenada Y del primer punto del segmento.
+\param[in] xB Coordenada X del segundo punto del segmento.
+\param[in] yB Coordenada Y del segundo punto del segmento.
+\return Dos posibilidades:
+        - 0: El punto de trabajo no está situado entre los dos puntos dato o es
+             igual a alguno de ellos.
+        - Distinto de 0: El punto de trabajo sí está situado entre los dos
+          puntos dato.
+\note Esta función sirve de apoyo para \ref PtoComunSegmParalelos2D.
+\date 14 de mayo de 2011: Creación de la función.
+\todo Esta función no está probada.
+*/
+int PuntoEntreDosPuntos2DColin(const double x,
+                               const double y,
+                               const double xA,
+                               const double yA,
+                               const double xB,
+                               const double yB);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula un punto común entre dos segmentos paralelos AB y CD.
+\param[in] xA Coordenada X del punto A.
+\param[in] yA Coordenada Y del punto A.
+\param[in] xB Coordenada X del punto B.
+\param[in] yB Coordenada Y del punto B.
+\param[in] xC Coordenada X del punto C.
+\param[in] yC Coordenada Y del punto C.
+\param[in] xD Coordenada X del punto D.
+\param[in] yD Coordenada Y del punto D.
+\param[out] x Coordenada X del punto común.
+\param[out] y Coordenada Y del punto común.
+\return Dos posibilidades:
+        - #GEOC_SEG_NO_INTERSEC: Los segmentos no tienen ningún punto en común.
+        - #GEOC_SEG_INTERSEC_EXTREMO_COLIN: Los segmentos tienen un extremo
+          común y son colineales.
+        - #GEOC_SEG_INTERSEC_MISMO_SEG: Los dos segmentos son idénticos.
+        - #GEOC_SEG_INTERSEC_COLIN: Los segmentos tienen más de un punto en
+          común.
+\note Esta función sirve de apoyo para \ref IntersecSegmentos2D.
+\note Esta función utiliza internamente la función \ref TresPuntosColineales2D,
+      que no es robusta. En consecuencia, los resultados de esta función tampoco
+      lo son.
+\note Si los segmentos se tocan en los dos extremos (son el mismo segmento), las
+      coordenadas devueltas son siempre las del vértice A.
+\note Si los segmentos tienen más de un punto en común, pero no son el mismo
+      segmento, las coordenadas de salida siempre son las de un punto extremo de
+      un segmento. Este punto extremo se intentará que sea uno de los puntos
+      iniciales de algún segmento, anque si no lo es, será uno de los finales.
+      El orden de preferencia de las coordenadas de salida es: A, C, B, D.
+\date 14 de mayo de 2011: Creación de la función.
+\date 21 de mayo de 2011: Adición de nuevos valores de salida:
+      #GEOC_SEG_INTERSEC_EXTREMO_COLIN y #GEOC_SEG_INTERSEC_MISMO_SEG.
+\todo Esta función no está probada.
+*/
+int PtoComunSegmParalelos2D(const double xA,
+                            const double yA,
+                            const double xB,
+                            const double yB,
+                            const double xC,
+                            const double yC,
+                            const double xD,
+                            const double yD,
+                            double* x,
+                            double* y);
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Calcula la intersección de dos segmentos AB y CD en el plano.
+\param[in] xA Coordenada X del punto A.
+\param[in] yA Coordenada Y del punto A.
+\param[in] xB Coordenada X del punto B.
+\param[in] yB Coordenada Y del punto B.
+\param[in] xC Coordenada X del punto C.
+\param[in] yC Coordenada Y del punto C.
+\param[in] xD Coordenada X del punto D.
+\param[in] yD Coordenada Y del punto D.
+\param[out] x Coordenada X del punto común.
+\param[out] y Coordenada Y del punto común.
+\return Cinco posibilidades:
+        - #GEOC_SEG_NO_INTERSEC: Los segmentos no tienen ningún punto en común.
+        - #GEOC_SEG_INTERSEC: Los segmentos se cortan en un punto.
+        - #GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN: El extremo de un segmento toca
+          al otro segmento, pero los segmentos no son colineales.
+        - #GEOC_SEG_INTERSEC_EXTREMO_COLIN: Los segmentos tienen un extremo
+          común y son colineales.
+        - #GEOC_SEG_INTERSEC_MISMO_SEG: Los dos segmentos son idénticos.
+        - #GEOC_SEG_INTERSEC_COLIN: Los segmentos tienen más de un punto en
+          común.
+\note Esta función utiliza internamente la función \ref PtoComunSegmParalelos2D,
+      que no es robusta. En consecuencia, los resultados de esta función tampoco
+      lo son.
+\note Si los segmentos se tocan en los dos extremos (son el mismo segmento), las
+      coordenadas devueltas son siempre las del vértice A.
+\note Si los segmentos tienen más de un punto en común, pero no son el mismo
+      segmento, las coordenadas de salida siempre son las de un punto extremo de
+      un segmento. Este punto extremo se intentará que sea uno de los puntos
+      iniciales de algún segmento, anque si no lo es, será uno de los finales.
+      El orden de preferencia de las coordenadas de salida es: A, C, B, D.
+\date 14 de mayo de 2011: Creación de la función.
+\date 21 de mayo de 2011: Adición de un nuevo valor de salida:
+      #GEOC_SEG_INTERSEC_MISMO_SEG.
+\date 06 de julio de 2011: Adición de chequeo rápido al principio de la función
+      para descartar que los segmentos no tienen ningún punto en común.
+*/
+int IntersecSegmentos2D(const double xA,
+                        const double yA,
+                        const double xB,
+                        const double yB,
+                        const double xC,
+                        const double yC,
+                        const double xD,
+                        const double yD,
+                        double* x,
+                        double* y);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/libgeoc/ventorno.h b/src/libgeoc/ventorno.h
new file mode 100755
index 0000000..d330d35
--- /dev/null
+++ b/src/libgeoc/ventorno.h
@@ -0,0 +1,100 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup anespec general
+@{
+\file ventorno.h
+\brief Definición de variables de entorno y declaración de funciones para su
+       control.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 31 de marzo de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _VENTORNO_H_
+#define _VENTORNO_H_
+/******************************************************************************/
+/******************************************************************************/
+#include<stdlib.h>
+#include<string.h>
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ENV_NOM_VAR_PILOMBS
+\brief Nombre de la variable de entorno para imprimir o no pasos intermedios en
+       la ejecución de la función \ref AnalisisLombSig.
+\date 31 de marzo de 2011: Creación de la constante.
+*/
+#define GEOC_ENV_NOM_VAR_PILOMBS "GEOC_ENV_PILOMBS"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\def GEOC_ENV_VAL_REF_PILOMBS
+\brief Valor de referencia de la variable de entorno #GEOC_ENV_NOM_VAR_PILOMBS.
+\date 31 de marzo de 2011: Creación de la constante.
+*/
+#define GEOC_ENV_VAL_REF_PILOMBS "0"
+/******************************************************************************/
+/******************************************************************************/
+/**
+\brief Comprueba si una variable de entorno está definida y es igual a un valor.
+\param[in] var Nombre de la variable de entorno a comprobar.
+\param[in] valRef Valor de referencia de la variable de entorno.
+\return Tres posibilidades:
+        - Menor que 0: La variable de entorno no está definida.
+        - 0: La variable de entorno existe, pero tiene un valor distinto a
+             \em valRef.
+        - Mayor que 0: La variable de entorno existe y tiene el mismo valor que
+                       \em valRef.
+\date 31 de marzo de 2011: Creación de la función.
+\todo Esta función todavía no está probada.
+*/
+int VarEnvValRef(const char* var,
+                 const char* valRef);
+/******************************************************************************/
+/******************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/octclip.h b/src/octclip.h
new file mode 100644
index 0000000..fbb2dea
--- /dev/null
+++ b/src/octclip.h
@@ -0,0 +1,31 @@
+/* -*- coding: utf-8 -*- */
+/* Copyright (C) 2011  José Luis García Pallero, <jgpallero at gmail.com>
+ *
+ * This file is part of OctCLIP.
+ *
+ * OctCLIP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+/******************************************************************************/
+/******************************************************************************/
+#ifndef _OCTCLIP_H_
+#define _OCTCLIP_H_
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/geom.h"
+/******************************************************************************/
+/******************************************************************************/
+#endif
+/******************************************************************************/
+/******************************************************************************/
diff --git a/src/polig.c b/src/polig.c
new file mode 100755
index 0000000..4cb3df9
--- /dev/null
+++ b/src/polig.c
@@ -0,0 +1,1815 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file polig.c
+\brief Definición de funciones para el trabajo con polígonos.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 20 de abril de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/polig.h"
+/******************************************************************************/
+/******************************************************************************/
+int GeocParOmpPolig(char version[])
+{
+    //comprobamos si hay paralelización
+#if defined(_OPENMP)
+    //comprobamos si hay que extraer versión
+    if(version!=NULL)
+    {
+        //calculamos la versión
+        VersionOpenMP(_OPENMP,version);
+    }
+    //salimos de la función
+    return 1;
+#else
+    if(version!=NULL)
+    {
+        //utilizamos la variable version para que no dé warming al compilar
+        strcpy(version,"");
+    }
+    //salimos de la función
+    return 0;
+#endif
+}
+/******************************************************************************/
+/******************************************************************************/
+polig* IniciaPoligVacio(void)
+{
+    //estructura de salida
+    polig* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para la estructura
+    sal = (polig*)malloc(sizeof(polig));
+    //comprobamos los posibles errores
+    if(sal==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //inicializamos los campos escalares a 0
+    sal->nElem = 0;
+    sal->nPolig = 0;
+    sal->hayLim = 0;
+    sal->hayArea = 0;
+    //inicializamos los campos vectoriales a NULL
+    sal->x = NULL;
+    sal->y = NULL;
+    sal->posIni = NULL;
+    sal->nVert = NULL;
+    sal->xMin = NULL;
+    sal->xMax = NULL;
+    sal->yMin = NULL;
+    sal->yMax = NULL;
+    sal->area = NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AuxCreaPolig1(const size_t nElem,
+                  const size_t* posNanX,
+                  const size_t* posNanY,
+                  const size_t nNanX,
+                  const size_t nNanY,
+                  size_t* nElemMax,
+                  size_t* nPolig)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de salida
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay el mismo número de NaN en los dos vectores
+    if(nNanX!=nNanY)
+    {
+        //salimos de la función
+        return GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG;
+    }
+    //comprobamos si hay NaN en las mismas posiciones de los vectores
+    for(i=0;i<nNanX;i++)
+    {
+        //comprobamos si las posiciones no son las mismas
+        if(posNanX[i]!=posNanY[i])
+        {
+            //salimos de la función
+            return GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos un número máximo de elementos de los vectores de coordenadas
+    //suponiendo que no hay NaN al principio ni al final y que no se repiten las
+    //coordenadas iniciales de cada polígono
+    *nElemMax = nElem+2+nNanX+1;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el número de polígonos, dependiendo del número de NaN
+    if((nNanX==0)||
+       ((nNanX==1)&&(posNanX[0]==0))||
+       ((nNanX==1)&&(posNanX[nNanX-1]==(nElem-1)))||
+       ((nNanX==2)&&(posNanX[0]==0)&&(posNanX[nNanX-1]==(nElem-1))))
+    {
+        //sólo hay un polígono
+        *nPolig = 1;
+    }
+    else if((posNanX[0]!=0)&&(posNanX[nNanX-1]!=(nElem-1)))
+    {
+        //si no hay NaN en los extremos, el número de polígonos es nNan+1
+        *nPolig = nNanX+1;
+    }
+    else if((posNanX[0]==0)&&(posNanX[nNanX-1]==(nElem-1)))
+    {
+        //si hay NaN en los dos extremos, el número de polígonos es nNan-1
+        *nPolig = nNanX-1;
+    }
+    else
+    {
+        //en otro caso, es el número de NaN
+        *nPolig = nNanX;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AuxCreaPolig2(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   double* xSal,
+                   double* ySal,
+                   size_t* nCopias)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //en principio, el número de puntos copiados es igual al indicado
+    *nCopias = nElem;
+    //contemplamos una posible salida rápida
+    if(nElem==0)
+    {
+        //salimos de la función
+        return;
+    }
+    //recorremos los puntos de trabajo
+    for(i=0;i<nElem;i++)
+    {
+        //vamos copiando
+        xSal[i] = x[i*incX];
+        ySal[i] = y[i*incY];
+    }
+    //comprobamos si hay que copiar el primer punto al final
+    if((x[0]!=x[(nElem-1)*incX])||(y[0]!=y[(nElem-1)*incY]))
+    {
+        //repetimos el primer punto
+        xSal[nElem] = x[0];
+        ySal[nElem] = y[0];
+        //aumentamos el contador de puntos copiados
+        (*nCopias)++;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AuxCreaPolig3(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   const size_t* posNan,
+                   const size_t nNan,
+                   double* xSal,
+                   double* ySal,
+                   size_t* posIni,
+                   size_t* nVert,
+                   size_t* nPtos,
+                   size_t* nPolig)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //número de vértices del polígono a copiar y posición inicial de un polígono
+    size_t nV=0,pI=0;
+    //número de vértices copiados
+    size_t nCopias=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos las variables de número de puntos copiados y número de
+    //polígonos
+    *nPtos = 0;
+    *nPolig = 0;
+    //comprobamos si los vectores empiezan directamente con coordenadas
+    if((nNan==0)||(posNan[0]!=0))
+    {
+        //el primer elemento de los vectores de salida es NaN
+        xSal[0] = GeocNan();
+        ySal[0] = GeocNan();
+        //aumentamos la variable de número de puntos copiados
+        (*nPtos)++;
+        //calculamos el número de vértices del polígono
+        if(nNan)
+        {
+            //si hay valores NaN, el número de vértices es igual a la posición
+            //del siguiente NaN
+            nV = posNan[0];
+        }
+        else
+        {
+            //si no hay NaN, el número de vértices es igual al número de
+            //elementos de los vectores de coordenadas
+            nV = nElem;
+        }
+        //copiamos el primer polígono
+        AuxCreaPolig2(&x[0],&y[0],nV,incX,incY,&xSal[*nPtos],&ySal[*nPtos],
+                      &nCopias);
+        //indicamos la posición de inicio del polígono y el número de vértices
+        posIni[*nPolig] = 1;
+        nVert[*nPolig] = nCopias;
+        //sumamos el número de puntos copiados a la variable
+        (*nPtos) += nCopias;
+        //aumentamos el contador de polígonos
+        (*nPolig)++;
+    }
+    //recorremos el número de NaN
+    for(i=0;i<nNan;i++)
+    {
+        //copiamos el NaN
+        xSal[*nPtos] = GeocNan();
+        ySal[*nPtos] = GeocNan();
+        //aumentamos la variable de número de puntos copiados
+        (*nPtos)++;
+        //posición del primer punto del polígono
+        pI = posNan[i]+1;
+        //sólo continuamos si el NaN no es la última posición de los vectores
+        if(pI!=nElem)
+        {
+            //calculo el número de puntos del polígono, dependiendo del NaN de
+            //trabajo
+            if(i!=(nNan-1))
+            {
+                //todavía hay más NaN por delante
+                nV = posNan[i+1]-pI;
+            }
+            else
+            {
+                //este es el último NaN de la lista
+                nV = nElem-pI;
+            }
+            //copiamos las coordenadas del polígono
+            AuxCreaPolig2(&x[pI*incX],&y[pI*incY],nV,incX,incY,&xSal[*nPtos],
+                          &ySal[*nPtos],&nCopias);
+            //comprobamos el número de puntos copiados
+            if(nCopias)
+            {
+                //indicamos la posición de inicio del polígono y el número de
+                //vértices
+                posIni[*nPolig] = *nPtos;
+                nVert[*nPolig] = nCopias;
+                //sumamos el número de puntos copiados a la variable
+                (*nPtos) += nCopias;
+                //aumentamos el contador de polígonos
+                (*nPolig)++;
+            }
+            else
+            {
+                //si no se han copiado puntos, el polígono era falso (había dos
+                //NaN seguidos, luego descuento el último NaN copiado
+                (*nPtos)--;
+            }
+        }
+    }
+    //copiamos el último NaN, si no se ha copiado ya
+    if(!EsGeocNan(xSal[(*nPtos)-1]))
+    {
+        //copiamos
+        xSal[*nPtos] = GeocNan();
+        ySal[*nPtos] = GeocNan();
+        //aumentamos el contador de puntos
+        (*nPtos)++;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+polig* CreaPolig(const double* x,
+                 const double* y,
+                 const size_t nElem,
+                 const size_t incX,
+                 const size_t incY,
+                 int* idError)
+{
+    //número de puntos
+    size_t ptos=0;
+    //número máximo de elementos de los vectores de coordenadas
+    size_t nElemMax=0;
+    //número de polígonos
+    size_t nPolig=0;
+    //número de identificadores NaN
+    size_t nNanX=0,nNanY=0;
+    //posiciones de los identificadores NaN
+    size_t* posNanX=NULL;
+    size_t* posNanY=NULL;
+    //estructura de salida
+    polig* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable de error
+    *idError = GEOC_ERR_NO_ERROR;
+    //creamos la estructura vacía
+    sal = IniciaPoligVacio();
+    //comprobamos los posibles errores
+    if(sal==NULL)
+    {
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //contemplamos una posible salida rápida
+    if(nElem==0)
+    {
+        //devolvemos la estructura vacía
+        return sal;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contamos el número de identificadores NaN en los vectores de entrada
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(posNanX,x,nNanX,posNanY,y,nNanY)
+#endif
+{
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //contamos el número de indentificadores NaN en el vector X
+    posNanX = PosGeocNanEnVector(x,nElem,incX,&nNanX);
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //contamos el número de indentificadores NaN en el vector Y
+    posNanY = PosGeocNanEnVector(y,nElem,incY,&nNanY);
+} // --> fin del #pragma omp parallel sections
+    //comprobamos los posibles errores de asignación de memoria
+    if(((posNanX==NULL)&&(nNanX!=0))||((posNanY==NULL)&&(nNanY!=0)))
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(sal);
+        free(posNanX);
+        free(posNanY);
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si los vectores tienen bien colocados los NaN y calculamos
+    //el número máximo de elementos de los vectores de la estructura y el
+    //número de polígonos
+    *idError = AuxCreaPolig1(nElem,posNanX,posNanY,nNanX,nNanY,&nElemMax,
+                             &nPolig);
+    //comprobamos los posibles errores
+    if(*idError!=GEOC_ERR_NO_ERROR)
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(sal);
+        free(posNanX);
+        free(posNanY);
+        //escribimos el mensaje de error
+        if(*idError==GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo "
+                       "número de polígonos");
+        }
+        else if(*idError==GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen los mismos "
+                       "polígonos");
+        }
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos el número de polígonos
+    sal->nPolig = nPolig;
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(sal,nElemMax,nPolig)
+#endif
+{
+    //asignamos memoria para los vectores de la estructura
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->x = (double*)malloc(nElemMax*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->y = (double*)malloc(nElemMax*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->posIni = (size_t*)malloc(nPolig*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->nVert = (size_t*)malloc(nPolig*sizeof(double));
+} // --> fin del #pragma omp parallel sections
+    //comprobamos los posibles errores
+    if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL))
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(sal);
+        free(posNanX);
+        free(posNanY);
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //copiamos los polígonos a la estructura
+    //como ya sabemos que el número de NaN y sus posiciones son los mismos para
+    //los vectores x e y, trabajamos con los valores para el vector x
+    AuxCreaPolig3(x,y,nElem,incX,incY,posNanX,nNanX,sal->x,sal->y,sal->posIni,
+                  sal->nVert,&ptos,&nPolig);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay de verdad algún polígono
+    if(nPolig==0)
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(sal);
+        free(posNanX);
+        free(posNanY);
+        //creamos la estructura vacía
+        sal = IniciaPoligVacio();
+        //comprobamos los posibles errores
+        if(sal==NULL)
+        {
+            //asignamos la variable de error
+            *idError = GEOC_ERR_ASIG_MEMORIA;
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //salimos de la función
+        return sal;
+    }
+    //asignamos el número de elementos a la estructura
+    sal->nElem = ptos;
+    //comprobamos si hay que reajustar el tamaño de los vectores de coordenadas
+    if(ptos!=nElemMax)
+    {
+        //asignamos el nuevo tamaño de los vectores
+        sal->nElem = ptos;
+        //reajustamos los tamaños
+        sal->x = (double*)realloc(sal->x,ptos*sizeof(double));
+        sal->y = (double*)realloc(sal->y,ptos*sizeof(double));
+    }
+    //comprobamos si el número de polígonos es el estimado
+    if(nPolig!=sal->nPolig)
+    {
+        //asignamos de nuevo la variable de número de polígonos
+        sal->nPolig = nPolig;
+        //reajustamos los tamaños
+        sal->posIni = (size_t*)realloc(sal->posIni,nPolig*sizeof(size_t));
+        sal->nVert = (size_t*)realloc(sal->nVert,nPolig*sizeof(size_t));
+    }
+    //comprobamos los posibles errores
+    if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL))
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(sal);
+        free(posNanX);
+        free(posNanY);
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //liberamos la memoria asignada
+    free(posNanX);
+    free(posNanY);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+void EnlazaCamposPolig(polig* poliEnt,
+                       polig* poliSal)
+{
+    //LIBERAMOS LA POSIBLE MEMORIA ASIGNADA A LOS CAMPOS VECTORIALES DE LA
+    //ESTRUCTURA DE SALIDA
+    //comprobamos si hay algún elemento en los vectores de coordenadas
+    if(poliSal->nElem)
+    {
+        free(poliSal->x);
+        free(poliSal->y);
+    }
+    //comprobamos si hay algún polígono en los vectores de posiciones
+    if(poliSal->nPolig)
+    {
+        free(poliSal->posIni);
+        free(poliSal->nVert);
+    }
+    //comprobamos si hay límites calculados
+    if(poliSal->hayLim)
+    {
+        free(poliSal->xMin);
+        free(poliSal->xMax);
+        free(poliSal->yMin);
+        free(poliSal->yMax);
+    }
+    //comprobamos si hay superficies calculadas
+    if(poliSal->hayArea)
+    {
+        free(poliSal->area);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //enlazamos todos los campos de la estructura de entrada en la de salida
+    poliSal->nElem = poliEnt->nElem;
+    poliSal->x = poliEnt->x;
+    poliSal->y = poliEnt->y;
+    poliSal->nPolig = poliEnt->nPolig;
+    poliSal->posIni = poliEnt->posIni;
+    poliSal->nVert = poliEnt->nVert;
+    poliSal->hayLim = poliEnt->hayLim;
+    poliSal->xMin = poliEnt->xMin;
+    poliSal->xMax = poliEnt->xMax;
+    poliSal->yMin = poliEnt->yMin;
+    poliSal->yMax = poliEnt->yMax;
+    poliSal->hayArea = poliEnt->hayArea;
+    poliSal->area = poliEnt->area;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+polig* CopiaPolig(const polig* poli,
+                  int* idError)
+{
+    //polígono de salida
+    polig* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable de error
+    *idError = GEOC_ERR_NO_ERROR;
+    //inicializamos el polígono de salida
+    sal = IniciaPoligVacio();
+    //comprobamos los posibles errores
+    if(sal==NULL)
+    {
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //sólo continuamos si el polígono de entrada contiene datos
+    if(poli->nElem)
+    {
+        //copiamos las coordenadas de los vértices
+        *idError = AnyadeDatosPolig(sal,poli->x,poli->y,poli->nElem,1,1);
+        //comprobamos si ha ocurrido algún error
+        if((*idError)!=GEOC_ERR_NO_ERROR)
+        {
+            //liberamos la memoria asignada
+            LibMemPolig(sal);
+            //escribimos el mensaje de error
+            if((*idError)==GEOC_ERR_ASIG_MEMORIA)
+            {
+                GEOC_ERROR("Error de asignación de memoria");
+            }
+            else if((*idError)==GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG)
+            {
+                GEOC_ERROR("Error: Los vectores de coordenadas del polígono\n"
+                           "de entrada no contienen el mismo número de "
+                           "polígonos");
+            }
+            else if((*idError)==GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG)
+            {
+                GEOC_ERROR("Error: Los vectores de coordenadas del polígono\n"
+                           "de entrada no contienen los mismos polígonos");
+            }
+            //salimos de la función
+            return NULL;
+        }
+        //comprobamos si hay que calcular límites
+        if(poli->hayLim)
+        {
+            //calculamos los límites
+            *idError = CalcLimitesPolig(sal);
+            //comprobamos los posibles errores
+            if((*idError)!=GEOC_ERR_NO_ERROR)
+            {
+                //liberamos la memoria asignada
+                LibMemPolig(sal);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+        }
+        //comprobamos si hay que calcular superficies
+        if(poli->hayArea)
+        {
+            //calculamos las áreas
+            *idError = CalcAreaPolig(sal);
+            //comprobamos los posibles errores
+            if((*idError)!=GEOC_ERR_NO_ERROR)
+            {
+                //liberamos la memoria asignada
+                LibMemPolig(sal);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AnyadePoligPolig(polig* poli,
+                     const polig* anyade)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //número total de elementos
+    size_t nElem=0,nPolig=0;
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //si el polígono a añadir está vacío, salimos de la función
+    if((anyade!=NULL)&&(anyade->nPolig==0))
+    {
+        //salimos de la función sin hacer nada
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el número total de elementos del polígono conjunto
+    nElem = poli->nElem+anyade->nElem;
+    //si el polígono original contenía datos, al número total de elementos hay
+    //que restarle 1 por el NaN común que sobra al juntar las dos estructuras
+    if(poli->nPolig)
+    {
+        nElem--;
+    }
+    //calculamos el número total de polígonos
+    nPolig = poli->nPolig+anyade->nPolig;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //reasignamos memoria para cubrir los nuevos datos
+    poli->x = (double*)realloc(poli->x,nElem*sizeof(double));
+    poli->y = (double*)realloc(poli->y,nElem*sizeof(double));
+    poli->posIni = (size_t*)realloc(poli->posIni,nPolig*sizeof(size_t));
+    poli->nVert = (size_t*)realloc(poli->nVert,nPolig*sizeof(size_t));
+    //reasignamos también para los posibles vectores de límites y superficies
+    if(poli->hayLim)
+    {
+        poli->xMin = (double*)realloc(poli->xMin,nPolig*sizeof(double));
+        poli->xMax = (double*)realloc(poli->xMax,nPolig*sizeof(double));
+        poli->yMin = (double*)realloc(poli->yMin,nPolig*sizeof(double));
+        poli->yMax = (double*)realloc(poli->yMax,nPolig*sizeof(double));
+    }
+    if(poli->hayArea)
+    {
+        poli->area = (double*)realloc(poli->area,nPolig*sizeof(double));
+    }
+    //comprobamos los posibles errores en las asignaciones obligatorias
+    if((poli->x==NULL)||(poli->y==NULL)||(poli->posIni==NULL)||
+       (poli->nVert==NULL))
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    //comprobamos los posibles errores en las asignaciones de límites
+    if(poli->hayLim)
+    {
+        if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)||
+           (poli->yMax==NULL))
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+    }
+    //comprobamos los posibles errores en las asignaciones de áreas
+    if(poli->hayArea)
+    {
+        if(poli->area==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos la posición de inicio para copiar en la estructura de salida
+    //si la estructura de salida está vacía, se comienza en la primera posición
+    //si tiene datos, se comienza a continuación en la última (dentro del bucle,
+    //la suma de posIni hace que se comience a continuación de la última)
+    pos = (poli->nPolig==0) ? 0 : poli->nElem-1;
+    //recorremos el número de nuevos elementos
+    for(i=0;i<anyade->nElem;i++)
+    {
+        //copiamos las coordenadas
+        poli->x[pos+i] = anyade->x[i];
+        poli->y[pos+i] = anyade->y[i];
+    }
+    //calculamos las posiciones a sumar para ajustar las posiciones de inicio de
+    //los polígonos añadidos
+    //si la estructura de salida está vacía, se copian las posiciones tal cual
+    //si tiene datos, se suman las posiciones ya ocupadas
+    pos = (poli->nPolig==0) ? 0 : poli->nElem-1;
+    //recorremos el número de polígonos
+    for(i=0;i<anyade->nPolig;i++)
+    {
+        //copiamos las posiciones de inicio actualizadas y el número de vértices
+        poli->posIni[poli->nPolig+i] = anyade->posIni[i]+pos;
+        poli->nVert[poli->nPolig+i] = anyade->nVert[i];
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que calcular límites
+    if(poli->hayLim)
+    {
+        //comprobamos si ya están calculados
+        if(anyade->hayLim)
+        {
+            //recorremos el número de polígonos y copiamos los límites
+            for(i=0;i<anyade->nPolig;i++)
+            {
+                //copiamos los límites
+                poli->xMin[poli->nPolig+i] = anyade->xMin[i];
+                poli->xMax[poli->nPolig+i] = anyade->xMax[i];
+                poli->yMin[poli->nPolig+i] = anyade->yMin[i];
+                poli->yMax[poli->nPolig+i] = anyade->yMax[i];
+            }
+        }
+        else
+        {
+            //calculamos los límites y los copiamos
+            LimitesPoligonosPolig(&(anyade->x[1]),&(anyade->y[1]),1,1,
+                                  anyade->posIni,anyade->nVert,anyade->nPolig,
+                                  anyade->posIni[0],&(poli->xMin[poli->nPolig]),
+                                  &(poli->xMax[poli->nPolig]),
+                                  &(poli->yMin[poli->nPolig]),
+                                  &(poli->yMax[poli->nPolig]));
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que calcular áreas
+    if(poli->hayArea)
+    {
+        //comprobamos si ya están calculadas
+        if(anyade->hayArea)
+        {
+            //recorremos el número de polígonos y copiamos las superficies
+            for(i=0;i<anyade->nPolig;i++)
+            {
+                //copiamos los límites
+                poli->area[poli->nPolig+i] = anyade->area[i];
+            }
+        }
+        else
+        {
+            //calculamos las superficies y las copiamos
+            AreaPoligonosSimplesPolig(&(anyade->x[1]),&(anyade->y[1]),1,1,
+                                      anyade->posIni,anyade->nVert,
+                                      anyade->nPolig,anyade->posIni[0],
+                                      &(poli->area[poli->nPolig]));
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ajustamos los tamaños antes de salir
+    poli->nElem = nElem;
+    poli->nPolig = nPolig;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AnyadeDatosPolig(polig* poli,
+                     const double* x,
+                     const double* y,
+                     const size_t nElem,
+                     const size_t incX,
+                     const size_t incY)
+{
+    //polígono auxiliar
+    polig* aux=NULL;
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contemplamos una posible salida rápida
+    if(nElem==0)
+    {
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos un nuevo polígono con los datos a añadir
+    aux = CreaPolig(x,y,nElem,incX,incY,&estado);
+    //comprobamos los posibles errores
+    if(estado!=GEOC_ERR_NO_ERROR)
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(aux);
+        //escribimos el mensaje de error
+        if(estado==GEOC_ERR_ASIG_MEMORIA)
+        {
+            GEOC_ERROR("Error de asignación de memoria");
+        }
+        else if(estado==GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo "
+                       "número de polígonos");
+        }
+        else if(estado==GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen los mismos "
+                       "polígonos");
+        }
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //añadimos la nueva estructura
+    estado = AnyadePoligPolig(poli,aux);
+    //comprobamos los posibles errores
+    if(estado!=GEOC_ERR_NO_ERROR)
+    {
+        //liberamos la memoria asignada
+        LibMemPolig(aux);
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //liberamos la memoria utilizada
+    LibMemPolig(aux);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void LibMemPolig(polig* datos)
+{
+    //comprobamos si hay memoria que liberar
+    if(datos!=NULL)
+    {
+        //liberamos la memoria asignada al vector de coordenadas X
+        if(datos->x!=NULL)
+        {
+            free(datos->x);
+        }
+        //liberamos la memoria asignada al vector de coordenadas Y
+        if(datos->y!=NULL)
+        {
+            free(datos->y);
+        }
+        //liberamos la memoria asignada al vector de posiciones
+        if(datos->posIni!=NULL)
+        {
+            free(datos->posIni);
+        }
+        //liberamos la memoria asignada al vector de número de vértices
+        if(datos->nVert!=NULL)
+        {
+            free(datos->nVert);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas X mínimas
+        if(datos->xMin!=NULL)
+        {
+            free(datos->xMin);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas X máximas
+        if(datos->xMax!=NULL)
+        {
+            free(datos->xMax);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas Y mínimas
+        if(datos->yMin!=NULL)
+        {
+            free(datos->yMin);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas Y máximas
+        if(datos->yMax!=NULL)
+        {
+            free(datos->yMax);
+        }
+        //liberamos la memoria asignada al vector de áreas
+        if(datos->area!=NULL)
+        {
+            free(datos->area);
+        }
+        //liberamos la memoria asignada a la estructura
+        free(datos);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int CalcLimitesPolig(polig* poli)
+{
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos salida rápida
+    if((poli->nPolig==0)||(poli->hayLim))
+    {
+        //salimos de la función si la estructura no contiene polígonos o si
+        //éstos ya tienen calculados sus límites
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(poli)
+#endif
+{
+    //asignamos memoria para los vectores de límites
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->xMin = (double*)malloc((poli->nPolig)*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->xMax = (double*)malloc((poli->nPolig)*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->yMin = (double*)malloc((poli->nPolig)*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->yMax = (double*)malloc((poli->nPolig)*sizeof(double));
+} // --> fin del #pragma omp parallel sections
+    //comprobamos los posibles errores
+    if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)||
+       (poli->yMax==NULL))
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    //indicamos que sí hay límites
+    poli->hayLim = 1;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos los límites de todos los polígonos
+    LimitesPoligonosPolig(poli->x,poli->y,1,1,poli->posIni,poli->nVert,
+                          poli->nPolig,0,poli->xMin,poli->xMax,poli->yMin,
+                          poli->yMax);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void LimitesPoligono(const double* x,
+                     const double* y,
+                     const size_t nElem,
+                     const size_t incX,
+                     const size_t incY,
+                     double* xMin,
+                     double* xMax,
+                     double* yMin,
+                     double* yMax)
+{
+    //posiciones de los elementos máximo y mínimo
+    size_t posXMin=0,posXMax=0,posYMin=0,posYMax=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //buscamos las posiciones de los elementos máximo y mínimo
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(x,posXMin,posXMax,y,posYMin,posYMax)
+#endif
+{
+    //posiciones en el vector X
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    MinMax(x,nElem,incX,&posXMin,&posXMax);
+    //posiciones en el vector Y
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    MinMax(y,nElem,incY,&posYMin,&posYMax);
+} // --> fin del #pragma omp parallel sections
+    //extraemos los valores de las posiciones calculadas
+    *xMin = x[posXMin*incX];
+    *xMax = x[posXMax*incX];
+    *yMin = y[posYMin*incY];
+    *yMax = y[posYMax*incY];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void LimitesPoligonosPolig(const double* x,
+                           const double* y,
+                           const size_t incX,
+                           const size_t incY,
+                           const size_t* posIni,
+                           const size_t* nVert,
+                           const size_t nPolig,
+                           const size_t restaPosIni,
+                           double* xMin,
+                           double* xMax,
+                           double* yMin,
+                           double* yMax)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //posición inicial del polígono de trabajo
+    size_t pI=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) schedule(dynamic) \
+ shared(posIni,x,y,nVert,xMin,xMax,yMin,yMax) \
+ private(i,pI)
+#endif
+    //recorremos el número de polígonos
+    for(i=0;i<nPolig;i++)
+    {
+        //calculamos la posición inicial del polígono
+        pI = posIni[i]-restaPosIni;
+        //calculamos los límites
+        LimitesPoligono(&x[pI*incX],&y[pI*incY],nVert[i],incX,incY,&xMin[i],
+                        &xMax[i],&yMin[i],&yMax[i]);
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int CalcAreaPolig(polig* poli)
+{
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos salida rápida
+    if((poli->nPolig==0)||(poli->hayArea))
+    {
+        //salimos de la función si la estructura no contiene polígonos o si
+        //éstos ya tienen calculada su superficie
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para el vector de superficies
+    poli->area = (double*)malloc((poli->nPolig)*sizeof(double));
+    //comprobamos los posibles errores
+    if(poli->area==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    //indicamos que sí hay superficies
+    poli->hayArea = 1;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos las superficies de todos los polígonos
+    AreaPoligonosSimplesPolig(poli->x,poli->y,1,1,poli->posIni,poli->nVert,
+                              poli->nPolig,0,poli->area);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+double AreaPoligonoSimple(const double* x,
+                          const double* y,
+                          const size_t nElem,
+                          const size_t incX,
+                          const size_t incY)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //número de elementos de trabajo, que inicializamos con el valor pasado
+    size_t nElemTrab=nElem;
+    //variable de salida
+    double area=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //si el primero punto es el mismo que el último, restamos una unidad al
+    //número de elementos pasado, ya que el algoritmo está preparado para
+    //trabajar con un vector en el que no se repite el primer punto
+    if((x[0]==x[(nElem-1)*incX])&&(y[0]==y[(nElem-1)*incY]))
+    {
+        //el número de elementos de trabajo es uno menos que el pasado
+        nElemTrab = nElem-1;
+    }
+    //el algoritmo utilizado es la segunda expresión de la ecuación 21.4.20 del
+    //Numerical Recipes, tercera edición, página 1127
+    //recorremos los puntos hasta el penúltimo
+    for(i=0;i<(nElemTrab-1);i++)
+    {
+        //vamos sumando
+        area += (x[(i+1)*incX]+x[i*incX])*(y[(i+1)*incY]-y[i*incY]);
+    }
+    //sumamos la contribución del último lado, es decir, el lado que contiene
+    //como vértice final al primer punto
+    area += (x[0]+x[(nElemTrab-1)*incX])*(y[0]-y[(nElemTrab-1)*incY]);
+    //dividimos entre dos para calcular el área real
+    area /= 2.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return area;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AreaPoligonosSimplesPolig(const double* x,
+                               const double* y,
+                               const size_t incX,
+                               const size_t incY,
+                               const size_t* posIni,
+                               const size_t* nVert,
+                               const size_t nPolig,
+                               const size_t restaPosIni,
+                               double* area)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //posición inicial del polígono de trabajo
+    size_t pI=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) schedule(dynamic) \
+ shared(posIni,area,x,y,nVert) \
+ private(i,pI)
+#endif
+    //recorremos el número de polígonos
+    for(i=0;i<nPolig;i++)
+    {
+        //calculamos la posición inicial del polígono
+        pI = posIni[i]-restaPosIni;
+        //calculamos la superficie
+        area[i] = AreaPoligonoSimple(&x[pI*incX],&y[pI*incY],nVert[i],incX,
+                                     incY);
+    } // --> fin del #pragma omp parallel for
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void EscalaYTrasladaPolig(polig* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim,
+                          const int aplicaArea)
+{
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(poli)
+#endif
+{
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos los factores de escala y las traslaciones a las coordenadas X
+    EscalaYTrasladaVector(poli->x,poli->nElem,1,escalaX,trasladaX);
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos los factores de escala y las traslaciones a las coordenadas Y
+    EscalaYTrasladaVector(poli->y,poli->nElem,1,escalaY,trasladaY);
+} // --> fin del #pragma omp parallel sections
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE
+    //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO
+    //TOTAL DE VÉRTICES
+    //comprobamos si hay que aplicar el factor a los límites
+    if(aplicaLim&&poli->hayLim)
+    {
+        //aplicamos los factores de escala y las traslaciones a los límites
+        EscalaYTrasladaVector(poli->xMin,poli->nPolig,1,escalaX,trasladaX);
+        EscalaYTrasladaVector(poli->xMax,poli->nPolig,1,escalaX,trasladaX);
+        EscalaYTrasladaVector(poli->yMin,poli->nPolig,1,escalaY,trasladaY);
+        EscalaYTrasladaVector(poli->yMax,poli->nPolig,1,escalaY,trasladaY);
+    }
+    //comprobamos si hay que aplicar el factor a las superficies
+    if(aplicaArea&&poli->hayArea)
+    {
+        //aplicamos el factor de escala a las áreas
+        EscalaYTrasladaVector(poli->area,poli->nPolig,1,fabs(escalaX*escalaY),
+                              0.0);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void TrasladaYEscalaPolig(polig* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim,
+                          const int aplicaArea)
+{
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(poli)
+#endif
+{
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos las traslaciones y los factores de escala a las coordenadas X
+    TrasladaYEscalaVector(poli->x,poli->nElem,1,escalaX,trasladaX);
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos las traslaciones y los factores de escala a las coordenadas Y
+    TrasladaYEscalaVector(poli->y,poli->nElem,1,escalaY,trasladaY);
+} // --> fin del #pragma omp parallel sections
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE
+    //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO
+    //TOTAL DE VÉRTICES
+    //comprobamos si hay que aplicar el factor a los límites
+    if(aplicaLim&&poli->hayLim)
+    {
+        //aplicamos las traslaciones y los factores de escala a los límites
+        TrasladaYEscalaVector(poli->xMin,poli->nPolig,1,escalaX,trasladaX);
+        TrasladaYEscalaVector(poli->xMax,poli->nPolig,1,escalaX,trasladaX);
+        TrasladaYEscalaVector(poli->yMin,poli->nPolig,1,escalaY,trasladaY);
+        TrasladaYEscalaVector(poli->yMax,poli->nPolig,1,escalaY,trasladaY);
+    }
+    //comprobamos si hay que aplicar el factor a las superficies
+    if(aplicaArea&&poli->hayArea)
+    {
+        //aplicamos el factor de escala a las áreas
+        TrasladaYEscalaVector(poli->area,poli->nPolig,1,fabs(escalaX*escalaY),
+                              0.0);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void MuevePolig(polig* poli,
+                const double escalaX,
+                const double escalaY,
+                const double trasladaX,
+                const double trasladaY,
+                const int orden,
+                const int aplicaLim,
+                const int aplicaArea)
+{
+    //comprobamos el orden de aplicación de los factores
+    if(orden==0)
+    {
+        //primero los factores de escala y luego las traslaciones
+        EscalaYTrasladaPolig(poli,escalaX,escalaY,trasladaX,trasladaY,aplicaLim,
+                             aplicaArea);
+    }
+    else
+    {
+        //primero las traslaciones y luego los factores de escala
+        TrasladaYEscalaPolig(poli,escalaX,escalaY,trasladaX,trasladaY,aplicaLim,
+                             aplicaArea);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AligeraPolig(polig* poli,
+                 const double tol,
+                 const enum GEOC_DPEUCKER_ROBUSTO robusto,
+                 const size_t nPtosRobusto,
+                 const size_t nSegRobusto)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //posición inicial del polígono de trabajo y número de puntos del aligerado
+    size_t posIni=0,nPtos=0;
+    //puntos colineales
+    int colin=0;
+    //coordenadas de los polígonos aligerados
+    double* x=NULL;
+    double* y=NULL;
+    //estructura auxiliar
+    polig* aux=NULL;
+    //vector de posiciones después del aligerado
+    size_t* pos=NULL;
+    //variable de salida
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos una posible salida rápida
+    if(poli->nPolig==0)
+    {
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar vacía
+    aux = IniciaPoligVacio();
+    //comprobamos los posibles errores
+    if(aux==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos el número de polígonos almacenados
+    for(i=0;i<poli->nPolig;i++)
+    {
+        //extraemos la posición inicial del polígono de trabajo
+        posIni = poli->posIni[i];
+        //aligeramos el polígono de trabajo
+        pos = AligeraPolilinea(&(poli->x[posIni]),&(poli->y[posIni]),
+                               poli->nVert[i],1,1,tol,robusto,nPtosRobusto,
+                               nSegRobusto,&nPtos);
+        //comprobamos posibles errores
+        if(pos==NULL)
+        {
+            //liberamos la memoria asignada
+            LibMemPolig(aux);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+        //comprobamos si el polígono se ha quedado en tres puntos
+        if(nPtos==3)
+        {
+            //comprobamos si los tres puntos son colineales
+            colin = TresPuntosColineales2D(poli->x[posIni+pos[0]],
+                                           poli->y[posIni+pos[0]],
+                                           poli->x[posIni+pos[1]],
+                                           poli->y[posIni+pos[1]],
+                                           poli->x[posIni+pos[2]],
+                                           poli->y[posIni+pos[2]]);
+        }
+        //comprobamos si después del aligerado queda algún polígono
+        if((nPtos>3)||((nPtos==3)&&(!colin)))
+        {
+            //asignamos memoria para los vectores de coordenadas del polígono
+            //aligerado
+            x = (double*)malloc(nPtos*sizeof(double));
+            y = (double*)malloc(nPtos*sizeof(double));
+            //comprobamos posibles errores
+            if((x==NULL)||(y==NULL))
+            {
+                //liberamos la memoria asignada
+                LibMemPolig(aux);
+                free(pos);
+                free(x);
+                free(y);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return GEOC_ERR_ASIG_MEMORIA;
+            }
+            //recorremos el número de puntos del polígono aligerado
+            for(j=0;j<nPtos;j++)
+            {
+                //copiamos las coordenadas
+                x[j] = poli->x[posIni+pos[j]];
+                y[j] = poli->y[posIni+pos[j]];
+            }
+            //añadimos las coordenadas al polígono aligerado
+            estado = AnyadeDatosPolig(aux,x,y,nPtos,1,1);
+            //sólo puede haber ocurrido un error de asignación de memoria, ya
+            //que suponemos que el polígono de entrada es correcto
+            if(estado!=GEOC_ERR_NO_ERROR)
+            {
+                //liberamos la memoria asignada
+                LibMemPolig(aux);
+                free(pos);
+                free(x);
+                free(y);
+                //escribimos el mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return GEOC_ERR_ASIG_MEMORIA;
+            }
+            //liberamos la memoria asignada a los vectores de coordenadas
+            free(x);
+            free(y);
+        }
+        //liberamos la memoria asignada al vector de posiciones del aligerado
+        free(pos);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que calcular límites
+    if(poli->hayLim)
+    {
+        //calculamos los límites
+        estado = CalcLimitesPolig(aux);
+        //comprobamos los posibles errores
+        if(estado!=GEOC_ERR_NO_ERROR)
+        {
+            //liberamos la memoria asignada
+            LibMemPolig(aux);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+    }
+    //comprobamos si hay que calcular superficies
+    if(poli->hayArea)
+    {
+        //calculamos las áreas
+        estado = CalcAreaPolig(aux);
+        //comprobamos los posibles errores
+        if(estado!=GEOC_ERR_NO_ERROR)
+        {
+            //liberamos la memoria asignada
+            LibMemPolig(aux);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //enlazamos los campos de la estructura auxiliar a los de la estructura de
+    //salida
+    EnlazaCamposPolig(aux,poli);
+    //liberamos la memoria asignada a la estructura auxiliar (pero no a sus
+    //campos)
+    free(aux);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void ImprimeCabeceraPoligFichero(const polig* poli,
+                                 const size_t indice,
+                                 const char iniCab[],
+                                 const int impLim,
+                                 const char formCoor[],
+                                 const int impArea,
+                                 const char formArea[],
+                                 const double factorX,
+                                 const double factorY,
+                                 const int repitePrimerPunto,
+                                 FILE* idFich)
+{
+    //número de vértices del polígono de trabajo
+    size_t nVert=0;
+    //superficie de los polígonos
+    double area=0.0;
+    //límites
+    double xMin=0.0,xMax=0.0,yMin=0.0,yMax=0.0,limAux=0.0;
+    //variables de posición
+    size_t pos=0,posXMin=0,posXMax=0,posYMin=0,posYMax=0;
+    //variable auxiliar
+    size_t aux=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ajustamos la variable auxiliar como el posible número a restar si no hay
+    //que repetir el primer vértice del polígono
+    aux = (repitePrimerPunto) ? 0 : 1;
+    //número de vértices a imprimir del polígono
+    nVert = poli->nVert[indice]-aux;
+    //posición de inicio del polígono
+    pos = poli->posIni[indice];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //imprimimos la marca de inicio y el número de vértices
+    fprintf(idFich,"%s %8zu",iniCab,nVert);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que imprimir la superficie
+    if(impArea)
+    {
+        //comprobamos si ya está calculada la superficie o no
+        if(poli->hayArea)
+        {
+            //aplicamos los factores de escala y extraemos la superficie
+            area = poli->area[indice]*fabs(factorX)*fabs(factorY);
+        }
+        else
+        {
+            //calculamos la superficie
+            area = AreaPoligonoSimple(&(poli->x[pos]),&(poli->y[pos]),
+                                      poli->nVert[indice],1,1);
+            //aplicamos los factores de escala
+            area *= fabs(factorX)*fabs(factorY);
+        }
+        //imprimimos el valor de la superficie
+        fprintf(idFich," ");
+        fprintf(idFich,formArea,area);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que imprimir los límites
+    if(impLim)
+    {
+        //comprobamos si ya están calculados los límites
+        if(poli->hayLim)
+        {
+            //extraemos los límites
+            xMin = poli->xMin[indice];
+            xMax = poli->xMax[indice];
+            yMin = poli->yMin[indice];
+            yMax = poli->yMax[indice];
+        }
+        else
+        {
+            //buscamos las posiciones de los elementos máximo y mínimo
+            //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+shared(poli,pos,nVert,posXMin,posXMax,posYMin,posYMax)
+#endif
+{
+            //posiciones en el vector X
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+            MinMax(&(poli->x[pos]),nVert,1,&posXMin,&posXMax);
+            //posiciones en el vector Y
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+            MinMax(&(poli->y[pos]),nVert,1,&posYMin,&posYMax);
+} // --> fin del #pragma omp parallel sections
+            //extraemos los valores extremos
+            xMin = poli->x[pos+posXMin];
+            xMax = poli->x[pos+posXMax];
+            yMin = poli->y[pos+posYMin];
+            yMax = poli->y[pos+posYMax];
+        }
+        //comprobamos si el factor de escala para X es negativo
+        if(factorX<0.0)
+        {
+            //los límites cambian
+            limAux = xMin;
+            xMin = xMax;
+            xMax = limAux;
+            //aplicamos el factor de escala
+            xMin *= factorX;
+            xMax *= factorX;
+        }
+        //comprobamos si el factor de escala para Y es negativo
+        if(factorY<0.0)
+        {
+            //los límites cambian
+            limAux = yMin;
+            yMin = yMax;
+            yMax = limAux;
+            //aplicamos el factor de escala
+            yMin *= factorY;
+            yMax *= factorY;
+        }
+        //imprimimos los límites
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,xMin);
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,xMax);
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,yMin);
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,yMax);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salto de línea final
+    fprintf(idFich,"\n");
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void ImprimePoligFichero(const polig* poli,
+                         const double factorX,
+                         const double factorY,
+                         const int repitePrimerPunto,
+                         const int iniNan,
+                         const int finNan,
+                         const char formCoor[],
+                         const int impCabecera,
+                         const char iniCab[],
+                         const int impLim,
+                         const int impArea,
+                         const char formArea[],
+                         FILE* idFich)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //cadena de formato para imprimir los posibles valores NaN
+    char formNan[GEOC_NAN_LON_FORM_NUM_SIMPLE+1];
+    //variable de posición
+    size_t pos=0;
+    //variable auxiliar
+    size_t aux=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si la estructura contiene algún polígono
+    if(poli->nPolig==0)
+    {
+        //salimos sin imprimir nada
+        return;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos la cadena de formato para imprimir los polibles NaN
+    FormatoNumFormatoTexto(formCoor,formNan);
+    //ajustamos la variable auxiliar como el posible número a restar si no hay
+    //que repetir el primer vértice de los polígonos
+    aux = (repitePrimerPunto) ? 0 : 1;
+    //comprobamos si hay que imprimir la marca separadora al principio
+    if(iniNan)
+    {
+        //la imprimimos
+        ImprimeGeocNanTexto(idFich,2,formNan,1);
+    }
+    //recorremos el número de polígonos
+    for(i=0;i<poli->nPolig;i++)
+    {
+        //comprobamos si hay que imprimir la cabecera
+        if(impCabecera)
+        {
+            //imprimos la cabecera
+            ImprimeCabeceraPoligFichero(poli,i,iniCab,impLim,formCoor,impArea,
+                                        formArea,factorX,factorY,
+                                        repitePrimerPunto,idFich);
+        }
+        //posición del punto inicial del polígono
+        pos = poli->posIni[i];
+        //recorremos el número de vértices del polígono de trabajo
+        for(j=0;j<(poli->nVert[i]-aux);j++)
+        {
+            //imprimimos las coordenadas, multiplicadas por los factores
+            fprintf(idFich,formCoor,factorX*poli->x[pos+j]);
+            fprintf(idFich,formCoor,factorY*poli->y[pos+j]);
+            fprintf(idFich,"\n");
+        }
+        //imprimimos la marca separadora al final (menos para el último)
+        if(i!=(poli->nPolig-1))
+        {
+            ImprimeGeocNanTexto(idFich,2,formNan,1);
+        }
+    }
+    //comprobamos si hay que imprimir la marca separadora al final
+    if(finNan)
+    {
+        //la imprimimos
+        ImprimeGeocNanTexto(idFich,2,formNan,1);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/polil.c b/src/polil.c
new file mode 100755
index 0000000..1da9d89
--- /dev/null
+++ b/src/polil.c
@@ -0,0 +1,1463 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file polil.c
+\brief Definición de funciones para el trabajo con polilíneas.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 03 de junio de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/polil.h"
+/******************************************************************************/
+/******************************************************************************/
+int GeocParOmpPolil(char version[])
+{
+    //comprobamos si hay paralelización
+#if defined(_OPENMP)
+    //comprobamos si hay que extraer versión
+    if(version!=NULL)
+    {
+        //calculamos la versión
+        VersionOpenMP(_OPENMP,version);
+    }
+    //salimos de la función
+    return 1;
+#else
+    if(version!=NULL)
+    {
+        //utilizamos la variable version para que no dé warming al compilar
+        strcpy(version,"");
+    }
+    //salimos de la función
+    return 0;
+#endif
+}
+/******************************************************************************/
+/******************************************************************************/
+polil* IniciaPolilVacia(void)
+{
+    //estructura de salida
+    polil* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para la estructura
+    sal = (polil*)malloc(sizeof(polil));
+    //comprobamos los posibles errores
+    if(sal==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //inicializamos los campos escalares a 0
+    sal->nElem = 0;
+    sal->nPolil = 0;
+    sal->hayLim = 0;
+    //inicializamos los campos vectoriales a NULL
+    sal->x = NULL;
+    sal->y = NULL;
+    sal->posIni = NULL;
+    sal->nVert = NULL;
+    sal->xMin = NULL;
+    sal->xMax = NULL;
+    sal->yMin = NULL;
+    sal->yMax = NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AuxCreaPolil1(const size_t nElem,
+                  const size_t* posNanX,
+                  const size_t* posNanY,
+                  const size_t nNanX,
+                  const size_t nNanY,
+                  size_t* nElemMax,
+                  size_t* nPolil)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de salida
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay el mismo número de NaN en los dos vectores
+    if(nNanX!=nNanY)
+    {
+        //salimos de la función
+        return GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL;
+    }
+    //comprobamos si hay NaN en las mismas posiciones de los vectores
+    for(i=0;i<nNanX;i++)
+    {
+        //comprobamos si las posiciones no son las mismas
+        if(posNanX[i]!=posNanY[i])
+        {
+            //salimos de la función
+            return GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos un número máximo de elementos de los vectores de coordenadas
+    //inicializamos con el número de elementos pasados
+    *nElemMax = nElem;
+    //comprobamos si en la primera posición hay NaN o si no hay ninguno
+    if((nNanX==0)||(nNanX&&(posNanX[0]!=0)))
+    {
+        //hace falta un elemento para el primer NaN
+        (*nElemMax)++;
+    }
+    //comprobamos si en la última posición hay NaN o si no hay ninguno
+    if((nNanX==0)||(nNanX&&(posNanX[nNanX-1]!=(nElem-1))))
+    {
+        //hace falta un elemento para el último NaN
+        (*nElemMax)++;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el número de polilíneas, dependiendo del número de NaN
+    if((nNanX==0)||
+       ((nNanX==1)&&(posNanX[0]==0))||
+       ((nNanX==1)&&(posNanX[nNanX-1]==(nElem-1)))||
+       ((nNanX==2)&&(posNanX[0]==0)&&(posNanX[nNanX-1]==(nElem-1))))
+    {
+        //sólo hay un polígono
+        *nPolil = 1;
+    }
+    else if((posNanX[0]!=0)&&(posNanX[nNanX-1]!=(nElem-1)))
+    {
+        //si no hay NaN en los extremos, el número de polilíneas es nNan+1
+        *nPolil = nNanX+1;
+    }
+    else if((posNanX[0]==0)&&(posNanX[nNanX-1]==(nElem-1)))
+    {
+        //si hay NaN en los dos extremos, el número de polilíneas es nNan-1
+        *nPolil = nNanX-1;
+    }
+    else
+    {
+        //en otro caso, es el número de NaN
+        *nPolil = nNanX;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AuxCreaPolil2(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   double* xSal,
+                   double* ySal)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contemplamos una posible salida rápida
+    if(nElem==0)
+    {
+        //salimos de la función
+        return;
+    }
+    //recorremos los puntos de trabajo
+    for(i=0;i<nElem;i++)
+    {
+        //vamos copiando
+        xSal[i] = x[i*incX];
+        ySal[i] = y[i*incY];
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void AuxCreaPolil3(const double* x,
+                   const double* y,
+                   const size_t nElem,
+                   const size_t incX,
+                   const size_t incY,
+                   const size_t* posNan,
+                   const size_t nNan,
+                   double* xSal,
+                   double* ySal,
+                   size_t* posIni,
+                   size_t* nVert,
+                   size_t* nPtos,
+                   size_t* nPolil)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //número de vértices de la polilínea a copiar
+    size_t nV=0;
+    //posición inicial de una polilínea
+    size_t pI=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos las variables de número de puntos copiados y número de
+    //polilíneas
+    *nPtos = 0;
+    *nPolil = 0;
+    //comprobamos si los vectores empiezan directamente con coordenadas
+    if((nNan==0)||(posNan[0]!=0))
+    {
+        //el primer elemento de los vectores de salida es NaN
+        xSal[0] = GeocNan();
+        ySal[0] = GeocNan();
+        //aumentamos la variable de número de puntos copiados
+        (*nPtos)++;
+        //calculamos el número de vértices de la polilínea
+        if(nNan)
+        {
+            //si hay valores NaN, el número de vértices es igual a la posición
+            //del siguiente NaN
+            nV = posNan[0];
+        }
+        else
+        {
+            //si no hay NaN, el número de vértices es igual al número de
+            //elementos de los vectores de coordenadas
+            nV = nElem;
+        }
+        //copiamos la primera polilínea
+        AuxCreaPolil2(&x[0],&y[0],nV,incX,incY,&xSal[*nPtos],&ySal[*nPtos]);
+        //indicamos la posición de inicio del polígono y el número de vértices
+        posIni[*nPolil] = 1;
+        nVert[*nPolil] = nV;
+        //sumamos el número de puntos copiados a la variable
+        (*nPtos) += nV;
+        //aumentamos el contador de polilíneas
+        (*nPolil)++;
+    }
+    //recorremos el número de NaN
+    for(i=0;i<nNan;i++)
+    {
+        //copiamos el NaN
+        xSal[*nPtos] = GeocNan();
+        ySal[*nPtos] = GeocNan();
+        //aumentamos la variable de número de puntos copiados
+        (*nPtos)++;
+        //posición del primer punto de la polilínea
+        pI = posNan[i]+1;
+        //sólo continuamos si el NaN no es la última posición de los vectores
+        if(pI!=nElem)
+        {
+            //calculo el número de puntos de la polilínea, dependiendo del NaN
+            //de trabajo
+            if(i!=(nNan-1))
+            {
+                //todavía hay más NaN por delante
+                nV = posNan[i+1]-pI;
+            }
+            else
+            {
+                //este es el último NaN de la lista
+                nV = nElem-pI;
+            }
+            //copiamos las coordenadas de la polilínea
+            AuxCreaPolil2(&x[pI*incX],&y[pI*incY],nV,incX,incY,&xSal[*nPtos],
+                          &ySal[*nPtos]);
+            //comprobamos el número de puntos copiados
+            if(nV)
+            {
+                //indicamos la posición de inicio de la polilínea y el número de
+                //vértices
+                posIni[*nPolil] = *nPtos;
+                nVert[*nPolil] = nV;
+                //sumamos el número de puntos copiados a la variable
+                (*nPtos) += nV;
+                //aumentamos el contador de polilíneas
+                (*nPolil)++;
+            }
+            else
+            {
+                //si no se han copiado puntos, la polilínea era falsa (había dos
+                //NaN seguidos, luego descuento el último NaN copiado
+                (*nPtos)--;
+            }
+        }
+    }
+    //copiamos el último NaN, si no se ha copiado ya
+    if(!EsGeocNan(xSal[(*nPtos)-1]))
+    {
+        //copiamos
+        xSal[*nPtos] = GeocNan();
+        ySal[*nPtos] = GeocNan();
+        //aumentamos el contador de puntos
+        (*nPtos)++;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+polil* CreaPolil(const double* x,
+                 const double* y,
+                 const size_t nElem,
+                 const size_t incX,
+                 const size_t incY,
+                 int* idError)
+{
+    //número de puntos
+    size_t ptos=0;
+    //número máximo de elementos de los vectores de coordenadas
+    size_t nElemMax=0;
+    //número de polilíneas
+    size_t nPolil=0;
+    //número de identificadores NaN
+    size_t nNanX=0,nNanY=0;
+    //posiciones de los identificadores NaN
+    size_t* posNanX=NULL;
+    size_t* posNanY=NULL;
+    //estructura de salida
+    polil* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable de error
+    *idError = GEOC_ERR_NO_ERROR;
+    //creamos la estructura vacía
+    sal = IniciaPolilVacia();
+    //comprobamos los posibles errores
+    if(sal==NULL)
+    {
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //contemplamos una posible salida rápida
+    if(nElem==0)
+    {
+        //devolvemos la estructura vacía
+        return sal;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contamos el número de identificadores NaN en los vectores de entrada
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(posNanX,x,nNanX,posNanY,y,nNanY)
+#endif
+{
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //contamos el número de indentificadores NaN en el vector X
+    posNanX = PosGeocNanEnVector(x,nElem,incX,&nNanX);
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //contamos el número de indentificadores NaN en el vector Y
+    posNanY = PosGeocNanEnVector(y,nElem,incY,&nNanY);
+} // --> fin del #pragma omp parallel sections
+    //comprobamos los posibles errores de asignación de memoria
+    if(((posNanX==NULL)&&(nNanX!=0))||((posNanY==NULL)&&(nNanY!=0)))
+    {
+        //liberamos la memoria asignada
+        LibMemPolil(sal);
+        free(posNanX);
+        free(posNanY);
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si los vectores tienen bien colocados los NaN y calculamos
+    //el número máximo de elementos de los vectores de la estructura y el
+    //número de polilíneas
+    *idError = AuxCreaPolil1(nElem,posNanX,posNanY,nNanX,nNanY,&nElemMax,
+                             &nPolil);
+    //comprobamos los posibles errores
+    if(*idError!=GEOC_ERR_NO_ERROR)
+    {
+        //liberamos la memoria asignada
+        LibMemPolil(sal);
+        free(posNanX);
+        free(posNanY);
+        //escribimos el mensaje de error
+        if(*idError==GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo "
+                       "número de polilíneas");
+        }
+        else if(*idError==GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen las mismas "
+                       "polilíneas");
+        }
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos el número de polilíneas
+    sal->nPolil = nPolil;
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(sal,nElemMax,nPolil)
+#endif
+{
+    //asignamos memoria para los vectores de la estructura
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->x = (double*)malloc(nElemMax*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->y = (double*)malloc(nElemMax*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->posIni = (size_t*)malloc(nPolil*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    sal->nVert = (size_t*)malloc(nPolil*sizeof(double));
+} // --> fin del #pragma omp parallel sections
+    //comprobamos los posibles errores
+    if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL))
+    {
+        //liberamos la memoria asignada
+        LibMemPolil(sal);
+        free(posNanX);
+        free(posNanY);
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //copiamos las polilíneas a la estructura
+    //como ya sabemos que el número de NaN y sus posiciones son los mismos para
+    //los vectores x e y, trabajamos con los valores para el vector x
+    AuxCreaPolil3(x,y,nElem,incX,incY,posNanX,nNanX,sal->x,sal->y,sal->posIni,
+                  sal->nVert,&ptos,&nPolil);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay de verdad alguna polilínea
+    if(nPolil==0)
+    {
+        //liberamos la memoria asignada
+        LibMemPolil(sal);
+        free(posNanX);
+        free(posNanY);
+        //creamos la estructura vacía
+        sal = IniciaPolilVacia();
+        //comprobamos los posibles errores
+        if(sal==NULL)
+        {
+            //asignamos la variable de error
+            *idError = GEOC_ERR_ASIG_MEMORIA;
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //salimos de la función
+        return sal;
+    }
+    //asignamos el número de elementos a la estructura
+    sal->nElem = ptos;
+    //comprobamos si hay que reajustar el tamaño de los vectores de coordenadas
+    if(ptos!=nElemMax)
+    {
+        //asignamos el nuevo tamaño de los vectores
+        sal->nElem = ptos;
+        //reajustamos los tamaños
+        sal->x = (double*)realloc(sal->x,ptos*sizeof(double));
+        sal->y = (double*)realloc(sal->y,ptos*sizeof(double));
+    }
+    //comprobamos si el número de polilíneas es el estimado
+    if(nPolil!=sal->nPolil)
+    {
+        //asignamos de nuevo la variable de número de polilíneas
+        sal->nPolil = nPolil;
+        //reajustamos los tamaños
+        sal->posIni = (size_t*)realloc(sal->posIni,nPolil*sizeof(size_t));
+        sal->nVert = (size_t*)realloc(sal->nVert,nPolil*sizeof(size_t));
+    }
+    //comprobamos los posibles errores
+    if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL))
+    {
+        //liberamos la memoria asignada
+        LibMemPolil(sal);
+        free(posNanX);
+        free(posNanY);
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //liberamos la memoria asignada
+    free(posNanX);
+    free(posNanY);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+void EnlazaCamposPolil(polil* poliEnt,
+                       polil* poliSal)
+{
+    //LIBERAMOS LA POSIBLE MEMORIA ASIGNADA A LOS CAMPOS VECTORIALES DE LA
+    //ESTRUCTURA DE SALIDA
+    //comprobamos si hay algún elemento en los vectores de coordenadas
+    if(poliSal->nElem)
+    {
+        free(poliSal->x);
+        free(poliSal->y);
+    }
+    //comprobamos si hay alguna polilínea en los vectores de posiciones
+    if(poliSal->nPolil)
+    {
+        free(poliSal->posIni);
+        free(poliSal->nVert);
+    }
+    //comprobamos si hay límites calculados
+    if(poliSal->hayLim)
+    {
+        free(poliSal->xMin);
+        free(poliSal->xMax);
+        free(poliSal->yMin);
+        free(poliSal->yMax);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //enlazamos todos los campos de la estructura de entrada en la de salida
+    poliSal->nElem = poliEnt->nElem;
+    poliSal->x = poliEnt->x;
+    poliSal->y = poliEnt->y;
+    poliSal->nPolil = poliEnt->nPolil;
+    poliSal->posIni = poliEnt->posIni;
+    poliSal->nVert = poliEnt->nVert;
+    poliSal->hayLim = poliEnt->hayLim;
+    poliSal->xMin = poliEnt->xMin;
+    poliSal->xMax = poliEnt->xMax;
+    poliSal->yMin = poliEnt->yMin;
+    poliSal->yMax = poliEnt->yMax;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+polil* CopiaPolil(const polil* poli,
+                  int* idError)
+{
+    //polilínea de salida
+    polil* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable de error
+    *idError = GEOC_ERR_NO_ERROR;
+    //inicializamos la polilínea de salida
+    sal = IniciaPolilVacia();
+    //comprobamos los posibles errores
+    if(sal==NULL)
+    {
+        //asignamos la variable de error
+        *idError = GEOC_ERR_ASIG_MEMORIA;
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //sólo continuamos si la polilínea de entrada contiene datos
+    if(poli->nElem)
+    {
+        //copiamos las coordenadas de los vértices
+        *idError = AnyadeDatosPolil(sal,poli->x,poli->y,poli->nElem,1,1);
+        //comprobamos si ha ocurrido algún error
+        if((*idError)!=GEOC_ERR_NO_ERROR)
+        {
+            //liberamos la memoria asignada
+            LibMemPolil(sal);
+            //escribimos el mensaje de error
+            if((*idError)==GEOC_ERR_ASIG_MEMORIA)
+            {
+                GEOC_ERROR("Error de asignación de memoria");
+            }
+            else if((*idError)==GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL)
+            {
+                GEOC_ERROR("Error: Los vectores de coordenadas de la\n"
+                           "polilínea de entrada no contienen el mismo número "
+                           "de polilíneas");
+            }
+            else if((*idError)==GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL)
+            {
+                GEOC_ERROR("Error: Los vectores de coordenadas de la\n"
+                           "polilínea de entrada no contienen las mismas "
+                           "polilíneas");
+            }
+            //salimos de la función
+            return NULL;
+        }
+        //comprobamos si hay que calcular límites
+        if(poli->hayLim)
+        {
+            //calculamos los límites
+            *idError = CalcLimitesPolil(sal);
+            //comprobamos los posibles errores
+            if((*idError)!=GEOC_ERR_NO_ERROR)
+            {
+                //liberamos la memoria asignada
+                LibMemPolil(sal);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AnyadePolilPolil(polil* poli,
+                     const polil* anyade)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de posición
+    size_t pos=0;
+    //número total de elementos
+    size_t nElem=0,nPolil=0;
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //si la polilínea a añadir está vacía, salimos de la función
+    if((anyade!=NULL)&&(anyade->nPolil==0))
+    {
+        //salimos de la función sin hacer nada
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el número total de elementos de la polilínea conjunta
+    nElem = poli->nElem+anyade->nElem;
+    //si la polilínea original contenía datos, al número total de elementos hay
+    //que restarle 1 por el NaN común que sobra al juntar las dos estructuras
+    if(poli->nPolil)
+    {
+        nElem--;
+    }
+    //calculamos el número total de polilíneas
+    nPolil = poli->nPolil+anyade->nPolil;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //reasignamos memoria para cubrir los nuevos datos
+    poli->x = (double*)realloc(poli->x,nElem*sizeof(double));
+    poli->y = (double*)realloc(poli->y,nElem*sizeof(double));
+    poli->posIni = (size_t*)realloc(poli->posIni,nPolil*sizeof(size_t));
+    poli->nVert = (size_t*)realloc(poli->nVert,nPolil*sizeof(size_t));
+    //reasignamos también para los posibles vectores de límites
+    if(poli->hayLim)
+    {
+        poli->xMin = (double*)realloc(poli->xMin,nPolil*sizeof(double));
+        poli->xMax = (double*)realloc(poli->xMax,nPolil*sizeof(double));
+        poli->yMin = (double*)realloc(poli->yMin,nPolil*sizeof(double));
+        poli->yMax = (double*)realloc(poli->yMax,nPolil*sizeof(double));
+    }
+    //comprobamos los posibles errores en las asignaciones obligatorias
+    if((poli->x==NULL)||(poli->y==NULL)||(poli->posIni==NULL)||
+       (poli->nVert==NULL))
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    //comprobamos los posibles errores en las asignaciones de límites
+    if(poli->hayLim)
+    {
+        if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)||
+           (poli->yMax==NULL))
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos la posición de inicio para copiar en la estructura de salida
+    //si la estructura de salida está vacía, se comienza en la primera posición
+    //si tiene datos, se comienza a continuación en la última (dentro del bucle,
+    //la suma de posIni hace que se comience a continuación de la última)
+    pos = (poli->nPolil==0) ? 0 : poli->nElem-1;
+    //recorremos el número de nuevos elementos
+    for(i=0;i<anyade->nElem;i++)
+    {
+        //copiamos las coordenadas
+        poli->x[pos+i] = anyade->x[i];
+        poli->y[pos+i] = anyade->y[i];
+    }
+    //calculamos las posiciones a sumar para ajustar las posiciones de inicio de
+    //las polilíneas añadidas
+    //si la estructura de salida está vacía, se copian las posiciones tal cual
+    //si tiene datos, se suman las posiciones ya ocupadas
+    pos = (poli->nPolil==0) ? 0 : poli->nElem-1;
+    //recorremos el número de polilíneas
+    for(i=0;i<anyade->nPolil;i++)
+    {
+        //copiamos las posiciones de inicio actualizadas y el número de vértices
+        poli->posIni[poli->nPolil+i] = anyade->posIni[i]+pos;
+        poli->nVert[poli->nPolil+i] = anyade->nVert[i];
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que calcular límites
+    if(poli->hayLim)
+    {
+        //comprobamos si ya están calculados
+        if(anyade->hayLim)
+        {
+            //recorremos el número de polilíneas y copiamos los límites
+            for(i=0;i<anyade->nPolil;i++)
+            {
+                //copiamos los límites
+                poli->xMin[poli->nPolil+i] = anyade->xMin[i];
+                poli->xMax[poli->nPolil+i] = anyade->xMax[i];
+                poli->yMin[poli->nPolil+i] = anyade->yMin[i];
+                poli->yMax[poli->nPolil+i] = anyade->yMax[i];
+            }
+        }
+        else
+        {
+            //calculamos los límites y los copiamos
+            LimitesPoligonosPolig(&(anyade->x[1]),&(anyade->y[1]),1,1,
+                                  anyade->posIni,anyade->nVert,anyade->nPolil,
+                                  anyade->posIni[0],&(poli->xMin[poli->nPolil]),
+                                  &(poli->xMax[poli->nPolil]),
+                                  &(poli->yMin[poli->nPolil]),
+                                  &(poli->yMax[poli->nPolil]));
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ajustamos los tamaños antes de salir
+    poli->nElem = nElem;
+    poli->nPolil = nPolil;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AnyadeDatosPolil(polil* poli,
+                     const double* x,
+                     const double* y,
+                     const size_t nElem,
+                     const size_t incX,
+                     const size_t incY)
+{
+    //polilínea auxiliar
+    polil* aux=NULL;
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contemplamos una posible salida rápida
+    if(nElem==0)
+    {
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos una nueva polilínea con los datos a añadir
+    aux = CreaPolil(x,y,nElem,incX,incY,&estado);
+    //comprobamos los posibles errores
+    if(estado!=GEOC_ERR_NO_ERROR)
+    {
+        //liberamos la memoria asignada
+        LibMemPolil(aux);
+        //escribimos el mensaje de error
+        if(estado==GEOC_ERR_ASIG_MEMORIA)
+        {
+            GEOC_ERROR("Error de asignación de memoria");
+        }
+        else if(estado==GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo "
+                       "número de polilíneas");
+        }
+        else if(estado==GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL)
+        {
+            GEOC_ERROR("Error: Los vectores de trabajo no contienen las mismas "
+                       "polilíneas");
+        }
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //añadimos la nueva estructura
+    estado = AnyadePolilPolil(poli,aux);
+    //comprobamos los posibles errores
+    if(estado!=GEOC_ERR_NO_ERROR)
+    {
+        //liberamos la memoria asignada
+        LibMemPolil(aux);
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //liberamos la memoria utilizada
+    LibMemPolil(aux);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void LibMemPolil(polil* datos)
+{
+    //comprobamos si hay memoria que liberar
+    if(datos!=NULL)
+    {
+        //liberamos la memoria asignada al vector de coordenadas X
+        if(datos->x!=NULL)
+        {
+            free(datos->x);
+        }
+        //liberamos la memoria asignada al vector de coordenadas Y
+        if(datos->y!=NULL)
+        {
+            free(datos->y);
+        }
+        //liberamos la memoria asignada al vector de posiciones
+        if(datos->posIni!=NULL)
+        {
+            free(datos->posIni);
+        }
+        //liberamos la memoria asignada al vector de número de vértices
+        if(datos->nVert!=NULL)
+        {
+            free(datos->nVert);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas X mínimas
+        if(datos->xMin!=NULL)
+        {
+            free(datos->xMin);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas X máximas
+        if(datos->xMax!=NULL)
+        {
+            free(datos->xMax);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas Y mínimas
+        if(datos->yMin!=NULL)
+        {
+            free(datos->yMin);
+        }
+        //liberamos la memoria asignada a los vector de coordenadas Y máximas
+        if(datos->yMax!=NULL)
+        {
+            free(datos->yMax);
+        }
+        //liberamos la memoria asignada a la estructura
+        free(datos);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int CalcLimitesPolil(polil* poli)
+{
+    //variable de estado (salida)
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos salida rápida
+    if((poli->nPolil==0)||(poli->hayLim))
+    {
+        //salimos de la función si la estructura no contiene polilíneas o si
+        //éstas ya tienen calculados sus límites
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(poli)
+#endif
+{
+    //asignamos memoria para los vectores de límites
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->xMin = (double*)malloc((poli->nPolil)*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->xMax = (double*)malloc((poli->nPolil)*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->yMin = (double*)malloc((poli->nPolil)*sizeof(double));
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    poli->yMax = (double*)malloc((poli->nPolil)*sizeof(double));
+} // --> fin del #pragma omp parallel sections
+    //comprobamos los posibles errores
+    if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)||
+       (poli->yMax==NULL))
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    //indicamos que sí hay límites
+    poli->hayLim = 1;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos los límites de todas las polilíneas
+    LimitesPoligonosPolig(poli->x,poli->y,1,1,poli->posIni,poli->nVert,
+                          poli->nPolil,0,poli->xMin,poli->xMax,poli->yMin,
+                          poli->yMax);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void EscalaYTrasladaPolil(polil* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim)
+{
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(poli)
+#endif
+{
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos los factores de escala y las traslaciones a las coordenadas X
+    EscalaYTrasladaVector(poli->x,poli->nElem,1,escalaX,trasladaX);
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos los factores de escala y las traslaciones a las coordenadas Y
+    EscalaYTrasladaVector(poli->y,poli->nElem,1,escalaY,trasladaY);
+} // --> fin del #pragma omp parallel sections
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE
+    //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO
+    //TOTAL DE VÉRTICES
+    //comprobamos si hay que aplicar el factor a los límites
+    if(aplicaLim&&poli->hayLim)
+    {
+        //aplicamos los factores de escala y las traslaciones a los límites
+        EscalaYTrasladaVector(poli->xMin,poli->nPolil,1,escalaX,trasladaX);
+        EscalaYTrasladaVector(poli->xMax,poli->nPolil,1,escalaX,trasladaX);
+        EscalaYTrasladaVector(poli->yMin,poli->nPolil,1,escalaY,trasladaY);
+        EscalaYTrasladaVector(poli->yMax,poli->nPolil,1,escalaY,trasladaY);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void TrasladaYEscalaPolil(polil* poli,
+                          const double escalaX,
+                          const double escalaY,
+                          const double trasladaX,
+                          const double trasladaY,
+                          const int aplicaLim)
+{
+    //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+ shared(poli)
+#endif
+{
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos las traslaciones y los factores de escala a las coordenadas X
+    TrasladaYEscalaVector(poli->x,poli->nElem,1,escalaX,trasladaX);
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+    //aplicamos las traslaciones y los factores de escala a las coordenadas Y
+    TrasladaYEscalaVector(poli->y,poli->nElem,1,escalaY,trasladaY);
+} // --> fin del #pragma omp parallel sections
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE
+    //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO
+    //TOTAL DE VÉRTICES
+    //comprobamos si hay que aplicar el factor a los límites
+    if(aplicaLim&&poli->hayLim)
+    {
+        //aplicamos las traslaciones y los factores de escala a los límites
+        TrasladaYEscalaVector(poli->xMin,poli->nPolil,1,escalaX,trasladaX);
+        TrasladaYEscalaVector(poli->xMax,poli->nPolil,1,escalaX,trasladaX);
+        TrasladaYEscalaVector(poli->yMin,poli->nPolil,1,escalaY,trasladaY);
+        TrasladaYEscalaVector(poli->yMax,poli->nPolil,1,escalaY,trasladaY);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void MuevePolil(polil* poli,
+                const double escalaX,
+                const double escalaY,
+                const double trasladaX,
+                const double trasladaY,
+                const int orden,
+                const int aplicaLim)
+{
+    //comprobamos el orden de aplicación de los factores
+    if(orden==0)
+    {
+        //primero los factores de escala y luego las traslaciones
+        EscalaYTrasladaPolil(poli,escalaX,escalaY,trasladaX,trasladaY,
+                             aplicaLim);
+    }
+    else
+    {
+        //primero las traslaciones y luego los factores de escala
+        TrasladaYEscalaPolil(poli,escalaX,escalaY,trasladaX,trasladaY,
+                             aplicaLim);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int AligeraPolil(polil* poli,
+                 const double tol,
+                 const enum GEOC_DPEUCKER_ROBUSTO robusto,
+                 const size_t nPtosRobusto,
+                 const size_t nSegRobusto)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //posición inicial de la polilínea de trabajo y número de puntos aligerados
+    size_t posIni=0,nPtos=0;
+    //polilínea que es un mismo punto
+    int pmp=0;
+    //coordenadas de las polilíneas aligeradas
+    double* x=NULL;
+    double* y=NULL;
+    //estructura auxiliar
+    polil* aux=NULL;
+    //vector de posiciones después del aligerado
+    size_t* pos=NULL;
+    //variable de salida
+    int estado=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos una posible salida rápida
+    if(poli->nPolil==0)
+    {
+        //salimos de la función
+        return estado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar vacía
+    aux = IniciaPolilVacia();
+    //comprobamos los posibles errores
+    if(aux==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return GEOC_ERR_ASIG_MEMORIA;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos el número de polilíneas almacenadas
+    for(i=0;i<poli->nPolil;i++)
+    {
+        //extraemos la posición inicial de la polilínea de trabajo
+        posIni = poli->posIni[i];
+        //aligeramos la polilínea de trabajo
+        pos = AligeraPolilinea(&(poli->x[posIni]),&(poli->y[posIni]),
+                               poli->nVert[i],1,1,tol,robusto,nPtosRobusto,
+                               nSegRobusto,&nPtos);
+        //comprobamos posibles errores
+        if(pos==NULL)
+        {
+            //liberamos la memoria asignada
+            LibMemPolil(aux);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+        //comprobamos si la polilínea se ha quedado en dos puntos
+        if(nPtos==2)
+        {
+            //comprobamos si los tres puntos son colineales
+            pmp = ((poli->x[posIni+pos[0]])==(poli->x[posIni+pos[1]]))&&
+                  ((poli->y[posIni+pos[0]])==(poli->y[posIni+pos[1]]));
+        }
+        //comprobamos si después del aligerado todavía queda una polilínea que
+        //no sea un único punto
+        if((nPtos>2)||((nPtos==2)&&(!pmp)))
+        {
+            //asignamos memoria para los vectores de coordenadas de la polilínea
+            //aligerada
+            x = (double*)malloc(nPtos*sizeof(double));
+            y = (double*)malloc(nPtos*sizeof(double));
+            //comprobamos posibles errores
+            if((x==NULL)||(y==NULL))
+            {
+                //liberamos la memoria asignada
+                LibMemPolil(aux);
+                free(pos);
+                free(x);
+                free(y);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return GEOC_ERR_ASIG_MEMORIA;
+            }
+            //recorremos el número de puntos de la polilínea aligerada
+            for(j=0;j<nPtos;j++)
+            {
+                //copiamos las coordenadas
+                x[j] = poli->x[posIni+pos[j]];
+                y[j] = poli->y[posIni+pos[j]];
+            }
+            //añadimos las coordenadas a la polilínea aligerada
+            estado = AnyadeDatosPolil(aux,x,y,nPtos,1,1);
+            //sólo puede haber ocurrido un error de asignación de memoria, ya
+            //que suponemos que la polilínea de entrada es correcta
+            if(estado!=GEOC_ERR_NO_ERROR)
+            {
+                //liberamos la memoria asignada
+                LibMemPolil(aux);
+                free(pos);
+                free(x);
+                free(y);
+                //escribimos el mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return GEOC_ERR_ASIG_MEMORIA;
+            }
+            //liberamos la memoria asignada a los vectores de coordenadas
+            free(x);
+            free(y);
+        }
+        //liberamos la memoria asignada al vector de posiciones del aligerado
+        free(pos);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que calcular límites
+    if(poli->hayLim)
+    {
+        //calculamos los límites
+        estado = CalcLimitesPolil(aux);
+        //comprobamos los posibles errores
+        if(estado!=GEOC_ERR_NO_ERROR)
+        {
+            //liberamos la memoria asignada
+            LibMemPolil(aux);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return GEOC_ERR_ASIG_MEMORIA;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //enlazamos los campos de la estructura auxiliar a los de la estructura de
+    //salida
+    EnlazaCamposPolil(aux,poli);
+    //liberamos la memoria asignada a la estructura auxiliar (pero no a sus
+    //campos)
+    free(aux);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return estado;
+}
+/******************************************************************************/
+/******************************************************************************/
+void ImprimeCabeceraPolilFichero(const polil* poli,
+                                 const size_t indice,
+                                 const char iniCab[],
+                                 const int impLim,
+                                 const char formCoor[],
+                                 const double factorX,
+                                 const double factorY,
+                                 FILE* idFich)
+{
+    //número de vértices de la polilínea de trabajo
+    size_t nVert=0;
+    //límites
+    double xMin=0.0,xMax=0.0,yMin=0.0,yMax=0.0,limAux=0.0;
+    //variables de posición
+    size_t pos=0,posXMin=0,posXMax=0,posYMin=0,posYMax=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //número de vértices a imprimir de la polilínea
+    nVert = poli->nVert[indice];
+    //posición de inicio de la polilínea
+    pos = poli->posIni[indice];
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //imprimimos la marca de inicio y el número de vértices
+    fprintf(idFich,"%s %8zu",iniCab,nVert);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si hay que imprimir los límites
+    if(impLim)
+    {
+        //comprobamos si ya están calculados los límites
+        if(poli->hayLim)
+        {
+            //extraemos los límites
+            xMin = poli->xMin[indice];
+            xMax = poli->xMax[indice];
+            yMin = poli->yMin[indice];
+            yMax = poli->yMax[indice];
+        }
+        else
+        {
+            //buscamos las posiciones de los elementos máximo y mínimo
+            //paralelización con OpenMP
+#if defined(_OPENMP)
+#pragma omp parallel sections default(none) \
+shared(poli,pos,nVert,posXMin,posXMax,posYMin,posYMax)
+#endif
+{
+            //posiciones en el vector X
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+            MinMax(&(poli->x[pos]),nVert,1,&posXMin,&posXMax);
+            //posiciones en el vector Y
+#if defined(_OPENMP)
+#pragma omp section
+#endif
+            MinMax(&(poli->y[pos]),nVert,1,&posYMin,&posYMax);
+} // --> fin del #pragma omp parallel sections
+            //extraemos los valores extremos
+            xMin = poli->x[pos+posXMin];
+            xMax = poli->x[pos+posXMax];
+            yMin = poli->y[pos+posYMin];
+            yMax = poli->y[pos+posYMax];
+        }
+        //comprobamos si el factor de escala para X es negativo
+        if(factorX<0.0)
+        {
+            //los límites cambian
+            limAux = xMin;
+            xMin = xMax;
+            xMax = limAux;
+            //aplicamos el factor de escala
+            xMin *= factorX;
+            xMax *= factorX;
+        }
+        //comprobamos si el factor de escala para Y es negativo
+        if(factorY<0.0)
+        {
+            //los límites cambian
+            limAux = yMin;
+            yMin = yMax;
+            yMax = limAux;
+            //aplicamos el factor de escala
+            yMin *= factorY;
+            yMax *= factorY;
+        }
+        //imprimimos los límites
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,xMin);
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,xMax);
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,yMin);
+        fprintf(idFich," ");
+        fprintf(idFich,formCoor,yMax);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salto de línea final
+    fprintf(idFich,"\n");
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+void ImprimePolilFichero(const polil* poli,
+                         const double factorX,
+                         const double factorY,
+                         const int iniNan,
+                         const int finNan,
+                         const char formCoor[],
+                         const int impCabecera,
+                         const char iniCab[],
+                         const int impLim,
+                         FILE* idFich)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //cadena de formato para imprimir los posibles valores NaN
+    char formNan[GEOC_NAN_LON_FORM_NUM_SIMPLE+1];
+    //variable de posición
+    size_t pos=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si la estructura contiene alguna polilínea
+    if(poli->nPolil==0)
+    {
+        //salimos sin imprimir nada
+        return;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos la cadena de formato para imprimir los polibles NaN
+    FormatoNumFormatoTexto(formCoor,formNan);
+    //comprobamos si hay que imprimir la marca separadora al principio
+    if(iniNan)
+    {
+        //la imprimimos
+        ImprimeGeocNanTexto(idFich,2,formNan,1);
+    }
+    //recorremos el número de polilíneas
+    for(i=0;i<poli->nPolil;i++)
+    {
+        //comprobamos si hay que imprimir la cabecera
+        if(impCabecera)
+        {
+            //imprimos la cabecera
+            ImprimeCabeceraPolilFichero(poli,i,iniCab,impLim,formCoor,factorX,
+                                        factorY,idFich);
+        }
+        //posición del punto inicial de la polilínea
+        pos = poli->posIni[i];
+        //recorremos el número de vértices de la polilínea de trabajo
+        for(j=0;j<poli->nVert[i];j++)
+        {
+            //imprimimos las coordenadas, multiplicadas por factor
+            fprintf(idFich,formCoor,factorX*poli->x[pos+j]);
+            fprintf(idFich,formCoor,factorY*poli->y[pos+j]);
+            fprintf(idFich,"\n");
+        }
+        //imprimimos la marca separadora al final (menos para el último)
+        if(i!=(poli->nPolil-1))
+        {
+            ImprimeGeocNanTexto(idFich,2,formNan,1);
+        }
+    }
+    //comprobamos si hay que imprimir la marca separadora al final
+    if(finNan)
+    {
+        //la imprimimos
+        ImprimeGeocNanTexto(idFich,2,formNan,1);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/ptopol.c b/src/ptopol.c
new file mode 100755
index 0000000..a44d9e0
--- /dev/null
+++ b/src/ptopol.c
@@ -0,0 +1,1007 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file ptopol.c
+\brief Declaración de funciones para la realización de chequeos de inclusión de
+       puntos en polígonos.
+
+En el momento de la compilación ha de seleccionarse el tipo de dato que se
+utilizará en los cálculos intermedios de las funciones
+\ref PtoEnPoligonoVerticeBorde y \ref PtoEnPoligonoVerticeBordeDouble. Si los
+puntos de trabajo están muy alejados de los polígonos pueden darse casos de
+resultados erróneos. Sería conveniente que los cálculos internedios se hiciesen
+en variables de 64 bits, pero el tipo <tt>long int</tt> suele ser de 4 bytes en
+procesadores de 32 bits. Para seleccionar este tipo como <tt>long long int</tt>,
+lo que en procesadores de 32 bits equivale a una variable de 64 bits, es
+necesario definir la variable para el preprocesador \em PTOPOL_BORDE_LONG_64. En
+procesadores de 64 bits no es necesario (aunque puede utilizarse), ya que el
+tipo <tt>long int</tt> tiene una longitud de 64 bits. Si no se define la
+variable, se usará un tipo <tt>long int</tt> para los cálculos intermedios. En
+\p gcc, las variables para el preprocesador se pasan como \em -DXXX, donde
+\em XXX es la variable a introducir. El uso del tipo <tt>long long int</tt> en
+procesadores de 32 bits puede hacer que las funciones se ejecuten hasta 10 veces
+más lentamente que si se utiliza el tipo <tt>long int</tt>. Con cálculos
+internos de 32 bits las coordenadas de los vértices del polígono no han de estar
+más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos
+de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas
+3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al
+centímetro. Con esto podríamos chequear un punto en un polo con respecto a un
+polígono en el ecuador en coordenadas UTM expresadas en centímetros.
+\author José Luis García Pallero, jgpallero at gmail.com
+\note Este fichero contiene funciones paralelizadas con OpenMP.
+\date 05 de abril de 2010
+\section Licencia Licencia
+Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/ptopol.h"
+/******************************************************************************/
+/******************************************************************************/
+int GeocParOmpPtopol(char version[])
+{
+    //comprobamos si hay paralelización
+#if defined(_OPENMP)
+    //comprobamos si hay que extraer versión
+    if(version!=NULL)
+    {
+        //calculamos la versión
+        VersionOpenMP(_OPENMP,version);
+    }
+    //salimos de la función
+    return 1;
+#else
+    if(version!=NULL)
+    {
+        //utilizamos la variable version para que no dé warming al compilar
+        strcpy(version,"");
+    }
+    //salimos de la función
+    return 0;
+#endif
+}
+/******************************************************************************/
+/******************************************************************************/
+int GeocLongLongIntPtopol(void)
+{
+    //comprobamos si se ha pasado la variable del preprocesador
+#if defined(PTOPOL_BORDE_LONG_64)
+    return 1;
+#else
+    return 0;
+#endif
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnRectangulo(const double x,
+                    const double y,
+                    const double xMin,
+                    const double xMax,
+                    const double yMin,
+                    const double yMax)
+{
+    //posibles posiciones del punto
+    if((x<xMin)||(x>xMax)||(y<yMin)||(y>yMax))
+    {
+        //punto fuera
+        return GEOC_PTO_FUERA_POLIG;
+    }
+    else if((x>xMin)&&(x<xMax)&&(y>yMin)&&(y<yMax))
+    {
+        //punto dentro
+        return GEOC_PTO_DENTRO_POLIG;
+    }
+    else if(((x==xMin)&&(y==yMax))||((x==xMax)&&(y==yMax))||
+            ((x==xMax)&&(y==yMin))||((x==xMin)&&(y==yMin)))
+    {
+        //punto en un vértice
+        return GEOC_PTO_VERTICE_POLIG;
+    }
+    else
+    {
+        //punto en el borde
+        return GEOC_PTO_BORDE_POLIG;
+    }
+}
+/******************************************************************************/
+/******************************************************************************/
+int RectanguloEnRectangulo(const int borde,
+                           const double xMin1,
+                           const double xMax1,
+                           const double yMin1,
+                           const double yMax1,
+                           const double xMin2,
+                           const double xMax2,
+                           const double yMin2,
+                           const double yMax2)
+{
+    //variable de salida, que inicializamos como polígonos no disjuntos
+    int sal=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el borde se tiene en cuenta o no
+    if(borde)
+    {
+        //el borde se tiene en cuenta
+        if((xMin1>=xMin2)&&(xMax1<=xMax2)&&(yMin1>=yMin2)&&(yMax1<=yMax2))
+        {
+            //el rectángulo está contenido
+            sal = 1;
+        }
+    }
+    else
+    {
+        //el borde no se tiene en cuenta
+        if((xMin1>xMin2)&&(xMax1<xMax2)&&(yMin1>yMin2)&&(yMax1<yMax2))
+        {
+            //el rectángulo está contenido
+            sal = 1;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+int RectDisjuntos(const double xMin1,
+                  const double xMax1,
+                  const double yMin1,
+                  const double yMax1,
+                  const double xMin2,
+                  const double xMax2,
+                  const double yMin2,
+                  const double yMax2)
+{
+    //variable de salida, que inicializamos como polígonos no disjuntos
+    int sal=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si son disjuntos
+    if((xMin1>xMax2)||(xMax1<xMin2)||(yMin1>yMax2)||(yMax1<yMin2))
+    {
+        //los restángulos son disjuntos
+        sal = 1;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligono(const double x,
+                  const double y,
+                  const double* coorX,
+                  const double* coorY,
+                  const size_t N,
+                  const size_t incX,
+                  const size_t incY)
+{
+    //índices para recorrer un bucle
+    size_t i=0,j=0;
+    //variables de posición
+    size_t posIX=0,posJX=0,posIY=0,posJY=0;
+    //variable de salida
+    int c=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos todos los vértices del polígono
+    for(i=0,j=N-1;i<N;j=i++)
+    {
+        //calculamos previamente las posiciones para multiplicar menos
+        posIX = i*incX;
+        posJX = j*incX;
+        posIY = i*incY;
+        posJY = j*incY;
+        //calculamos
+        if(((coorY[posIY]>y)!=(coorY[posJY]>y))&&
+           (x<(coorX[posJX]-coorX[posIX])*(y-coorY[posIY])/
+              (coorY[posJY]-coorY[posIY])+coorX[posIX]))
+        {
+            c = !c;
+        }
+    }
+    //asignamos el elemento de salida
+    if(c)
+    {
+        //el punto está dentro del polígono
+        c = GEOC_PTO_DENTRO_POLIG;
+    }
+    else
+    {
+        //el punto está fuera del polígono
+        c = GEOC_PTO_FUERA_POLIG;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return c;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligonoVertice(const double x,
+                         const double y,
+                         const double* coorX,
+                         const double* coorY,
+                         const size_t N,
+                         const size_t incX,
+                         const size_t incY)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable de salida, que inicializamos fuera del polígono
+    int pos=GEOC_PTO_FUERA_POLIG;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el punto es un vértice
+    for(i=0;i<N;i++)
+    {
+        //comprobamos las coordenadas
+        if((x==coorX[i*incX])&&(y==coorY[i*incY]))
+        {
+            //indicamos que el punto es un vértice
+            pos = GEOC_PTO_VERTICE_POLIG;
+            //salimos del bucle
+            break;
+        }
+    }
+    //sólo continuamos si el punto no es un vértice
+    if(pos!=GEOC_PTO_VERTICE_POLIG)
+    {
+        //calculamos la posición sin tener en cuenta el borde
+        pos = PtoEnPoligono(x,y,coorX,coorY,N,incX,incY);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return pos;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligonoVerticeBorde(const long x,
+                              const long y,
+                              const long* coorX,
+                              const long* coorY,
+                              const size_t N,
+                              const size_t incX,
+                              const size_t incY)
+{
+    //NOTA: SE MANTIENEN MUCHOS DE LOS COMENTARIOS ORIGINALES
+    //índices de vértices
+    size_t i=0,i1=0;
+    //number of (right,left) edge/ray crossings
+    int Rcross=0,Lcross=0;
+    //flags indicating the edge strads the X axis
+    int Rstrad=0,Lstrad=0;
+    //coordenadas del polígono referidas al punto de trabajo
+    ptopol_long cx=0,cy=0,cx1=0,cy1=0;
+    //número de elementos de trabajo del polígono
+    size_t n=N;
+    //variable auxiliar
+    double X=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el primer vértice se repite al final
+    if((coorX[0]==coorX[(N-1)*incX])&&(coorY[0]==coorY[(N-1)*incY]))
+    {
+        //trabajamos con todos los vértices, menos el último
+        n = N-1;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //for each edge e=(i-1,i), see if crosses ray
+    for(i=0;i<n;i++)
+    {
+        //referimos el vértice de trabajo al punto
+        cx = coorX[i*incX]-x;
+        cy = coorY[i*incY]-y;
+        //comprobamos si el punto es un vértice del polígono
+        if((cx==0)&&(cy==0))
+        {
+            //el punto es un vértice
+            return GEOC_PTO_VERTICE_POLIG;
+        }
+        //calculamos el índice del punto anterior en el polígono
+        i1 = (i) ? i-1 : n-1;
+        //referimos el vértice de trabajo al punto según el nuevo índice
+        cx1 = coorX[i1*incX]-x;
+        cy1 = coorY[i1*incY]-y;
+        //check if e straddles X axis, with bias above/below
+        Rstrad = (cy>0)!=(cy1>0);
+        Lstrad = (cy<0)!=(cy1<0);
+        //straddle computation
+        if(Rstrad||Lstrad)
+        {
+            //compute intersection of e with x axis
+            X = ((double)(cx*cy1-cx1*cy))/((double)(cy1-cy));
+            //crosses ray if strictly positive intersection
+            if(Rstrad&&(X>0.0))
+            {
+                Rcross++;
+            }
+            //crosses ray if strictly negative intersection
+            if(Lstrad&&(X<0.0))
+            {
+                Lcross++;
+            }
+        }
+    }
+    //q on the edge if left and right cross are not the same parity
+    if((Rcross%2)!=(Lcross%2))
+    {
+        //el punto está en un borde
+        return GEOC_PTO_BORDE_POLIG;
+    }
+    //q inside if an odd number of crossings
+    if((Rcross%2)==1)
+    {
+        //el punto es interior
+        return GEOC_PTO_DENTRO_POLIG;
+    }
+    else
+    {
+        //el punto es exterior
+        return GEOC_PTO_FUERA_POLIG;
+    }
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligonoVerticeBordeDouble(const double x,
+                                    const double y,
+                                    const double* coorX,
+                                    const double* coorY,
+                                    const size_t N,
+                                    const size_t incX,
+                                    const size_t incY,
+                                    const double factor,
+                                    const int redondeo)
+{
+    //NOTA: SE MANTIENEN LOS COMENTARIOS ORIGINALES DE LA FUNCIÓN PARA VARIABLES
+    //DE TIPO ENTERO
+    //índices de vértices
+    size_t i=0,i1=0;
+    //number of (right,left) edge/ray crossings
+    int Rcross=0,Lcross=0;
+    //flags indicating the edge strads the X axis
+    int Rstrad=0,Lstrad=0;
+    //punto a evaluar pasado a número entero
+    ptopol_long fX=0,fY=0;
+    //coordenadas del polígono referidas al punto de trabajo
+    ptopol_long cx=0,cy=0,cx1=0,cy1=0;
+    //número de elementos de trabajo del polígono
+    size_t n=N;
+    //variable auxiliar
+    double X=0.0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si el primer vértice se repite al final
+    if((coorX[0]==coorX[(N-1)*incX])&&(coorY[0]==coorY[(N-1)*incY]))
+    {
+        //trabajamos con todos los vértices, menos el último
+        n = N-1;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //pasamos a número entero el punto a evaluar
+    if(redondeo)
+    {
+        //redondeo
+        fX = (ptopol_long)(round(factor*x));
+        fY = (ptopol_long)(round(factor*y));
+    }
+    else
+    {
+        //truncamiento
+        fX = (ptopol_long)(factor*x);
+        fY = (ptopol_long)(factor*y);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //for each edge e=(i-1,i), see if crosses ray
+    for(i=0;i<n;i++)
+    {
+        //calculamos el índice del punto anterior en el polígono
+        i1 = (i) ? i-1 : n-1;
+        //para referir los vértices de trabajo al punto, comprobamos si hay que
+        //redondear o truncar
+        if(redondeo)
+        {
+            //redondeo del vértice actual
+            cx = (ptopol_long)(round(factor*coorX[i*incX]))-fX;
+            cy = (ptopol_long)(round(factor*coorY[i*incY]))-fY;
+            //redondeo del vértice anterior
+            cx1 = (ptopol_long)(round(factor*coorX[i1*incX]))-fX;
+            cy1 = (ptopol_long)(round(factor*coorY[i1*incY]))-fY;
+        }
+        else
+        {
+            //truncamiento del vértice actual
+            cx = (ptopol_long)(factor*coorX[i*incX])-fX;
+            cy = (ptopol_long)(factor*coorY[i*incY])-fY;
+            //redondeo del vértice anterior
+            cx1 = (ptopol_long)(factor*coorX[i1*incX])-fX;
+            cy1 = (ptopol_long)(factor*coorY[i1*incY])-fY;
+        }
+        //comprobamos si el punto es un vértice del polígono
+        if((cx==0)&&(cy==0))
+        {
+            //el punto es un vértice
+            return GEOC_PTO_VERTICE_POLIG;
+        }
+        //check if e straddles X axis, with bias above/below
+        Rstrad = (cy>0)!=(cy1>0);
+        Lstrad = (cy<0)!=(cy1<0);
+        //straddle computation
+        if(Rstrad||Lstrad)
+        {
+            //compute intersection of e with x axis
+            X = ((double)(cx*cy1-cx1*cy))/((double)(cy1-cy));
+            //crosses ray if strictly positive intersection
+            if(Rstrad&&(X>0.0))
+            {
+                Rcross++;
+            }
+            //crosses ray if strictly negative intersection
+            if(Lstrad&&(X<0.0))
+            {
+                Lcross++;
+            }
+        }
+    }
+    //q on the edge if left and right cross are not the same parity
+    if((Rcross%2)!=(Lcross%2))
+    {
+        //el punto está en un borde
+        return GEOC_PTO_BORDE_POLIG;
+    }
+    //q inside if an odd number of crossings
+    if((Rcross%2)==1)
+    {
+        //el punto es interior
+        return GEOC_PTO_DENTRO_POLIG;
+    }
+    else
+    {
+        //el punto es exterior
+        return GEOC_PTO_FUERA_POLIG;
+    }
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t* BuscaGeocNanEnVectores(const double* x,
+                               const double* y,
+                               const size_t N,
+                               const size_t incX,
+                               const size_t incY,
+                               size_t* nNan)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //identificadores de NaN
+    int esNanX=0,esNanY=0;
+    //vector de salida
+    size_t* salida=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos a 0 el número de NaN encontrados
+    *nNan = 0;
+    //comprobamos una posible salida rápida
+    if(N==0)
+    {
+        //salimos de la función
+        return salida;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos los elementos de los vectores
+    for(i=0;i<N;i++)
+    {
+        //inicializamos los identificadores de NaN
+        esNanX = 0;
+        esNanY = 0;
+        //comprobamos si el elemento del vector X es NaN
+        if(EsGeocNan(x[i*incX]))
+        {
+            //la X es NaN
+            esNanX = 1;
+            //comprobamos si tenemos vector Y
+            if(y!=NULL)
+            {
+                //comprobamos si el elemento del vector Y es NaN
+                if(EsGeocNan(y[i*incY]))
+                {
+                    //la Y es NaN
+                    esNanY = 1;
+                }
+            }
+        }
+        //comprobamos si hemos encontrado NaN
+        if((esNanX&&(y==NULL))||(esNanX&&esNanY))
+        {
+            //aumentamos el contador de NaN encontrados
+            (*nNan)++;
+            //reasignamos memoria a la salida
+            salida = (size_t*)realloc(salida,(*nNan)*sizeof(size_t));
+            //comprobamos los posibles errores
+            if(salida==NULL)
+            {
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //indicamos la posición del valor NaN
+            salida[(*nNan)-1] = i;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+void DatosPoliIndividualEnVecInd(const size_t* posInd,
+                                 const size_t indPosInd,
+                                 const size_t incX,
+                                 const size_t incY,
+                                 size_t* iniX,
+                                 size_t* iniY,
+                                 size_t* nElem)
+{
+    //posiciones de inicio y final en los vectores de vértices
+    *iniX = (posInd[indPosInd]+1)*incX;
+    *iniY = (posInd[indPosInd]+1)*incY;
+    //número de vértices del polígono
+    *nElem = posInd[indPosInd+1]-posInd[indPosInd]-1;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligonoInd(const double x,
+                     const double y,
+                     const double* coorX,
+                     const double* coorY,
+                     const size_t N,
+                     const size_t incX,
+                     const size_t incY,
+                     const size_t* posNan,
+                     const size_t nNan,
+                     size_t* poli)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //posiciones de inicio de los vértices X e Y
+    size_t iniX=0,iniY=0;
+    //número de elementos del polígono a chequear
+    size_t nElem=0;
+    //variable auxiliar de situación de punto
+    int posAux=0;
+    //variable indicadora de continuación de chequeos
+    size_t continuar=1;
+    //variable de salida
+    int pos=GEOC_PTO_FUERA_POLIG;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el polígono que contiene al punto
+    *poli = 0;
+    //comprobamos si hay valores NaN
+    if(nNan)
+    {
+        //paralelización con OpenMP
+        //utilizo schedule(dynamic) para que los polígonos vayan siendo
+        //chequeados uno a uno según los hilos de ejecución van quedándose
+        //libres
+        //hago esto porque es muy probable que los polígonos vengan listados de
+        //mayor a menor número de vértices y así se podrá trabajar con varios
+        //polígonos pequeños mientras se testea uno grande
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) schedule(dynamic) \
+ shared(continuar,posNan,coorX,coorY,pos,poli) \
+ private(i,iniX,iniY,nElem,posAux)
+#endif
+        //recorremos desde el primer NaN hasta el penúltimo
+        for(i=0;i<(nNan-1);i++)
+        {
+            //hacemos que todos los hilos vean la variable continuar actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+            //comprobamos si hay que continuar chequeando polígonos
+            if(continuar)
+            {
+                //extraemos los datos de definición del polígono
+                DatosPoliIndividualEnVecInd(posNan,i,incX,incY,&iniX,&iniY,
+                                            &nElem);
+                //comprobamos la inclusión para el polígono de trabajo
+                posAux = PtoEnPoligono(x,y,&coorX[iniX],&coorY[iniY],nElem,incX,
+                                       incY);
+                //me aseguro de que las variables involucradas sean actualizadas
+                //por un hilo cada vez, sin posibilidad de modificación por
+                //varios al mismo tiempo
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+{
+                //si el punto no está fuera, no se han de hacer más operaciones
+                //el continuar==1 asegura que nos quedemos con el primer
+                //polígono en que está incluido el punto, ya que una vez que el
+                //hilo con punto encontrado actualice la variable continuar, el
+                //resto con posibles resultados positivos no pasarán este if()
+                if((continuar==1)&&(posAux!=GEOC_PTO_FUERA_POLIG))
+                {
+                    //asignamos la variable de salida
+                    pos = posAux;
+                    //asignamos el polígono que contiene al punto
+                    *poli = i;
+                    //indicamos que no hay que continuar haciendo pruebas
+                    //esta variable se usa para el caso de ejecución en paralelo
+                    continuar = 0;
+                    //hacemos que todos los hilos vean la variable continuar
+                    //actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+                }
+}
+            }
+        } // --> fin del #pragma omp parallel for
+    }
+    else
+    {
+        //hacemos una comprobación normal
+        pos = PtoEnPoligono(x,y,coorX,coorY,N,incX,incY);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return pos;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligonoVerticeInd(const double x,
+                            const double y,
+                            const double* coorX,
+                            const double* coorY,
+                            const size_t N,
+                            const size_t incX,
+                            const size_t incY,
+                            const size_t* posNan,
+                            const size_t nNan,
+                            size_t* poli)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //posiciones de inicio de los vértices X e Y
+    size_t iniX=0,iniY=0;
+    //número de elementos del polígono a chequear
+    size_t nElem=0;
+    //variable auxiliar de situación de punto
+    int posAux=0;
+    //variable indicadora de continuación de chequeos
+    size_t continuar=1;
+    //variable de salida
+    int pos=GEOC_PTO_FUERA_POLIG;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el polígono que contiene al punto
+    *poli = 0;
+    //comprobamos si hay valores NaN
+    if(nNan)
+    {
+        //paralelización con OpenMP
+        //utilizo schedule(dynamic) para que los polígonos vayan siendo
+        //chequeados uno a uno según los hilos de ejecución van quedándose
+        //libres
+        //hago esto porque es muy probable que los polígonos vengan listados de
+        //mayor a menor número de vértices y así se podrá trabajar con varios
+        //polígonos pequeños mientras se testea uno grande
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) schedule(dynamic) \
+ shared(continuar,posNan,coorX,coorY,pos,poli) \
+ private(i,iniX,iniY,nElem,posAux)
+#endif
+        //recorremos desde el primer NaN hasta el penúltimo
+        for(i=0;i<(nNan-1);i++)
+        {
+            //hacemos que todos los hilos vean la variable continuar actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+            //comprobamos si hay que continuar chequeando polígonos
+            if(continuar)
+            {
+                //extraemos los datos de definición del polígono
+                DatosPoliIndividualEnVecInd(posNan,i,incX,incY,&iniX,&iniY,
+                                            &nElem);
+                //comprobamos la inclusión para el polígono de trabajo
+                posAux = PtoEnPoligonoVertice(x,y,&coorX[iniX],&coorY[iniY],
+                                              nElem,incX,incY);
+                //me aseguro de que las variables involucradas sean actualizadas
+                //por un hilo cada vez, sin posibilidad de modificación por
+                //varios al mismo tiempo
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+{
+                //si el punto no está fuera, no se han de hacer más operaciones
+                //el continuar==1 asegura que nos quedemos con el primer
+                //polígono en que está incluido el punto, ya que una vez que el
+                //hilo con punto encontrado actualice la variable continuar, el
+                //resto con posibles resultados positivos no pasarán este if()
+                if((continuar==1)&&(posAux!=GEOC_PTO_FUERA_POLIG))
+                {
+                    //asignamos la variable de salida
+                    pos = posAux;
+                    //asignamos el polígono que contiene al punto
+                    *poli = i;
+                    //indicamos que no hay que continuar haciendo pruebas
+                    //esta variable se usa para el caso de ejecución en paralelo
+                    continuar = 0;
+                    //hacemos que todos los hilos vean la variable continuar
+                    //actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+                }
+}
+            }
+        } // --> fin del #pragma omp parallel for
+    }
+    else
+    {
+        //hacemos una comprobación normal
+        pos = PtoEnPoligonoVertice(x,y,coorX,coorY,N,incX,incY);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return pos;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligonoVerticeBordeInd(const long x,
+                                 const long y,
+                                 const long* coorX,
+                                 const long* coorY,
+                                 const size_t N,
+                                 const size_t incX,
+                                 const size_t incY,
+                                 const size_t* posNan,
+                                 const size_t nNan,
+                                 size_t* poli)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //posiciones de inicio de los vértices X e Y
+    size_t iniX=0,iniY=0;
+    //número de elementos del polígono a chequear
+    size_t nElem=0;
+    //variable auxiliar de situación de punto
+    int posAux=0;
+    //variable indicadora de continuación de chequeos
+    size_t continuar=1;
+    //variable de salida
+    int pos=GEOC_PTO_FUERA_POLIG;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el polígono que contiene al punto
+    *poli = 0;
+    //comprobamos si hay valores NaN
+    if(nNan)
+    {
+        //paralelización con OpenMP
+        //utilizo schedule(dynamic) para que los polígonos vayan siendo
+        //chequeados uno a uno según los hilos de ejecución van quedándose
+        //libres
+        //hago esto porque es muy probable que los polígonos vengan listados de
+        //mayor a menor número de vértices y así se podrá trabajar con varios
+        //polígonos pequeños mientras se testea uno grande
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) schedule(dynamic) \
+ shared(continuar,posNan,coorX,coorY,pos,poli) \
+ private(i,iniX,iniY,nElem,posAux)
+#endif
+        //recorremos desde el primer NaN hasta el penúltimo
+        for(i=0;i<(nNan-1);i++)
+        {
+            //hacemos que todos los hilos vean la variable continuar actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+            //comprobamos si hay que continuar chequeando polígonos
+            if(continuar)
+            {
+                //extraemos los datos de definición del polígono
+                DatosPoliIndividualEnVecInd(posNan,i,incX,incY,&iniX,&iniY,
+                                            &nElem);
+                //comprobamos la inclusión para el polígono de trabajo
+                posAux = PtoEnPoligonoVerticeBorde(x,y,&coorX[iniX],
+                                                   &coorY[iniY],nElem,incX,
+                                                   incY);
+                //me aseguro de que las variables involucradas sean actualizadas
+                //por un hilo cada vez, sin posibilidad de modificación por
+                //varios al mismo tiempo
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+{
+                //si el punto no está fuera, no se han de hacer más operaciones
+                //el continuar==1 asegura que nos quedemos con el primer
+                //polígono en que está incluido el punto, ya que una vez que el
+                //hilo con punto encontrado actualice la variable continuar, el
+                //resto con posibles resultados positivos no pasarán este if()
+                if((continuar==1)&&(posAux!=GEOC_PTO_FUERA_POLIG))
+                {
+                    //asignamos la variable de salida
+                    pos = posAux;
+                    //asignamos el polígono que contiene al punto
+                    *poli = i;
+                    //indicamos que no hay que continuar haciendo pruebas
+                    //esta variable se usa para el caso de ejecución en paralelo
+                    continuar = 0;
+                    //hacemos que todos los hilos vean la variable continuar
+                    //actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+                }
+}
+            }
+        } // --> fin del #pragma omp parallel for
+    }
+    else
+    {
+        //hacemos una comprobación normal
+        pos = PtoEnPoligonoVerticeBorde(x,y,coorX,coorY,N,incX,incY);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return pos;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoEnPoligonoVerticeBordeDoubleInd(const double x,
+                                       const double y,
+                                       const double* coorX,
+                                       const double* coorY,
+                                       const size_t N,
+                                       const size_t incX,
+                                       const size_t incY,
+                                       const double factor,
+                                       const int redondeo,
+                                       const size_t* posNan,
+                                       const size_t nNan,
+                                       size_t* poli)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //posiciones de inicio de los vértices X e Y
+    size_t iniX=0,iniY=0;
+    //número de elementos del polígono a chequear
+    size_t nElem=0;
+    //variable auxiliar de situación de punto
+    int posAux=0;
+    //variable indicadora de continuación de chequeos
+    size_t continuar=1;
+    //variable de salida
+    int pos=GEOC_PTO_FUERA_POLIG;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el polígono que contiene al punto
+    *poli = 0;
+    //comprobamos si hay valores NaN
+    if(nNan)
+    {
+        //paralelización con OpenMP
+        //utilizo schedule(dynamic) para que los polígonos vayan siendo
+        //chequeados uno a uno según los hilos de ejecución van quedándose
+        //libres
+        //hago esto porque es muy probable que los polígonos vengan listados de
+        //mayor a menor número de vértices y así se podrá trabajar con varios
+        //polígonos pequeños mientras se testea uno grande
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) schedule(dynamic) \
+ shared(continuar,posNan,coorX,coorY,pos,poli) \
+ private(i,iniX,iniY,nElem,posAux)
+#endif
+        //recorremos desde el primer NaN hasta el penúltimo
+        for(i=0;i<(nNan-1);i++)
+        {
+            //hacemos que todos los hilos vean la variable continuar actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+            //comprobamos si hay que continuar chequeando polígonos
+            if(continuar)
+            {
+                //extraemos los datos de definición del polígono
+                DatosPoliIndividualEnVecInd(posNan,i,incX,incY,&iniX,&iniY,
+                                            &nElem);
+                //comprobamos la inclusión para el polígono de trabajo
+                posAux = PtoEnPoligonoVerticeBordeDouble(x,y,&coorX[iniX],
+                                                         &coorY[iniY],nElem,
+                                                         incX,incY,factor,
+                                                         redondeo);
+                //me aseguro de que las variables involucradas sean actualizadas
+                //por un hilo cada vez, sin posibilidad de modificación por
+                //varios al mismo tiempo
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+{
+                //si el punto no está fuera, no se han de hacer más operaciones
+                //el continuar==1 asegura que nos quedemos con el primer
+                //polígono en que está incluido el punto, ya que una vez que el
+                //hilo con punto encontrado actualice la variable continuar, el
+                //resto con posibles resultados positivos no pasarán este if()
+                if((continuar==1)&&(posAux!=GEOC_PTO_FUERA_POLIG))
+                {
+                    //asignamos la variable de salida
+                    pos = posAux;
+                    //asignamos el polígono que contiene al punto
+                    *poli = i;
+                    //indicamos que no hay que continuar haciendo pruebas
+                    //esta variable se usa para el caso de ejecución en paralelo
+                    continuar = 0;
+                    //hacemos que todos los hilos vean la variable continuar
+                    //actualizada
+#if defined(_OPENMP)
+#pragma omp flush(continuar)
+#endif
+                }
+}
+            }
+        } // --> fin del #pragma omp parallel for
+    }
+    else
+    {
+        //hacemos una comprobación normal
+        pos = PtoEnPoligonoVerticeBordeDouble(x,y,coorX,coorY,N,incX,incY,
+                                              factor,redondeo);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return pos;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/recpolil.c b/src/recpolil.c
new file mode 100755
index 0000000..c7ba145
--- /dev/null
+++ b/src/recpolil.c
@@ -0,0 +1,1402 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom gshhs
+@{
+\file recpolil.c
+\brief Definición funciones para el recorte de polilíneas por medio de
+       polígonos.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 05 de junio de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/recpolil.h"
+/******************************************************************************/
+/******************************************************************************/
+vertPolilClip* CreaVertPolilClip(const double x,
+                                 const double y,
+                                 vertPolilClip* anterior,
+                                 vertPolilClip* siguiente,
+                                 const char orig,
+                                 const char pos,
+                                 const double alfa)
+{
+    //variable de salida (nuevo vértice)
+    vertPolilClip* nuevoVert=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos memoria para el nuevo vértice
+    nuevoVert = (vertPolilClip*)malloc(sizeof(vertPolilClip));
+    //comprobamos los posibles errores
+    if(nuevoVert==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos los vértices anterior y posterior
+    nuevoVert->anterior = anterior;
+    nuevoVert->siguiente = siguiente;
+    //si anterior es un vértice bueno
+    if(anterior!=NULL)
+    {
+        //lo apuntamos al vértice creado
+        nuevoVert->anterior->siguiente = nuevoVert;
+    }
+    //si siguiente es un vértice bueno
+    if(siguiente!=NULL)
+    {
+        //indicamos que el vértice creado es el anterior
+        nuevoVert->siguiente->anterior = nuevoVert;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos el resto de campos
+    nuevoVert->x = x;
+    nuevoVert->y = y;
+    nuevoVert->orig = orig;
+    nuevoVert->pos = pos;
+    nuevoVert->alfa = alfa;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return nuevoVert;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPolilClip* CreaPolilClip(const double* x,
+                             const double* y,
+                             const size_t nCoor,
+                             const size_t incX,
+                             const size_t incY)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //variable auxiliar de posición
+    size_t posIni=0;
+    //otra variable auxiliar
+    int hayVert=0;
+    //estructura auxiliar
+    vertPolilClip* aux=NULL;
+    //variable de salida
+    vertPolilClip* poli=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //buscamos el primer punto que sea distinto de NaN
+    for(i=0;i<nCoor;i++)
+    {
+        //comprobamos si el elemento es distinto de NaN
+        if((!EsGeocNan(x[i*incX]))&&(!EsGeocNan(y[i*incY])))
+        {
+            //indicamos que sí hay vértices de trabajo
+            hayVert = 1;
+            //guardamos la posición de este elemento
+            posIni = i;
+            //salimos del bucle
+            break;
+        }
+    }
+    //si no hay ningún vértice distinto de NaN
+    if(!hayVert)
+    {
+        //salimos de la función
+        return poli;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el primer elemento (indicamos que está fuera del polígono
+    //que recortará a la polilínea, ya que el valor verdadero de pos se indicará
+    //en otra función)
+    poli = CreaVertPolilClip(x[posIni*incX],y[posIni*incY],NULL,NULL,1,0,0.0);
+    //comprobamos los posibles errores
+    if(poli==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    //asignamos el elemento creado a la variable auxiliar
+    aux = poli;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos los puntos de trabajo
+    for(i=(posIni+1);i<nCoor;i++)
+    {
+        //comprobamos si el elemento es distinto de NaN
+        if((!EsGeocNan(x[i*incX]))&&(!EsGeocNan(y[i*incY])))
+        {
+            //vamos añadiendo vértices al final (seguimos indicando que están
+            //fuera del polígono que recortará a la polilínea)
+            aux = CreaVertPolilClip(x[i*incX],y[i*incY],aux,NULL,1,0,0.0);
+            //comprobamos los posibles errores
+            if(aux==NULL)
+            {
+                //liberamos la memoria asignada hasta ahora
+                LibMemPolilClip(poli);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return poli;
+}
+/******************************************************************************/
+/******************************************************************************/
+void LibMemPolilClip(vertPolilClip* poli)
+{
+    //estructura auxiliar
+    vertPolilClip* aux=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //trabajamos mientras quede memoria
+    while(poli!=NULL)
+    {
+        //apuntamos con la estructura auxiliar hacia la memoria a liberar
+        aux = poli;
+        //apuntamos con la estructura principal al siguiente vértice
+        poli = poli->siguiente;
+        //liberamos la memoria
+        free(aux);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPolilClip* ReiniciaPolilClip(vertPolilClip* poli)
+{
+    //estructura que apunta al espacio en memoria a liberar
+    vertPolilClip* borra=NULL;
+    //estructura auxiliar
+    vertPolilClip* aux=NULL;
+    //estructura de salida
+    vertPolilClip* sal=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar
+    aux = poli;
+    //comprobamos una posible salida rápida
+    if(aux==NULL)
+    {
+        //salimos de la función
+        return NULL;
+    }
+    //buscamos para la estructura de salida el primer vértice original
+    while(aux!=NULL)
+    {
+        //comprobamos si estamos ante un vértice bueno
+        if(aux->orig)
+        {
+            //asignamos la variable de salida
+            sal = aux;
+            //salimos del bucle
+            break;
+        }
+        //siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //volvemos a inicializar la variable auxiliar
+    aux = poli;
+    //mientras la variable de trabajo no apunte a NULL
+    while(aux!=NULL)
+    {
+        //comprobamos si estamos ante un vértice a borrar
+        if(aux->orig==0)
+        {
+            //lo almacenamos en la estructura de borrado
+            borra = aux;
+            //actualizamos el puntero de vértice siguiente
+            if(aux->anterior!=NULL)
+            {
+                //cuando el vértice a borrar no es el primero de la lista
+                aux->anterior->siguiente = aux->siguiente;
+            }
+            else if(aux->siguiente!=NULL)
+            {
+                //cuando el vértice a borrar es el primero de la lista
+                aux->siguiente->anterior = NULL;
+            }
+            //actualizamos el puntero de vértice anterior
+            if(aux->siguiente!=NULL)
+            {
+                //cuando el vértice a borrar no es el último de la lista
+                aux->siguiente->anterior = aux->anterior;
+            }
+            else if(aux->anterior!=NULL)
+            {
+                //cuando el vértice a borrar es el último de la lista
+                aux->anterior->siguiente = NULL;
+            }
+            //apuntamos al siguiente elemento
+            aux = aux->siguiente;
+            //liberamos la memoria
+            free(borra);
+        }
+        else
+        {
+            //reinicializamos el resto de miembros, menos las coordenadas
+            //originales y el identificador de vértice original
+            aux->pos = GEOC_PTO_FUERA_POLIG;
+            aux->alfa = 0.0;
+            //siguiente elemento
+            aux = aux->siguiente;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+vertPolilClip* SiguienteVertOrigPolilClip(vertPolilClip* vert)
+{
+    //variable de salida, que inicializamos con la dirección de entrada
+    vertPolilClip* sal=vert;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //si estamos ante un vértice original, pasamos al siguiente
+    if((sal!=NULL)&&sal->orig)
+    {
+        //apuntamos al siguiente vértice
+        sal = sal->siguiente;
+    }
+    //vamos rechazando vérties no originales (el bucle se para cuando llegamos
+    //al final o a un vértice que no es original)
+    while((sal!=NULL)&&(sal->orig==0))
+    {
+        //pasamos al siguiente vértice
+        sal = sal->siguiente;
+    }
+    //si hemos llegado a un vértice que no es original, apuntamos a NULL
+    if((sal!=NULL)&&(sal->orig==0))
+    {
+        //asignamos NULL
+        sal = NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return sal;
+}
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+void InsertaVertPolilClip(vertPolilClip* ins,
+                          vertPolilClip* extremoIni,
+                          vertPolilClip* extremoFin)
+{
+    //estructura auxiliar
+    vertPolilClip* aux=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el vértice auxiliar como el extremo inicial pasado
+    aux = extremoIni;
+    //mientras no lleguemos al extremo final y el punto a insertar esté más
+    //lejos del origen que el punto de trabajo
+    while((aux!=extremoFin)&&((aux->alfa)<=(ins->alfa)))
+    {
+        //avanzamos al siguiente vértice
+        aux = aux->siguiente;
+    }
+    //insertamos el punto y ordenamos los punteros de vértices anterior y
+    //posterior
+    ins->siguiente = aux;
+    ins->anterior = aux->anterior;
+    ins->anterior->siguiente = ins;
+    ins->siguiente->anterior = ins;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t NumeroVertOrigPolilClip(vertPolilClip* poli)
+{
+    //estructura auxiliar
+    vertPolilClip* aux=NULL;
+    //variable de salida
+    size_t num=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar con la dirección de entrada
+    aux = poli;
+    //comprobamos si estamos ante un vértice original
+    if(aux->orig)
+    {
+        //si no es un vértice original, nos posicionamos en el siguiente que sí
+        //lo sea
+        aux = SiguienteVertOrigPolilClip(aux);
+    }
+    //mientras no lleguemos al final
+    while(aux!=NULL)
+    {
+        //aumentamos el contador de vértices originales
+        num++;
+        //nos posicionamos en el siguiente vértice original
+        aux = SiguienteVertOrigPolilClip(aux);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return num;
+}
+/******************************************************************************/
+/******************************************************************************/
+size_t NumeroVertPolilClip(vertPolilClip* poli)
+{
+    //estructura auxiliar
+    vertPolilClip* aux=NULL;
+    //variable de salida
+    size_t num=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar con la dirección de entrada
+    aux = poli;
+    //mientras no lleguemos al final
+    while(aux!=NULL)
+    {
+        //aumentamos el contador de vértices
+        num++;
+        //nos posicionamos en el siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return num;
+}
+/******************************************************************************/
+/******************************************************************************/
+int Paso1Recpolil(vertPolilClip* poli,
+                  vertPoliClip* poliRec,
+                  size_t* nIntersec)
+{
+    //estructuras auxiliares que apuntan a los elementos pasados
+    vertPolilClip* auxA=NULL;
+    vertPoliClip* auxC=NULL;
+    //estructuras auxiliares para trabajar con el siguiente vértice
+    vertPolilClip* auxB=NULL;
+    vertPoliClip* auxD=NULL;
+    //vértices de intersección a insertar
+    vertPolilClip* insPolil=NULL;
+    //coordenadas de la intersección de dos segmentos
+    double xI=0.0,yI=0.0;
+    //longitud de segmento y parámetro alfa
+    double lon=0.0,alfa=0.0;
+    //código de intersección de segmentos
+    int intersec=0;
+    //variable auxiliar
+    int nuevoPunto=0;
+    //variable de salida
+    int salida=GEOC_ERR_NO_ERROR;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el número de intersecciones a 0
+    *nIntersec = 0;
+    //EL PRIMER PASO DEL ALGORITMO DE RECORTE DE POLILÍNEAS ES EL CÁLCULO DE
+    //TODOS LOS PUNTOS DE INTERSECCIÓN ENTRE LOS POLÍGONOS
+    //recorremos los vértices de la polilínea
+    for(auxA=poli;auxA->siguiente!=NULL;auxA=auxA->siguiente)
+    {
+        //sólo trabajamos si el vértice es original
+        if(auxA->orig)
+        {
+            //recorremos los vértices del polígono de recorte
+            for(auxC=poliRec;auxC->siguiente!=NULL;auxC=auxC->siguiente)
+            {
+                //sólo trabajamos si el vértice es original (esto hace que
+                //podamos trabajar con un polígono proveniente de una operación
+                //booleana previa entre polígonos
+                if(auxC->interseccion==0)
+                {
+                    //siguiente vértice de los segmentos
+                    auxB = SiguienteVertOrigPolilClip(auxA);
+                    auxD = SiguienteVertOrigPoliClip(auxC);
+                    //calculamos la intersección de los segmentos
+                    intersec = IntersecSegmentos2D(auxA->x,auxA->y,auxB->x,
+                                                   auxB->y,auxC->x,auxC->y,
+                                                   auxD->x,auxD->y,&xI,&yI);
+                    //comprobamos la posición relativa del primer punto del
+                    //segmento de la polilínea con respecto al polígono
+                    //esta función sólo marca dentro o fuera
+                    auxA->pos = (char)PtoEnPoliClip(auxA->x,auxA->y,poliRec);
+                    //comprobamos si el segmento de la polilínea contiene al
+                    //último punto de ésta, por lo que el bucle se acabará aquí
+                    if(auxB->siguiente==NULL)
+                    {
+                        //comprobamos la posición relativa del último punto
+                        auxB->pos = (char)PtoEnPoliClip(auxB->x,auxB->y,
+                                                        poliRec);
+                    }
+                    //comprobamos si hay que aumentar el contador de
+                    //intersecciones
+                    if(intersec!=GEOC_SEG_NO_INTERSEC)
+                    {
+                        //aumentamos el contador de intersecciones
+                        (*nIntersec)++;
+                    }
+                    //comprobamos el tipo de intersección
+                    if(intersec==GEOC_SEG_INTERSEC)
+                    {
+                        //INTERSECCIÓN LIMPIA
+                        //calculamos la longitud del segmento de la polilínea
+                        lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y);
+                        //calculamos los parámetros alfa
+                        alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon;
+                        //creamos el nuevo vértice a insertar
+                        insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0,
+                                                     (char)GEOC_PTO_BORDE_POLIG,
+                                                     alfa);
+                        //comprobamos los posibles errores
+                        if(insPolil==NULL)
+                        {
+                            //mensaje de error
+                            GEOC_ERROR("Error de asignación de memoria");
+                            //salimos de la función
+                            return GEOC_ERR_ASIG_MEMORIA;
+                        }
+                        //añadimos el punto de intersección
+                        InsertaVertPolilClip(insPolil,auxA,auxB);
+                    }
+                    else if(intersec==GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN)
+                    {
+                        //EL EXTREMO DE UN SEGMENTO TOCA AL OTRO SEGMENTO, PERO
+                        //LOS SEGMENTOS NO SON COLINEALES
+                        //comprobamos si el extremo que toca es el inicial del
+                        //segmento de la polilínea
+                        if((xI==auxA->x)&&(yI==auxA->y))
+                        {
+                            //el primer punto del segmento está en el borde
+                            auxA->pos = (char)GEOC_PTO_BORDE_POLIG;
+                        }
+                        else if((xI!=auxB->x)||(yI!=auxB->y))
+                        {
+                            //el extremo que toca es del segmento del polígono y
+                            //no toca al punto final del segmento de la
+                            //polilínea
+                            //calculamos la longitud del segmento de la
+                            //polilínea
+                            lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y);
+                            //calculamos los parámetros alfa
+                            alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon;
+                            //creamos el nuevo vértice a insertar
+                            insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0,
+                                                     (char)GEOC_PTO_BORDE_POLIG,
+                                                         alfa);
+                            //comprobamos los posibles errores
+                            if(insPolil==NULL)
+                            {
+                                //mensaje de error
+                                GEOC_ERROR("Error de asignación de memoria");
+                                //salimos de la función
+                                return GEOC_ERR_ASIG_MEMORIA;
+                            }
+                            //añadimos el punto de intersección
+                            InsertaVertPolilClip(insPolil,auxA,auxB);
+                        }
+                        else
+                        {
+                            //comprobamos si estamos ante el segmento que
+                            //contiene al último punto de la polilínea
+                            if(auxB->siguiente==NULL)
+                            {
+                                //el último punto del segmento está en el borde
+                                auxB->pos = (char)GEOC_PTO_BORDE_POLIG;
+                            }
+                            else
+                            {
+                                //disminuimos el contador de intersecciones, ya
+                                //que esta se detectará en la siguiente vuelta
+                                //del bucle
+                                (*nIntersec)--;
+                            }
+                        }
+                    }
+                    else if(intersec==GEOC_SEG_INTERSEC_EXTREMO_COLIN)
+                    {
+                        //LOS SEGMENTOS SON COLINEALES PERO SÓLO SE TOCAN EN EL
+                        //EXTREMO
+                        //comprobamos si el extremo que toca es el primero
+                        if((xI==auxA->x)&&(yI==auxA->y))
+                        {
+                            //el primer punto del segmento está en el borde
+                            auxA->pos = (char)GEOC_PTO_BORDE_POLIG;
+                        }
+                        else
+                        {
+                            //comprobamos si estamos ante el segmento que
+                            //contiene al último punto de la polilínea
+                            if(auxB->siguiente==NULL)
+                            {
+                                //el último punto del segmento está en el borde
+                                auxB->pos = (char)GEOC_PTO_BORDE_POLIG;
+                            }
+                            else
+                            {
+                                //disminuimos el contador de intersecciones, ya
+                                //que esta se detectará en la siguiente vuelta
+                                //del bucle
+                                (*nIntersec)--;
+                            }
+                        }
+                    }
+                    else if(intersec==GEOC_SEG_INTERSEC_MISMO_SEG)
+                    {
+                        //AMBOS SEGMENTOS SON EL MISMO
+                        //el primer punto del segmento está en el borde
+                        auxA->pos = (char)GEOC_PTO_BORDE_POLIG;
+                        //comprobamos si estamos ante el segmento que contiene
+                        //al último punto de la polilínea
+                        if(auxB->siguiente==NULL)
+                        {
+                            //aumentamos el contador de intersecciones
+                            (*nIntersec)++;
+                            //el último punto del segmento está en el borde
+                            auxB->pos = (char)GEOC_PTO_BORDE_POLIG;
+                        }
+                    }
+                    else if(intersec==GEOC_SEG_INTERSEC_COLIN)
+                    {
+                        //LOS SEGMENTOS TIENEN MÁS DE UN PUNTO EN COMÚN, PERO NO
+                        //SON EL MISMO
+                        //comprobamos si el extremo inicial está tocando el
+                        //polígono o no
+                        if((xI==auxA->x)&&(yI==auxA->y))
+                        {
+                            //el primer punto del segmento está en el borde
+                            auxA->pos = (char)GEOC_PTO_BORDE_POLIG;
+                            //identificador de nuevo punto
+                            nuevoPunto = 0;
+                            //comprobamos si alguno de los extremos del segmento
+                            //del polígono está dentro del segmento de la
+                            //polilínea
+                            if(PuntoEntreDosPuntos2DColin(auxC->x,auxC->y,
+                                                          auxA->x,auxA->y,
+                                                          auxB->x,auxB->y))
+                            {
+                                //nuevo punto
+                                nuevoPunto = 1;
+                                //coordenadas del punto intersección
+                                xI = auxC->x;
+                                yI = auxC->y;
+                            }
+                            else if(PuntoEntreDosPuntos2DColin(auxD->x,auxD->y,
+                                                               auxA->x,auxA->y,
+                                                               auxB->x,auxB->y))
+                            {
+                                //nuevo punto
+                                nuevoPunto = 1;
+                                //coordenadas del punto intersección
+                                xI = auxD->x;
+                                yI = auxD->y;
+                            }
+                            //comprobamos si hay que añadir el nuevo punto
+                            if(nuevoPunto)
+                            {
+                                //aumentamos el contador de intersecciones
+                                (*nIntersec)++;
+                                //calculamos la longitud del segmento de la
+                                //polilínea
+                                lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y);
+                                //calculamos los parámetros alfa
+                                alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon;
+                                //creamos el nuevo vértice a insertar
+                                insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0,
+                                                     (char)GEOC_PTO_BORDE_POLIG,
+                                                            alfa);
+                                //comprobamos los posibles errores
+                                if(insPolil==NULL)
+                                {
+                                    //mensaje de error
+                                    GEOC_ERROR("Error de asignación de memoria");
+                                    //salimos de la función
+                                    return GEOC_ERR_ASIG_MEMORIA;
+                                }
+                                //añadimos el punto de intersección
+                                InsertaVertPolilClip(insPolil,auxA,auxB);
+                            }
+                            //comprobamos si estamos ante el segmento que
+                            //contiene al último punto de la polilínea
+                            if(auxB->siguiente==NULL)
+                            {
+                                //comprobamos si el último punto del segmento
+                                //de la polilínea está contenido en el segmento
+                                //del polígono
+                                if(PuntoEntreDosPuntos2DColin(auxB->x,auxB->y,
+                                                              auxC->x,auxC->y,
+                                                              auxD->x,auxD->y))
+                                {
+                                    //aumentamos el contador de intersecciones
+                                    (*nIntersec)++;
+                                    //indicamos que el último punto del segmento
+                                    //de la polilínea está en el borde
+                                    auxB->pos = (char)GEOC_PTO_BORDE_POLIG;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            //comprobamos si el vértice a añadir es el extremo
+                            //final del segmento del polígono (la función
+                            //devuelve las coordenadas del extremo final del
+                            //segmento de la polilínea
+                            if((xI==auxB->x)&&(yI==auxB->y))
+                            {
+                                //asignamos las coordenadas de salida correctas
+                                xI = auxD->x;
+                                yI = auxD->y;
+                            }
+                            //calculamos la longitud del segmento de la
+                            //polilínea
+                            lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y);
+                            //calculamos los parámetros alfa
+                            alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon;
+                            //creamos el nuevo vértice a insertar
+                            insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0,
+                                                     (char)GEOC_PTO_BORDE_POLIG,
+                                                         alfa);
+                            //comprobamos los posibles errores
+                            if(insPolil==NULL)
+                            {
+                                //mensaje de error
+                                GEOC_ERROR("Error de asignación de memoria");
+                                //salimos de la función
+                                return GEOC_ERR_ASIG_MEMORIA;
+                            }
+                            //añadimos el punto de intersección
+                            InsertaVertPolilClip(insPolil,auxA,auxB);
+                            //comprobamos si estamos ante el segmento que
+                            //contiene al último punto de la polilínea
+                            if(auxB->siguiente==NULL)
+                            {
+                                //aumentamos el contador de intersecciones
+                                (*nIntersec)++;
+                                //indicamos que el último punto del segmento de
+                                //la polilínea está en el borde
+                                auxB->pos = (char)GEOC_PTO_BORDE_POLIG;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+polil* Paso2Recpolil(vertPolilClip* poli,
+                     const enum GEOC_OP_BOOL_POLIL op)
+{
+    //estructura auxiliar
+    vertPolilClip* aux=NULL;
+    //vectores de coordenadas de los vértices del resultado
+    double* x=NULL;
+    double* y=NULL;
+    //número de elementos de los vectores x e y
+    size_t nPtos=0;
+    //número de elementos para los que ha sido asignada memoria
+    size_t nElem=0;
+    //variable de estado
+    int estado=GEOC_ERR_NO_ERROR;
+    //polilínea de salida
+    polil* resultado=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //chequeamos una posible salida rápida porque la polilínea sea NULL
+    if(poli==NULL)
+    {
+        //creamos la estructura vacía
+        resultado = IniciaPolilVacia();
+        //comprobamos los posibles errores
+        if(resultado==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //salimos de la función
+        return resultado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la estructura auxiliar con la dirección de entrada
+    aux = poli;
+    //distinguimos entre las dos operaciones
+    //por defecto, recorte
+    if(op!=GeocOpBoolFuera)
+    {
+        //vamos recorriendo vértices de la polilínea
+        do
+        {
+            //comprobamos si el vértice es del borde o de dentro del polígono
+            if(aux->pos==GEOC_PTO_DENTRO_POLIG)
+            {
+                //un punto de dentro del polígono siempre pertenece a la
+                //polilínea recortada
+                //no hace falta asignar los elementos NaN de separación de
+                //polilíneas, que ya se añaden cuando de trabaja con un punto de
+                //borde
+                //aumentamos el número de elementos almacenados en los vectores
+                //de coordenadas
+                nPtos++;
+                //comprobamos si hay que reasignar memoria
+                if(nPtos>nElem)
+                {
+                    //aumentamos el número de elementos
+                    nElem += GEOC_RECPOLIL_BUFFER_PTOS;
+                    //reasignamos memoria
+                    x = (double*)realloc(x,nElem*sizeof(double));
+                    y = (double*)realloc(y,nElem*sizeof(double));
+                    //comprobamos los posibles errores
+                    if((x==NULL)||(y==NULL))
+                    {
+                        //liberamos la posible memoria asignada
+                        free(x);
+                        free(y);
+                        //mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                }
+                //asignamos las coordenadas del vértice
+                x[nPtos-1] = aux->x;
+                y[nPtos-1] = aux->y;
+            }
+            else if(aux->pos==GEOC_PTO_BORDE_POLIG)
+            {
+                //comprobamos la situación de los vértices anterior y siguiente
+                //para la posible reasignación de memoria
+                if((aux->anterior==NULL)||(aux->siguiente==NULL)||
+                   (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)||
+                   (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //este es un vértice de comienzo o fin de una polilínea, por
+                    //lo que necesitamos memoria para las coordenadas y el
+                    //marcador NaN
+                    nPtos += 2;
+                }
+                else
+                {
+                    //este vértice pertenece al interior del polígono
+                    nPtos++;
+                }
+                //comprobamos si hay que reasignar memoria
+                if(nPtos>nElem)
+                {
+                    //aumentamos el número de elementos
+                    nElem += GEOC_RECPOLIL_BUFFER_PTOS;
+                    //reasignamos memoria
+                    x = (double*)realloc(x,nElem*sizeof(double));
+                    y = (double*)realloc(y,nElem*sizeof(double));
+                    //comprobamos los posibles errores
+                    if((x==NULL)||(y==NULL))
+                    {
+                        //liberamos la posible memoria asignada
+                        free(x);
+                        free(y);
+                        //mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                }
+                //comprobamos de nuevo la situación de los vértices anterior y
+                //posterior
+                if((aux->anterior==NULL)||
+                   (aux->anterior->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //el vértice es inicio de polilínea
+                    //asignamos los valores NaN de separación
+                    x[nPtos-2] = GeocNan();
+                    y[nPtos-2] = GeocNan();
+                    //asignamos las coordenadas del vértice
+                    x[nPtos-1] = aux->x;
+                    y[nPtos-1] = aux->y;
+                }
+                else if((aux->siguiente==NULL)||
+                        (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //el vértice es final de polilínea
+                    //asignamos las coordenadas del vértice
+                    x[nPtos-2] = aux->x;
+                    y[nPtos-2] = aux->y;
+                    //asignamos los valores NaN de separación
+                    x[nPtos-1] = GeocNan();
+                    y[nPtos-1] = GeocNan();
+                }
+                else
+                {
+                    //el vértice pertenece a la polilínea recortada
+                    x[nPtos-1] = aux->x;
+                    y[nPtos-1] = aux->y;
+                }
+            }
+            //avanzamos al siguiente vértice
+            aux = aux->siguiente;
+        }while(aux!=NULL);
+    }
+    else
+    {
+        //vamos recorriendo vértices de la polilínea
+        do
+        {
+            //comprobamos si el vértice es del borde o de fuera del polígono
+            if(aux->pos==GEOC_PTO_FUERA_POLIG)
+            {
+                //un punto de fuera del polígono siempre pertenece a la
+                //polilínea exterior
+                //no hace falta asignar los elementos NaN de separación de
+                //polilíneas, que ya se añaden cuando de trabaja con un punto de
+                //borde
+                //aumentamos el número de elementos almacenados en los vectores
+                //de coordenadas
+                nPtos++;
+                //comprobamos si hay que reasignar memoria
+                if(nPtos>nElem)
+                {
+                    //aumentamos el número de elementos
+                    nElem += GEOC_RECPOLIL_BUFFER_PTOS;
+                    //reasignamos memoria
+                    x = (double*)realloc(x,nElem*sizeof(double));
+                    y = (double*)realloc(y,nElem*sizeof(double));
+                    //comprobamos los posibles errores
+                    if((x==NULL)||(y==NULL))
+                    {
+                        //liberamos la posible memoria asignada
+                        free(x);
+                        free(y);
+                        //mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                }
+                //asignamos las coordenadas del vértice
+                x[nPtos-1] = aux->x;
+                y[nPtos-1] = aux->y;
+            }
+            else if(aux->pos==GEOC_PTO_BORDE_POLIG)
+            {
+                //comprobamos la situación de los vértices anterior y siguiente
+                //para la posible reasignación de memoria
+                if((aux->anterior!=NULL)&&(aux->siguiente!=NULL)&&
+                   (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)&&
+                   (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //este vértice pertenece al exterior del polígono
+                    nPtos++;
+                }
+                else if(((aux->anterior==NULL)||
+                         (aux->anterior->pos!=GEOC_PTO_FUERA_POLIG))&&
+                        (aux->siguiente!=NULL)&&
+                        (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //este es un vértice de comienzo de una polilínea, por lo
+                    //que necesitamos memoria para las coordenadas y el marcador
+                    //NaN
+                    nPtos += 2;
+                }
+                else if(((aux->siguiente==NULL)||
+                         (aux->siguiente->pos!=GEOC_PTO_FUERA_POLIG))&&
+                        (aux->anterior!=NULL)&&
+                        (aux->anterior->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //este es un vértice de fin de una polilínea, por lo que
+                    //necesitamos memoria para las coordenadas y el marcador NaN
+                    nPtos += 2;
+                }
+                //comprobamos si hay que reasignar memoria
+                if(nPtos>nElem)
+                {
+                    //aumentamos el número de elementos
+                    nElem += GEOC_RECPOLIL_BUFFER_PTOS;
+                    //reasignamos memoria
+                    x = (double*)realloc(x,nElem*sizeof(double));
+                    y = (double*)realloc(y,nElem*sizeof(double));
+                    //comprobamos los posibles errores
+                    if((x==NULL)||(y==NULL))
+                    {
+                        //liberamos la posible memoria asignada
+                        free(x);
+                        free(y);
+                        //mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                }
+                //comprobamos de nuevo la situación de los vértices anterior y
+                //posterior
+                if((aux->anterior!=NULL)&&(aux->siguiente!=NULL)&&
+                   (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)&&
+                   (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //el vértice pertenece a la polilínea recortada
+                    x[nPtos-1] = aux->x;
+                    y[nPtos-1] = aux->y;
+                }
+                else if(((aux->anterior==NULL)||
+                         (aux->anterior->pos!=GEOC_PTO_FUERA_POLIG))&&
+                        (aux->siguiente!=NULL)&&
+                        (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //el vértice es inicio de polilínea
+                    //asignamos los valores NaN de separación
+                    x[nPtos-2] = GeocNan();
+                    y[nPtos-2] = GeocNan();
+                    //asignamos las coordenadas del vértice
+                    x[nPtos-1] = aux->x;
+                    y[nPtos-1] = aux->y;
+                }
+                else if(((aux->siguiente==NULL)||
+                         (aux->siguiente->pos!=GEOC_PTO_FUERA_POLIG))&&
+                        (aux->anterior!=NULL)&&
+                        (aux->anterior->pos==GEOC_PTO_FUERA_POLIG))
+                {
+                    //el vértice es final de polilínea
+                    //asignamos las coordenadas del vértice
+                    x[nPtos-2] = aux->x;
+                    y[nPtos-2] = aux->y;
+                    //asignamos los valores NaN de separación
+                    x[nPtos-1] = GeocNan();
+                    y[nPtos-1] = GeocNan();
+                }
+            }
+            //avanzamos al siguiente vértice
+            aux = aux->siguiente;
+        }while(aux!=NULL);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos la estructura de salida
+    resultado = CreaPolil(x,y,nPtos,1,1,&estado);
+    //comprobamos los posibles errores
+    if(resultado==NULL)
+    {
+        //liberamos la memoria asignada
+        free(x);
+        free(y);
+        //comprobamos el error
+        if(estado==GEOC_ERR_ASIG_MEMORIA)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+        }
+        else
+        {
+            //mensaje de error
+            GEOC_ERROR("Error en la llamada a 'CreaPolil()'\nEste error no "
+                       "puede producirse aquí porque los NaN deben estar "
+                       "bien puestos");
+        }
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //liberamos la memoria utilizada
+    free(x);
+    free(y);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return resultado;
+}
+/******************************************************************************/
+/******************************************************************************/
+polil* RecortaPolil(vertPolilClip* poli,
+                    vertPoliClip* poliRec,
+                    const enum GEOC_OP_BOOL_POLIL op,
+                    size_t* nIntersec)
+{
+    //identificador de error
+    int idError=GEOC_ERR_NO_ERROR;
+    //polilínea de salida de salida
+    polil* resultado=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //PRIMER PASO DEL ALGORITMO: CÁLCULO DE TODOS LOS PUNTOS DE INTERSECCIÓN
+    //ENTRE LA POLILÍNEA Y EL POLÍGONO
+    //calculamos los puntos de intersección
+    idError = Paso1Recpolil(poli,poliRec,nIntersec);
+    //comprobamos los posibles errores
+    if(idError==GEOC_ERR_ASIG_MEMORIA)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria en la llamada a "
+                   "'Paso1Recpolil'");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si no hay intersecciones
+    if(!(*nIntersec))
+    {
+        //comprobamos las posibles situaciones relativas entre la polilínea y el
+        //polígono que pueden producir cero intersecciones
+        if(PtoEnPoliClip(poli->x,poli->y,poliRec)==GEOC_PTO_FUERA_POLIG)
+        {
+            //LA POLILÍNEA ESTÁ FUERA DEL POLÍGONO DE RECORTE
+            //distinguimos las operaciones (por defecto, dentro)
+            if(op!=GeocOpBoolFuera)
+            {
+                //el resultado es una polilínea vacía
+                resultado = CreaPolilPolilClip(NULL);
+            }
+            else
+            {
+                //el resultado es la polilínea original
+                resultado = CreaPolilPolilClip(poli);
+            }
+        }
+        else
+        {
+            //LA POLILÍNEA ESTÁ DENTRO DEL POLÍGONO DE RECORTE
+            //distinguimos las operaciones (por defecto, dentro)
+            if(op!=GeocOpBoolFuera)
+            {
+                //el resultado es la polilínea original
+                resultado = CreaPolilPolilClip(poli);
+            }
+            else
+            {
+                //el resultado es una polilínea vacía
+                resultado = CreaPolilPolilClip(NULL);
+            }
+        }
+        //comprobamos los posibles errores
+        if(resultado==NULL)
+        {
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //salimos de la función
+        return resultado;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //realizamos la operación si hay alguna intersección
+    resultado = Paso2Recpolil(poli,op);
+    //comprobamos los posibles errores
+    if(resultado==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria en la llamada a "
+                    "'Paso2Recpolil'");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return resultado;
+}
+/******************************************************************************/
+/******************************************************************************/
+polil* RecortaPolilMult(const polil* poli,
+                        const polig* poliRec,
+                        const enum GEOC_OP_BOOL_POLIL op,
+                        size_t* nIntersec)
+{
+    //índices para recorrer bucles
+    size_t i=0,j=0;
+    //variable de posición
+    size_t pos=0;
+    //posición de un rectángulo con respecto a otro
+    int pr=0;
+    //número de intersecciones auxiliar
+    size_t nInt=0;
+    //variable de error
+    int estado=GEOC_ERR_NO_ERROR;
+    //listas de trabajo
+    vertPolilClip* polilClip=NULL;
+    vertPoliClip* poligClip=NULL;
+    //polilínea auxiliar
+    polil* polilAux=NULL;
+    //variable de salida
+    polil* resultado=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos el número total de intersecciones
+    *nIntersec = 0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //inicializamos la variable de salida
+    resultado = IniciaPolilVacia();
+    //comprobamos los posibles errores
+    if(resultado==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos las polilíneas a recortar
+    for(i=0;i<poli->nPolil;i++)
+    {
+        //dirección de inicio de los vértices de la polilínea
+        pos = poli->posIni[i];
+        //creamos la polilínea a recortar de trabajo
+        polilClip = CreaPolilClip(&(poli->x[pos]),&(poli->y[pos]),
+                                  poli->nVert[i],1,1);
+        //comprobamos los posibles errores
+        if(polilClip==NULL)
+        {
+            //liberamos la memoria asignada hasta ahora
+            LibMemPolil(resultado);
+            //mensaje de error
+            GEOC_ERROR("Error de asignación de memoria");
+            //salimos de la función
+            return NULL;
+        }
+        //recorremos los polígonos de recorte
+        for(j=0;j<poliRec->nPolig;j++)
+        {
+            //comprobamos si la polilínea y el polígono tienen definidos sus
+            //límites
+            if((poli->hayLim)&&(poliRec->hayLim))
+            {
+                //comprobamos si los restángulos que encierran a la polilínea y
+                //al polígono son disjuntos o no
+                pr = RectDisjuntos(poli->xMin[i],poli->xMax[i],poli->yMin[i],
+                                   poli->yMax[i],
+                                   poliRec->xMin[j],poliRec->xMax[j],
+                                   poliRec->yMin[j],poliRec->yMax[j]);
+                //comprobamos los casos particulares si los rectángulos son
+                //disjuntos
+                if(pr&&(op==GeocOpBoolDentro))
+                {
+                    //si buscamos la parte de la polilínea que cae dentro del
+                    //polígono, no se añade nada
+                    //vamos a la siguiente vuelta del bucle
+                    continue;
+                }
+                else if(pr&&(op==GeocOpBoolFuera))
+                {
+                    //si buscamos la parte de la polilínea que cae fuera del
+                    //polígono, se añade la polilínea entera
+                    estado = AnyadeDatosPolil(resultado,&(poli->x[pos]),
+                                              &(poli->y[pos]),poli->nVert[i],1,
+                                              1);
+                    //comprobamos los posibles errores, que sólo pueden ser de
+                    //asignación de memoria
+                    if(estado!=GEOC_ERR_NO_ERROR)
+                    {
+                        //liberamos la posible memoria asignada hasta ahora
+                        LibMemPolilClip(polilClip);
+                        LibMemPolil(resultado);
+                        //lanzamos el mensaje de error
+                        GEOC_ERROR("Error de asignación de memoria");
+                        //salimos de la función
+                        return NULL;
+                    }
+                    //vamos a la siguiente vuelta del bucle
+                    continue;
+                }
+            }
+            //dirección de inicio de los vértices del polígono de recorte
+            pos = poliRec->posIni[j];
+            //creamos el polígono de recorte de trabajo
+            poligClip = CreaPoliClip(&(poliRec->x[pos]),&(poliRec->y[pos]),
+                                     poliRec->nVert[j],1,1);
+            //comprobamos los posibles errores
+            if(poligClip==NULL)
+            {
+                //liberamos la memoria asignada hasta ahora
+                LibMemPolilClip(polilClip);
+                LibMemPolil(resultado);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //recortamos
+            polilAux = RecortaPolil(polilClip,poligClip,op,&nInt);
+            //comprobamos los posibles errores
+            if(polilAux==NULL)
+            {
+                //liberamos la posible memoria asignada hasta ahora
+                LibMemPolilClip(polilClip);
+                LibMemPoliClip(poligClip);
+                LibMemPolil(resultado);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //sumamos el número de intersecciones
+            (*nIntersec) += nInt;
+            //añadimos la polilínea recortada a la variable de salida
+            if(AnyadePolilPolil(resultado,polilAux)==GEOC_ERR_ASIG_MEMORIA)
+            {
+                //liberamos la posible memoria asignada hasta ahora
+                LibMemPolilClip(polilClip);
+                LibMemPoliClip(poligClip);
+                LibMemPolil(polilAux);
+                LibMemPolil(resultado);
+                //mensaje de error
+                GEOC_ERROR("Error de asignación de memoria");
+                //salimos de la función
+                return NULL;
+            }
+            //liberamos la memoria asignada al polígono de esta vuelta del bucle
+            LibMemPoliClip(poligClip);
+            //liberamos la memoria asignada a la polilínea auxiliar
+            LibMemPolil(polilAux);
+            //reinicializamos la polilínea a recortar
+            polilClip = ReiniciaPolilClip(polilClip);
+        }
+        //liberamos la memoria asignada a la polilínea de esta vuelta del bucle
+        LibMemPolilClip(polilClip);
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return resultado;
+}
+/******************************************************************************/
+/******************************************************************************/
+polil* CreaPolilPolilClip(vertPolilClip* poli)
+{
+    //índice para recorrer bucles
+    size_t i=0;
+    //número de elementos
+    size_t nVert=0,nElem=0;
+    //estructura auxiliar
+    vertPolilClip* aux=poli;
+    //variable de salida
+    polil* result=NULL;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //creamos la estructura vacía
+    result = IniciaPolilVacia();
+    //comprobamos los posibles errores
+    if(result==NULL)
+    {
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //contamos todos los vértices de la polilínea
+    nVert = NumeroVertPolilClip(poli);
+    //contemplamos una posible salida rápida
+    if(nVert==0)
+    {
+        //devolvemos la estructura vacía
+        return result;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //número de elementos de los vectores de coordenadas
+    nElem = nVert+2;
+    //asignamos memoria para los vectores de coordenadas de la estructura
+    result->x = (double*)malloc(nElem*sizeof(double));
+    result->y = (double*)malloc(nElem*sizeof(double));
+    //asignamos memoria para los vectores de posición
+    result->posIni = (size_t*)malloc(sizeof(size_t));
+    result->nVert = (size_t*)malloc(sizeof(size_t));
+    //comprobamos los posibles errores de asignación de memoria
+    if((result->x==NULL)||(result->y==NULL)||(result->posIni==NULL)||
+       (result->nVert==NULL))
+    {
+        //liberamos la posible memoria asignada
+        LibMemPolil(result);
+        //mensaje de error
+        GEOC_ERROR("Error de asignación de memoria");
+        //salimos de la función
+        return NULL;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //asignamos el número de elementos de los vectores de coordenadas y de
+    //polilíneas
+    result->nElem = nElem;
+    result->nPolil = 1;
+    //asignamos la posición de inicio y el número de vértices
+    result->posIni[0] = 1;
+    result->nVert[0] = nVert;
+    //asignamos los separadores de polilínea al principio y al final
+    result->x[0] = GeocNan();
+    result->y[0] = GeocNan();
+    result->x[nElem-1] = GeocNan();
+    result->y[nElem-1] = GeocNan();
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //recorremos los vértices de la polilínea
+    for(i=1;i<=nVert;i++)
+    {
+        //copio las coordenadas del vértice
+        result->x[i] = aux->x;
+        result->y[i] = aux->y;
+        //siguiente vértice
+        aux = aux->siguiente;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return result;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/segmento.c b/src/segmento.c
new file mode 100755
index 0000000..6bb5220
--- /dev/null
+++ b/src/segmento.c
@@ -0,0 +1,292 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup geom
+@{
+\file segmento.c
+\brief Definición de funciones para la realización de cálculos con segmentos.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 22 de abril de 2011
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/segmento.h"
+/******************************************************************************/
+/******************************************************************************/
+double PosPtoRecta2D(const double x,
+                     const double y,
+                     const double xIni,
+                     const double yIni,
+                     const double xFin,
+                     const double yFin)
+{
+    //calculamos y salimos de la función
+    return (xIni-x)*(yFin-y)-(xFin-x)*(yIni-y);
+}
+/******************************************************************************/
+/******************************************************************************/
+int TresPuntosColineales2D(const double xA,
+                           const double yA,
+                           const double xB,
+                           const double yB,
+                           const double xC,
+                           const double yC)
+{
+    //variable de salida
+    int colin=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //utilizamos la función de posición de punto con respecto a una recta,
+    //aunque no es una función robusta
+    //son colineales si el resultado es 0.0
+    colin = (PosPtoRecta2D(xA,yA,xB,yB,xC,yC)==0.0) ? 1 : 0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return colin;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PuntoEntreDosPuntos2DColin(const double x,
+                               const double y,
+                               const double xA,
+                               const double yA,
+                               const double xB,
+                               const double yB)
+{
+    //código de salida
+    int cod=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //distinguimos entre segmento vertical y no vertical
+    if(xA!=xB)
+    {
+        //segmento no vertical, utilizamos las coordenadas X
+        cod = ((xA<x)&&(x<xB))||((xA>x)&&(x>xB));
+    }
+    else
+    {
+        //segmento vertical, utilizamos las coordenadas Y
+        cod = ((yA<y)&&(y<yB))||((yA>y)&&(y>yB));
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return cod;
+}
+/******************************************************************************/
+/******************************************************************************/
+int PtoComunSegmParalelos2D(const double xA,
+                            const double yA,
+                            const double xB,
+                            const double yB,
+                            const double xC,
+                            const double yC,
+                            const double xD,
+                            const double yD,
+                            double* x,
+                            double* y)
+{
+    //variable de salida
+    int cod=GEOC_SEG_NO_INTERSEC;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si los puntos son colineales
+    if(!TresPuntosColineales2D(xA,yA,xB,yB,xC,yC))
+    {
+        //los segmentos son paralelos, pero no se cortan
+        return GEOC_SEG_NO_INTERSEC;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si los segmentos son el mismo
+    if(((xA==xC)&&(yA==yC)&&(xB==xD)&&(yB==yD))||
+       ((xA==xD)&&(yA==yD)&&(xB==xC)&&(yB==yC)))
+    {
+        //coordenadas de salida
+        *x = xA;
+        *y = yA;
+        //los segmentos son el mismo
+        return GEOC_SEG_INTERSEC_MISMO_SEG;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si algún punto está entre medias del otro segmento
+    if(PuntoEntreDosPuntos2DColin(xA,yA,xC,yC,xD,yD))
+    {
+        //el punto A está en el segmento CD
+        *x = xA;
+        *y = yA;
+        //salimos
+        return GEOC_SEG_INTERSEC_COLIN;
+    }
+    else if(PuntoEntreDosPuntos2DColin(xC,yC,xA,yA,xB,yB))
+    {
+        //el punto C está en el segmento AB
+        *x = xC;
+        *y = yC;
+        //salimos
+        return GEOC_SEG_INTERSEC_COLIN;
+    }
+    else if(PuntoEntreDosPuntos2DColin(xB,yB,xC,yC,xD,yD))
+    {
+        //el punto B está en el segmento CD
+        *x = xB;
+        *y = yB;
+        //salimos
+        return GEOC_SEG_INTERSEC_COLIN;
+    }
+    else if(PuntoEntreDosPuntos2DColin(xD,yD,xA,yA,xB,yB))
+    {
+        //el punto D está en el segmento AB
+        *x = xD;
+        *y = yD;
+        //salimos
+        return GEOC_SEG_INTERSEC_COLIN;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si sólo comparten el extremo A
+    if(((xA==xC)&&(yA==yC))||((xA==xD)&&(yA==yD)))
+    {
+        //coordenadas de salida
+        *x = xA;
+        *y = yA;
+        //los segmentos comparten un extremo
+        return GEOC_SEG_INTERSEC_EXTREMO_COLIN;
+    }
+    //comprobamos si sólo comparten el extremo B
+    if(((xB==xC)&&(yB==yC))||((xB==xD)&&(yB==yD)))
+    {
+        //coordenadas de salida
+        *x = xB;
+        *y = yB;
+        //los segmentos comparten un extremo
+        return GEOC_SEG_INTERSEC_EXTREMO_COLIN;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return cod;
+}
+/******************************************************************************/
+/******************************************************************************/
+int IntersecSegmentos2D(const double xA,
+                        const double yA,
+                        const double xB,
+                        const double yB,
+                        const double xC,
+                        const double yC,
+                        const double xD,
+                        const double yD,
+                        double* x,
+                        double* y)
+{
+    //parámetros de las ecuaciones
+    double s=0.0,t=0.0,num=0.0,den=0.0;
+    //variable de salida
+    int cod=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si los rectángulos que encierran a los segmentos son disjuntos
+    if(RectDisjuntos(GEOC_MIN(xA,xB),GEOC_MAX(xA,xB),GEOC_MIN(yA,yB),
+                     GEOC_MAX(yA,yB),GEOC_MIN(xC,xD),GEOC_MAX(xC,xD),
+                     GEOC_MIN(yC,yD),GEOC_MAX(yC,yD)))
+    {
+        //si los rectángulos son disjuntos, los segmentos no se tocan
+        cod = GEOC_SEG_NO_INTERSEC;
+        //salimos de la función
+        return cod;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el denominador
+    den = xA*(yD-yC)+xB*(yC-yD)+xD*(yB-yA)+xC*(yA-yB);
+    //si el denominador es 0.0, los segmentos son paralelos
+    if(den==0.0)
+    {
+        //calculamos el punto común
+        cod = PtoComunSegmParalelos2D(xA,yA,xB,yB,xC,yC,xD,yD,x,y);
+        //salimos de la función
+        return cod;
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //calculamos el numerador
+    num = xA*(yD-yC)+xC*(yA-yD)+xD*(yC-yA);
+    //un extremo de un segmento puede estar encima del otro segmento, pero los
+    //segmentos no son colineales
+    if((num==0.0)||(num==den))
+    {
+        //asignamos la variable de salida
+        cod = GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN;
+    }
+    //calculamos el parámetro s
+    s = num/den;
+    //calculamos de nuevo el numerador
+    num = -(xA*(yC-yB)+xB*(yA-yC)+xC*(yB-yA));
+    //un extremo de un segmento puede estar encima del otro segmento, pero los
+    //segmentos no son colineales
+    if((num==0.0)||(num==den))
+    {
+        //asignamos la variable de salida
+        cod = GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN;
+    }
+    //calculamos el parámetro t
+    t = num/den;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //comprobamos si estamos ante una intersección pura y dura o los segmentos
+    //no se cortan
+    if((s>0.0)&&(s<1.0)&&(t>0.0)&&(t<1.0))
+    {
+        //asignamos la variable de salida
+        cod = GEOC_SEG_INTERSEC;
+    }
+    else if((s<0.0)||(s>1.0)||(t<0.0)||(t>1.0))
+    {
+        //asignamos la variable de salida
+        cod = GEOC_SEG_NO_INTERSEC;
+    }
+    //calculamos las coordenadas del punto intersección
+    *x = xA+s*(xB-xA);
+    *y = yA+s*(yB-yA);
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return cod;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
diff --git a/src/ventorno.c b/src/ventorno.c
new file mode 100755
index 0000000..d5ca57f
--- /dev/null
+++ b/src/ventorno.c
@@ -0,0 +1,86 @@
+/* -*- coding: utf-8 -*- */
+/**
+\ingroup anespec general
+@{
+\file ventorno.c
+\brief Definición de funciones para el control de variables de entorno.
+\author José Luis García Pallero, jgpallero at gmail.com
+\date 31 de marzo de 2011
+\version 1.0
+\section Licencia Licencia
+Copyright (c) 2011, José Luis García Pallero. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+- Neither the name of the copyright holders nor the names of its contributors
+  may be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/******************************************************************************/
+/******************************************************************************/
+#include"libgeoc/ventorno.h"
+/******************************************************************************/
+/******************************************************************************/
+int VarEnvValRef(const char* var,
+                 const char* valRef)
+{
+    //posible valor de la variable de entorno
+    char* valEnv=NULL;
+    //variable de salida
+    int salida=0;
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //extraemos el valor de la variable de entorno
+    valEnv = getenv(var);
+    //comprobamos si la variable está definida
+    if(valEnv==NULL)
+    {
+        //se devuelve menor que 0
+        salida = -1;
+    }
+    else
+    {
+        //comprobamos su valor
+        if(strcmp(valEnv,valRef))
+        {
+            //su valor es distinto al de referencia
+            salida = 0;
+        }
+        else
+        {
+            //si es igual al de referencia
+            salida = 1;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
+    //salimos de la función
+    return salida;
+}
+/******************************************************************************/
+/******************************************************************************/
+/** @} */
+/******************************************************************************/
+/******************************************************************************/
+/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
+/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
+/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
+/* kate: backspace-indents on; show-tabs on; */
+/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */

-- 
Alioth's /home/groups/pkg-octave/bin/git-commit-notice on /srv/git.debian.org/git/pkg-octave/octave-octclip.git



More information about the Pkg-octave-commit mailing list