diff --git a/Changelog b/Changelog index c268df1ed..55a7a885b 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,15 @@ version 1.0.2 (not yet released) + * change default land-sea mask (now 2.5 minute resolution). + * add etopo method (similar to bluemarble, but plots etopo + relief image from www.ngdc.noaa.gov/mgg/global as a map background). + * add shadedrelief method (similar to bluemarble, but plots shaded + relief image from naturalearthdata.com as a map background). + * replace pyshapelib with pure python shapelib.py from + pyshp.googlecode.com. Allows full python 3 compatibility. + * fix doc/conf.py to use inheritance_diagram from Sphinx, not + matplotlib. + * fix drawlsmask so cylindrical projections work correctly when + longitude range outside of -180 to 180. * python 3 compatibility. * added lic_demo.py to examples (line integral convolution, requires scikit.vectorplot). diff --git a/LICENSE_pyshapelib b/LICENSE_pyshapelib deleted file mode 100644 index 92b8903ff..000000000 --- a/LICENSE_pyshapelib +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library 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 Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/MANIFEST.in b/MANIFEST.in index cc51ddc8a..658613f12 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,7 +2,6 @@ include FAQ include README include MANIFEST.in include LICENSE_proj4 -include LICENSE_pyshapelib include LICENSE_data include API_CHANGES include KNOWN_BUGS @@ -12,6 +11,7 @@ include setup.cfg include setupegg.py include nad2bin.c include src/* +include examples/makelsmask.py include examples/allskymap.py include examples/allskymap_cr_example.py include examples/plothighsandlows.py @@ -86,14 +86,10 @@ include lib/mpl_toolkits/__init__.py include lib/mpl_toolkits/basemap/__init__.py include lib/mpl_toolkits/basemap/proj.py include lib/mpl_toolkits/basemap/pyproj.py +include lib/mpl_toolkits/basemap/shapefile.py include lib/mpl_toolkits/basemap/cm.py -include lib/mpl_toolkits/basemap/netcdf.py -include lib/mpl_toolkits/basemap/pupynere.py -include lib/mpl_toolkits/basemap/netcdftime.py -include pyshapelib/README pyshapelib/COPYING pyshapelib/ChangeLog pyshapelib/NEWS -include pyshapelib/*.i pyshapelib/*.c pyshapelib/*.py pyshapelib/*.h -include pyshapelib/*.shp pyshapelib/*.shx pyshapelib/*.dbf -include pyshapelib/shapelib/*.c pyshapelib/shapelib/*.h +include lib/mpl_toolkits/basemap/solar.py +include lib/mpl_toolkits/basemap/test.py include doc/users/figures/*py include doc/users/*rst include doc/api/*rst @@ -102,6 +98,4 @@ include doc/make.py include doc/conf.py include doc/index.rst recursive-include geos-3.2.0 * -recursive-include lib/dbflib * -recursive-include lib/shapelib * recursive-include lib/mpl_toolkits/basemap/data * diff --git a/README b/README index 09e6b6d73..bc88ba2c4 100644 --- a/README +++ b/README @@ -31,9 +31,6 @@ source code for the GEOS library is included in the 'geos-3.1.1' directory under the terms given in LICENSE_geos. -pyshapelib by Bernhard Herzog is included in the 'pyshapelib' directory -under the terms given in LICENSE_pyshapelib. - the coastline, lake, river and political boundary data are extracted from datasets provided with the Generic Mapping Tools (http://gmt.soest.hawaii.edu) @@ -105,13 +102,6 @@ run the usual 'python setup.py install'. Check your installation by running "from mpl_toolkits.basemap import Basemap" at the python prompt. -Basemap includes three auxilliary packages, pydap (http://pydap.org, just -the client is included), httplib2 and pyshapelib. By default, setup.py checks to -see if these are already installed, and if so does not try to overwrite -them. If you get import errors related to either of these two packages, -edit setup.cfg and set pydap, httplib2 and/or pyshapelib to True to force -installation of the included versions. - 4) To test, cd to the examples directory and run 'python simpletest.py'. To run all the examples (except those that have extra dependencies or require an internet connection), execute 'python run_all.py'. diff --git a/README-devel b/README-devel deleted file mode 100644 index 3cf4a5242..000000000 --- a/README-devel +++ /dev/null @@ -1,31 +0,0 @@ -To make a release: - -1) check out a fresh copy from SVN. -2) run python setup.py sdist to make the source tarball. -3) run python setupegg.py bdist_egg to make a binary egg. - (repeat this step on ppc mac, intel mac and windows, for - python 2.4 and python 2.5). - to create binary installers, run - python setup.py build --compiler=mingw32 bdist_wininst on windows. - bdist_mpkg (http://cheeseshop.python.org/pypi/bdist_mpkg/ on macos x. -4) put the *_h.txt boundary files in a tar.gz file - (basemap-data-hires-X.Y.Z.tar.gz). -5) anon ftp the files files to SF - local> cd dist - local> ncftp upload.sourceforge.net - ncftp> cd incoming - ncftp> put tar.gz, *egg -6) go to https://sourceforge.net/project/admin/?group_id=80706 and do - a file release. Click on the "Admin" tab to log in as an admin, - and then the "File Releases" tab. Go to the bottom and click "add - release" and enter the package name but not the version number in - the "Package Name" box. You will then be prompted for the "New - release name" at which point you can add the version number, eg - somepackage-0.1 and click "Create this release". - - You will then be taken to a fairly self explanatory page where you - can enter the Change notes, the release notes, and select which - packages from the incoming ftp archive you want to include in this - release. For each binary, you will need to select the platform and - file type, and when you are done you click on the "notify users who - are monitoring this package link" diff --git a/doc/conf.py b/doc/conf.py index f88ff6afd..d3d828145 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -23,10 +23,10 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['matplotlib.sphinxext.mathmpl', 'math_symbol_table', +extensions = ['matplotlib.sphinxext.mathmpl', 'sphinx.ext.autodoc', 'matplotlib.sphinxext.only_directives', - 'matplotlib.sphinxext.plot_directive', 'inheritance_diagram', - 'gen_rst', + 'matplotlib.sphinxext.plot_directive', + 'sphinx.ext.inheritance_diagram', 'matplotlib.sphinxext.ipython_console_highlighting'] # Add any paths that contain templates here, relative to this directory. diff --git a/doc/users/installing.rst b/doc/users/installing.rst index bdbd5ea36..1add754e4 100644 --- a/doc/users/installing.rst +++ b/doc/users/installing.rst @@ -32,22 +32,6 @@ numpy 1.2.1 (or later) `PROJ4 `__ Cartographic Projections Library. Patched version automatically built into basemap. -`pyshapelib `__ - C library with python interface for reading ESRI shapefiles. - If not present, will be installed with basemap. - -`pupynere `__ - Pure python `netCDF `__ - reader. Patched version automatically installed with basemap. - -`pydap `__ - Pure python `OPeNDAP `__ implementation. - If not present, client (not server) will be installed with basemap. - -`httplib2 `__ (needed for pydap client). - If not present, will be installed with basemap. - - **Optional libraries** PIL @@ -58,7 +42,7 @@ Installation ============ Windows binary installers are available for -`download `__. +`download `_) are provided, along with methods for plotting them. The `GEOS library `_ is used internally to clip the coastline and polticial boundary features to the desired map projection region. -Basemap provides facilities for reading data in `netCDF -`_ and `Shapefile -`_ formats, as well as -directly over http using `OPeNDAP `_. -This functionality is provided through the `PyDAP `_ -client, and a python interface to the `Shapefile C library -`_. +Basemap provides facilities for reading `shapefiles +`_. Basemap is geared toward the needs of earth scientists, particular oceanographers and meteorologists. I originally wrote Basemap to help in my diff --git a/examples/README b/examples/README index 3a2af55ce..8d437a094 100644 --- a/examples/README +++ b/examples/README @@ -144,3 +144,5 @@ ploticos.py demonstrates plotting on unstructured grids. lic_demo.py shows how to use vectorplot scikit to visualize vector fields with Line Integral Convolutions (LIC). + +makelsmask.py use is_land method to generate land-sea mask from built-in GSSH coastline data,then plot mask with drawlsmask. diff --git a/examples/makelsmask.py b/examples/makelsmask.py new file mode 100644 index 000000000..930d26bb8 --- /dev/null +++ b/examples/makelsmask.py @@ -0,0 +1,28 @@ +from mpl_toolkits.basemap import Basemap +import matplotlib.pyplot as plt +import numpy as np +# make land-sea-lake mask from built-in coastline dataset using is_land method. +# this is very slow! +minutes = 150 +resolution = 'c' + +delon = minutes/60. +nlons = int(360./delon); nlons = nlons + 1 +nlats = int(180./delon); nlats = nlats + 1 +print minutes,nlons,nlats,resolution +lons = np.linspace(-180,180,nlons) +lats = np.linspace(-90,90,nlats) +lsmask = np.zeros((len(lats),len(lons)),dtype=np.uint8) +print lsmask.shape, lsmask.dtype + +m =\ +Basemap(llcrnrlon=-180,llcrnrlat=-90,urcrnrlon=180,urcrnrlat=90,resolution=resolution,projection='cyl') +for j,lat in enumerate(lats): + #print j + for i,lon in enumerate(lons): + lsmask[j,i] = m.is_land(lon,lat) +m.drawlsmask(land_color='coral',ocean_color='aqua',lsmask=lsmask,lsmask_lons=lons,lsmask_lats=lats,lakes=True) +plt.title('%s minute degree land-sea mask' % minutes) +#lsmask.tofile('%sminlsmask_gshhs_%s.dat' % (minutes, resolution)) + +plt.show() diff --git a/examples/maskoceans.py b/examples/maskoceans.py index e8a308aec..814d47725 100644 --- a/examples/maskoceans.py +++ b/examples/maskoceans.py @@ -20,7 +20,7 @@ # interpolate land/sea mask to topo grid, mask ocean values. # output may look 'blocky' near coastlines, since data is at much # lower resolution than land/sea mask. -topo = maskoceans(lons, lats, topoin, inlands=False) +topo = maskoceans(lons, lats, topoin) # make contour plot (ocean values will be masked) CS=m.contourf(x,y,topo,np.arange(-300,3001,50),cmap=plt.cm.jet,extend='both') #im=m.pcolormesh(x,y,topo,cmap=plt.cm.jet,vmin=-300,vmax=3000) @@ -39,7 +39,7 @@ x, y = m(lons, lats) topo = interp(topoin,lons1,lats1,lons,lats,order=1) # interpolate land/sea mask to topo grid, mask ocean values. -topo = maskoceans(lons, lats, topo, inlands=False) +topo = maskoceans(lons, lats, topo) # make contour plot (ocean values will be masked) CS=m.contourf(x,y,topo,np.arange(-300,3001,50),cmap=plt.cm.jet,extend='both') #im=m.pcolormesh(x,y,topo,cmap=plt.cm.jet,vmin=-300,vmax=3000) diff --git a/examples/wiki_example.py b/examples/wiki_example.py index 8a0712c15..87bccc96d 100644 --- a/examples/wiki_example.py +++ b/examples/wiki_example.py @@ -36,6 +36,22 @@ x, y = map(lons*180./np.pi, lats*180./np.pi) # contour data over the map. cs = map.contour(x,y,wave+mean,15,linewidths=1.5) +plt.title('filled continent background') + +# as above, but use land-sea mask image as map background. +fig = plt.figure() +map.drawmapboundary() +map.drawmeridians(np.arange(0,360,30)) +map.drawparallels(np.arange(-90,90,30)) +# plot filled circles at the locations of the cities. +map.plot(xc,yc,'wo') +# plot the names of five cities. +for name,xpt,ypt in zip(cities,xc,yc): + plt.text(xpt+50000,ypt+50000,name,fontsize=9,color='w') +# contour data over the map. +cs = map.contour(x,y,wave+mean,15,linewidths=1.5) +plt.title('land-sea mask background') +map.drawlsmask(ocean_color='aqua',land_color='coral') # as above, but use blue marble image as map background. fig = plt.figure() @@ -49,6 +65,37 @@ plt.text(xpt+50000,ypt+50000,name,fontsize=9,color='w') # contour data over the map. cs = map.contour(x,y,wave+mean,15,linewidths=1.5) -# draw blue marble image in background. -map.bluemarble(scale=0.5) +plt.title('blue marble background') +map.bluemarble() + +# as above, but use shaded relief image as map background. +fig = plt.figure() +map.drawmapboundary() +map.drawmeridians(np.arange(0,360,30)) +map.drawparallels(np.arange(-90,90,30)) +# plot filled circles at the locations of the cities. +map.plot(xc,yc,'wo') +# plot the names of five cities. +for name,xpt,ypt in zip(cities,xc,yc): + plt.text(xpt+50000,ypt+50000,name,fontsize=9,color='w') +# contour data over the map. +cs = map.contour(x,y,wave+mean,15,linewidths=1.5) +plt.title('shaded relief background') +map.shadedrelief() + +# as above, but use etopo image as map background. +fig = plt.figure() +map.drawmapboundary() +map.drawmeridians(np.arange(0,360,30)) +map.drawparallels(np.arange(-90,90,30)) +# plot filled circles at the locations of the cities. +map.plot(xc,yc,'wo') +# plot the names of five cities. +for name,xpt,ypt in zip(cities,xc,yc): + plt.text(xpt+50000,ypt+50000,name,fontsize=9,color='w') +# contour data over the map. +cs = map.contour(x,y,wave+mean,15,linewidths=1.5) +plt.title('etopo background') +map.etopo() + plt.show() diff --git a/lib/dbflib/__init__.py b/lib/dbflib/__init__.py deleted file mode 100644 index a11ffcbc7..000000000 --- a/lib/dbflib/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from dbflib import * diff --git a/lib/dbflib/dbflib.py b/lib/dbflib/dbflib.py deleted file mode 100644 index 0f5ffb620..000000000 --- a/lib/dbflib/dbflib.py +++ /dev/null @@ -1,76 +0,0 @@ -# This file was created automatically by SWIG. -import dbflibc -class DBFFile: - def __init__(self,*args): - self.this = apply(dbflibc.new_DBFFile,args) - self.thisown = 1 - - def __del__(self,dbflibc=dbflibc): - if self.thisown == 1 : - dbflibc.delete_DBFFile(self) - def close(*args): - val = apply(dbflibc.DBFFile_close,args) - return val - def field_count(*args): - val = apply(dbflibc.DBFFile_field_count,args) - return val - def record_count(*args): - val = apply(dbflibc.DBFFile_record_count,args) - return val - def field_info(*args): - val = apply(dbflibc.DBFFile_field_info,args) - return val - def read_record(*args): - val = apply(dbflibc.DBFFile_read_record,args) - return val - def read_attribute(*args): - val = apply(dbflibc.DBFFile_read_attribute,args) - return val - def add_field(*args): - val = apply(dbflibc.DBFFile_add_field,args) - return val - def write_record(*args): - val = apply(dbflibc.DBFFile_write_record,args) - return val - def commit(*args): - val = apply(dbflibc.DBFFile_commit,args) - return val - def __repr__(self): - return "" % (self.this,) - if not dbflibc._have_commit: del commit - - def __del__(self,dbflibc=dbflibc): - if getattr(self, 'thisown', 0): - dbflibc.delete_DBFFile(self) - -class DBFFilePtr(DBFFile): - def __init__(self,this): - self.this = this - self.thisown = 0 - self.__class__ = DBFFile - - - - - -#-------------- FUNCTION WRAPPERS ------------------ - -def open(*args, **kwargs): - val = apply(dbflibc.open,args,kwargs) - if val: val = DBFFilePtr(val); val.thisown = 1 - return val - -def create(*args, **kwargs): - val = apply(dbflibc.create,args,kwargs) - if val: val = DBFFilePtr(val); val.thisown = 1 - return val - - - -#-------------- VARIABLE WRAPPERS ------------------ - -FTString = dbflibc.FTString -FTInteger = dbflibc.FTInteger -FTDouble = dbflibc.FTDouble -FTInvalid = dbflibc.FTInvalid -_have_commit = dbflibc._have_commit diff --git a/lib/mpl_toolkits/basemap/__init__.py b/lib/mpl_toolkits/basemap/__init__.py index 7fbf96c4b..6be23f756 100644 --- a/lib/mpl_toolkits/basemap/__init__.py +++ b/lib/mpl_toolkits/basemap/__init__.py @@ -1697,11 +1697,7 @@ def readshapefile(self,shapefile,name,drawbounds=True,zorder=None, vertices. If ``drawbounds=True`` a matplotlib.patches.LineCollection object is appended to the tuple. """ - try: - import dbflib - from shapelib import ShapeFile - except ImportError: - raise ImportError('pyshapelib not installed') + from .shapefile import Reader if not os.path.exists('%s.shp'%shapefile): raise IOError('cannot locate %s.shp'%shapefile) if not os.path.exists('%s.shx'%shapefile): @@ -1711,27 +1707,29 @@ def readshapefile(self,shapefile,name,drawbounds=True,zorder=None, # open shapefile, read vertices for each object, convert # to map projection coordinates (only works for 2D shape types). try: - shp = ShapeFile(shapefile) + shf = Reader(shapefile) except: raise IOError('error reading shapefile %s.shp' % shapefile) - try: - dbf = dbflib.open(shapefile) - except: - raise IOError('error reading dbffile %s.dbf' % shapefile) - info = shp.info() - if info[1] not in [1,3,5,8]: - raise ValueError('readshapefile can only handle 2D shape types') + fields = shf.fields + coords = []; attributes = [] msg=dedent(""" shapefile must have lat/lon vertices - it looks like this one has vertices in map projection coordinates. You can convert the shapefile to geographic coordinates using the shpproj utility from the shapelib tools (http://shapelib.maptools.org/shapelib-tools.html)""") - if info[1] in [1,8]: # a Point or MultiPoint file. - coords = [] - nelements = shp.info()[0] - for nelement in range(nelements): - shp_object = shp.read_object(nelement) - verts = shp_object.vertices() + shptype = shf.shapes()[0].shapeType + bbox = shf.bbox.tolist() + info = (shf.numRecords,shptype,bbox[0:2]+[0.,0.],bbox[2:]+[0.,0.]) + npoly = 0 + for shprec in shf.shapeRecords(): + shp = shprec.shape; rec = shprec.record + npoly = npoly + 1 + if shptype != shp.shapeType: + raise ValueError('readshapefile can only handle a single shape type per file') + if shptype not in [1,3,5,8]: + raise ValueError('readshapefile can only handle 2D shape types') + verts = shp.points + if shptype in [1,8]: # a Point or MultiPoint shape. lons, lats = list(zip(*verts)) if max(lons) > 721. or min(lons) < -721. or max(lats) > 91. or min(lats) < -91: raise ValueError(msg) @@ -1741,48 +1739,44 @@ def readshapefile(self,shapefile,name,drawbounds=True,zorder=None, else: # single Point x,y = self(lons[0], lats[0]) coords.append((x,y)) - attributes = [dbf.read_record(i) for i in range(nelements)] - self.__dict__[name]=coords - self.__dict__[name+'_info']=attributes - else: # a Polyline or Polygon file. - shpsegs = [] - shpinfo = [] - for npoly in range(shp.info()[0]): - shp_object = shp.read_object(npoly) - verts = shp_object.vertices() - rings = len(verts) - for ring in range(rings): - lons, lats = list(zip(*verts[ring])) + attdict={} + for r,key in zip(rec,fields[1:]): + attdict[key[0]]=r + attributes.append(attdict) + else: # a Polyline or Polygon shape. + parts = shp.parts.tolist() + ringnum = 0 + for indx1,indx2 in zip(parts,parts[1:]+[len(verts)]): + ringnum = ringnum + 1 + lons, lats = list(zip(*verts[indx1:indx2+1])) if max(lons) > 721. or min(lons) < -721. or max(lats) > 91. or min(lats) < -91: raise ValueError(msg) x, y = self(lons, lats) - shpsegs.append(list(zip(x,y))) - if ring == 0: - shapedict = dbf.read_record(npoly) + coords.append(list(zip(x,y))) + attdict={} + for r,key in zip(rec,fields[1:]): + attdict[key[0]]=r # add information about ring number to dictionary. - shapedict['RINGNUM'] = ring+1 - shapedict['SHAPENUM'] = npoly+1 - shpinfo.append(shapedict) - # draw shape boundaries using LineCollection. - if drawbounds: - # get current axes instance (if none specified). - ax = ax or self._check_ax() - # make LineCollections for each polygon. - lines = LineCollection(shpsegs,antialiaseds=(1,)) - lines.set_color(color) - lines.set_linewidth(linewidth) - lines.set_label('_nolabel_') - if zorder is not None: - lines.set_zorder(zorder) - ax.add_collection(lines) - # set axes limits to fit map region. - self.set_axes_limits(ax=ax) - info = info + (lines,) - # save segments/polygons and shape attribute dicts as class attributes. - self.__dict__[name]=shpsegs - self.__dict__[name+'_info']=shpinfo - shp.close() - dbf.close() + attdict['RINGNUM'] = ringnum + attdict['SHAPENUM'] = npoly + attributes.append(attdict) + # draw shape boundaries for polylines, polygons using LineCollection. + if shptype not in [1,8] and drawbounds: + # get current axes instance (if none specified). + ax = ax or self._check_ax() + # make LineCollections for each polygon. + lines = LineCollection(coords,antialiaseds=(1,)) + lines.set_color(color) + lines.set_linewidth(linewidth) + lines.set_label('_nolabel_') + if zorder is not None: + lines.set_zorder(zorder) + ax.add_collection(lines) + # set axes limits to fit map region. + self.set_axes_limits(ax=ax) + info = info + (lines,) + self.__dict__[name]=coords + self.__dict__[name+'_info']=attributes return info def drawparallels(self,circles,color='k',linewidth=1.,zorder=None, \ @@ -3150,7 +3144,7 @@ def barbs(self, x, y, u, v, *args, **kwargs): return retnh,retsh def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None, - lsmask_lons=None,lsmask_lats=None,lakes=False,**kwargs): + lsmask_lons=None,lsmask_lats=None,lakes=True,**kwargs): """ Draw land-sea mask image. @@ -3168,13 +3162,12 @@ def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None, Default gray ("0.8"). ocean_color desired ocean color (color name or rgba tuple). Default white. - lakes If True, inland lakes are also colored with - ocean_color (default is lakes=False). - lsmask An array of 0's for ocean pixels, 1's for - land pixels and optionally 2's for inland - lake pixels defining a global land-sea mask. - Default is None, and default - 5-minute resolution land-sea mask is used. + lsmask An array of 0's for ocean pixels and 1's for + land pixels defining a global land-sea mask. + Default is None + (default 2.5-minute resolution land-sea mask is used). + lakes Deprecated - currently ignored but kept for + backwards compatibility. Lakes are always plotted. lsmask_lons 1d array of longitudes for lsmask (ignored if lsmask is None). Longitudes must be ordered from -180 W eastward. @@ -3187,7 +3180,7 @@ def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None, If any of the lsmask, lsmask_lons or lsmask_lats keywords are not set, the default land-sea mask from - http://www.ngdc.noaa.gov/ecosys/cdroms/graham/graham/graham.htm. + http://www.shadedrelief.com/natural3/pages/extra.html is used. Extra keyword ``ax`` can be used to override the default axis instance. @@ -3221,7 +3214,6 @@ def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None, if self.lsmask is None: # read in land/sea mask. lsmask_lons, lsmask_lats, lsmask = _readlsmask() - # instance variable lsmask is set on first invocation, # it contains the land-sea mask interpolated to the native # projection grid. Further calls to drawlsmask will not @@ -3237,9 +3229,9 @@ def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None, # stack grids side-by-side (in longitiudinal direction), so # any range of longitudes may be plotted on a world map. lsmask_lons = \ - np.concatenate((lsmask_lons,lsmask_lons+360),1) + np.concatenate((lsmask_lons,lsmask_lons[1:]+360),1) lsmask = \ - np.concatenate((lsmask,lsmask),1) + np.concatenate((lsmask,lsmask[:,1:]),1) # transform mask to nx x ny regularly spaced native projection grid # nx and ny chosen to have roughly the same horizontal @@ -3271,11 +3263,6 @@ def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None, mask[j,:]=np.where(np.logical_or(xxxmax[j]),\ 255,mask[j,:]) self.lsmask = mask - # optionally, set lakes to ocean color. - if lakes: - mask = np.where(self.lsmask==2,0,self.lsmask) - else: - mask = self.lsmask ny, nx = mask.shape rgba = np.ones((ny,nx,4),np.uint8) rgba_land = np.array(rgba_land,np.uint8) @@ -3305,6 +3292,41 @@ def bluemarble(self,ax=None,scale=None,**kwargs): else: return self.warpimage(image='bluemarble',scale=scale,**kwargs) + def shadedrelief(self,ax=None,scale=None,**kwargs): + """ + display shaded relief image (from http://www.shadedreliefdata.com) + as map background. + Default image size is 10800x5400, which can be quite slow and + use quite a bit of memory. The ``scale`` keyword can be used + to downsample the image (``scale=0.5`` downsamples to 5400x2700). + + \**kwargs passed on to :meth:`imshow`. + + returns a matplotlib.image.AxesImage instance. + """ + if ax is not None: + return self.warpimage(image='shadedrelief',ax=ax,scale=scale,**kwargs) + else: + return self.warpimage(image='shadedrelief',scale=scale,**kwargs) + + def etopo(self,ax=None,scale=None,**kwargs): + """ + display etopo relief image (from + http://www.ngdc.noaa.gov/mgg/global/global.html) + as map background. + Default image size is 5400x2700, which can be quite slow and + use quite a bit of memory. The ``scale`` keyword can be used + to downsample the image (``scale=0.5`` downsamples to 5400x2700). + + \**kwargs passed on to :meth:`imshow`. + + returns a matplotlib.image.AxesImage instance. + """ + if ax is not None: + return self.warpimage(image='etopo',ax=ax,scale=scale,**kwargs) + else: + return self.warpimage(image='etopo',scale=scale,**kwargs) + def warpimage(self,image="bluemarble",scale=None,**kwargs): """ Display an image (filename given by ``image`` keyword) as a map background. @@ -3339,6 +3361,14 @@ def warpimage(self,image="bluemarble",scale=None,**kwargs): # from NASA (http://visibleearth.nasa.gov). if image == "bluemarble": file = os.path.join(basemap_datadir,'bmng.jpg') + # display shaded relief image (from + # http://www.shadedreliefdata.com) + elif image == "shadedrelief": + file = os.path.join(basemap_datadir,'shadedrelief.jpg') + # display etopo image (from + # http://www.ngdc.noaa.gov/mgg/image/globalimages.html) + elif image == "etopo": + file = os.path.join(basemap_datadir,'etopo1.jpg') else: file = image # if image is same as previous invocation, used cached data. @@ -3348,7 +3378,7 @@ def warpimage(self,image="bluemarble",scale=None,**kwargs): else: newfile = False if file.startswith('http'): - from urllib.request import urlretrieve + from urllib import urlretrieve self._bm_file, headers = urlretrieve(file) else: self._bm_file = file @@ -3976,7 +4006,7 @@ def _choosecorners(width,height,**kwargs): else: return corners -def maskoceans(lonsin,latsin,datain,inlands=False): +def maskoceans(lonsin,latsin,datain,inlands=True): """ mask data (``datain``), defined on a grid with latitudes ``latsin`` longitudes ``lonsin`` so that points over water will not be plotted. @@ -3990,9 +4020,9 @@ def maskoceans(lonsin,latsin,datain,inlands=False): grid. datain rank-2 input array on grid defined by ``lonsin`` and ``latsin``. - inlands if False, mask only ocean points. If True, mask - ocean points and points over inland water bodies. - Default False. + inlands Deprecated (set to True). In previous versions + if False, masked only ocean points and not inland + lakes. ============== ==================================================== returns a masked array the same shape as datain with "wet" points masked. @@ -4002,18 +4032,19 @@ def maskoceans(lonsin,latsin,datain,inlands=False): # nearest-neighbor interpolation to output grid. lsmasko = interp(lsmask,lsmask_lons,lsmask_lats,lonsin,latsin,masked=True,order=0) # mask input data. - if inlands: # mask inland water bodies. - mask = np.logical_or(lsmasko==0,lsmasko==2) - else: # mask just marine areas. - mask = lsmasko == 0 + mask = lsmasko == 0 return ma.masked_array(datain,mask=mask) def _readlsmask(): # read in land/sea mask. - lsmaskf = open(os.path.join(basemap_datadir,'5minmask.bin'),'rb') - nlons = 4320; nlats = nlons/2 + import gzip + lsmaskf = gzip.open(os.path.join(basemap_datadir,'lsmask.bin'),'rb') + nlons = 8192; nlats = nlons/2 + lsmask =\ + np.reshape(np.fromstring(lsmaskf.read(),dtype=np.uint8),(nlats,nlons)) + lsmask = np.where(lsmask==255,0,1) + lsmaskf.close() delta = 360./float(nlons) - lsmask = np.reshape(np.fromstring(lsmaskf.read(),np.uint8),(nlats,nlons)) lsmask_lons = np.arange(-180,180.,delta) lsmask_lats = np.arange(-90.,90+0.5*delta,delta) # add cyclic point in longitude diff --git a/lib/mpl_toolkits/basemap/data/5minmask.bin b/lib/mpl_toolkits/basemap/data/5minmask.bin deleted file mode 100644 index 6328b70e6..000000000 Binary files a/lib/mpl_toolkits/basemap/data/5minmask.bin and /dev/null differ diff --git a/lib/mpl_toolkits/basemap/data/lsmask.bin b/lib/mpl_toolkits/basemap/data/lsmask.bin new file mode 100644 index 000000000..1199a7ab8 Binary files /dev/null and b/lib/mpl_toolkits/basemap/data/lsmask.bin differ diff --git a/lib/mpl_toolkits/basemap/data/shadedrelief.jpg b/lib/mpl_toolkits/basemap/data/shadedrelief.jpg new file mode 100644 index 000000000..429930ae2 Binary files /dev/null and b/lib/mpl_toolkits/basemap/data/shadedrelief.jpg differ diff --git a/lib/mpl_toolkits/basemap/etopo1.jpg b/lib/mpl_toolkits/basemap/etopo1.jpg new file mode 100644 index 000000000..01259f43d Binary files /dev/null and b/lib/mpl_toolkits/basemap/etopo1.jpg differ diff --git a/lib/mpl_toolkits/basemap/shapefile.py b/lib/mpl_toolkits/basemap/shapefile.py new file mode 100644 index 000000000..05fe8943b --- /dev/null +++ b/lib/mpl_toolkits/basemap/shapefile.py @@ -0,0 +1,773 @@ +""" +shapefile.py +Provides read and write support for ESRI Shapefiles +author: jlawheadgeospatialpython.com +date: 20110131 +""" + +from struct import pack, unpack, calcsize, error +import os +import time +import array +import sys + +# python 2.5 compatibility for byte literals. +if sys.version < '3': + def b(x): + return x +else: + import codecs + def b(x): + return codecs.latin_1_encode(x)[0] + +# +# Constants for shape types +NULL = 0 +POINT = 1 +POLYLINE = 3 +POLYGON = 5 +MULTIPOINT = 8 +POINTZ = 11 +POLYLINEZ = 13 +POLYGONZ = 15 +MULTIPOINTZ = 18 +POINTM = 21 +POLYLINEM = 23 +POLYGONM = 25 +MULTIPOINTM = 28 +MULTIPATCH = 31 + +class _Array(array.array): + """Converts python tuples to lits of the appropritate type. + Used to unpack different shapefile header parts.""" + def __repr__(self): + return str(self.tolist()) + +class _Shape: + def __init__(self, shapeType=None): + """Stores the geometry of the different shape types + specified in the Shapefile spec. Shape types are + usually point, polyline, or polygons. Every shape type + except the "Null" type contains points at some level for + example verticies in a polygon. If a shape type has + multiple shapes containing points within a single + geometry record then those shapes are called parts. Parts + are designated by their starting index in geometry record's + list of shapes.""" + self.shapeType = shapeType + self.points = [] + +class _ShapeRecord: + """A shape object of any type.""" + def __init__(self, shape=None, record=None): + self.shape = shape + self.record = record + +class ShapefileException(Exception): + """An exception to handle shapefile specific problems.""" + pass + +class Reader: + """Reads the three files of a shapefile as a unit or + separately. If one of the three files (.shp, .shx, + .dbf) is missing no exception is thrown until you try + to call a method that depends on that particular file. + The .shx index file is used if available for efficiency + but is not required to read the geometry from the .shp + file. The "shapefile" argument in the constructor is the + name of the file you want to open. + + You can instantiate a Reader without specifying a shapefile + and then specify one later with the load() method. + + Only the shapefile headers are read upon loading. Content + within each file is only accessed when required and as + efficiently as possible. Shapefiles are usually not large + but they can be. + """ + def __init__(self, shapefile=None): + self.shp = None + self.shx = None + self.dbf = None + self.shapeName = "Not specified" + self._offsets = [] + self.shpLength = None + self.numRecords = None + self.fields = [] + self.__dbfHdrLength = 0 + self.load(shapefile) + + def load(self, shapefile=None): + """Opens a shapefile from a filename or file-like + object. Normally this method would be called by the + constructor with the file object or file name as an + argument.""" + if shapefile: + (shapeName, ext) = os.path.splitext(shapefile) + self.shapeName = shapeName + try: + self.shp = open("%s.shp" % shapeName, "rb") + self.__shpHeader() + except IOError: pass + try: + self.shx = open("%s.shx" % shapeName, "rb") + # self.__shapeIndex() + except IOError: pass + try: + self.dbf = open("%s.dbf" % shapeName, "rb") + self.__dbfHeader() + except IOError: pass + + def __getFileObj(self, f): + """Checks to see if the requested shapefile file object is + available. If not a ShapefileException is raised.""" + if not f: + raise ShapefileException("Required file not available.") + return f + + def __restrictIndex(self, i): + """Provides list-like handling of a record index with a clearer + error message if the index is out of bounds.""" + if self.numRecords: + max = self.numRecords - 1 + if abs(i) > max: + raise IndexError("Shape or Record index out of range.") + if i < 0: i = list(range(self.numRecords))[i] + return i + + def __shpHeader(self): + """Reads the header information from a .shp or .shx file.""" + f = self.__getFileObj(self.shp) + # File length (16-bit word * 2 = bytes) + f.seek(24) + self.shpLength = unpack(">i", f.read(4))[0] * 2 + # Shape type + f.seek(32) + self.shapeType= unpack("i", f.read(4))[0] + # The shapefile's bounding box (lower left, upper right) + self.bbox = _Array('d', unpack("<4d", f.read(32))) + # Elevation + self.elevation = _Array('d', unpack("<2d", f.read(16))) + # Measure + self.measure = _Array('d', unpack("<2d", f.read(16))) + + def __shape(self): + """Returns the header info and geometry for a single shape.""" + f = self.__getFileObj(self.shp) + record = _Shape() + nParts = nPoints = zmin = zmax = mmin = mmax = None + (recNum, recLength) = unpack(">2i", f.read(8)) + shapeType = unpack("i", f.read(4))[0] * 2) - 100 + numRecords = int(shxRecordLength / 8) + # Jump to the first record. + f.seek(100) + for r in range(numRecords): + # Offsets are 16-bit words just like the file length + self._offsets.append(unpack(">i", f.read(4))[0] * 2) + f.seek(f.tell() + 4) + if i: + return self._offsets[i] + + def shape(self, i=0): + """Returns a shape object for a shape in the the geometry + record file.""" + f = self.shp + i = self.__restrictIndex(i) + offset = self.__shapeIndex(i) + if not offset: + # Shx index not available so use the full list. + shapes = self.shapes() + return shapes[i] + f.seek(offset) + return self.__shape() + + def shapes(self): + """Returns all shapes in a shapefile.""" + self.shp.seek(100) + shapes = [] + while self.shp.tell() < self.shpLength: + shapes.append(self.__shape()) + return shapes + + def __dbfHeaderLength(self): + """Retrieves the header length of a dbf file header.""" + if not self.__dbfHdrLength: + f = self.__getFileObj(self.dbf) + (self.numRecords, self.__dbfHdrLength) = \ + unpack("6i", 9994,0,0,0,0,0)) + # File length (Bytes / 2 = 16-bit words) + if headerType == 'shp': + f.write(pack(">i", int(self.__shpFileLength()))) + elif headerType == 'shx': + f.write(pack('>i', int(((100 + (len(self._shapes) * 8)) / 2)))) + # Version, Shape type + f.write(pack("<2i", 1000, self.shapeType)) + # The shapefile's bounding box (lower left, upper right) + if self.shapeType != 0: + try: + f.write(pack("<4d", *self.bbox())) + except error: + raise ShapefileException("Failed to write shapefile bounding box. Floats required.") + else: + f.write(pack("<4d", 0,0,0,0)) + # Elevation + z = self.zbox() + # Measure + m = self.mbox() + try: + f.write(pack("<4d", z[0], z[1], m[0], m[1])) + except error: + raise ShapefileException("Failed to write shapefile elevation and measure values. Floats required.") + + def __dbfHeader(self): + """Writes the dbf header and field descriptors.""" + f = self.__getFileObj(self.dbf) + f.seek(0) + version = 3 + year, month, day = time.localtime()[:3] + year -= 1900 + # Remove deletion flag placeholder from fields + for field in self.fields: + if field[0][:8] == (b('Deletion')): + self.fields.remove(field) + numRecs = len(self.records) + numFields = len(self.fields) + headerLength = numFields * 32 + 33 + recordLength = sum([int(field[2]) for field in self.fields]) + 1 + header = pack('2i", recNum, 0)) + recNum += 1 + start = f.tell() + # Shape Type + f.write(pack("i", int(length))) + f.seek(finish) + + def __shxRecords(self): + """Writes the shx records.""" + f = self.__getFileObj(self.shx) + f.seek(100) + for i in range(len(self._shapes)): + f.write(pack(">i", int(self._offsets[i]/2))) + f.write(pack(">i", int(self._lengths[i]))) + + def __dbfRecords(self): + """Writes the dbf records.""" + f = self.__getFileObj(self.dbf) + for record in self.records: + if not self.fields[0][0].startswith("Deletion"): + f.write(pack('c', ' ')) # deletion flag + for (fieldName, fieldType, size, decimal), value in zip(self.fields, record): + fieldType = fieldType.upper() + size = int(size) + if fieldType.upper() == "N": + value = value.rjust(size) + elif fieldType == 'L': + value = value[0].upper() + else: + value = value[:size].ljust(size) + assert len(value) == size + f.write(pack('%ss' % len(value), value)) + + def null(self): + """Creates a null shape.""" + self._shapes.append(_Shape(NULL)) + + def point(self, x, y, z=0, m=0): + """Creates a point shape.""" + pointShape = _Shape(POINT) + pointShape.points.append([x, y, z, m]) + self._shapes.append(pointShape) + + def line(self, parts=[], shapeType=POLYLINE): + """Creates a line shape. This method is just a convienience method + which wraps 'poly()'. + """ + self.poly(parts, shapeType, []) + + def poly(self, parts=[], shapeType=POLYGON, partTypes=[]): + """Creates a shape that has multiple collections of points (parts) + including lines, polygons, and even multipoint shapes. If no shape type + is specified it defaults to 'polygon'. If no part types are specified + (which they normally won't be) then all parts default to the shape type. + """ + polyShape = _Shape(shapeType) + polyShape.parts = [] + polyShape.points = [] + for part in parts: + polyShape.parts.append(len(polyShape.points)) + for point in part: + # Make sure point has z and m values + while len(point) < 4: + point.append(0) + polyShape.points.append(point) + if polyShape.shapeType == 31: + if not partTypes: + for part in parts: + partTypes.append(polyShape.shapeType) + polyShape.partTypes = partTypes + self._shapes.append(polyShape) + + def field(self, name, fieldType="C", size="50", decimal=0): + """Adds a dbf field descriptor to the shapefile.""" + self.fields.append((name, fieldType, size, decimal)) + + def record(self, *recordList, **recordDict): + """Creates a dbf attribute record. You can submit either a sequence of + field values or keyword arguments of field names and values. Before + adding records you must add fields for the record values using the + fields() method. If the record values exceed the number of fields the + extra ones won't be added. In the case of using keyword arguments to specify + field/value pairs only fields matching the already registered fields + will be added.""" + record = [] + fieldCount = len(self.fields) + # Compensate for deletion flag + if self.fields[0][0].startswith("Deletion"): fieldCount -= 1 + if recordList: + [record.append(recordList[i]) for i in range(fieldCount)] + elif recordDict: + for field in self.fields: + if field[0] in recordDict: + val = recordDict[field[0]] + if val: + record.append(val) + else: + record.append("") + if record: + self.records.append(record) + + def shape(self, i): + return self._shapes[i] + + def shapes(self): + """Return the current list of shapes.""" + return self._shapes + + def saveShp(self, target): + """Save an shp file.""" + target = os.path.splitext(target)[0] + '.shp' + if not self.shapeType: + self.shapeType = self._shapes[0].shapeType + self.shp = self.__getFileObj(target) + self.__shapefileHeader(self.shp, headerType='shp') + self.__shpRecords() + self.shp.close() + + def saveShx(self, target): + """Save an shx file.""" + target = os.path.splitext(target)[0] + '.shx' + if not self.shapeType: + self.shapeType = self._shapes[0].shapeType + self.shx = self.__getFileObj(target) + self.__shapefileHeader(self.shx, headerType='shx') + self.__shxRecords() + self.shx.close() + + def saveDbf(self, target): + """Save a dbf file.""" + target = os.path.splitext(target)[0] + '.dbf' + self.dbf = self.__getFileObj(target) + self.__dbfHeader() + self.__dbfRecords() + self.dbf.close() + + def save(self, target=""): + """Save the shapefile data to three files or + three file-like objects. SHP and DBF files can + be written exclusively using saveShp, saveShx, and saveDbf respectively.""" + # TODO: Create a unique filename for target if None. + self.saveShp(target) + self.saveShx(target) + self.saveDbf(target) diff --git a/lib/shapelib/__init__.py b/lib/shapelib/__init__.py deleted file mode 100644 index 366d494ae..000000000 --- a/lib/shapelib/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from shapelib import * diff --git a/lib/shapelib/shapelib.py b/lib/shapelib/shapelib.py deleted file mode 100644 index d981a6423..000000000 --- a/lib/shapelib/shapelib.py +++ /dev/null @@ -1,119 +0,0 @@ -# This file was created automatically by SWIG. -import shapelibc -class SHPObject: - def __init__(self,*args): - self.this = apply(shapelibc.new_SHPObject,args) - self.thisown = 1 - - def __del__(self,shapelibc=shapelibc): - if self.thisown == 1 : - shapelibc.delete_SHPObject(self) - def extents(*args): - val = apply(shapelibc.SHPObject_extents,args) - return val - def vertices(*args): - val = apply(shapelibc.SHPObject_vertices,args) - return val - __setmethods__ = { - } - def __setattr__(self,name,value): - if (name == "this") or (name == "thisown"): self.__dict__[name] = value; return - method = SHPObject.__setmethods__.get(name,None) - if method: return method(self,value) - self.__dict__[name] = value - __getmethods__ = { - "type" : shapelibc.SHPObject_type_get, - "id" : shapelibc.SHPObject_id_get, - } - def __getattr__(self,name): - method = SHPObject.__getmethods__.get(name,None) - if method: return method(self) - raise AttributeError,name - def __repr__(self): - return "" % (self.this,) -class SHPObjectPtr(SHPObject): - def __init__(self,this): - self.this = this - self.thisown = 0 - self.__class__ = SHPObject - - - -class ShapeFile: - def __init__(self,*args): - self.this = apply(shapelibc.new_ShapeFile,args) - self.thisown = 1 - - def __del__(self,shapelibc=shapelibc): - if self.thisown == 1 : - shapelibc.delete_ShapeFile(self) - def close(*args): - val = apply(shapelibc.ShapeFile_close,args) - return val - def info(*args): - val = apply(shapelibc.ShapeFile_info,args) - return val - def read_object(*args): - val = apply(shapelibc.ShapeFile_read_object,args) - if val: val = SHPObjectPtr(val) ; val.thisown = 1 - return val - def write_object(*args): - val = apply(shapelibc.ShapeFile_write_object,args) - return val - def cobject(*args): - val = apply(shapelibc.ShapeFile_cobject,args) - return val - def __repr__(self): - return "" % (self.this,) -class ShapeFilePtr(ShapeFile): - def __init__(self,this): - self.this = this - self.thisown = 0 - self.__class__ = ShapeFile - - - - - -#-------------- FUNCTION WRAPPERS ------------------ - -def open(*args, **kwargs): - val = apply(shapelibc.open,args,kwargs) - if val: val = ShapeFilePtr(val); val.thisown = 1 - return val - -def create(*args, **kwargs): - val = apply(shapelibc.create,args,kwargs) - if val: val = ShapeFilePtr(val); val.thisown = 1 - return val - -c_api = shapelibc.c_api - -type_name = shapelibc.type_name - -part_type_name = shapelibc.part_type_name - - - -#-------------- VARIABLE WRAPPERS ------------------ - -SHPT_NULL = shapelibc.SHPT_NULL -SHPT_POINT = shapelibc.SHPT_POINT -SHPT_ARC = shapelibc.SHPT_ARC -SHPT_POLYGON = shapelibc.SHPT_POLYGON -SHPT_MULTIPOINT = shapelibc.SHPT_MULTIPOINT -SHPT_POINTZ = shapelibc.SHPT_POINTZ -SHPT_ARCZ = shapelibc.SHPT_ARCZ -SHPT_POLYGONZ = shapelibc.SHPT_POLYGONZ -SHPT_MULTIPOINTZ = shapelibc.SHPT_MULTIPOINTZ -SHPT_POINTM = shapelibc.SHPT_POINTM -SHPT_ARCM = shapelibc.SHPT_ARCM -SHPT_POLYGONM = shapelibc.SHPT_POLYGONM -SHPT_MULTIPOINTM = shapelibc.SHPT_MULTIPOINTM -SHPT_MULTIPATCH = shapelibc.SHPT_MULTIPATCH -SHPP_TRISTRIP = shapelibc.SHPP_TRISTRIP -SHPP_TRIFAN = shapelibc.SHPP_TRIFAN -SHPP_OUTERRING = shapelibc.SHPP_OUTERRING -SHPP_INNERRING = shapelibc.SHPP_INNERRING -SHPP_FIRSTRING = shapelibc.SHPP_FIRSTRING -SHPP_RING = shapelibc.SHPP_RING diff --git a/pyshapelib/COPYING b/pyshapelib/COPYING deleted file mode 100644 index 92b8903ff..000000000 --- a/pyshapelib/COPYING +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library 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 Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/pyshapelib/ChangeLog b/pyshapelib/ChangeLog deleted file mode 100644 index 75dcab853..000000000 --- a/pyshapelib/ChangeLog +++ /dev/null @@ -1,193 +0,0 @@ -2005-06-30 Bernhard Herzog - - * shapelib.i (new_SHPObject): Fix the test for the length of the - part types. It used the wrong variable. - - * shapelib_wrap.c: Regenerated from shapelib.i - - * pytest.py (make_shapefile): Add some more comments and add an - example with a polygon with a hole. - -2004-12-27 Bernhard Reiter - - * README: Refering to the new homepage shapelib.maptools.org now. - -2004-12-13 Bernhard Herzog - - * dbflib.py: Updated from difflib.i with SWIG. - - * dbflib.i: Work around a bug in the generated python code which - leads to exception in the __del__ method when the constructor - fails. See the comments in the code for more details. - -2004-05-28 Bernhard Herzog - - * README: Flesh out the some more. Correct the shapelib - requirements. - - * NEWS: Update the date of the actual release of 0.3 - -2004-05-28 Bernhard Herzog - - * setup.py: Determine shp_dir correctly when run with bdist_rpm - (dbf_macros): Remove a debug print - - * NEWS: Also mention the new (compared to 0.2) setup.py - - * MANIFEST.in: New. Define which files belong into a source - distribution - -2004-05-17 Bernhard Herzog - - * README: Update for new release - - * setup.py (dbf_macros): New. Return the preprocessor macros - needed to compile the dbflib wrapper. Determine whether - DBFUpdateHeader is available and define the right value of - HAVE_UPDATE_HEADER - (extensions): Use dbf_macros for the dbflibc extension - - * dbflib_wrap.c, dbflib.py: Update from dbflib.i - - * dbflib.i (DBFInfo_commit): New. Implementation of the commit - method. This new indirection is necessary because we use the - DBFUpdateHeader function now which is not available in shapelib <= - 1.2.10 - (DBFFile::commit): Use DBFInfo_commit as implementation - (pragma __class__): New. Kludge to remove the commit method when - the DBFUpdateHeader function isn't available - (_have_commit): New. Helper for the pragma kludge. - -2003-11-03 Bernhard Herzog - - * dbflib.i (do_read_attribute): New helper function for reading - one attribute as a python object - (DBFInfo_read_attribute): New. Implement the read_attribute method - (DBFInfo_read_record): Use do_read_attribute to read the - individual values - (struct DBFFile): Add the read_attribute method. - - * dbflib_wrap.c, dbflib.py: Update from dbflib.i. - -2003-09-29 Bernhard Herzog - - * dbflib.i: Add exception typemap for the add_field method. Fixes - Thuban bug RT#1842 - - * dbflib_wrap.c: Update from dbflib.i - - * testdbf.py: New. Test cases for the dbflib bindings based on the - unittest module - -2003-08-18 Bernhard Herzog - - * dbflib.i (DBFInfo_write_record): Use PySequence_Check instead of - PyMapping_Check to distinguish between sequences and mappings - because in Python 2.3, PyMapping_Check returns true for tuples and - lists too. - -2003-05-28 Bernhard Herzog - - * dbflib.i (DBFInfo_read_record): Read NULL fields as None unless - it's a string field. DBF files can't distinguish between NULL and - an empty string. Also, check the return value of - DBFReadStringAttribute which may return NULL to indicate errors. - - * dbflib_wrap.c: Updated from dbflib.i - -2002-08-27 Bernhard Herzog - - * dbflib.i: Raise an exception if open or create fails. - - * shapelib.i: Slightly better wording for the IOError exception - that open and create may raise. - - * shapelib_wrap.c, dbflib_wrap.c: Regenerated - -2002-08-22 Bernhard Herzog - - * dbflib.i (DBFFile::commit): New method for DBFCommit. - - * dbflib_wrap.c, dbflib.py: Update from dbflib.i - -2002-08-15 Bernhard Herzog - - * shapelib.i, dbflib.i: Make the NOCHECK trick for the ShapeFile * - check typemap work with SWIG 1.3. - - * shapelib_wrap.c, dbflib_wrap.c: Regenerate from the .i files. - -2002-05-10 Bernhard Herzog - - * dbflib.i (DBFInfo_write_record): Only DECREF if the return value - of PyMapping_GetItemString is not NULL. Also, test the return - value of PySequence_GetItem - (write_field): Remove some debug prints - - * dbflib_wrap.c: Updated from dbflib.i - -2002-05-07 Bernhard Herzog - - * shptreemodule.c (SHPTreeType, initshptree): Set SHPTreeType's - PyType_Type pointer in the init function. - (shptree_methods): Use METH_VARARGS - (shptree_dealloc): Use PyMem_DEL - (shptree_find_shapes): Add a missing return - -2002-05-07 Bernhard Herzog - - * shptreemodule.c: New file with a simple wrapper for shapelib's - quadtree - - * setup.py: Some fixes to use explicit forward slashes as - directory separators because of distutils. - (extensions): Add the shptree module. - - * pytest.py (read_shapefile): Add some demo calls for the shptree - module - - * pyshapelib_api.h (PyShapeLibAPI): Add some of the shptree - functions. - (PYSHAPELIB_IMPORT_API): New macro to import the API - - * shapelib.i (the_api): add the tree API functions. - - * shapelib_wrap.c: Updated from shapelib.i with SWIG. - -2002-04-11 Bernhard Herzog - - * pyshapelib_api.h: New file with a limited C-level API for - accessing shapilib functions from other Python-extensions. - - * shapelib.i: Export the C-level API with the c_api function. - - * shapelib.py, shapelib_wrap.c: Updated from shapelib.i. Still - done with a very old version of SWIG, but it's probably not worth - it to try it with a newer version as long as this still works. - -2001-07-18 Bernhard Herzog - - * shapelib.i (open_ShapeFile): declare the swig prototype - correctly with ShapeFile* as return type - (ShapeFile.cobject): New method returning the SHPHandle* as a - CObject - - * Makefile (VERSION): Increase to 0.3 - - * setup.py, MANIFEST.in: New files for python distutils. - -2001-06-15 Bernhard Herzog - - * Makefile (VERSION): Increase to 0.2 - -2001-06-14 Bernhard Herzog - - * shapelib.i: Add the functions SHPTypeName as type_name and - SHPPartTypeName as part_type_name - (SHPObject_vertices): - (build_vertex_list): Put building a list of vertices into the - separate function build_vertex_list so that SHPObject_vertices can - support SHPT_POINT too. - - * ChangeLog: create ChangeLog - diff --git a/pyshapelib/MANIFEST.in b/pyshapelib/MANIFEST.in deleted file mode 100644 index 5d8bf8673..000000000 --- a/pyshapelib/MANIFEST.in +++ /dev/null @@ -1,8 +0,0 @@ -include README COPYING ChangeLog NEWS -include *.i *.c *.py *.h -include MANIFEST.in - -# prune the references to the shapelib files which are in either .. or -# ../shapelib. These are pulled in by distutils because they're -# referenced by the Extension objects -prune .. diff --git a/pyshapelib/NEWS b/pyshapelib/NEWS deleted file mode 100644 index 7fc900db4..000000000 --- a/pyshapelib/NEWS +++ /dev/null @@ -1,43 +0,0 @@ -pyshapelib 0.3 (2004-05-28) -=========================== - - * New module shptree. It's a simple wrapper for shapelib's quadtree. - - * Provide a way to access the shapelib module and shapefile objects - from C. It's not documented, unfortunately, but pyshapelib_api.h may - be a starting point. This feature is used in Thuban which could be - used as an example. - - * distutils based build and install script, setup.py - -Module dbflib: - - * dbf objects now have a method commit if compiled with shapelib newer - than 1.2.10 (that is only the CVS version of shapelib at the time of - writing). This method calls the new function dbflib DBFUpdateHeader. - - * New method read_attribute which reads a single attribute instead of a - whole record like read_record - - * NULL values are now returned as None. DBF files don't really support - NULL, but this change matches a new feature in shapelib 1.2.9. It's - not clear whether it should be implemented in the python wrapper in - this way. It might be better to make it optional. - - -pyshapelib 0.2 (2001-06-15) -=========================== - -Module shapelib: - - * new module level functions type_name and part_type_name - (corresponding to SHPTypeName and SHPPartTypeName) - - * The vertices() method of shape objects works for shape type - SHPT_POINT, too. - - -pyshapelib 0.1 (2000-12-20) -=========================== - -Initial public release diff --git a/pyshapelib/README b/pyshapelib/README deleted file mode 100644 index b41d140c8..000000000 --- a/pyshapelib/README +++ /dev/null @@ -1,98 +0,0 @@ - -Python bindings for Shapelib -============================ - -These are three python modules for shapelib: - - shapelib read/write shapefiles - - dbflib read/write dbf files - - shptree quadtree for shapes - -Shapelib is a free software library for reading and writing ESRI shape -files and can be found at http://shapelib.maptools.org/. - -The bindings were partly created with SWIG, a tool that can generate -wrappers of C and C++ libraries for a variety of scripting languages. -It's homepage is http://www.swig.org. - -The bindings themselves don't have a homepage at the moment, but the -source tarballs/zip files can be downloaded from -http://ftp.intevation.de/users/bh/pyshapelib/ - - -Requirements ------------- - -To compile the bindings, you need shapelib 1.2.9 or newer and Python 2.0 -or newer. - -SWIG is not required. The files generated by SWIG are contained in the -archive. If you modify shapelib.i or dbflib.i and need to recreate the -generated files, you need SWIG 1.3 Alpha 5. It's unlikely that other -versions will work. - -You also need Python, of course. If you installed prebuilt packages -such as RPMs of some Linux distributions, please make sure that the -development package is also installed. - - -License -------- - -The shapelib python bindings are covered by the LGPL. See COPYING for -more information. - - -Compilation and Installation ----------------------------- - -Pyshapelib uses the python distutils which come with Python 2.0 or newer -and are also available separately from python.org for older versions. - -To compile the bindings, unpack the archive under the shapelib archive -or move the directory there if you've already unpacked it. The setup -script expects to find the shapelib files in the parent directory. Then -run - - python setup.py build - -to build the bindings. The result can be found under the (new) build -subirectory. - -To install run - - python setup.py install - -which will install the bindings into python's site-packages directory. -You can use the intall command's --prefix option to select a different -installatin directory. - -For more information about the setup.py script, invoke it with the ---help option: - - python setup.py --help - - -Documentation -------------- - -There's no real documentation for the python bindings themselves, but -there's a simple demo/test script called pytest.py. - -The change history is recorded in NEWS and in detail in ChangeLog. - - -Contact Information -------------------- - -pyshapelib is currently being developed as part of the interactive -viewer for geographic data Thuban, so the best way to reach the -developers is to post on the Thuban mailing lists. - -Thuban: - http://thuban.intevation.org/ - -Thuban mailing lists: - http://thuban.intevation.org/mailinglist.html diff --git a/pyshapelib/dbflib.i b/pyshapelib/dbflib.i deleted file mode 100644 index ee4f13fe0..000000000 --- a/pyshapelib/dbflib.i +++ /dev/null @@ -1,597 +0,0 @@ -/* SWIG (www.swig.org) interface file for the dbf interface of shapelib - * - * At the moment (Dec 2000) this file is only useful to generate Python - * bindings. Invoke swig as follows: - * - * swig -python -shadow dbflib.i - * - * to generate dbflib_wrap.c and dbflib.py. dbflib_wrap.c defines a - * bunch of Python-functions that wrap the appripriate dbflib functions - * and dbflib.py contains an object oriented wrapper around - * dbflib_wrap.c. - * - * This module defines one object type: DBFFile. - */ - -/* this is the dbflib module */ -%module dbflib - -/* first a %{,%} block. These blocks are copied verbatim to the - * dbflib_wrap.c file and are not parsed by SWIG. This is the place to - * import headerfiles and define helper-functions that are needed by the - * automatically generated wrappers. - */ - -%{ -#include "shapefil.h" - - -/* Read one attribute from the dbf handle and return it as a new python object - * - * If an error occurs, set the appropriate Python exception and return - * NULL. - * - * Assume that the values of the record and field arguments are valid. - * The name argument will be passed to DBFGetFieldInfo as is and should - * thus be either NULL or a pointer to an array of at least 12 chars - */ -static PyObject * -do_read_attribute(DBFInfo * handle, int record, int field, char * name) -{ - int type, width; - PyObject *value; - - type = DBFGetFieldInfo(handle, field, name, &width, NULL); - /* For strings NULL and the empty string are indistinguishable - * in DBF files. We prefer empty strings instead for backwards - * compatibility reasons because older wrapper versions returned - * emtpy strings as empty strings. - */ - if (type != FTString && DBFIsAttributeNULL(handle, record, field)) - { - value = Py_None; - Py_INCREF(value); - } - else - { - switch (type) - { - case FTString: - { - const char * temp = DBFReadStringAttribute(handle, record, field); - if (temp) - { - value = PyString_FromString(temp); - } - else - { - PyErr_Format(PyExc_IOError, - "Can't read value for row %d column %d", - record, field); - value = NULL; - } - break; - } - case FTInteger: - value = PyInt_FromLong(DBFReadIntegerAttribute(handle, record, - field)); - break; - case FTDouble: - value = PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, - field)); - break; - default: - PyErr_Format(PyExc_TypeError, "Invalid field data type %d", - type); - value = NULL; - } - } - if (!value) - return NULL; - - return value; -} - -/* the read_attribute method. Return the value of the given record and - * field as a python object of the appropriate type. - * - * In case of error, set a python exception and return NULL. Since that - * value will be returned to the python interpreter as is, the - * interpreter should recognize the exception. - */ - -static PyObject * -DBFInfo_read_attribute(DBFInfo * handle, int record, int field) -{ - if (record < 0 || record >= DBFGetRecordCount(handle)) - { - PyErr_Format(PyExc_ValueError, - "record index %d out of bounds (record count: %d)", - record, DBFGetRecordCount(handle)); - return NULL; - } - - if (field < 0 || field >= DBFGetFieldCount(handle)) - { - PyErr_Format(PyExc_ValueError, - "field index %d out of bounds (field count: %d)", - field, DBFGetFieldCount(handle)); - return NULL; - } - - return do_read_attribute(handle, record, field, NULL); -} - - -/* the read_record method. Return the record record as a dictionary with - * whose keys are the names of the fields, and their values as the - * appropriate Python type. - * - * In case of error, set a python exception and return NULL. Since that - * value will be returned to the python interpreter as is, the - * interpreter should recognize the exception. - */ - -static PyObject * -DBFInfo_read_record(DBFInfo * handle, int record) -{ - int num_fields; - int i; - int type, width; - char name[12]; - PyObject *dict; - PyObject *value; - - if (record < 0 || record >= DBFGetRecordCount(handle)) - { - PyErr_Format(PyExc_ValueError, - "record index %d out of bounds (record count: %d)", - record, DBFGetRecordCount(handle)); - return NULL; - } - - dict = PyDict_New(); - if (!dict) - return NULL; - - num_fields = DBFGetFieldCount(handle); - for (i = 0; i < num_fields; i++) - { - value = do_read_attribute(handle, record, i, name); - if (!value) - goto fail; - - PyDict_SetItemString(dict, name, value); - Py_DECREF(value); - } - - return dict; - - fail: - Py_XDECREF(dict); - return NULL; -} - -/* the write_record method. Write the record record given wither as a - * dictionary or a sequence (i.e. a list or a tuple). - * - * If it's a dictionary the keys must be the names of the fields and - * their value must have a suitable type. Only the fields actually - * contained in the dictionary are written. Fields for which there's no - * item in the dict are not modified. - * - * If it's a sequence, all fields must be present in the right order. - * - * In case of error, set a python exception and return NULL. Since that - * value will be returned to the python interpreter as is, the - * interpreter should recognize the exception. - * - * The method is implemented with two c-functions, write_field to write - * a single field and DBFInfo_write_record as the front-end. - */ - - -/* write a single field of a record. */ -static int -write_field(DBFHandle handle, int record, int field, int type, - PyObject * value) -{ - char * string_value; - int int_value; - double double_value; - - if (value == Py_None) - { - if (!DBFWriteNULLAttribute(handle, record, field)) - { - PyErr_Format(PyExc_IOError, - "can't write NULL field %d of record %d", - field, record); - return 0; - } - } - else - { - switch (type) - { - case FTString: - string_value = PyString_AsString(value); - if (!string_value) - return 0; - if (!DBFWriteStringAttribute(handle, record, field, string_value)) - { - PyErr_Format(PyExc_IOError, - "can't write field %d of record %d", - field, record); - return 0; - } - break; - - case FTInteger: - int_value = PyInt_AsLong(value); - if (int_value == -1 && PyErr_Occurred()) - return 0; - if (!DBFWriteIntegerAttribute(handle, record, field, int_value)) - { - PyErr_Format(PyExc_IOError, - "can't write field %d of record %d", - field, record); - return 0; - } - break; - - case FTDouble: - double_value = PyFloat_AsDouble(value); - if (double_value == -1 && PyErr_Occurred()) - return 0; - if (!DBFWriteDoubleAttribute(handle, record, field, double_value)) - { - PyErr_Format(PyExc_IOError, - "can't write field %d of record %d", - field, record); - return 0; - } - break; - - default: - PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type); - return 0; - } - } - - return 1; -} - -static -PyObject * -DBFInfo_write_record(DBFHandle handle, int record, PyObject *record_object) -{ - int num_fields; - int i, length; - int type, width; - char name[12]; - PyObject * value = NULL; - - num_fields = DBFGetFieldCount(handle); - - /* We used to use PyMapping_Check to test whether record_object is a - * dictionary like object instead of PySequence_Check to test - * whether it's a sequence. Unfortunately in Python 2.3 - * PyMapping_Check returns true for lists and tuples too so the old - * approach doesn't work anymore. - */ - if (PySequence_Check(record_object)) - { - /* It's a sequence object. Iterate through all items in the - * sequence and write them to the appropriate field. - */ - length = PySequence_Length(record_object); - if (length != num_fields) - { - PyErr_SetString(PyExc_TypeError, - "record must have one item for each field"); - goto fail; - } - for (i = 0; i < length; i++) - { - type = DBFGetFieldInfo(handle, i, name, &width, NULL); - value = PySequence_GetItem(record_object, i); - if (value) - { - if (!write_field(handle, record, i, type, value)) - goto fail; - Py_DECREF(value); - } - else - { - goto fail; - } - } - } - else - { - /* It's a dictionary-like object. Iterate over the names of the - * known fields and write the corresponding item - */ - for (i = 0; i < num_fields; i++) - { - type = DBFGetFieldInfo(handle, i, name, &width, NULL); - - /* if the dictionary has the key name write that object to - * the appropriate field, other wise just clear the python - * exception and do nothing. - */ - value = PyMapping_GetItemString(record_object, name); - if (value) - { - if (!write_field(handle, record, i, type, value)) - goto fail; - Py_DECREF(value); - } - else - { - PyErr_Clear(); - } - } - } - - Py_INCREF(Py_None); - return Py_None; - - fail: - Py_XDECREF(value); - return NULL; -} -%} - - -/* The commit method implementation - * - * The method relies on the DBFUpdateHeader method which is not - * available in shapelib <= 1.2.10. setup.py defines - * HAVE_UPDATE_HEADER's value depending on whether the function is - * available in the shapelib version the code is compiled with. - */ -%{ -static -void -DBFInfo_commit(DBFHandle handle) -{ -#if HAVE_UPDATE_HEADER - DBFUpdateHeader(handle); -#endif -} -%} - - -/* - * The SWIG Interface definition. - */ - -/* include some common SWIG type definitions and standard exception - handling code */ -%include typemaps.i -%include exception.i - -/* As for ShapeFile in shapelib.i, We define a new C-struct that holds - * the DBFHandle. This is mainly done so we can separate the close() - * method from the destructor but it also helps with exception handling. - * - * After the DBFFile has been opened or created the handle is not NULL. - * The close() method closes the file and sets handle to NULL as an - * indicator that the file has been closed. - */ - -%{ - typedef struct { - DBFHandle handle; - } DBFFile; -%} - - -/* The first argument to the DBFFile methods is a DBFFile pointer. - * We have to check whether handle is not NULL in most methods but not - * all. In the destructor and the close method, it's OK for handle to be - * NULL. We achieve this by checking whether the preprocessor macro - * NOCHECK_$name is defined. SWIG replaces $name with the name of the - * function for which the code is inserted. In the %{,%}-block below we - * define the macros for the destructor and the close() method. - */ - -%typemap(python,check) DBFFile *{ -%#ifndef NOCHECK_$name - if (!$target || !$target->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); -%#endif -} - -%{ -#define NOCHECK_delete_DBFFile -#define NOCHECK_DBFFile_close -%} - - -/* An exception handle for the constructor and the module level open() - * and create() functions. - * - * Annoyingly, we *have* to put braces around the SWIG_exception() - * calls, at least in the python case, because of the way the macro is - * written. Of course, always putting braces around the branches of an - * if-statement is often considered good practice. - */ -%typemap(python,except) DBFFile * { - $function; - if (!$source) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!$source->handle) - { - SWIG_exception(SWIG_IOError, "$name failed"); - } -} - -/* Exception handler for the add_field method */ -%typemap(python,except) int DBFFile_add_field { - $function; - if ($source < 0) - { - SWIG_exception(SWIG_RuntimeError, "add_field failed"); - } -} - -/* define and use some typemaps for the field_info() method whose - * C-implementation has three output parameters that are returned - * through pointers passed into the function. SWIG already has - * definitions for common types such as int* and we can use those for - * the last two parameters: - */ - -%apply int * OUTPUT { int * output_width } -%apply int * OUTPUT { int * output_decimals } - -/* the fieldname has to be defined manually: */ -%typemap(python,ignore) char *fieldname_out(char temp[12]) { - $target = temp; -} - -%typemap(python,argout) char *fieldname_out() { - PyObject * string = PyString_FromString($source); - $target = t_output_helper($target,string); -} - - - -/* - * The SWIG-version of the DBFFile struct - */ - -typedef struct -{ - %addmethods { - DBFFile(const char *file, const char * mode = "rb") { - DBFFile * self = malloc(sizeof(DBFFile)); - if (self) - self->handle = DBFOpen(file, mode); - return self; - } - - ~DBFFile() { - if (self->handle) - DBFClose(self->handle); - free(self); - } - - void close() { - if (self->handle) - DBFClose(self->handle); - self->handle = NULL; - } - - int field_count() { - return DBFGetFieldCount(self->handle); - } - - int record_count() { - return DBFGetRecordCount(self->handle); - } - - int field_info(int iField, char * fieldname_out, - int * output_width, int * output_decimals) { - return DBFGetFieldInfo(self->handle, iField, fieldname_out, - output_width, output_decimals); - } - - PyObject * read_record(int record) { - return DBFInfo_read_record(self->handle, record); - } - - PyObject * read_attribute(int record, int field) { - return DBFInfo_read_attribute(self->handle, record, field); - } - - int add_field(const char * pszFieldName, DBFFieldType eType, - int nWidth, int nDecimals) { - return DBFAddField(self->handle, pszFieldName, eType, nWidth, - nDecimals); - } - - PyObject *write_record(int record, PyObject *dict_or_sequence) { - return DBFInfo_write_record(self->handle, record, - dict_or_sequence); - } - - void commit() { - DBFInfo_commit(self->handle); - } - /* Delete the commit method from the class if it doesn't have a - * real implementation. - */ - %pragma(python) addtomethod="__class__:if not dbflibc._have_commit: del commit" - - /* The __del__ method generated by the old SWIG version we're - * tries to access self.thisown which may not be set at all when - * there was an exception during construction. Therefore we - * override it with our own version. - * FIXME: It would be better to upgrade to a newer SWIG version - * or to get rid of SWIG entirely. - */ - %pragma(python) addtoclass = " - def __del__(self,dbflibc=dbflibc): - if getattr(self, 'thisown', 0): - dbflibc.delete_DBFFile(self) - " - - - } -} DBFFile; - - -/* - * Two module level functions, open() and create() that correspond to - * DBFOpen and DBFCreate respectively. open() is equivalent to the - * DBFFile constructor. - */ - - -%{ - DBFFile * open_DBFFile(const char * file, const char * mode) - { - DBFFile * self = malloc(sizeof(DBFFile)); - if (self) - self->handle = DBFOpen(file, mode); - return self; - } -%} - -%name(open) %new DBFFile * open_DBFFile(const char * file, - const char * mode = "rb"); - -%{ - DBFFile * create_DBFFile(const char * file) - { - DBFFile * self = malloc(sizeof(DBFFile)); - if (self) - self->handle = DBFCreate(file); - return self; - } -%} -%name(create) %new DBFFile * create_DBFFile(const char * file); - - - -/* constant definitions copied from shapefil.h */ -typedef enum { - FTString, - FTInteger, - FTDouble, - FTInvalid -} DBFFieldType; - - -/* Put the value of the HAVE_UPDATE_HEADER preprocessor macro into the - * wrapper so that the __class__ pragma above knows when to remove the - * commit method - */ -const int _have_commit = HAVE_UPDATE_HEADER; - diff --git a/pyshapelib/dbflib_wrap.c b/pyshapelib/dbflib_wrap.c deleted file mode 100644 index f6192db3d..000000000 --- a/pyshapelib/dbflib_wrap.c +++ /dev/null @@ -1,1421 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3u-20020503-1857 (Alpha 5) - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -#define SWIGPYTHON -/*********************************************************************** - * common.swg - * - * This file contains generic SWIG runtime support for pointer - * type checking as well as a few commonly used macros to control - * external linkage. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (c) 1999-2000, The University of Chicago - * - * This file may be freely redistributed without license or fee provided - * this copyright message remains intact. - ************************************************************************/ - -#include - -#if defined(_WIN32) || defined(__WIN32__) -# if defined(_MSC_VER) -# if defined(STATIC_LINKED) -# define SWIGEXPORT(a) a -# else -# define SWIGEXPORT(a) __declspec(dllexport) a -# endif -# else -# if defined(__BORLANDC__) -# define SWIGEXPORT(a) a _export -# else -# define SWIGEXPORT(a) a -# endif -#endif -#else -# define SWIGEXPORT(a) a -#endif - -#ifdef SWIG_GLOBAL -#define SWIGRUNTIME(a) SWIGEXPORT(a) -#else -#define SWIGRUNTIME(a) static a -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct swig_type_info { - char *name; - void *(*converter)(void *); - char *str; - struct swig_type_info *next; - struct swig_type_info *prev; -} swig_type_info; - -#ifdef SWIG_NOINCLUDE -SWIGEXPORT(swig_type_info *) SWIG_TypeRegister(swig_type_info *); -SWIGEXPORT(swig_type_info *) SWIG_TypeCheck(char *c, swig_type_info *); -SWIGEXPORT(void *) SWIG_TypeCast(swig_type_info *, void *); -#else - -static swig_type_info *swig_type_list = 0; - -/* Register a type mapping with the type-checking */ -SWIGRUNTIME(swig_type_info *) -SWIG_TypeRegister(swig_type_info *ti) -{ - swig_type_info *tc, *head, *ret, *next; - /* Check to see if this type has already been registered */ - tc = swig_type_list; - while (tc) { - if (strcmp(tc->name, ti->name) == 0) { - /* Already exists in the table. Just add additional types to the list */ - head = tc; - next = tc->next; - goto l1; - } - tc = tc->prev; - } - head = ti; - next = 0; - - /* Place in list */ - ti->prev = swig_type_list; - swig_type_list = ti; - - /* Build linked lists */ - l1: - ret = head; - tc = ti + 1; - /* Patch up the rest of the links */ - while (tc->name) { - head->next = tc; - tc->prev = head; - head = tc; - tc++; - } - head->next = next; - return ret; -} - -/* Check the typename */ -SWIGRUNTIME(swig_type_info *) -SWIG_TypeCheck(char *c, swig_type_info *ty) -{ - swig_type_info *s; - if (!ty) return 0; /* Void pointer */ - s = ty->next; /* First element always just a name */ - while (s) { - if (strcmp(s->name,c) == 0) { - if (s == ty->next) return s; - /* Move s to the top of the linked list */ - s->prev->next = s->next; - if (s->next) { - s->next->prev = s->prev; - } - /* Insert s as second element in the list */ - s->next = ty->next; - if (ty->next) ty->next->prev = s; - ty->next = s; - return s; - } - s = s->next; - } - return 0; -} - -/* Cast a pointer (needed for C++ inheritance */ -SWIGRUNTIME(void *) -SWIG_TypeCast(swig_type_info *ty, void *ptr) -{ - if ((!ty) || (!ty->converter)) return ptr; - return (*ty->converter)(ptr); -} - -/* Search for a swig_type_info structure */ -SWIGRUNTIME(void *) -SWIG_TypeQuery(const char *name) { - swig_type_info *ty = swig_type_list; - while (ty) { - if (ty->str && (strcmp(name,ty->str) == 0)) return ty; - if (ty->name && (strcmp(name,ty->name) == 0)) return ty; - ty = ty->prev; - } - return 0; -} - -#endif - -#ifdef __cplusplus -} -#endif - - - -/*********************************************************************** - * python.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - ************************************************************************/ - -#include -#include "Python.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SWIG_PY_INT 1 -#define SWIG_PY_FLOAT 2 -#define SWIG_PY_STRING 3 -#define SWIG_PY_POINTER 4 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef SWIG_NOINCLUDE - -SWIGEXPORT(PyObject *) SWIG_newvarlink(); -SWIGEXPORT(void) SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *)); -SWIGEXPORT(int) SWIG_ConvertPtr(PyObject *, void **, swig_type_info *, int); -SWIGEXPORT(void) SWIG_MakePtr(char *c, void *, swig_type_info *); -SWIGEXPORT(PyObject *) SWIG_NewPointerObj(void *, swig_type_info *); -SWIGEXPORT(void) SWIG_InstallConstants(PyObject *d, swig_const_info constants[]); - -#else - -/* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - -typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; -} swig_globalvar; - -typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; -} swig_varlinkobject; - -static PyObject * -swig_varlink_repr(swig_varlinkobject *v) { - v = v; - return PyString_FromString(""); -} - -static int -swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) { - swig_globalvar *var; - flags = flags; - fprintf(fp,"Global variables { "); - for (var = v->vars; var; var=var->next) { - fprintf(fp,"%s", var->name); - if (var->next) fprintf(fp,", "); - } - fprintf(fp," }\n"); - return 0; -} - -static PyObject * -swig_varlink_getattr(swig_varlinkobject *v, char *n) { - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - return (*var->get_attr)(); - } - var = var->next; - } - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - return NULL; -} - -static int -swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - return (*var->set_attr)(p); - } - var = var->next; - } - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - return 1; -} - -statichere PyTypeObject varlinktype = { - PyObject_HEAD_INIT(0) - 0, - "swigvarlink", /* Type name */ - sizeof(swig_varlinkobject), /* Basic size */ - 0, /* Itemsize */ - 0, /* Deallocator */ - (printfunc) swig_varlink_print, /* Print */ - (getattrfunc) swig_varlink_getattr, /* get attr */ - (setattrfunc) swig_varlink_setattr, /* Set attr */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_mapping*/ - 0, /* tp_hash */ -}; - -/* Create a variable linking object for use later */ -SWIGRUNTIME(PyObject *) -SWIG_newvarlink(void) { - swig_varlinkobject *result = 0; - result = PyMem_NEW(swig_varlinkobject,1); - varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ - result->ob_type = &varlinktype; - result->vars = 0; - result->ob_refcnt = 0; - Py_XINCREF((PyObject *) result); - return ((PyObject*) result); -} - -SWIGRUNTIME(void) -SWIG_addvarlink(PyObject *p, char *name, - PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v; - swig_globalvar *gv; - v= (swig_varlinkobject *) p; - gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - gv->name = (char *) malloc(strlen(name)+1); - strcpy(gv->name,name); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - v->vars = gv; -} -/* Convert a pointer value */ -SWIGRUNTIME(int) -SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { - unsigned long p; - register int d; - swig_type_info *tc; - char *c; - static PyObject *SWIG_this = 0; - int newref = 0; - - if (!obj || (obj == Py_None)) { - *ptr = 0; - return 0; - } -#ifdef SWIG_COBJECT_TYPES - if (!(PyCObject_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_InternFromString("this"); - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyCObject_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - *ptr = PyCObject_AsVoidPtr(obj); - c = (char *) PyCObject_GetDesc(obj); - if (newref) Py_DECREF(obj); - goto cobject; -#else - if (!(PyString_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_InternFromString("this"); - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyString_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - c = PyString_AsString(obj); - p = 0; - /* Pointer values must start with leading underscore */ - if (*c != '_') { - *ptr = (void *) 0; - if (strcmp(c,"NULL") == 0) { - if (newref) Py_DECREF(obj); - return 0; - } else { - if (newref) Py_DECREF(obj); - goto type_error; - } - } - c++; - /* Extract hex value from pointer */ - while ((d = *c)) { - if ((d >= '0') && (d <= '9')) - p = (p << 4) + (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - p = (p << 4) + (d - ('a'-10)); - else - break; - c++; - } - *ptr = (void *) p; - if (newref) Py_DECREF(obj); -#endif - -#ifdef SWIG_COBJECT_TYPES -cobject: -#endif - - if (ty) { - tc = SWIG_TypeCheck(c,ty); - if (!tc) goto type_error; - *ptr = SWIG_TypeCast(tc,(void*)p); - } - return 0; - -type_error: - - if (flags) { - if (ty) { - char *temp = (char *) malloc(64+strlen(ty->name)); - sprintf(temp,"Type error. Expected %s", ty->name); - PyErr_SetString(PyExc_TypeError, temp); - free((char *) temp); - } else { - PyErr_SetString(PyExc_TypeError,"Expected a pointer"); - } - } - return -1; -} - -/* Take a pointer and convert it to a string */ -SWIGRUNTIME(void) -SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty) { - static char hex[17] = "0123456789abcdef"; - unsigned long p, s; - char result[32], *r; - r = result; - p = (unsigned long) ptr; - if (p > 0) { - while (p > 0) { - s = p & 0xf; - *(r++) = hex[s]; - p = p >> 4; - } - *r = '_'; - while (r >= result) - *(c++) = *(r--); - strcpy (c, ty->name); - } else { - strcpy (c, "NULL"); - } -} - -/* Create a new pointer object */ -SWIGRUNTIME(PyObject *) -SWIG_NewPointerObj(void *ptr, swig_type_info *type) { - char result[512]; - PyObject *robj; - if (!ptr) { - Py_INCREF(Py_None); - return Py_None; - } -#ifdef SWIG_COBJECT_TYPES - robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, type->name, NULL); -#else - SWIG_MakePtr(result,ptr,type); - robj = PyString_FromString(result); -#endif - return robj; -} - -/* Install Constants */ -SWIGRUNTIME(void) -SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { - int i; - PyObject *obj; - for (i = 0; constants[i].type; i++) { - switch(constants[i].type) { - case SWIG_PY_INT: - obj = PyInt_FromLong(constants[i].lvalue); - break; - case SWIG_PY_FLOAT: - obj = PyFloat_FromDouble(constants[i].dvalue); - break; - case SWIG_PY_STRING: - obj = PyString_FromString((char *) constants[i].pvalue); - break; - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d,constants[i].name,obj); - Py_DECREF(obj); - } - } -} - -#endif - -#ifdef __cplusplus -} -#endif - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_DBFFile swig_types[0] -static swig_type_info *swig_types[2]; - -/* -------- TYPES TABLE (END) -------- */ - - -/*----------------------------------------------- - @(target):= dbflibc.so - ------------------------------------------------*/ -#define SWIG_init initdbflibc - -#define SWIG_name "dbflibc" - -#include "shapefil.h" - - -/* Read one attribute from the dbf handle and return it as a new python object - * - * If an error occurs, set the appropriate Python exception and return - * NULL. - * - * Assume that the values of the record and field arguments are valid. - * The name argument will be passed to DBFGetFieldInfo as is and should - * thus be either NULL or a pointer to an array of at least 12 chars - */ -static PyObject * -do_read_attribute(DBFInfo * handle, int record, int field, char * name) -{ - int type, width; - PyObject *value; - - type = DBFGetFieldInfo(handle, field, name, &width, NULL); - /* For strings NULL and the empty string are indistinguishable - * in DBF files. We prefer empty strings instead for backwards - * compatibility reasons because older wrapper versions returned - * emtpy strings as empty strings. - */ - if (type != FTString && DBFIsAttributeNULL(handle, record, field)) - { - value = Py_None; - Py_INCREF(value); - } - else - { - switch (type) - { - case FTString: - { - const char * temp = DBFReadStringAttribute(handle, record, field); - if (temp) - { - value = PyString_FromString(temp); - } - else - { - PyErr_Format(PyExc_IOError, - "Can't read value for row %d column %d", - record, field); - value = NULL; - } - break; - } - case FTInteger: - value = PyInt_FromLong(DBFReadIntegerAttribute(handle, record, - field)); - break; - case FTDouble: - value = PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, - field)); - break; - default: - PyErr_Format(PyExc_TypeError, "Invalid field data type %d", - type); - value = NULL; - } - } - if (!value) - return NULL; - - return value; -} - -/* the read_attribute method. Return the value of the given record and - * field as a python object of the appropriate type. - * - * In case of error, set a python exception and return NULL. Since that - * value will be returned to the python interpreter as is, the - * interpreter should recognize the exception. - */ - -static PyObject * -DBFInfo_read_attribute(DBFInfo * handle, int record, int field) -{ - if (record < 0 || record >= DBFGetRecordCount(handle)) - { - PyErr_Format(PyExc_ValueError, - "record index %d out of bounds (record count: %d)", - record, DBFGetRecordCount(handle)); - return NULL; - } - - if (field < 0 || field >= DBFGetFieldCount(handle)) - { - PyErr_Format(PyExc_ValueError, - "field index %d out of bounds (field count: %d)", - field, DBFGetFieldCount(handle)); - return NULL; - } - - return do_read_attribute(handle, record, field, NULL); -} - - -/* the read_record method. Return the record record as a dictionary with - * whose keys are the names of the fields, and their values as the - * appropriate Python type. - * - * In case of error, set a python exception and return NULL. Since that - * value will be returned to the python interpreter as is, the - * interpreter should recognize the exception. - */ - -static PyObject * -DBFInfo_read_record(DBFInfo * handle, int record) -{ - int num_fields; - int i; - int type, width; - char name[12]; - PyObject *dict; - PyObject *value; - - if (record < 0 || record >= DBFGetRecordCount(handle)) - { - PyErr_Format(PyExc_ValueError, - "record index %d out of bounds (record count: %d)", - record, DBFGetRecordCount(handle)); - return NULL; - } - - dict = PyDict_New(); - if (!dict) - return NULL; - - num_fields = DBFGetFieldCount(handle); - for (i = 0; i < num_fields; i++) - { - value = do_read_attribute(handle, record, i, name); - if (!value) - goto fail; - - PyDict_SetItemString(dict, name, value); - Py_DECREF(value); - } - - return dict; - - fail: - Py_XDECREF(dict); - return NULL; -} - -/* the write_record method. Write the record record given wither as a - * dictionary or a sequence (i.e. a list or a tuple). - * - * If it's a dictionary the keys must be the names of the fields and - * their value must have a suitable type. Only the fields actually - * contained in the dictionary are written. Fields for which there's no - * item in the dict are not modified. - * - * If it's a sequence, all fields must be present in the right order. - * - * In case of error, set a python exception and return NULL. Since that - * value will be returned to the python interpreter as is, the - * interpreter should recognize the exception. - * - * The method is implemented with two c-functions, write_field to write - * a single field and DBFInfo_write_record as the front-end. - */ - - -/* write a single field of a record. */ -static int -write_field(DBFHandle handle, int record, int field, int type, - PyObject * value) -{ - char * string_value; - int int_value; - double double_value; - - if (value == Py_None) - { - if (!DBFWriteNULLAttribute(handle, record, field)) - { - PyErr_Format(PyExc_IOError, - "can't write NULL field %d of record %d", - field, record); - return 0; - } - } - else - { - switch (type) - { - case FTString: - string_value = PyString_AsString(value); - if (!string_value) - return 0; - if (!DBFWriteStringAttribute(handle, record, field, string_value)) - { - PyErr_Format(PyExc_IOError, - "can't write field %d of record %d", - field, record); - return 0; - } - break; - - case FTInteger: - int_value = PyInt_AsLong(value); - if (int_value == -1 && PyErr_Occurred()) - return 0; - if (!DBFWriteIntegerAttribute(handle, record, field, int_value)) - { - PyErr_Format(PyExc_IOError, - "can't write field %d of record %d", - field, record); - return 0; - } - break; - - case FTDouble: - double_value = PyFloat_AsDouble(value); - if (double_value == -1 && PyErr_Occurred()) - return 0; - if (!DBFWriteDoubleAttribute(handle, record, field, double_value)) - { - PyErr_Format(PyExc_IOError, - "can't write field %d of record %d", - field, record); - return 0; - } - break; - - default: - PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type); - return 0; - } - } - - return 1; -} - -static -PyObject * -DBFInfo_write_record(DBFHandle handle, int record, PyObject *record_object) -{ - int num_fields; - int i, length; - int type, width; - char name[12]; - PyObject * value = NULL; - - num_fields = DBFGetFieldCount(handle); - - /* We used to use PyMapping_Check to test whether record_object is a - * dictionary like object instead of PySequence_Check to test - * whether it's a sequence. Unfortunately in Python 2.3 - * PyMapping_Check returns true for lists and tuples too so the old - * approach doesn't work anymore. - */ - if (PySequence_Check(record_object)) - { - /* It's a sequence object. Iterate through all items in the - * sequence and write them to the appropriate field. - */ - length = PySequence_Length(record_object); - if (length != num_fields) - { - PyErr_SetString(PyExc_TypeError, - "record must have one item for each field"); - goto fail; - } - for (i = 0; i < length; i++) - { - type = DBFGetFieldInfo(handle, i, name, &width, NULL); - value = PySequence_GetItem(record_object, i); - if (value) - { - if (!write_field(handle, record, i, type, value)) - goto fail; - Py_DECREF(value); - } - else - { - goto fail; - } - } - } - else - { - /* It's a dictionary-like object. Iterate over the names of the - * known fields and write the corresponding item - */ - for (i = 0; i < num_fields; i++) - { - type = DBFGetFieldInfo(handle, i, name, &width, NULL); - - /* if the dictionary has the key name write that object to - * the appropriate field, other wise just clear the python - * exception and do nothing. - */ - value = PyMapping_GetItemString(record_object, name); - if (value) - { - if (!write_field(handle, record, i, type, value)) - goto fail; - Py_DECREF(value); - } - else - { - PyErr_Clear(); - } - } - } - - Py_INCREF(Py_None); - return Py_None; - - fail: - Py_XDECREF(value); - return NULL; -} - -static -void -DBFInfo_commit(DBFHandle handle) -{ -#if HAVE_UPDATE_HEADER - DBFUpdateHeader(handle); -#endif -} - -static PyObject* l_output_helper(PyObject* target, PyObject* o) { - PyObject* o2; - if (!target) { - target = o; - } else if (target == Py_None) { - Py_DECREF(Py_None); - target = o; - } else { - if (!PyList_Check(target)) { - o2 = target; - target = PyList_New(0); - PyList_Append(target, o2); - Py_XDECREF(o2); - } - PyList_Append(target,o); - Py_XDECREF(o); - } - return target; -} - -static PyObject* t_output_helper(PyObject* target, PyObject* o) { - PyObject* o2; - PyObject* o3; - - if (!target) { - target = o; - } else if (target == Py_None) { - Py_DECREF(Py_None); - target = o; - } else { - if (!PyTuple_Check(target)) { - o2 = target; - target = PyTuple_New(1); - PyTuple_SetItem(target, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SetItem(o3, 0, o); - - o2 = target; - target = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return target; -} - -#define SWIG_MemoryError 1 -#define SWIG_IOError 2 -#define SWIG_RuntimeError 3 -#define SWIG_IndexError 4 -#define SWIG_TypeError 5 -#define SWIG_DivisionByZero 6 -#define SWIG_OverflowError 7 -#define SWIG_SyntaxError 8 -#define SWIG_ValueError 9 -#define SWIG_SystemError 10 -#define SWIG_UnknownError 99 - -static void _SWIG_exception(int code, char *msg) { - switch(code) { - case SWIG_MemoryError: - PyErr_SetString(PyExc_MemoryError,msg); - break; - case SWIG_IOError: - PyErr_SetString(PyExc_IOError,msg); - break; - case SWIG_RuntimeError: - PyErr_SetString(PyExc_RuntimeError,msg); - break; - case SWIG_IndexError: - PyErr_SetString(PyExc_IndexError,msg); - break; - case SWIG_TypeError: - PyErr_SetString(PyExc_TypeError,msg); - break; - case SWIG_DivisionByZero: - PyErr_SetString(PyExc_ZeroDivisionError,msg); - break; - case SWIG_OverflowError: - PyErr_SetString(PyExc_OverflowError,msg); - break; - case SWIG_SyntaxError: - PyErr_SetString(PyExc_SyntaxError,msg); - break; - case SWIG_ValueError: - PyErr_SetString(PyExc_ValueError,msg); - break; - case SWIG_SystemError: - PyErr_SetString(PyExc_SystemError,msg); - break; - default: - PyErr_SetString(PyExc_RuntimeError,msg); - break; - } -} - -#define SWIG_exception(a,b) { _SWIG_exception(a,b); return NULL; } - - typedef struct { - DBFHandle handle; - } DBFFile; - -#define NOCHECK_delete_DBFFile -#define NOCHECK_DBFFile_close - - DBFFile * open_DBFFile(const char * file, const char * mode) - { - DBFFile * self = malloc(sizeof(DBFFile)); - if (self) - self->handle = DBFOpen(file, mode); - return self; - } - - DBFFile * create_DBFFile(const char * file) - { - DBFFile * self = malloc(sizeof(DBFFile)); - if (self) - self->handle = DBFCreate(file); - return self; - } -#ifdef __cplusplus -extern "C" { -#endif -static PyObject *_wrap_open(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg0 ; - char *arg1 = "rb" ; - DBFFile *result ; - - if(!PyArg_ParseTuple(args,"s|s:open",&arg0,&arg1)) return NULL; - { - result = (DBFFile *)open_DBFFile((char const *)arg0,(char const *)arg1); - ; - if (!result) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!result->handle) - { - SWIG_exception(SWIG_IOError, "open_DBFFile failed"); - } - }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_DBFFile); - return resultobj; -} - - -static PyObject *_wrap_create(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg0 ; - DBFFile *result ; - - if(!PyArg_ParseTuple(args,"s:create",&arg0)) return NULL; - { - result = (DBFFile *)create_DBFFile((char const *)arg0); - ; - if (!result) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!result->handle) - { - SWIG_exception(SWIG_IOError, "create_DBFFile failed"); - } - }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_DBFFile); - return resultobj; -} - - -DBFFile * new_DBFFile(char const *file,char const *mode) { - { - DBFFile * self = malloc(sizeof(DBFFile)); - if (self) - self->handle = DBFOpen(file, mode); - return self; - } -} - - -static PyObject *_wrap_new_DBFFile(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg0 ; - char *arg1 = "rb" ; - DBFFile *result ; - - if(!PyArg_ParseTuple(args,"s|s:new_DBFFile",&arg0,&arg1)) return NULL; - { - result = (DBFFile *)new_DBFFile((char const *)arg0,(char const *)arg1); - ; - if (!result) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!result->handle) - { - SWIG_exception(SWIG_IOError, "new_DBFFile failed"); - } - }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_DBFFile); - return resultobj; -} - - -void delete_DBFFile(DBFFile *self) { - { - if (self->handle) - DBFClose(self->handle); - free(self); - } -} - - -static PyObject *_wrap_delete_DBFFile(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - PyObject * argo0 =0 ; - - if(!PyArg_ParseTuple(args,"O:delete_DBFFile",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_delete_DBFFile - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - delete_DBFFile(arg0); - Py_INCREF(Py_None); - resultobj = Py_None; - return resultobj; -} - - -void DBFFile_close(DBFFile *self) { - { - if (self->handle) - DBFClose(self->handle); - self->handle = NULL; - } -} - - -static PyObject *_wrap_DBFFile_close(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - PyObject * argo0 =0 ; - - if(!PyArg_ParseTuple(args,"O:DBFFile_close",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_close - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - DBFFile_close(arg0); - Py_INCREF(Py_None); - resultobj = Py_None; - return resultobj; -} - - -int DBFFile_field_count(DBFFile *self) { - { - return DBFGetFieldCount(self->handle); - } -} - - -static PyObject *_wrap_DBFFile_field_count(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - PyObject * argo0 =0 ; - int result ; - - if(!PyArg_ParseTuple(args,"O:DBFFile_field_count",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_field_count - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - result = (int )DBFFile_field_count(arg0); - resultobj = PyInt_FromLong((long)result); - return resultobj; -} - - -int DBFFile_record_count(DBFFile *self) { - { - return DBFGetRecordCount(self->handle); - } -} - - -static PyObject *_wrap_DBFFile_record_count(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - PyObject * argo0 =0 ; - int result ; - - if(!PyArg_ParseTuple(args,"O:DBFFile_record_count",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_record_count - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - result = (int )DBFFile_record_count(arg0); - resultobj = PyInt_FromLong((long)result); - return resultobj; -} - - -int DBFFile_field_info(DBFFile *self,int iField,char *fieldname_out,int *output_width,int *output_decimals) { - { - return DBFGetFieldInfo(self->handle, iField, fieldname_out, - output_width, output_decimals); - } -} - - -static PyObject *_wrap_DBFFile_field_info(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - int arg1 ; - char *arg2 ; - int *arg3 ; - int *arg4 ; - char temp[12] ; - int temp0 ; - int temp1 ; - PyObject * argo0 =0 ; - int result ; - - { - arg2 = temp; - } - { - arg3 = &temp0; - } - { - arg4 = &temp1; - } - if(!PyArg_ParseTuple(args,"Oi:DBFFile_field_info",&argo0,&arg1)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_field_info - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - result = (int )DBFFile_field_info(arg0,arg1,arg2,arg3,arg4); - resultobj = PyInt_FromLong((long)result); - { - PyObject * string = PyString_FromString(arg2); - resultobj = t_output_helper(resultobj,string); - } - { - PyObject *o; - o = PyInt_FromLong((long) (*arg3)); - resultobj = t_output_helper(resultobj, o); - } - { - PyObject *o; - o = PyInt_FromLong((long) (*arg4)); - resultobj = t_output_helper(resultobj, o); - } - return resultobj; -} - - -PyObject * DBFFile_read_record(DBFFile *self,int record) { - { - return DBFInfo_read_record(self->handle, record); - } -} - - -static PyObject *_wrap_DBFFile_read_record(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - int arg1 ; - PyObject * argo0 =0 ; - PyObject *result ; - - if(!PyArg_ParseTuple(args,"Oi:DBFFile_read_record",&argo0,&arg1)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_read_record - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - result = (PyObject *)DBFFile_read_record(arg0,arg1); - { - resultobj = result; - } - return resultobj; -} - - -PyObject * DBFFile_read_attribute(DBFFile *self,int record,int field) { - { - return DBFInfo_read_attribute(self->handle, record, field); - } -} - - -static PyObject *_wrap_DBFFile_read_attribute(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - int arg1 ; - int arg2 ; - PyObject * argo0 =0 ; - PyObject *result ; - - if(!PyArg_ParseTuple(args,"Oii:DBFFile_read_attribute",&argo0,&arg1,&arg2)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_read_attribute - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - result = (PyObject *)DBFFile_read_attribute(arg0,arg1,arg2); - { - resultobj = result; - } - return resultobj; -} - - -int DBFFile_add_field(DBFFile *self,char const *pszFieldName,DBFFieldType eType,int nWidth,int nDecimals) { - { - return DBFAddField(self->handle, pszFieldName, eType, nWidth, - nDecimals); - } -} - - -static PyObject *_wrap_DBFFile_add_field(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - char *arg1 ; - int arg2 ; - int arg3 ; - int arg4 ; - PyObject * argo0 =0 ; - int result ; - - if(!PyArg_ParseTuple(args,"Osiii:DBFFile_add_field",&argo0,&arg1,&arg2,&arg3,&arg4)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_add_field - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - { - result = (int )DBFFile_add_field(arg0,(char const *)arg1,(DBFFieldType )arg2,arg3,arg4); - ; - if (result < 0) - { - SWIG_exception(SWIG_RuntimeError, "add_field failed"); - } - }resultobj = PyInt_FromLong((long)result); - return resultobj; -} - - -PyObject * DBFFile_write_record(DBFFile *self,int record,PyObject *dict_or_sequence) { - { - return DBFInfo_write_record(self->handle, record, - dict_or_sequence); - } -} - - -static PyObject *_wrap_DBFFile_write_record(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - int arg1 ; - PyObject *arg2 ; - PyObject * argo0 =0 ; - PyObject * obj2 = 0 ; - PyObject *result ; - - if(!PyArg_ParseTuple(args,"OiO:DBFFile_write_record",&argo0,&arg1,&obj2)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - arg2 = obj2; - } - { - #ifndef NOCHECK_DBFFile_write_record - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - result = (PyObject *)DBFFile_write_record(arg0,arg1,arg2); - { - resultobj = result; - } - return resultobj; -} - - -void DBFFile_commit(DBFFile *self) { - { - DBFInfo_commit(self->handle); - } -} - - -static PyObject *_wrap_DBFFile_commit(PyObject *self, PyObject *args) { - PyObject *resultobj; - DBFFile *arg0 ; - PyObject * argo0 =0 ; - - if(!PyArg_ParseTuple(args,"O:DBFFile_commit",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_DBFFile_commit - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "dbffile already closed"); - #endif - } - DBFFile_commit(arg0); - Py_INCREF(Py_None); - resultobj = Py_None; - return resultobj; -} - - -static PyMethodDef dbflibcMethods[] = { - { "open", _wrap_open, METH_VARARGS }, - { "create", _wrap_create, METH_VARARGS }, - { "new_DBFFile", _wrap_new_DBFFile, METH_VARARGS }, - { "delete_DBFFile", _wrap_delete_DBFFile, METH_VARARGS }, - { "DBFFile_close", _wrap_DBFFile_close, METH_VARARGS }, - { "DBFFile_field_count", _wrap_DBFFile_field_count, METH_VARARGS }, - { "DBFFile_record_count", _wrap_DBFFile_record_count, METH_VARARGS }, - { "DBFFile_field_info", _wrap_DBFFile_field_info, METH_VARARGS }, - { "DBFFile_read_record", _wrap_DBFFile_read_record, METH_VARARGS }, - { "DBFFile_read_attribute", _wrap_DBFFile_read_attribute, METH_VARARGS }, - { "DBFFile_add_field", _wrap_DBFFile_add_field, METH_VARARGS }, - { "DBFFile_write_record", _wrap_DBFFile_write_record, METH_VARARGS }, - { "DBFFile_commit", _wrap_DBFFile_commit, METH_VARARGS }, - { NULL, NULL } -}; - -#ifdef __cplusplus -} -#endif - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_DBFFile[] = {{"_p_DBFFile", 0, "DBFFile *"},{"_p_DBFFile"},{0}}; - -static swig_type_info *swig_types_initial[] = { -_swigt__p_DBFFile, -0 -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { - { SWIG_PY_INT, "FTString", (long) FTString, 0, 0, 0}, - { SWIG_PY_INT, "FTInteger", (long) FTInteger, 0, 0, 0}, - { SWIG_PY_INT, "FTDouble", (long) FTDouble, 0, 0, 0}, - { SWIG_PY_INT, "FTInvalid", (long) FTInvalid, 0, 0, 0}, - { SWIG_PY_INT, "_have_commit", (long) HAVE_UPDATE_HEADER, 0, 0, 0}, -{0}}; - -static PyObject *SWIG_globals; -#ifdef __cplusplus -extern "C" -#endif -SWIGEXPORT(void) initdbflibc(void) { - PyObject *m, *d; - int i; - SWIG_globals = SWIG_newvarlink(); - m = Py_InitModule("dbflibc", dbflibcMethods); - d = PyModule_GetDict(m); - for (i = 0; swig_types_initial[i]; i++) { - swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); - } - SWIG_InstallConstants(d,swig_const_table); -} - diff --git a/pyshapelib/pyshapelib_api.h b/pyshapelib/pyshapelib_api.h deleted file mode 100644 index 645272cd4..000000000 --- a/pyshapelib/pyshapelib_api.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Header file for the PyShapelib API for other Python modules */ -/* $Revision$ */ - -#ifndef PYSHAPELIB_API_H -#define PYSHAPELIB_API_H - -typedef struct { - /* Shapefile functions */ - SHPObject * (*SHPReadObject)(SHPHandle hSHP, int iShape); - void (*SHPDestroyObject)(SHPObject * psObject); - - /* SHPTree functions */ - SHPTree * (*SHPCreateTree)(SHPHandle hSHP, int nDimension, int nMaxDepth, - double *padfBoundsMin, double *padfBoundsMax); - void (*SHPDestroyTree)(SHPTree * hTree); - int * (*SHPTreeFindLikelyShapes)(SHPTree * hTree, double * padfBoundsMin, - double * padfBoundsMax, int *); -} PyShapeLibAPI; - - -/* Macro to import the shapelib module, extract the API pointer and - * assign it to the variable given as argument */ -#define PYSHAPELIB_IMPORT_API(apivariable) \ -{ \ - PyObject * shapelib = PyImport_ImportModule("shapelibc"); \ - if (shapelib) \ - { \ - PyObject * c_api_func = PyObject_GetAttrString(shapelib, "c_api"); \ - if (c_api_func) \ - { \ - PyObject * cobj = PyObject_CallObject(c_api_func, NULL); \ - if (cobj) \ - { \ - (apivariable) = (PyShapeLibAPI*)PyCObject_AsVoidPtr(cobj); \ - } \ - } \ - } \ -} - - -#endif /* PYSHAPELIB_API_H */ diff --git a/pyshapelib/pytest.py b/pyshapelib/pytest.py deleted file mode 100644 index af412a6c7..000000000 --- a/pyshapelib/pytest.py +++ /dev/null @@ -1,128 +0,0 @@ -import shapelib, dbflib, shptree - -# -# The the shapefile module -# - -def make_shapefile(filename): - # Create a shapefile with polygons - outfile = shapelib.create(filename, shapelib.SHPT_POLYGON) - - # Create one very simple polygon and write it to the shapefile. The - # vertices should be given in clockwise order to comply with the - # shapefile specification. - obj = shapelib.SHPObject(shapelib.SHPT_POLYGON, 1, - [[(10, 10), (10, 20), (20, 20), (10, 10)]]) - print obj.extents() - print obj.vertices() - outfile.write_object(-1, obj) - - # Create a polygon with a hole. Note that according to the - # shapefile specification, the vertices of the outer ring have to be - # in clockwise order and the inner rings have to be in counter - # clockwise order. - # - # There's an optional fourth parameter which when given must be a - # list of part types, one for each part of the shape. For polygons, - # the part type is always shapelib.SHPP_RING, though. The part - # types are only relevant for SHPT_MULTIPATCH shapefiles. - obj = shapelib.SHPObject(shapelib.SHPT_POLYGON, 1, - [[(0, 0), (0, 40), (40, 40), (40, 0), (0, 0)], - [(10, 10), (20, 10), (20, 20), (10, 20),(10, 10)], - ]) - print obj.extents() - print obj.vertices() - outfile.write_object(-1, obj) - - # close the file. - outfile.close() - -def read_shapefile(filename): - # open the shapefile - shp = shapelib.ShapeFile(filename) - - # the info method returns a tuple (num_shapes, type, min, max) where - # num_shapes is the number of shapes, type is the type code (one of - # the SHPT* constants defined in the shapelib module) and min and - # max are 4-element lists with the min. and max. values of the - # vertices. - print shp.info() - - # read_object reads a shape - obj = shp.read_object(0) - - # The vertices method returns the shape as a list of lists of tuples. - print obj.vertices()[0][:10] - - # The extents returns a tuple with two 4-element lists with the min. - # and max. values of the vertices. - print obj.extents() - - # The type attribute is the type code (one of the SHPT* constants - # defined in the shapelib module) - print obj.type - - # The id attribute is the shape id - print obj.id - - # the cobject method returns a PyCObject containing the shapelib - # SHPHandle. This is useful for passing shapefile objects to - # C-Python extensions. - print shp.cobject() - - # build a quad tree from the shapefile. The first argument must be - # the return value of the shape file object's cobject method (this - # is currently needed to access the shape file at the C-level). The - # second argument is the dimension and the third the maximum depth. - # 0 means to guess an appropriate depth - tree = shptree.SHPTree(shp.cobject(), 2, 0) - - # Retrieve the ids for a region. Here we just use the extents of the - # object previously read from the shapefile - minima, maxima = obj.extents() - print tree.find_shapes(minima[:2], maxima[:2]) - - -make_shapefile("testfile") -read_shapefile("testfile") - -# -# Test the DBF file module. -# - -def make_dbf(file): - # create a new dbf file and add three fields. - dbf = dbflib.create(file) - dbf.add_field("NAME", dbflib.FTString, 20, 0) - dbf.add_field("INT", dbflib.FTInteger, 10, 0) - dbf.add_field("FLOAT", dbflib.FTDouble, 10, 4) - -def add_dbf_records(file): - # add some records to file - dbf = dbflib.open(file, "r+b") - # Records can be added as a dictionary... - dbf.write_record(0, {'NAME': "Weatherwax", "INT":1, "FLOAT":3.1415926535}) - # ... or as a sequence - dbf.write_record(1, ("Ogg", 2, -1000.1234)) - -def list_dbf(file): - # print the contents of a dbf file to stdout - dbf = dbflib.DBFFile(file) - print "%d records, %d fields" % (dbf.record_count(), dbf.field_count()) - format = "" - for i in range(dbf.field_count()): - type, name, len, decc = dbf.field_info(i) - if type == 0: - format = format + " %%(%s)%ds" % (name, len) - elif type == 1: - format = format + " %%(%s)%dd" % (name, len) - elif type == 2: - format = format + " %%(%s)%dg" % (name, len) - print format - for i in range(dbf.record_count()): - print format % dbf.read_record(i) - - -make_dbf("testfile") -add_dbf_records("testfile") -list_dbf("testfile") diff --git a/pyshapelib/shapelib.i b/pyshapelib/shapelib.i deleted file mode 100644 index 5bc051f12..000000000 --- a/pyshapelib/shapelib.i +++ /dev/null @@ -1,612 +0,0 @@ -/* SWIG (www.swig.org) interface file for shapelib - * - * At the moment (Dec 2000) this file is only useful to generate Python - * bindings. Invoke swig as follows: - * - * swig -python -shadow shapelib.i - * - * to generate shapelib_wrap.c and shapelib.py. shapelib_wrap.c - * defines a bunch of Python-functions that wrap the appripriate - * shapelib functions and shapelib.py contains an object oriented - * wrapper around shapelib_wrap.c. - * - * Shapelib, and hence this module too, defines two types of objects, - * shapes and shapefiles. - */ - -%module shapelib - -/* - * First, a %{,%}-Block. These blocks are copied verbatim to the - * shapelib_wrap.c file and are not parsed by SWIG. This is the place to - * import headerfiles and define helper-functions that are needed by the - * automatically generated wrappers. - */ - -%{ - -/* import the shapelib headefile. */ -#include "shapefil.h" -#include "pyshapelib_api.h" - -/* - * Rename a few shapelib functions that are effectively methods with - * preprocessor macros so that they have the names that swig expects - * (e.g. the destructor of SHPObject has to be called delete_SHPObject) - */ - -#define delete_SHPObject SHPDestroyObject - -/* - * The extents() method of SHPObject. - * - * Return the extents as a tuple of two 4-element lists with the min. - * and max. values of x, y, z, m. - */ -static PyObject * -SHPObject_extents(SHPObject *object) -{ - return Py_BuildValue("[dddd][dddd]", - object->dfXMin, object->dfYMin, object->dfZMin, - object->dfMMin, - object->dfXMax, object->dfYMax, object->dfZMax, - object->dfMMax); -} - - -/* - * The vertices() method of SHPObject. - * - * Return the x and y coords of the vertices as a list of lists of - * tuples. - */ - -static PyObject* build_vertex_list(SHPObject *object, int index, int length); - -static PyObject* -SHPObject_vertices(SHPObject *object) -{ - PyObject *result = NULL; - PyObject *part = NULL; - int part_idx, vertex_idx; - int length = 0; - - - if (object->nParts > 0) - { - /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */ - - result = PyList_New(object->nParts); - if (!result) - return NULL; - - for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; - part_idx++) - { - if (part_idx < object->nParts - 1) - length = (object->panPartStart[part_idx + 1] - - object->panPartStart[part_idx]); - else - length = object->nVertices - object->panPartStart[part_idx]; - - part = build_vertex_list(object, vertex_idx, length); - if (!part) - goto fail; - - if (PyList_SetItem(result, part_idx, part) < 0) - goto fail; - - vertex_idx += length; - } - } - else - { - /* only one part. usual for SHPT_POINT */ - result = build_vertex_list(object, 0, object->nVertices); - } - - return result; - - fail: - Py_XDECREF(part); - Py_DECREF(result); - return NULL; -} - - -/* Return the length coordinates of the shape object starting at vertex - * index as a Python-list of tuples. Helper function for - * SHPObject_vertices. - */ -static PyObject* -build_vertex_list(SHPObject *object, int index, int length) -{ - int i; - PyObject * list; - PyObject * vertex = NULL; - - list = PyList_New(length); - if (!list) - return NULL; - - for (i = 0; i < length; i++, index++) - { - vertex = Py_BuildValue("dd", object->padfX[index], - object->padfY[index]); - if (!vertex) - goto fail; - if (PyList_SetItem(list, i, vertex) < 0) - goto fail; - } - - return list; - - fail: - Py_XDECREF(vertex); - Py_DECREF(list); - return NULL; -} - - - - - -/* The constructor of SHPObject. parts is a list of lists of tuples - * describing the parts and their vertices just likethe output of the - * vertices() method. part_type_list is the list of part-types and may - * be NULL. For the meaning of the part-types and their default value - * see the Shaplib documentation. - */ -SHPObject * new_SHPObject(int type, int id, PyObject * parts, - PyObject * part_type_list) -{ - /* arrays to hold thex and y coordinates of the vertices */ - double *xs = NULL, *ys = NULL; - /* number of all vertices of all parts */ - int num_vertices; - /* number of parts in the list parts */ - int num_parts; - /* start index of in xs and ys of the part currently worked on */ - int part_start; - /* array of start indices in xs and ys as expected by shapelib */ - int *part_starts = NULL; - - /* generic counter */ - int i; - - /* array of part types. holds the converted content of - * part_type_list. Stays NULL of part_type_list is NULL - */ - int *part_types = NULL; - - /* temporary python objects referring to the the list items being - * worked on. - */ - PyObject * part = NULL, *tuple = NULL; - - /* The result object */ - SHPObject *result; - - num_parts = PySequence_Length(parts); - num_vertices = 0; - - /* parts and part_types have to have the same lengths */ - if (part_type_list - && PySequence_Length(parts) != PySequence_Length(part_type_list)) - { - PyErr_SetString(PyExc_TypeError, - "parts and part_types have to have the same lengths"); - return NULL; - } - - /* determine how many vertices there are altogether */ - for (i = 0; i < num_parts; i++) - { - PyObject * part = PySequence_GetItem(parts, i); - if (!part) - return NULL; - num_vertices += PySequence_Length(part); - Py_DECREF(part); - } - - /* allocate the memory for the various arrays and check for memory - errors */ - xs = malloc(num_vertices * sizeof(double)); - ys = malloc(num_vertices * sizeof(double)); - part_starts = malloc(num_parts * sizeof(int)); - if (part_type_list) - part_types = malloc(num_parts * sizeof(int)); - - if (!xs || !ys || !part_starts || (part_type_list && !part_types)) - { - PyErr_NoMemory(); - goto fail; - } - - /* convert the part types */ - if (part_type_list) - { - for (i = 0; i < num_parts; i++) - { - PyObject * otype = PySequence_GetItem(part_type_list, i); - if (!otype) - return NULL; - part_types[i] = PyInt_AsLong(otype); - Py_DECREF(otype); - } - } - - /* convert the list of parts */ - part_start = 0; - for (i = 0; i < num_parts; i++) - { - int j, length; - - part = PySequence_GetItem(parts, i); - length = PySequence_Length(part); - part_starts[i] = part_start; - - for (j = 0; j < length; j++) - { - tuple = PySequence_GetItem(part, j); - if (!tuple) - goto fail; - - if (!PyArg_ParseTuple(tuple, "dd", xs + part_start + j, - ys + part_start + j)) - { - goto fail; - } - Py_DECREF(tuple); - tuple = NULL; - } - Py_DECREF(part); - part = NULL; - part_start += length; - } - - result = SHPCreateObject(type, id, num_parts, part_starts, part_types, - num_vertices, xs, ys, NULL, NULL); - free(xs); - free(ys); - free(part_starts); - free(part_types); - return result; - - fail: - free(xs); - free(ys); - free(part_starts); - free(part_types); - Py_XDECREF(part); - Py_XDECREF(tuple); - return NULL; -} - -%} - - - -/* - * The SWIG Interface definition. - */ - -/* include some common SWIG type definitions and standard exception - handling code */ -%include typemaps.i -%include exception.i - - -/* - * SHPObject -- Represents one shape - */ - -/* Exception typemap for the SHPObject constructor. The constructor the - the wrapper function defined above which returns NULL in case of - error. */ - -%typemap(python,except) SHPObject*new_SHPObject { - $function; - if (PyErr_Occurred()) - return NULL; -} - -/* Define the SHPObject struct for SWIG. This has to have the same name - * as the underlying C-struct in shapfil.h, but we don't have to repeat - * all the fields here, only those we want to access directly, and we - * can define methods for the object oriented interface. - */ - -typedef struct { - - /* The shape object has two read-only attributes: */ - - /* The type of the shape. In the c-struct defined the field is - * called 'nSHPType' but for the python bindings 'type' is more - * appropriate. - */ - %readonly %name(type) int nSHPType; - - /* The id of the shape. Here 'id' is a better name than 'nShapeId'. */ - %readonly %name(id) int nShapeId; - - /* The methods */ - %addmethods { - - /* the constructor */ - SHPObject(int type, int id, PyObject * parts, - PyObject * part_types = NULL); - - /* The destructor */ - ~SHPObject(); - - /* extents and vertices correspond to the SHPObject_extents and - * SHPObject_vertices defined above - */ - PyObject *extents(); - PyObject *vertices(); - } -} SHPObject; - - -/* - * ShapeFile -- Represents the shape file - */ - -/* Here we do things a little different. We define a new C-struct that - * holds the SHPHandle. This is mainly done so we can separate the - * close() method from the destructor but it also helps with exception - * handling. - * - * After the ShapeFile has been opened or created the handle is not - * NULL. The close() method closes the file and sets handle to NULL as - * an indicator that the file has been closed. - */ - -/* First, define the C-struct */ -%{ - typedef struct { - SHPHandle handle; - } ShapeFile; -%} - -/* define and use some typemaps for the info() method whose - * C-implementation has four output parameters that are returned through - * pointers passed into the function. SWIG already has definitions for - * common types such as int* and we can use those for the first two - * parameters: - */ - -%apply int * OUTPUT { int * output_entities } -%apply int * OUTPUT { int * output_type } - -/* for the last two, the 4-element arrays of min- and max-values, we - * have to define our own typemaps: - */ -%typemap (python,ignore) double * extents(double temp[4]) { - $target = temp; -} - -%typemap (python,argout) double * extents { - PyObject * list = Py_BuildValue("[dddd]", - $source[0], $source[1], - $source[2], $source[3]); - $target = t_output_helper($target,list); -} - -%apply double * extents { double * output_min_bounds } -%apply double * extents { double * output_max_bounds } - -/* The first argument to the ShapeFile methods is a ShapeFile pointer. - * We have to check whether handle is not NULL in most methods but not - * all. In the destructor and the close method, it's OK for handle to be - * NULL. We achieve this by checking whether the preprocessor macro - * NOCHECK_$name is defined. SWIG replaces $name with the name of the - * function for which the code is inserted. In the %{,%}-block below we - * define the macros for the destructor and the close() method. - */ - - -%typemap(python,check) ShapeFile *{ - %#ifndef NOCHECK_$name - if (!$target || !$target->handle) - SWIG_exception(SWIG_TypeError, "shapefile already closed"); - %#endif -} - -%{ -#define NOCHECK_delete_ShapeFile -#define NOCHECK_ShapeFile_close -%} - -/* An exception handle for the constructor and the module level open() - * and create() functions. - * - * Annoyingly, we *have* to put braces around the SWIG_exception() - * calls, at least in the python case, because of the way the macro is - * written. Of course, always putting braces around the branches of an - * if-statement is often considered good practice. - */ -%typemap(python,except) ShapeFile * { - $function; - if (!$source) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!$source->handle) - { - SWIG_exception(SWIG_IOError, "$name failed"); - } -} - - -/* - * The SWIG-version of the ShapeFile struct. - */ - -typedef struct -{ - /* Only methods and no attributes here: */ - %addmethods { - - /* The constructor. Takes two arguments, the filename and the - * optinal mode which are passed through to SHPOpen (due to the - * renaming trick) - */ - ShapeFile(char *file, char * mode = "rb") { - ShapeFile * self = malloc(sizeof(ShapeFile)); - if (self) - self->handle = SHPOpen(file, mode); - return self; - } - - /* The destructor. Equivalent to SHPClose */ - ~ShapeFile() { - if (self->handle) - SHPClose(self->handle); - free(self); - } - - /* close the shape file and set handle to NULL */ - void close() { - if (self->handle) - { - SHPClose(self->handle); - self->handle = NULL; - } - } - - /* info() -- Return a tuple (NUM_SHAPES, TYPE, MIN, MAX) where - * NUM_SHAPES is the number of shapes in the file, TYPE is the - * shape type and MIN and MAX are 4-element lists with the min. - * and max. values of the data. - * - * The arguments of the underlying shapelib function SHPGetInfo - * are all output parameters. To tell SWIG this, we have defined - * some typemaps above - */ - void info(int * output_entities, int * output_type, - double * output_min_bounds, double *output_max_bounds) { - SHPGetInfo(self->handle, output_entities, output_type, - output_min_bounds, output_max_bounds); - } - - /* Return object number i */ - %new SHPObject * read_object(int i) { - return SHPReadObject(self->handle, i); - } - - /* Write an object */ - int write_object(int iShape, SHPObject * psObject) { - return SHPWriteObject(self->handle, iShape, psObject); - } - - /* Return the shapelib SHPHandle as a Python CObject */ - PyObject * cobject() { - return PyCObject_FromVoidPtr(self->handle, NULL); - } - } - -} ShapeFile; - - -/* - * Two module level functions, open() and create() that correspond to - * SHPOpen and SHPCreate respectively. open() is equivalent to the - * ShapeFile constructor. - */ - -%{ - ShapeFile * open_ShapeFile(const char *filename, const char * mode) { - ShapeFile * self = malloc(sizeof(ShapeFile)); - if (self) - self->handle = SHPOpen(filename, mode); - return self; - } -%} - -%name(open) %new ShapeFile *open_ShapeFile(const char *filename, - const char * mode = "rb"); - - -%{ - ShapeFile * create_ShapeFile(const char *filename, int type) { - ShapeFile * self = malloc(sizeof(ShapeFile)); - if (self) - self->handle = SHPCreate(filename, type); - return self; - } -%} - -%name(create) %new ShapeFile * create_ShapeFile(const char *filename, - int type); - - -/* Module level function to expose some of the shapelib functions linked - * with the shapefile C-module to other Python extension modules. This - * is a kludge to make a Thuban extension work that reads shapes from - * shapefiles opened by the shapefile module. - */ - -%{ - static PyShapeLibAPI the_api = { - SHPReadObject, - SHPDestroyObject, - SHPCreateTree, - SHPDestroyTree, - SHPTreeFindLikelyShapes - }; - - PyObject * c_api() { - return PyCObject_FromVoidPtr(&the_api, NULL); - } -%} - -PyObject * c_api(); - - -/* - * Module Level functions - */ - -/* convert shapefile types to names */ -%name(type_name) const char *SHPTypeName(int nSHPType); -%name(part_type_name) const char *SHPPartTypeName(int nPartType); - - -/* - * Finally, constants copied from shapefil.h - */ - -/* -------------------------------------------------------------------- */ -/* Shape types (nSHPType) */ -/* -------------------------------------------------------------------- */ -#define SHPT_NULL 0 -#define SHPT_POINT 1 -#define SHPT_ARC 3 -#define SHPT_POLYGON 5 -#define SHPT_MULTIPOINT 8 -#define SHPT_POINTZ 11 -#define SHPT_ARCZ 13 -#define SHPT_POLYGONZ 15 -#define SHPT_MULTIPOINTZ 18 -#define SHPT_POINTM 21 -#define SHPT_ARCM 23 -#define SHPT_POLYGONM 25 -#define SHPT_MULTIPOINTM 28 -#define SHPT_MULTIPATCH 31 - - -/* -------------------------------------------------------------------- */ -/* Part types - everything but SHPT_MULTIPATCH just uses */ -/* SHPP_RING. */ -/* -------------------------------------------------------------------- */ - -#define SHPP_TRISTRIP 0 -#define SHPP_TRIFAN 1 -#define SHPP_OUTERRING 2 -#define SHPP_INNERRING 3 -#define SHPP_FIRSTRING 4 -#define SHPP_RING 5 - - diff --git a/pyshapelib/shapelib/dbfopen.c b/pyshapelib/shapelib/dbfopen.c deleted file mode 100644 index 6930197e2..000000000 --- a/pyshapelib/shapelib/dbfopen.c +++ /dev/null @@ -1,1573 +0,0 @@ -/****************************************************************************** - * $Id$ - * - * Project: Shapelib - * Purpose: Implementation of .dbf access API documented in dbf_api.html. - * Author: Frank Warmerdam, warmerdam@pobox.com - * - ****************************************************************************** - * Copyright (c) 1999, Frank Warmerdam - * - * This software is available under the following "MIT Style" license, - * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This - * option is discussed in more detail in shapelib.html. - * - * -- - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************** - * - * $Log$ - * Revision 1.1 2005/08/14 21:40:30 jswhit - * inclusion of pyshapelib - * - * Revision 1.3 2004/05/17 15:47:57 bh - * Update to newest shapelib and get rid of Thuban specific extensions, - * i.e. use the new DBFUpdateHeader instead of our DBFCommit kludge - * - * * libraries/shapelib/shpopen.c: Update to version from current - * shapelib CVS. - * - * * libraries/shapelib/shapefil.h: Update to version from current - * shapelib CVS. - * - * * libraries/shapelib/dbfopen.c: Update to version from current - * shapelib CVS. - * (DBFCommit): Effectively removed since shapelib itself has - * DBFUpdateHeader now which is better for what DBFCommit wanted to - * achieve. - * We're now using an unmodified version of dbfopen. - * - * * libraries/pyshapelib/dbflib_wrap.c, libraries/pyshapelib/dbflib.py: - * Update from dbflib.i - * - * * libraries/pyshapelib/dbflib.i (DBFInfo_commit): New. Implementation of - * the commit method. This new indirection is necessary because we use the - * DBFUpdateHeader function now which is not available in shapelib <= - * 1.2.10 - * (DBFFile::commit): Use DBFInfo_commit as implementation - * (pragma __class__): New. Kludge to remove the commit method when - * the DBFUpdateHeader function isn't available - * (_have_commit): New. Helper for the pragma kludge. - * - * * libraries/pyshapelib/setup.py (dbf_macros): New. Return the - * preprocessor macros needed to compile the dbflib wrapper. Determine - * whether DBFUpdateHeader is available and define the right value of - * HAVE_UPDATE_HEADER - * (extensions): Use dbf_macros for the dbflibc extension - * - * * setup.py (extensions): Add the HAVE_UPDATE_HEADER macro with - * value '1' to the Lib.dbflibc extension. This simply reflects the - * shapelib and pyshapelib updates - * - * Revision 1.53 2003/12/29 00:00:30 fwarmerdam - * mark DBFWriteAttributeDirectly as SHPAPI_CALL - * - * Revision 1.52 2003/07/08 15:20:03 warmerda - * avoid warnings about downcasting to unsigned char - * - * Revision 1.51 2003/07/08 13:50:15 warmerda - * DBFIsAttributeNULL check for pszValue==NULL - bug 360 - * - * Revision 1.50 2003/04/21 18:58:25 warmerda - * ensure current record is flushed at same time as header is updated - * - * Revision 1.49 2003/04/21 18:30:37 warmerda - * added header write/update public methods - * - * Revision 1.48 2003/03/10 14:51:27 warmerda - * DBFWrite* calls now return FALSE if they have to truncate - * - * Revision 1.47 2002/11/20 03:32:22 warmerda - * Ensure field name in DBFGetFieldIndex() is properly terminated. - * - * Revision 1.46 2002/10/09 13:10:21 warmerda - * Added check that width is positive. - * - * Revision 1.45 2002/09/29 00:00:08 warmerda - * added FTLogical and logical attribute read/write calls - * - * Revision 1.44 2002/05/07 13:46:11 warmerda - * Added DBFWriteAttributeDirectly(). - * - * Revision 1.43 2002/02/13 19:39:21 warmerda - * Fix casting issues in DBFCloneEmpty(). - * - * Revision 1.42 2002/01/15 14:36:07 warmerda - * updated email address - * - * Revision 1.41 2002/01/15 14:31:49 warmerda - * compute rather than copying nHeaderLength in DBFCloneEmpty() - * - * Revision 1.40 2002/01/09 04:32:35 warmerda - * fixed to read correct amount of header - * - * Revision 1.39 2001/12/11 22:41:03 warmerda - * improve io related error checking when reading header - * - * Revision 1.38 2001/11/28 16:07:31 warmerda - * Cleanup to avoid compiler warnings as suggested by Richard Hash. - * - * Revision 1.37 2001/07/04 05:18:09 warmerda - * do last fix properly - * - * Revision 1.36 2001/07/04 05:16:09 warmerda - * fixed fieldname comparison in DBFGetFieldIndex - * - * Revision 1.35 2001/06/22 02:10:06 warmerda - * fixed NULL shape support with help from Jim Matthews - * - * Revision 1.33 2001/05/31 19:20:13 warmerda - * added DBFGetFieldIndex() - * - * Revision 1.32 2001/05/31 18:15:40 warmerda - * Added support for NULL fields in DBF files - * - * Revision 1.31 2001/05/23 13:36:52 warmerda - * added use of SHPAPI_CALL - * - * Revision 1.30 2000/12/05 14:43:38 warmerda - * DBReadAttribute() white space trimming bug fix - * - * Revision 1.29 2000/10/05 14:36:44 warmerda - * fix bug with writing very wide numeric fields - * - * Revision 1.28 2000/09/25 14:18:07 warmerda - * Added some casts of strlen() return result to fix warnings on some - * systems, as submitted by Daniel. - * - * Revision 1.27 2000/09/25 14:15:51 warmerda - * added DBFGetNativeFieldType() - * - * Revision 1.26 2000/07/07 13:39:45 warmerda - * removed unused variables, and added system include files - * - * Revision 1.25 2000/05/29 18:19:13 warmerda - * avoid use of uchar, and adding casting fix - * - * Revision 1.24 2000/05/23 13:38:27 warmerda - * Added error checks on return results of fread() and fseek(). - * - * Revision 1.23 2000/05/23 13:25:49 warmerda - * Avoid crashing if field or record are out of range in dbfread*attribute(). - * - * Revision 1.22 1999/12/15 13:47:24 warmerda - * Added stdlib.h to ensure that atof() is prototyped. - * - * Revision 1.21 1999/12/13 17:25:46 warmerda - * Added support for upper case .DBF extention. - * - * Revision 1.20 1999/11/30 16:32:11 warmerda - * Use atof() instead of sscanf(). - * - * Revision 1.19 1999/11/05 14:12:04 warmerda - * updated license terms - * - * Revision 1.18 1999/07/27 00:53:28 warmerda - * ensure that whole old field value clear on write of string - * - * Revision 1.1 1999/07/05 18:58:07 warmerda - * New - * - * Revision 1.17 1999/06/11 19:14:12 warmerda - * Fixed some memory leaks. - * - * Revision 1.16 1999/06/11 19:04:11 warmerda - * Remoted some unused variables. - * - * Revision 1.15 1999/05/11 03:19:28 warmerda - * added new Tuple api, and improved extension handling - add from candrsn - * - * Revision 1.14 1999/05/04 15:01:48 warmerda - * Added 'F' support. - * - * Revision 1.13 1999/03/23 17:38:59 warmerda - * DBFAddField() now actually does return the new field number, or -1 if - * it fails. - * - * Revision 1.12 1999/03/06 02:54:46 warmerda - * Added logic to convert shapefile name to dbf filename in DBFOpen() - * for convenience. - * - * Revision 1.11 1998/12/31 15:30:34 warmerda - * Improved the interchangability of numeric and string attributes. Add - * white space trimming option for attributes. - * - * Revision 1.10 1998/12/03 16:36:44 warmerda - * Use r+b instead of rb+ for binary access. - * - * Revision 1.9 1998/12/03 15:34:23 warmerda - * Updated copyright message. - * - * Revision 1.8 1997/12/04 15:40:15 warmerda - * Added newline character after field definitions. - * - * Revision 1.7 1997/03/06 14:02:10 warmerda - * Ensure bUpdated is initialized. - * - * Revision 1.6 1996/02/12 04:54:41 warmerda - * Ensure that DBFWriteAttribute() returns TRUE if it succeeds. - * - * Revision 1.5 1995/10/21 03:15:12 warmerda - * Changed to use binary file access, and ensure that the - * field name field is zero filled, and limited to 10 chars. - * - * Revision 1.4 1995/08/24 18:10:42 warmerda - * Added use of SfRealloc() to avoid pre-ANSI realloc() functions such - * as on the Sun. - * - * Revision 1.3 1995/08/04 03:15:16 warmerda - * Fixed up header. - * - * Revision 1.2 1995/08/04 03:14:43 warmerda - * Added header. - */ - -static char rcsid[] = - "$Id$"; - -#include "shapefil.h" - -#include -#include -#include -#include - -#ifndef FALSE -# define FALSE 0 -# define TRUE 1 -#endif - -static int nStringFieldLen = 0; -static char * pszStringField = NULL; - -/************************************************************************/ -/* SfRealloc() */ -/* */ -/* A realloc cover function that will access a NULL pointer as */ -/* a valid input. */ -/************************************************************************/ - -static void * SfRealloc( void * pMem, int nNewSize ) - -{ - if( pMem == NULL ) - return( (void *) malloc(nNewSize) ); - else - return( (void *) realloc(pMem,nNewSize) ); -} - -/************************************************************************/ -/* DBFWriteHeader() */ -/* */ -/* This is called to write out the file header, and field */ -/* descriptions before writing any actual data records. This */ -/* also computes all the DBFDataSet field offset/size/decimals */ -/* and so forth values. */ -/************************************************************************/ - -static void DBFWriteHeader(DBFHandle psDBF) - -{ - unsigned char abyHeader[XBASE_FLDHDR_SZ]; - int i; - - if( !psDBF->bNoHeader ) - return; - - psDBF->bNoHeader = FALSE; - -/* -------------------------------------------------------------------- */ -/* Initialize the file header information. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < XBASE_FLDHDR_SZ; i++ ) - abyHeader[i] = 0; - - abyHeader[0] = 0x03; /* memo field? - just copying */ - - /* write out a dummy date */ - abyHeader[1] = 95; /* YY */ - abyHeader[2] = 7; /* MM */ - abyHeader[3] = 26; /* DD */ - - /* record count preset at zero */ - - abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256); - abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256); - - abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256); - abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256); - -/* -------------------------------------------------------------------- */ -/* Write the initial 32 byte file header, and all the field */ -/* descriptions. */ -/* -------------------------------------------------------------------- */ - fseek( psDBF->fp, 0, 0 ); - fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp ); - fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp ); - -/* -------------------------------------------------------------------- */ -/* Write out the newline character if there is room for it. */ -/* -------------------------------------------------------------------- */ - if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 ) - { - char cNewline; - - cNewline = 0x0d; - fwrite( &cNewline, 1, 1, psDBF->fp ); - } -} - -/************************************************************************/ -/* DBFFlushRecord() */ -/* */ -/* Write out the current record if there is one. */ -/************************************************************************/ - -static void DBFFlushRecord( DBFHandle psDBF ) - -{ - int nRecordOffset; - - if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 ) - { - psDBF->bCurrentRecordModified = FALSE; - - nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord - + psDBF->nHeaderLength; - - fseek( psDBF->fp, nRecordOffset, 0 ); - fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); - } -} - -/************************************************************************/ -/* DBFUpdateHeader() */ -/************************************************************************/ - -void SHPAPI_CALL -DBFUpdateHeader( DBFHandle psDBF ) - -{ - unsigned char abyFileHeader[32]; - - if( psDBF->bNoHeader ) - DBFWriteHeader( psDBF ); - - DBFFlushRecord( psDBF ); - - fseek( psDBF->fp, 0, 0 ); - fread( abyFileHeader, 32, 1, psDBF->fp ); - - abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256); - abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256); - abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256); - abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256); - - fseek( psDBF->fp, 0, 0 ); - fwrite( abyFileHeader, 32, 1, psDBF->fp ); - - fflush( psDBF->fp ); -} - -/************************************************************************/ -/* DBFOpen() */ -/* */ -/* Open a .dbf file. */ -/************************************************************************/ - -DBFHandle SHPAPI_CALL -DBFOpen( const char * pszFilename, const char * pszAccess ) - -{ - DBFHandle psDBF; - unsigned char *pabyBuf; - int nFields, nHeadLen, nRecLen, iField, i; - char *pszBasename, *pszFullname; - -/* -------------------------------------------------------------------- */ -/* We only allow the access strings "rb" and "r+". */ -/* -------------------------------------------------------------------- */ - if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 - && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0 - && strcmp(pszAccess,"r+b") != 0 ) - return( NULL ); - - if( strcmp(pszAccess,"r") == 0 ) - pszAccess = "rb"; - - if( strcmp(pszAccess,"r+") == 0 ) - pszAccess = "rb+"; - -/* -------------------------------------------------------------------- */ -/* Compute the base (layer) name. If there is any extension */ -/* on the passed in filename we will strip it off. */ -/* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszFilename)+5); - strcpy( pszBasename, pszFilename ); - for( i = strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - - pszFullname = (char *) malloc(strlen(pszBasename) + 5); - sprintf( pszFullname, "%s.dbf", pszBasename ); - - psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) ); - psDBF->fp = fopen( pszFullname, pszAccess ); - - if( psDBF->fp == NULL ) - { - sprintf( pszFullname, "%s.DBF", pszBasename ); - psDBF->fp = fopen(pszFullname, pszAccess ); - } - - free( pszBasename ); - free( pszFullname ); - - if( psDBF->fp == NULL ) - { - free( psDBF ); - return( NULL ); - } - - psDBF->bNoHeader = FALSE; - psDBF->nCurrentRecord = -1; - psDBF->bCurrentRecordModified = FALSE; - -/* -------------------------------------------------------------------- */ -/* Read Table Header info */ -/* -------------------------------------------------------------------- */ - pabyBuf = (unsigned char *) malloc(500); - if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 ) - { - fclose( psDBF->fp ); - free( pabyBuf ); - free( psDBF ); - return NULL; - } - - psDBF->nRecords = - pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256; - - psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256; - psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256; - - psDBF->nFields = nFields = (nHeadLen - 32) / 32; - - psDBF->pszCurrentRecord = (char *) malloc(nRecLen); - -/* -------------------------------------------------------------------- */ -/* Read in Field Definitions */ -/* -------------------------------------------------------------------- */ - - pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen); - psDBF->pszHeader = (char *) pabyBuf; - - fseek( psDBF->fp, 32, 0 ); - if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 ) - { - fclose( psDBF->fp ); - free( pabyBuf ); - free( psDBF ); - return NULL; - } - - psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields); - psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields); - psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields); - psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields); - - for( iField = 0; iField < nFields; iField++ ) - { - unsigned char *pabyFInfo; - - pabyFInfo = pabyBuf+iField*32; - - if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' ) - { - psDBF->panFieldSize[iField] = pabyFInfo[16]; - psDBF->panFieldDecimals[iField] = pabyFInfo[17]; - } - else - { - psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256; - psDBF->panFieldDecimals[iField] = 0; - } - - psDBF->pachFieldType[iField] = (char) pabyFInfo[11]; - if( iField == 0 ) - psDBF->panFieldOffset[iField] = 1; - else - psDBF->panFieldOffset[iField] = - psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1]; - } - - return( psDBF ); -} - -/************************************************************************/ -/* DBFClose() */ -/************************************************************************/ - -void SHPAPI_CALL -DBFClose(DBFHandle psDBF) -{ -/* -------------------------------------------------------------------- */ -/* Write out header if not already written. */ -/* -------------------------------------------------------------------- */ - if( psDBF->bNoHeader ) - DBFWriteHeader( psDBF ); - - DBFFlushRecord( psDBF ); - -/* -------------------------------------------------------------------- */ -/* Update last access date, and number of records if we have */ -/* write access. */ -/* -------------------------------------------------------------------- */ - if( psDBF->bUpdated ) - DBFUpdateHeader( psDBF ); - -/* -------------------------------------------------------------------- */ -/* Close, and free resources. */ -/* -------------------------------------------------------------------- */ - fclose( psDBF->fp ); - - if( psDBF->panFieldOffset != NULL ) - { - free( psDBF->panFieldOffset ); - free( psDBF->panFieldSize ); - free( psDBF->panFieldDecimals ); - free( psDBF->pachFieldType ); - } - - free( psDBF->pszHeader ); - free( psDBF->pszCurrentRecord ); - - free( psDBF ); - - if( pszStringField != NULL ) - { - free( pszStringField ); - pszStringField = NULL; - nStringFieldLen = 0; - } -} - -/************************************************************************/ -/* DBFCreate() */ -/* */ -/* Create a new .dbf file. */ -/************************************************************************/ - -DBFHandle SHPAPI_CALL -DBFCreate( const char * pszFilename ) - -{ - DBFHandle psDBF; - FILE *fp; - char *pszFullname, *pszBasename; - int i; - -/* -------------------------------------------------------------------- */ -/* Compute the base (layer) name. If there is any extension */ -/* on the passed in filename we will strip it off. */ -/* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszFilename)+5); - strcpy( pszBasename, pszFilename ); - for( i = strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - - pszFullname = (char *) malloc(strlen(pszBasename) + 5); - sprintf( pszFullname, "%s.dbf", pszBasename ); - free( pszBasename ); - -/* -------------------------------------------------------------------- */ -/* Create the file. */ -/* -------------------------------------------------------------------- */ - fp = fopen( pszFullname, "wb" ); - if( fp == NULL ) - return( NULL ); - - fputc( 0, fp ); - fclose( fp ); - - fp = fopen( pszFullname, "rb+" ); - if( fp == NULL ) - return( NULL ); - - free( pszFullname ); - -/* -------------------------------------------------------------------- */ -/* Create the info structure. */ -/* -------------------------------------------------------------------- */ - psDBF = (DBFHandle) malloc(sizeof(DBFInfo)); - - psDBF->fp = fp; - psDBF->nRecords = 0; - psDBF->nFields = 0; - psDBF->nRecordLength = 1; - psDBF->nHeaderLength = 33; - - psDBF->panFieldOffset = NULL; - psDBF->panFieldSize = NULL; - psDBF->panFieldDecimals = NULL; - psDBF->pachFieldType = NULL; - psDBF->pszHeader = NULL; - - psDBF->nCurrentRecord = -1; - psDBF->bCurrentRecordModified = FALSE; - psDBF->pszCurrentRecord = NULL; - - psDBF->bNoHeader = TRUE; - - return( psDBF ); -} - -/************************************************************************/ -/* DBFAddField() */ -/* */ -/* Add a field to a newly created .dbf file before any records */ -/* are written. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFAddField(DBFHandle psDBF, const char * pszFieldName, - DBFFieldType eType, int nWidth, int nDecimals ) - -{ - char *pszFInfo; - int i; - -/* -------------------------------------------------------------------- */ -/* Do some checking to ensure we can add records to this file. */ -/* -------------------------------------------------------------------- */ - if( psDBF->nRecords > 0 ) - return( -1 ); - - if( !psDBF->bNoHeader ) - return( -1 ); - - if( eType != FTDouble && nDecimals != 0 ) - return( -1 ); - - if( nWidth < 1 ) - return -1; - -/* -------------------------------------------------------------------- */ -/* SfRealloc all the arrays larger to hold the additional field */ -/* information. */ -/* -------------------------------------------------------------------- */ - psDBF->nFields++; - - psDBF->panFieldOffset = (int *) - SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); - - psDBF->panFieldSize = (int *) - SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); - - psDBF->panFieldDecimals = (int *) - SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); - - psDBF->pachFieldType = (char *) - SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ); - -/* -------------------------------------------------------------------- */ -/* Assign the new field information fields. */ -/* -------------------------------------------------------------------- */ - psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength; - psDBF->nRecordLength += nWidth; - psDBF->panFieldSize[psDBF->nFields-1] = nWidth; - psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals; - - if( eType == FTLogical ) - psDBF->pachFieldType[psDBF->nFields-1] = 'L'; - else if( eType == FTString ) - psDBF->pachFieldType[psDBF->nFields-1] = 'C'; - else - psDBF->pachFieldType[psDBF->nFields-1] = 'N'; - -/* -------------------------------------------------------------------- */ -/* Extend the required header information. */ -/* -------------------------------------------------------------------- */ - psDBF->nHeaderLength += 32; - psDBF->bUpdated = FALSE; - - psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32); - - pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1); - - for( i = 0; i < 32; i++ ) - pszFInfo[i] = '\0'; - - if( (int) strlen(pszFieldName) < 10 ) - strncpy( pszFInfo, pszFieldName, strlen(pszFieldName)); - else - strncpy( pszFInfo, pszFieldName, 10); - - pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1]; - - if( eType == FTString ) - { - pszFInfo[16] = (unsigned char) (nWidth % 256); - pszFInfo[17] = (unsigned char) (nWidth / 256); - } - else - { - pszFInfo[16] = (unsigned char) nWidth; - pszFInfo[17] = (unsigned char) nDecimals; - } - -/* -------------------------------------------------------------------- */ -/* Make the current record buffer appropriately larger. */ -/* -------------------------------------------------------------------- */ - psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord, - psDBF->nRecordLength); - - return( psDBF->nFields-1 ); -} - -/************************************************************************/ -/* DBFReadAttribute() */ -/* */ -/* Read one of the attribute fields of a record. */ -/************************************************************************/ - -static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, - char chReqType ) - -{ - int nRecordOffset; - unsigned char *pabyRec; - void *pReturnField = NULL; - - static double dDoubleField; - -/* -------------------------------------------------------------------- */ -/* Verify selection. */ -/* -------------------------------------------------------------------- */ - if( hEntity < 0 || hEntity >= psDBF->nRecords ) - return( NULL ); - - if( iField < 0 || iField >= psDBF->nFields ) - return( NULL ); - -/* -------------------------------------------------------------------- */ -/* Have we read the record? */ -/* -------------------------------------------------------------------- */ - if( psDBF->nCurrentRecord != hEntity ) - { - DBFFlushRecord( psDBF ); - - nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; - - if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 ) - { - fprintf( stderr, "fseek(%d) failed on DBF file.\n", - nRecordOffset ); - return NULL; - } - - if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, - 1, psDBF->fp ) != 1 ) - { - fprintf( stderr, "fread(%d) failed on DBF file.\n", - psDBF->nRecordLength ); - return NULL; - } - - psDBF->nCurrentRecord = hEntity; - } - - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; - -/* -------------------------------------------------------------------- */ -/* Ensure our field buffer is large enough to hold this buffer. */ -/* -------------------------------------------------------------------- */ - if( psDBF->panFieldSize[iField]+1 > nStringFieldLen ) - { - nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10; - pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen); - } - -/* -------------------------------------------------------------------- */ -/* Extract the requested field. */ -/* -------------------------------------------------------------------- */ - strncpy( pszStringField, - ((const char *) pabyRec) + psDBF->panFieldOffset[iField], - psDBF->panFieldSize[iField] ); - pszStringField[psDBF->panFieldSize[iField]] = '\0'; - - pReturnField = pszStringField; - -/* -------------------------------------------------------------------- */ -/* Decode the field. */ -/* -------------------------------------------------------------------- */ - if( chReqType == 'N' ) - { - dDoubleField = atof(pszStringField); - - pReturnField = &dDoubleField; - } - -/* -------------------------------------------------------------------- */ -/* Should we trim white space off the string attribute value? */ -/* -------------------------------------------------------------------- */ -#ifdef TRIM_DBF_WHITESPACE - else - { - char *pchSrc, *pchDst; - - pchDst = pchSrc = pszStringField; - while( *pchSrc == ' ' ) - pchSrc++; - - while( *pchSrc != '\0' ) - *(pchDst++) = *(pchSrc++); - *pchDst = '\0'; - - while( pchDst != pszStringField && *(--pchDst) == ' ' ) - *pchDst = '\0'; - } -#endif - - return( pReturnField ); -} - -/************************************************************************/ -/* DBFReadIntAttribute() */ -/* */ -/* Read an integer attribute. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField ) - -{ - double *pdValue; - - pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); - - if( pdValue == NULL ) - return 0; - else - return( (int) *pdValue ); -} - -/************************************************************************/ -/* DBFReadDoubleAttribute() */ -/* */ -/* Read a double attribute. */ -/************************************************************************/ - -double SHPAPI_CALL -DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField ) - -{ - double *pdValue; - - pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); - - if( pdValue == NULL ) - return 0.0; - else - return( *pdValue ); -} - -/************************************************************************/ -/* DBFReadStringAttribute() */ -/* */ -/* Read a string attribute. */ -/************************************************************************/ - -const char SHPAPI_CALL1(*) -DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField ) - -{ - return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) ); -} - -/************************************************************************/ -/* DBFReadLogicalAttribute() */ -/* */ -/* Read a logical attribute. */ -/************************************************************************/ - -const char SHPAPI_CALL1(*) -DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField ) - -{ - return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) ); -} - -/************************************************************************/ -/* DBFIsAttributeNULL() */ -/* */ -/* Return TRUE if value for field is NULL. */ -/* */ -/* Contributed by Jim Matthews. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField ) - -{ - const char *pszValue; - - pszValue = DBFReadStringAttribute( psDBF, iRecord, iField ); - - if( pszValue == NULL ) - return TRUE; - - switch(psDBF->pachFieldType[iField]) - { - case 'N': - case 'F': - /* NULL numeric fields have value "****************" */ - return pszValue[0] == '*'; - - case 'D': - /* NULL date fields have value "00000000" */ - return strncmp(pszValue,"00000000",8) == 0; - - case 'L': - /* NULL boolean fields have value "?" */ - return pszValue[0] == '?'; - - default: - /* empty string fields are considered NULL */ - return strlen(pszValue) == 0; - } -} - -/************************************************************************/ -/* DBFGetFieldCount() */ -/* */ -/* Return the number of fields in this table. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFGetFieldCount( DBFHandle psDBF ) - -{ - return( psDBF->nFields ); -} - -/************************************************************************/ -/* DBFGetRecordCount() */ -/* */ -/* Return the number of records in this table. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFGetRecordCount( DBFHandle psDBF ) - -{ - return( psDBF->nRecords ); -} - -/************************************************************************/ -/* DBFGetFieldInfo() */ -/* */ -/* Return any requested information about the field. */ -/************************************************************************/ - -DBFFieldType SHPAPI_CALL -DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName, - int * pnWidth, int * pnDecimals ) - -{ - if( iField < 0 || iField >= psDBF->nFields ) - return( FTInvalid ); - - if( pnWidth != NULL ) - *pnWidth = psDBF->panFieldSize[iField]; - - if( pnDecimals != NULL ) - *pnDecimals = psDBF->panFieldDecimals[iField]; - - if( pszFieldName != NULL ) - { - int i; - - strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 ); - pszFieldName[11] = '\0'; - for( i = 10; i > 0 && pszFieldName[i] == ' '; i-- ) - pszFieldName[i] = '\0'; - } - - if ( psDBF->pachFieldType[iField] == 'L' ) - return( FTLogical); - - else if( psDBF->pachFieldType[iField] == 'N' - || psDBF->pachFieldType[iField] == 'F' - || psDBF->pachFieldType[iField] == 'D' ) - { - if( psDBF->panFieldDecimals[iField] > 0 ) - return( FTDouble ); - else - return( FTInteger ); - } - else - { - return( FTString ); - } -} - -/************************************************************************/ -/* DBFWriteAttribute() */ -/* */ -/* Write an attribute record to the file. */ -/************************************************************************/ - -static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, - void * pValue ) - -{ - int nRecordOffset, i, j, nRetResult = TRUE; - unsigned char *pabyRec; - char szSField[400], szFormat[20]; - -/* -------------------------------------------------------------------- */ -/* Is this a valid record? */ -/* -------------------------------------------------------------------- */ - if( hEntity < 0 || hEntity > psDBF->nRecords ) - return( FALSE ); - - if( psDBF->bNoHeader ) - DBFWriteHeader(psDBF); - -/* -------------------------------------------------------------------- */ -/* Is this a brand new record? */ -/* -------------------------------------------------------------------- */ - if( hEntity == psDBF->nRecords ) - { - DBFFlushRecord( psDBF ); - - psDBF->nRecords++; - for( i = 0; i < psDBF->nRecordLength; i++ ) - psDBF->pszCurrentRecord[i] = ' '; - - psDBF->nCurrentRecord = hEntity; - } - -/* -------------------------------------------------------------------- */ -/* Is this an existing record, but different than the last one */ -/* we accessed? */ -/* -------------------------------------------------------------------- */ - if( psDBF->nCurrentRecord != hEntity ) - { - DBFFlushRecord( psDBF ); - - nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; - - fseek( psDBF->fp, nRecordOffset, 0 ); - fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); - - psDBF->nCurrentRecord = hEntity; - } - - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; - - psDBF->bCurrentRecordModified = TRUE; - psDBF->bUpdated = TRUE; - -/* -------------------------------------------------------------------- */ -/* Translate NULL value to valid DBF file representation. */ -/* */ -/* Contributed by Jim Matthews. */ -/* -------------------------------------------------------------------- */ - if( pValue == NULL ) - { - switch(psDBF->pachFieldType[iField]) - { - case 'N': - case 'F': - /* NULL numeric fields have value "****************" */ - memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*', - psDBF->panFieldSize[iField] ); - break; - - case 'D': - /* NULL date fields have value "00000000" */ - memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0', - psDBF->panFieldSize[iField] ); - break; - - case 'L': - /* NULL boolean fields have value "?" */ - memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?', - psDBF->panFieldSize[iField] ); - break; - - default: - /* empty string fields are considered NULL */ - memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0', - psDBF->panFieldSize[iField] ); - break; - } - return TRUE; - } - -/* -------------------------------------------------------------------- */ -/* Assign all the record fields. */ -/* -------------------------------------------------------------------- */ - switch( psDBF->pachFieldType[iField] ) - { - case 'D': - case 'N': - case 'F': - if( psDBF->panFieldDecimals[iField] == 0 ) - { - int nWidth = psDBF->panFieldSize[iField]; - - if( sizeof(szSField)-2 < nWidth ) - nWidth = sizeof(szSField)-2; - - sprintf( szFormat, "%%%dd", nWidth ); - sprintf(szSField, szFormat, (int) *((double *) pValue) ); - if( (int)strlen(szSField) > psDBF->panFieldSize[iField] ) - { - szSField[psDBF->panFieldSize[iField]] = '\0'; - nRetResult = FALSE; - } - - strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), - szSField, strlen(szSField) ); - } - else - { - int nWidth = psDBF->panFieldSize[iField]; - - if( sizeof(szSField)-2 < nWidth ) - nWidth = sizeof(szSField)-2; - - sprintf( szFormat, "%%%d.%df", - nWidth, psDBF->panFieldDecimals[iField] ); - sprintf(szSField, szFormat, *((double *) pValue) ); - if( (int) strlen(szSField) > psDBF->panFieldSize[iField] ) - { - szSField[psDBF->panFieldSize[iField]] = '\0'; - nRetResult = FALSE; - } - strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), - szSField, strlen(szSField) ); - } - break; - - case 'L': - if (psDBF->panFieldSize[iField] >= 1 && - (*(char*)pValue == 'F' || *(char*)pValue == 'T')) - *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue; - break; - - default: - if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] ) - { - j = psDBF->panFieldSize[iField]; - nRetResult = FALSE; - } - else - { - memset( pabyRec+psDBF->panFieldOffset[iField], ' ', - psDBF->panFieldSize[iField] ); - j = strlen((char *) pValue); - } - - strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), - (char *) pValue, j ); - break; - } - - return( nRetResult ); -} - -/************************************************************************/ -/* DBFWriteAttributeDirectly() */ -/* */ -/* Write an attribute record to the file, but without any */ -/* reformatting based on type. The provided buffer is written */ -/* as is to the field position in the record. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, - void * pValue ) - -{ - int nRecordOffset, i, j; - unsigned char *pabyRec; - -/* -------------------------------------------------------------------- */ -/* Is this a valid record? */ -/* -------------------------------------------------------------------- */ - if( hEntity < 0 || hEntity > psDBF->nRecords ) - return( FALSE ); - - if( psDBF->bNoHeader ) - DBFWriteHeader(psDBF); - -/* -------------------------------------------------------------------- */ -/* Is this a brand new record? */ -/* -------------------------------------------------------------------- */ - if( hEntity == psDBF->nRecords ) - { - DBFFlushRecord( psDBF ); - - psDBF->nRecords++; - for( i = 0; i < psDBF->nRecordLength; i++ ) - psDBF->pszCurrentRecord[i] = ' '; - - psDBF->nCurrentRecord = hEntity; - } - -/* -------------------------------------------------------------------- */ -/* Is this an existing record, but different than the last one */ -/* we accessed? */ -/* -------------------------------------------------------------------- */ - if( psDBF->nCurrentRecord != hEntity ) - { - DBFFlushRecord( psDBF ); - - nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; - - fseek( psDBF->fp, nRecordOffset, 0 ); - fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); - - psDBF->nCurrentRecord = hEntity; - } - - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; - -/* -------------------------------------------------------------------- */ -/* Assign all the record fields. */ -/* -------------------------------------------------------------------- */ - if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] ) - j = psDBF->panFieldSize[iField]; - else - { - memset( pabyRec+psDBF->panFieldOffset[iField], ' ', - psDBF->panFieldSize[iField] ); - j = strlen((char *) pValue); - } - - strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), - (char *) pValue, j ); - - psDBF->bCurrentRecordModified = TRUE; - psDBF->bUpdated = TRUE; - - return( TRUE ); -} - -/************************************************************************/ -/* DBFWriteDoubleAttribute() */ -/* */ -/* Write a double attribute. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField, - double dValue ) - -{ - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); -} - -/************************************************************************/ -/* DBFWriteIntegerAttribute() */ -/* */ -/* Write a integer attribute. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField, - int nValue ) - -{ - double dValue = nValue; - - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); -} - -/************************************************************************/ -/* DBFWriteStringAttribute() */ -/* */ -/* Write a string attribute. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField, - const char * pszValue ) - -{ - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) ); -} - -/************************************************************************/ -/* DBFWriteNULLAttribute() */ -/* */ -/* Write a string attribute. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField ) - -{ - return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) ); -} - -/************************************************************************/ -/* DBFWriteLogicalAttribute() */ -/* */ -/* Write a logical attribute. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField, - const char lValue) - -{ - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) ); -} - -/************************************************************************/ -/* DBFWriteTuple() */ -/* */ -/* Write an attribute record to the file. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple ) - -{ - int nRecordOffset, i; - unsigned char *pabyRec; - -/* -------------------------------------------------------------------- */ -/* Is this a valid record? */ -/* -------------------------------------------------------------------- */ - if( hEntity < 0 || hEntity > psDBF->nRecords ) - return( FALSE ); - - if( psDBF->bNoHeader ) - DBFWriteHeader(psDBF); - -/* -------------------------------------------------------------------- */ -/* Is this a brand new record? */ -/* -------------------------------------------------------------------- */ - if( hEntity == psDBF->nRecords ) - { - DBFFlushRecord( psDBF ); - - psDBF->nRecords++; - for( i = 0; i < psDBF->nRecordLength; i++ ) - psDBF->pszCurrentRecord[i] = ' '; - - psDBF->nCurrentRecord = hEntity; - } - -/* -------------------------------------------------------------------- */ -/* Is this an existing record, but different than the last one */ -/* we accessed? */ -/* -------------------------------------------------------------------- */ - if( psDBF->nCurrentRecord != hEntity ) - { - DBFFlushRecord( psDBF ); - - nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; - - fseek( psDBF->fp, nRecordOffset, 0 ); - fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); - - psDBF->nCurrentRecord = hEntity; - } - - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; - - memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength ); - - psDBF->bCurrentRecordModified = TRUE; - psDBF->bUpdated = TRUE; - - return( TRUE ); -} - -/************************************************************************/ -/* DBFReadTuple() */ -/* */ -/* Read one of the attribute fields of a record. */ -/************************************************************************/ - -const char SHPAPI_CALL1(*) -DBFReadTuple(DBFHandle psDBF, int hEntity ) - -{ - int nRecordOffset; - unsigned char *pabyRec; - static char *pReturnTuple = NULL; - - static int nTupleLen = 0; - -/* -------------------------------------------------------------------- */ -/* Have we read the record? */ -/* -------------------------------------------------------------------- */ - if( hEntity < 0 || hEntity >= psDBF->nRecords ) - return( NULL ); - - if( psDBF->nCurrentRecord != hEntity ) - { - DBFFlushRecord( psDBF ); - - nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; - - fseek( psDBF->fp, nRecordOffset, 0 ); - fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); - - psDBF->nCurrentRecord = hEntity; - } - - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; - - if ( nTupleLen < psDBF->nRecordLength) { - nTupleLen = psDBF->nRecordLength; - pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength); - } - - memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength ); - - return( pReturnTuple ); -} - -/************************************************************************/ -/* DBFCloneEmpty() */ -/* */ -/* Read one of the attribute fields of a record. */ -/************************************************************************/ - -DBFHandle SHPAPI_CALL -DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) -{ - DBFHandle newDBF; - - newDBF = DBFCreate ( pszFilename ); - if ( newDBF == NULL ) return ( NULL ); - - newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields ); - memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields ); - - newDBF->nFields = psDBF->nFields; - newDBF->nRecordLength = psDBF->nRecordLength; - newDBF->nHeaderLength = 32 * (psDBF->nFields+1); - - newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); - memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); - newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields ); - memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); - newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields ); - memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); - newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields ); - memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields ); - - newDBF->bNoHeader = TRUE; - newDBF->bUpdated = TRUE; - - DBFWriteHeader ( newDBF ); - DBFClose ( newDBF ); - - newDBF = DBFOpen ( pszFilename, "rb+" ); - - return ( newDBF ); -} - -/************************************************************************/ -/* DBFGetNativeFieldType() */ -/* */ -/* Return the DBase field type for the specified field. */ -/* */ -/* Value can be one of: 'C' (String), 'D' (Date), 'F' (Float), */ -/* 'N' (Numeric, with or without decimal), */ -/* 'L' (Logical), */ -/* 'M' (Memo: 10 digits .DBT block ptr) */ -/************************************************************************/ - -char SHPAPI_CALL -DBFGetNativeFieldType( DBFHandle psDBF, int iField ) - -{ - if( iField >=0 && iField < psDBF->nFields ) - return psDBF->pachFieldType[iField]; - - return ' '; -} - -/************************************************************************/ -/* str_to_upper() */ -/************************************************************************/ - -static void str_to_upper (char *string) -{ - int len; - short i = -1; - - len = strlen (string); - - while (++i < len) - if (isalpha(string[i]) && islower(string[i])) - string[i] = (char) toupper ((int)string[i]); -} - -/************************************************************************/ -/* DBFGetFieldIndex() */ -/* */ -/* Get the index number for a field in a .dbf file. */ -/* */ -/* Contributed by Jim Matthews. */ -/************************************************************************/ - -int SHPAPI_CALL -DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName) - -{ - char name[12], name1[12], name2[12]; - int i; - - strncpy(name1, pszFieldName,11); - name1[11] = '\0'; - str_to_upper(name1); - - for( i = 0; i < DBFGetFieldCount(psDBF); i++ ) - { - DBFGetFieldInfo( psDBF, i, name, NULL, NULL ); - strncpy(name2,name,11); - str_to_upper(name2); - - if(!strncmp(name1,name2,10)) - return(i); - } - return(-1); -} diff --git a/pyshapelib/shapelib/shapefil.h b/pyshapelib/shapelib/shapefil.h deleted file mode 100644 index e2ced88c1..000000000 --- a/pyshapelib/shapelib/shapefil.h +++ /dev/null @@ -1,538 +0,0 @@ -#ifndef _SHAPEFILE_H_INCLUDED -#define _SHAPEFILE_H_INCLUDED - -/****************************************************************************** - * $Id$ - * - * Project: Shapelib - * Purpose: Primary include file for Shapelib. - * Author: Frank Warmerdam, warmerdam@pobox.com - * - ****************************************************************************** - * Copyright (c) 1999, Frank Warmerdam - * - * This software is available under the following "MIT Style" license, - * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This - * option is discussed in more detail in shapelib.html. - * - * -- - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************** - * - * $Log$ - * Revision 1.1 2005/08/14 21:40:30 jswhit - * inclusion of pyshapelib - * - * Revision 1.3 2004/05/17 15:47:57 bh - * Update to newest shapelib and get rid of Thuban specific extensions, - * i.e. use the new DBFUpdateHeader instead of our DBFCommit kludge - * - * * libraries/shapelib/shpopen.c: Update to version from current - * shapelib CVS. - * - * * libraries/shapelib/shapefil.h: Update to version from current - * shapelib CVS. - * - * * libraries/shapelib/dbfopen.c: Update to version from current - * shapelib CVS. - * (DBFCommit): Effectively removed since shapelib itself has - * DBFUpdateHeader now which is better for what DBFCommit wanted to - * achieve. - * We're now using an unmodified version of dbfopen. - * - * * libraries/pyshapelib/dbflib_wrap.c, libraries/pyshapelib/dbflib.py: - * Update from dbflib.i - * - * * libraries/pyshapelib/dbflib.i (DBFInfo_commit): New. Implementation of - * the commit method. This new indirection is necessary because we use the - * DBFUpdateHeader function now which is not available in shapelib <= - * 1.2.10 - * (DBFFile::commit): Use DBFInfo_commit as implementation - * (pragma __class__): New. Kludge to remove the commit method when - * the DBFUpdateHeader function isn't available - * (_have_commit): New. Helper for the pragma kludge. - * - * * libraries/pyshapelib/setup.py (dbf_macros): New. Return the - * preprocessor macros needed to compile the dbflib wrapper. Determine - * whether DBFUpdateHeader is available and define the right value of - * HAVE_UPDATE_HEADER - * (extensions): Use dbf_macros for the dbflibc extension - * - * * setup.py (extensions): Add the HAVE_UPDATE_HEADER macro with - * value '1' to the Lib.dbflibc extension. This simply reflects the - * shapelib and pyshapelib updates - * - * Revision 1.28 2003/12/29 06:02:18 fwarmerdam - * added cpl_error.h option - * - * Revision 1.27 2003/04/21 18:30:37 warmerda - * added header write/update public methods - * - * Revision 1.26 2002/09/29 00:00:08 warmerda - * added FTLogical and logical attribute read/write calls - * - * Revision 1.25 2002/05/07 13:46:30 warmerda - * added DBFWriteAttributeDirectly(). - * - * Revision 1.24 2002/04/10 16:59:54 warmerda - * added SHPRewindObject - * - * Revision 1.23 2002/01/15 14:36:07 warmerda - * updated email address - * - * Revision 1.22 2002/01/15 14:32:00 warmerda - * try to improve SHPAPI_CALL docs - * - * Revision 1.21 2001/11/01 16:29:55 warmerda - * move pabyRec into SHPInfo for thread safety - * - * Revision 1.20 2001/07/20 13:06:02 warmerda - * fixed SHPAPI attribute for SHPTreeFindLikelyShapes - * - * Revision 1.19 2001/05/31 19:20:13 warmerda - * added DBFGetFieldIndex() - * - * Revision 1.18 2001/05/31 18:15:40 warmerda - * Added support for NULL fields in DBF files - * - * Revision 1.17 2001/05/23 13:36:52 warmerda - * added use of SHPAPI_CALL - * - * Revision 1.16 2000/09/25 14:15:59 warmerda - * added DBFGetNativeFieldType() - * - * Revision 1.15 2000/02/16 16:03:51 warmerda - * added null shape support - * - * Revision 1.14 1999/11/05 14:12:05 warmerda - * updated license terms - * - * Revision 1.13 1999/06/02 18:24:21 warmerda - * added trimming code - * - * Revision 1.12 1999/06/02 17:56:12 warmerda - * added quad'' subnode support for trees - * - * Revision 1.11 1999/05/18 19:11:11 warmerda - * Added example searching capability - * - * Revision 1.10 1999/05/18 17:49:38 warmerda - * added initial quadtree support - * - * Revision 1.9 1999/05/11 03:19:28 warmerda - * added new Tuple api, and improved extension handling - add from candrsn - * - * Revision 1.8 1999/03/23 17:22:27 warmerda - * Added extern "C" protection for C++ users of shapefil.h. - * - * Revision 1.7 1998/12/31 15:31:07 warmerda - * Added the TRIM_DBF_WHITESPACE and DISABLE_MULTIPATCH_MEASURE options. - * - * Revision 1.6 1998/12/03 15:48:15 warmerda - * Added SHPCalculateExtents(). - * - * Revision 1.5 1998/11/09 20:57:16 warmerda - * Altered SHPGetInfo() call. - * - * Revision 1.4 1998/11/09 20:19:33 warmerda - * Added 3D support, and use of SHPObject. - * - * Revision 1.3 1995/08/23 02:24:05 warmerda - * Added support for reading bounds. - * - * Revision 1.2 1995/08/04 03:17:39 warmerda - * Added header. - * - */ - -#include - -#ifdef USE_DBMALLOC -#include -#endif - -#ifdef USE_CPL -#include "cpl_error.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/************************************************************************/ -/* Configuration options. */ -/************************************************************************/ - -/* -------------------------------------------------------------------- */ -/* Should the DBFReadStringAttribute() strip leading and */ -/* trailing white space? */ -/* -------------------------------------------------------------------- */ -#define TRIM_DBF_WHITESPACE - -/* -------------------------------------------------------------------- */ -/* Should we write measure values to the Multipatch object? */ -/* Reportedly ArcView crashes if we do write it, so for now it */ -/* is disabled. */ -/* -------------------------------------------------------------------- */ -#define DISABLE_MULTIPATCH_MEASURE - -/* -------------------------------------------------------------------- */ -/* SHPAPI_CALL */ -/* */ -/* The following two macros are present to allow forcing */ -/* various calling conventions on the Shapelib API. */ -/* */ -/* To force __stdcall conventions (needed to call Shapelib */ -/* from Visual Basic and/or Dephi I believe) the makefile could */ -/* be modified to define: */ -/* */ -/* /DSHPAPI_CALL=__stdcall */ -/* */ -/* If it is desired to force export of the Shapelib API without */ -/* using the shapelib.def file, use the following definition. */ -/* */ -/* /DSHAPELIB_DLLEXPORT */ -/* */ -/* To get both at once it will be necessary to hack this */ -/* include file to define: */ -/* */ -/* #define SHPAPI_CALL __declspec(dllexport) __stdcall */ -/* #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall */ -/* */ -/* The complexity of the situtation is partly caused by the */ -/* peculiar requirement of Visual C++ that __stdcall appear */ -/* after any "*"'s in the return value of a function while the */ -/* __declspec(dllexport) must appear before them. */ -/* -------------------------------------------------------------------- */ - -#ifdef SHAPELIB_DLLEXPORT -# define SHPAPI_CALL __declspec(dllexport) -# define SHPAPI_CALL1(x) __declspec(dllexport) x -#endif - -#ifndef SHPAPI_CALL -# define SHPAPI_CALL -#endif - -#ifndef SHPAPI_CALL1 -# define SHPAPI_CALL1(x) x SHPAPI_CALL -#endif - -/************************************************************************/ -/* SHP Support. */ -/************************************************************************/ -typedef struct -{ - FILE *fpSHP; - FILE *fpSHX; - - int nShapeType; /* SHPT_* */ - - int nFileSize; /* SHP file */ - - int nRecords; - int nMaxRecords; - int *panRecOffset; - int *panRecSize; - - double adBoundsMin[4]; - double adBoundsMax[4]; - - int bUpdated; - - unsigned char *pabyRec; - int nBufSize; -} SHPInfo; - -typedef SHPInfo * SHPHandle; - -/* -------------------------------------------------------------------- */ -/* Shape types (nSHPType) */ -/* -------------------------------------------------------------------- */ -#define SHPT_NULL 0 -#define SHPT_POINT 1 -#define SHPT_ARC 3 -#define SHPT_POLYGON 5 -#define SHPT_MULTIPOINT 8 -#define SHPT_POINTZ 11 -#define SHPT_ARCZ 13 -#define SHPT_POLYGONZ 15 -#define SHPT_MULTIPOINTZ 18 -#define SHPT_POINTM 21 -#define SHPT_ARCM 23 -#define SHPT_POLYGONM 25 -#define SHPT_MULTIPOINTM 28 -#define SHPT_MULTIPATCH 31 - - -/* -------------------------------------------------------------------- */ -/* Part types - everything but SHPT_MULTIPATCH just uses */ -/* SHPP_RING. */ -/* -------------------------------------------------------------------- */ - -#define SHPP_TRISTRIP 0 -#define SHPP_TRIFAN 1 -#define SHPP_OUTERRING 2 -#define SHPP_INNERRING 3 -#define SHPP_FIRSTRING 4 -#define SHPP_RING 5 - -/* -------------------------------------------------------------------- */ -/* SHPObject - represents on shape (without attributes) read */ -/* from the .shp file. */ -/* -------------------------------------------------------------------- */ -typedef struct -{ - int nSHPType; - - int nShapeId; /* -1 is unknown/unassigned */ - - int nParts; - int *panPartStart; - int *panPartType; - - int nVertices; - double *padfX; - double *padfY; - double *padfZ; - double *padfM; - - double dfXMin; - double dfYMin; - double dfZMin; - double dfMMin; - - double dfXMax; - double dfYMax; - double dfZMax; - double dfMMax; -} SHPObject; - -/* -------------------------------------------------------------------- */ -/* SHP API Prototypes */ -/* -------------------------------------------------------------------- */ -SHPHandle SHPAPI_CALL - SHPOpen( const char * pszShapeFile, const char * pszAccess ); -SHPHandle SHPAPI_CALL - SHPCreate( const char * pszShapeFile, int nShapeType ); -void SHPAPI_CALL - SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType, - double * padfMinBound, double * padfMaxBound ); - -SHPObject SHPAPI_CALL1(*) - SHPReadObject( SHPHandle hSHP, int iShape ); -int SHPAPI_CALL - SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject ); - -void SHPAPI_CALL - SHPDestroyObject( SHPObject * psObject ); -void SHPAPI_CALL - SHPComputeExtents( SHPObject * psObject ); -SHPObject SHPAPI_CALL1(*) - SHPCreateObject( int nSHPType, int nShapeId, - int nParts, int * panPartStart, int * panPartType, - int nVertices, double * padfX, double * padfY, - double * padfZ, double * padfM ); -SHPObject SHPAPI_CALL1(*) - SHPCreateSimpleObject( int nSHPType, int nVertices, - double * padfX, double * padfY, double * padfZ ); - -int SHPAPI_CALL - SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ); - -void SHPAPI_CALL SHPClose( SHPHandle hSHP ); -void SHPAPI_CALL SHPWriteHeader( SHPHandle hSHP ); - -const char SHPAPI_CALL1(*) - SHPTypeName( int nSHPType ); -const char SHPAPI_CALL1(*) - SHPPartTypeName( int nPartType ); - -/* -------------------------------------------------------------------- */ -/* Shape quadtree indexing API. */ -/* -------------------------------------------------------------------- */ - -/* this can be two or four for binary or quad tree */ -#define MAX_SUBNODE 4 - -typedef struct shape_tree_node -{ - /* region covered by this node */ - double adfBoundsMin[4]; - double adfBoundsMax[4]; - - /* list of shapes stored at this node. The papsShapeObj pointers - or the whole list can be NULL */ - int nShapeCount; - int *panShapeIds; - SHPObject **papsShapeObj; - - int nSubNodes; - struct shape_tree_node *apsSubNode[MAX_SUBNODE]; - -} SHPTreeNode; - -typedef struct -{ - SHPHandle hSHP; - - int nMaxDepth; - int nDimension; - - SHPTreeNode *psRoot; -} SHPTree; - -SHPTree SHPAPI_CALL1(*) - SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth, - double *padfBoundsMin, double *padfBoundsMax ); -void SHPAPI_CALL - SHPDestroyTree( SHPTree * hTree ); - -int SHPAPI_CALL - SHPWriteTree( SHPTree *hTree, const char * pszFilename ); -SHPTree SHPAPI_CALL - SHPReadTree( const char * pszFilename ); - -int SHPAPI_CALL - SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject ); -int SHPAPI_CALL - SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject ); -int SHPAPI_CALL - SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId ); - -void SHPAPI_CALL - SHPTreeTrimExtraNodes( SHPTree * hTree ); - -int SHPAPI_CALL1(*) - SHPTreeFindLikelyShapes( SHPTree * hTree, - double * padfBoundsMin, - double * padfBoundsMax, - int * ); -int SHPAPI_CALL - SHPCheckBoundsOverlap( double *, double *, double *, double *, int ); - -/************************************************************************/ -/* DBF Support. */ -/************************************************************************/ -typedef struct -{ - FILE *fp; - - int nRecords; - - int nRecordLength; - int nHeaderLength; - int nFields; - int *panFieldOffset; - int *panFieldSize; - int *panFieldDecimals; - char *pachFieldType; - - char *pszHeader; - - int nCurrentRecord; - int bCurrentRecordModified; - char *pszCurrentRecord; - - int bNoHeader; - int bUpdated; -} DBFInfo; - -typedef DBFInfo * DBFHandle; - -typedef enum { - FTString, - FTInteger, - FTDouble, - FTLogical, - FTInvalid -} DBFFieldType; - -#define XBASE_FLDHDR_SZ 32 - -DBFHandle SHPAPI_CALL - DBFOpen( const char * pszDBFFile, const char * pszAccess ); -DBFHandle SHPAPI_CALL - DBFCreate( const char * pszDBFFile ); - -int SHPAPI_CALL - DBFGetFieldCount( DBFHandle psDBF ); -int SHPAPI_CALL - DBFGetRecordCount( DBFHandle psDBF ); -int SHPAPI_CALL - DBFAddField( DBFHandle hDBF, const char * pszFieldName, - DBFFieldType eType, int nWidth, int nDecimals ); - -DBFFieldType SHPAPI_CALL - DBFGetFieldInfo( DBFHandle psDBF, int iField, - char * pszFieldName, int * pnWidth, int * pnDecimals ); - -int SHPAPI_CALL - DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName); - -int SHPAPI_CALL - DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField ); -double SHPAPI_CALL - DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField ); -const char SHPAPI_CALL1(*) - DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField ); -const char SHPAPI_CALL1(*) - DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField ); -int SHPAPI_CALL - DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField ); - -int SHPAPI_CALL - DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField, - int nFieldValue ); -int SHPAPI_CALL - DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField, - double dFieldValue ); -int SHPAPI_CALL - DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField, - const char * pszFieldValue ); -int SHPAPI_CALL - DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField ); - -int SHPAPI_CALL - DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField, - const char lFieldValue); -int SHPAPI_CALL - DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, - void * pValue ); -const char SHPAPI_CALL1(*) - DBFReadTuple(DBFHandle psDBF, int hEntity ); -int SHPAPI_CALL - DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple ); - -DBFHandle SHPAPI_CALL - DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ); - -void SHPAPI_CALL - DBFClose( DBFHandle hDBF ); -void SHPAPI_CALL - DBFUpdateHeader( DBFHandle hDBF ); -char SHPAPI_CALL - DBFGetNativeFieldType( DBFHandle hDBF, int iField ); - -#ifdef __cplusplus -} -#endif - -#endif /* ndef _SHAPEFILE_H_INCLUDED */ diff --git a/pyshapelib/shapelib/shpopen.c b/pyshapelib/shapelib/shpopen.c deleted file mode 100644 index 67a80be05..000000000 --- a/pyshapelib/shapelib/shpopen.c +++ /dev/null @@ -1,2038 +0,0 @@ -/****************************************************************************** - * $Id$ - * - * Project: Shapelib - * Purpose: Implementation of core Shapefile read/write functions. - * Author: Frank Warmerdam, warmerdam@pobox.com - * - ****************************************************************************** - * Copyright (c) 1999, 2001, Frank Warmerdam - * - * This software is available under the following "MIT Style" license, - * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This - * option is discussed in more detail in shapelib.html. - * - * -- - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************** - * - * $Log$ - * Revision 1.1 2005/08/14 21:40:30 jswhit - * inclusion of pyshapelib - * - * Revision 1.3 2004/05/17 15:47:57 bh - * Update to newest shapelib and get rid of Thuban specific extensions, - * i.e. use the new DBFUpdateHeader instead of our DBFCommit kludge - * - * * libraries/shapelib/shpopen.c: Update to version from current - * shapelib CVS. - * - * * libraries/shapelib/shapefil.h: Update to version from current - * shapelib CVS. - * - * * libraries/shapelib/dbfopen.c: Update to version from current - * shapelib CVS. - * (DBFCommit): Effectively removed since shapelib itself has - * DBFUpdateHeader now which is better for what DBFCommit wanted to - * achieve. - * We're now using an unmodified version of dbfopen. - * - * * libraries/pyshapelib/dbflib_wrap.c, libraries/pyshapelib/dbflib.py: - * Update from dbflib.i - * - * * libraries/pyshapelib/dbflib.i (DBFInfo_commit): New. Implementation of - * the commit method. This new indirection is necessary because we use the - * DBFUpdateHeader function now which is not available in shapelib <= - * 1.2.10 - * (DBFFile::commit): Use DBFInfo_commit as implementation - * (pragma __class__): New. Kludge to remove the commit method when - * the DBFUpdateHeader function isn't available - * (_have_commit): New. Helper for the pragma kludge. - * - * * libraries/pyshapelib/setup.py (dbf_macros): New. Return the - * preprocessor macros needed to compile the dbflib wrapper. Determine - * whether DBFUpdateHeader is available and define the right value of - * HAVE_UPDATE_HEADER - * (extensions): Use dbf_macros for the dbflibc extension - * - * * setup.py (extensions): Add the HAVE_UPDATE_HEADER macro with - * value '1' to the Lib.dbflibc extension. This simply reflects the - * shapelib and pyshapelib updates - * - * Revision 1.44 2003/12/29 00:18:39 fwarmerdam - * added error checking for failed IO and optional CPL error reporting - * - * Revision 1.43 2003/12/01 16:20:08 warmerda - * be careful of zero vertex shapes - * - * Revision 1.42 2003/12/01 14:58:27 warmerda - * added degenerate object check in SHPRewindObject() - * - * Revision 1.41 2003/07/08 15:22:43 warmerda - * avoid warning - * - * Revision 1.40 2003/04/21 18:30:37 warmerda - * added header write/update public methods - * - * Revision 1.39 2002/08/26 06:46:56 warmerda - * avoid c++ comments - * - * Revision 1.38 2002/05/07 16:43:39 warmerda - * Removed debugging printf. - * - * Revision 1.37 2002/04/10 17:35:22 warmerda - * fixed bug in ring reversal code - * - * Revision 1.36 2002/04/10 16:59:54 warmerda - * added SHPRewindObject - * - * Revision 1.35 2001/12/07 15:10:44 warmerda - * fix if .shx fails to open - * - * Revision 1.34 2001/11/01 16:29:55 warmerda - * move pabyRec into SHPInfo for thread safety - * - * Revision 1.33 2001/07/03 12:18:15 warmerda - * Improved cleanup if SHX not found, provied by Riccardo Cohen. - * - * Revision 1.32 2001/06/22 01:58:07 warmerda - * be more careful about establishing initial bounds in face of NULL shapes - * - * Revision 1.31 2001/05/31 19:35:29 warmerda - * added support for writing null shapes - * - * Revision 1.30 2001/05/28 12:46:29 warmerda - * Add some checking on reasonableness of record count when opening. - * - * Revision 1.29 2001/05/23 13:36:52 warmerda - * added use of SHPAPI_CALL - * - * Revision 1.28 2001/02/06 22:25:06 warmerda - * fixed memory leaks when SHPOpen() fails - * - * Revision 1.27 2000/07/18 15:21:33 warmerda - * added better enforcement of -1 for append in SHPWriteObject - * - * Revision 1.26 2000/02/16 16:03:51 warmerda - * added null shape support - * - * Revision 1.25 1999/12/15 13:47:07 warmerda - * Fixed record size settings in .shp file (was 4 words too long) - * Added stdlib.h. - * - * Revision 1.24 1999/11/05 14:12:04 warmerda - * updated license terms - * - * Revision 1.23 1999/07/27 00:53:46 warmerda - * added support for rewriting shapes - * - * Revision 1.22 1999/06/11 19:19:11 warmerda - * Cleanup pabyRec static buffer on SHPClose(). - * - * Revision 1.21 1999/06/02 14:57:56 kshih - * Remove unused variables - * - * Revision 1.20 1999/04/19 21:04:17 warmerda - * Fixed syntax error. - * - * Revision 1.19 1999/04/19 21:01:57 warmerda - * Force access string to binary in SHPOpen(). - * - * Revision 1.18 1999/04/01 18:48:07 warmerda - * Try upper case extensions if lower case doesn't work. - * - * Revision 1.17 1998/12/31 15:29:39 warmerda - * Disable writing measure values to multipatch objects if - * DISABLE_MULTIPATCH_MEASURE is defined. - * - * Revision 1.16 1998/12/16 05:14:33 warmerda - * Added support to write MULTIPATCH. Fixed reading Z coordinate of - * MULTIPATCH. Fixed record size written for all feature types. - * - * Revision 1.15 1998/12/03 16:35:29 warmerda - * r+b is proper binary access string, not rb+. - * - * Revision 1.14 1998/12/03 15:47:56 warmerda - * Fixed setting of nVertices in SHPCreateObject(). - * - * Revision 1.13 1998/12/03 15:33:54 warmerda - * Made SHPCalculateExtents() separately callable. - * - * Revision 1.12 1998/11/11 20:01:50 warmerda - * Fixed bug writing ArcM/Z, and PolygonM/Z for big endian machines. - * - * Revision 1.11 1998/11/09 20:56:44 warmerda - * Fixed up handling of file wide bounds. - * - * Revision 1.10 1998/11/09 20:18:51 warmerda - * Converted to support 3D shapefiles, and use of SHPObject. - * - * Revision 1.9 1998/02/24 15:09:05 warmerda - * Fixed memory leak. - * - * Revision 1.8 1997/12/04 15:40:29 warmerda - * Fixed byte swapping of record number, and record length fields in the - * .shp file. - * - * Revision 1.7 1995/10/21 03:15:58 warmerda - * Added support for binary file access, the magic cookie 9997 - * and tried to improve the int32 selection logic for 16bit systems. - * - * Revision 1.6 1995/09/04 04:19:41 warmerda - * Added fix for file bounds. - * - * Revision 1.5 1995/08/25 15:16:44 warmerda - * Fixed a couple of problems with big endian systems ... one with bounds - * and the other with multipart polygons. - * - * Revision 1.4 1995/08/24 18:10:17 warmerda - * Switch to use SfRealloc() to avoid problems with pre-ANSI realloc() - * functions (such as on the Sun). - * - * Revision 1.3 1995/08/23 02:23:15 warmerda - * Added support for reading bounds, and fixed up problems in setting the - * file wide bounds. - * - * Revision 1.2 1995/08/04 03:16:57 warmerda - * Added header. - * - */ - -static char rcsid[] = - "$Id$"; - -#include "shapefil.h" - -#include -#include -#include -#include -#include - -typedef unsigned char uchar; - -#if UINT_MAX == 65535 -typedef long int32; -#else -typedef int int32; -#endif - -#ifndef FALSE -# define FALSE 0 -# define TRUE 1 -#endif - -#define ByteCopy( a, b, c ) memcpy( b, a, c ) -#ifndef MAX -# define MIN(a,b) ((ab) ? a : b) -#endif - -static int bBigEndian; - - -/************************************************************************/ -/* SwapWord() */ -/* */ -/* Swap a 2, 4 or 8 byte word. */ -/************************************************************************/ - -static void SwapWord( int length, void * wordP ) - -{ - int i; - uchar temp; - - for( i=0; i < length/2; i++ ) - { - temp = ((uchar *) wordP)[i]; - ((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1]; - ((uchar *) wordP)[length-i-1] = temp; - } -} - -/************************************************************************/ -/* SfRealloc() */ -/* */ -/* A realloc cover function that will access a NULL pointer as */ -/* a valid input. */ -/************************************************************************/ - -static void * SfRealloc( void * pMem, int nNewSize ) - -{ - if( pMem == NULL ) - return( (void *) malloc(nNewSize) ); - else - return( (void *) realloc(pMem,nNewSize) ); -} - -/************************************************************************/ -/* SHPWriteHeader() */ -/* */ -/* Write out a header for the .shp and .shx files as well as the */ -/* contents of the index (.shx) file. */ -/************************************************************************/ - -void SHPWriteHeader( SHPHandle psSHP ) - -{ - uchar abyHeader[100]; - int i; - int32 i32; - double dValue; - int32 *panSHX; - -/* -------------------------------------------------------------------- */ -/* Prepare header block for .shp file. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < 100; i++ ) - abyHeader[i] = 0; - - abyHeader[2] = 0x27; /* magic cookie */ - abyHeader[3] = 0x0a; - - i32 = psSHP->nFileSize/2; /* file size */ - ByteCopy( &i32, abyHeader+24, 4 ); - if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); - - i32 = 1000; /* version */ - ByteCopy( &i32, abyHeader+28, 4 ); - if( bBigEndian ) SwapWord( 4, abyHeader+28 ); - - i32 = psSHP->nShapeType; /* shape type */ - ByteCopy( &i32, abyHeader+32, 4 ); - if( bBigEndian ) SwapWord( 4, abyHeader+32 ); - - dValue = psSHP->adBoundsMin[0]; /* set bounds */ - ByteCopy( &dValue, abyHeader+36, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+36 ); - - dValue = psSHP->adBoundsMin[1]; - ByteCopy( &dValue, abyHeader+44, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+44 ); - - dValue = psSHP->adBoundsMax[0]; - ByteCopy( &dValue, abyHeader+52, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+52 ); - - dValue = psSHP->adBoundsMax[1]; - ByteCopy( &dValue, abyHeader+60, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+60 ); - - dValue = psSHP->adBoundsMin[2]; /* z */ - ByteCopy( &dValue, abyHeader+68, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+68 ); - - dValue = psSHP->adBoundsMax[2]; - ByteCopy( &dValue, abyHeader+76, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+76 ); - - dValue = psSHP->adBoundsMin[3]; /* m */ - ByteCopy( &dValue, abyHeader+84, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+84 ); - - dValue = psSHP->adBoundsMax[3]; - ByteCopy( &dValue, abyHeader+92, 8 ); - if( bBigEndian ) SwapWord( 8, abyHeader+92 ); - -/* -------------------------------------------------------------------- */ -/* Write .shp file header. */ -/* -------------------------------------------------------------------- */ - if( fseek( psSHP->fpSHP, 0, 0 ) != 0 - || fwrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_OpenFailed, - "Failure writing .shp header." ); -#endif - return; - } - -/* -------------------------------------------------------------------- */ -/* Prepare, and write .shx file header. */ -/* -------------------------------------------------------------------- */ - i32 = (psSHP->nRecords * 2 * sizeof(int32) + 100)/2; /* file size */ - ByteCopy( &i32, abyHeader+24, 4 ); - if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); - - if( fseek( psSHP->fpSHX, 0, 0 ) != 0 - || fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_OpenFailed, - "Failure writing .shx header." ); -#endif - return; - } - -/* -------------------------------------------------------------------- */ -/* Write out the .shx contents. */ -/* -------------------------------------------------------------------- */ - panSHX = (int32 *) malloc(sizeof(int32) * 2 * psSHP->nRecords); - - for( i = 0; i < psSHP->nRecords; i++ ) - { - panSHX[i*2 ] = psSHP->panRecOffset[i]/2; - panSHX[i*2+1] = psSHP->panRecSize[i]/2; - if( !bBigEndian ) SwapWord( 4, panSHX+i*2 ); - if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 ); - } - - if( fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX ) - != psSHP->nRecords ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_OpenFailed, - "Failure writing .shx contents." ); -#endif - } - - free( panSHX ); - -/* -------------------------------------------------------------------- */ -/* Flush to disk. */ -/* -------------------------------------------------------------------- */ - fflush( psSHP->fpSHP ); - fflush( psSHP->fpSHX ); -} - -/************************************************************************/ -/* shpopen() */ -/* */ -/* Open the .shp and .shx files based on the basename of the */ -/* files or either file name. */ -/************************************************************************/ - -SHPHandle SHPAPI_CALL -SHPOpen( const char * pszLayer, const char * pszAccess ) - -{ - char *pszFullname, *pszBasename; - SHPHandle psSHP; - - uchar *pabyBuf; - int i; - double dValue; - -/* -------------------------------------------------------------------- */ -/* Ensure the access string is one of the legal ones. We */ -/* ensure the result string indicates binary to avoid common */ -/* problems on Windows. */ -/* -------------------------------------------------------------------- */ - if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0 - || strcmp(pszAccess,"r+") == 0 ) - pszAccess = "r+b"; - else - pszAccess = "rb"; - -/* -------------------------------------------------------------------- */ -/* Establish the byte order on this machine. */ -/* -------------------------------------------------------------------- */ - i = 1; - if( *((uchar *) &i) == 1 ) - bBigEndian = FALSE; - else - bBigEndian = TRUE; - -/* -------------------------------------------------------------------- */ -/* Initialize the info structure. */ -/* -------------------------------------------------------------------- */ - psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1); - - psSHP->bUpdated = FALSE; - -/* -------------------------------------------------------------------- */ -/* Compute the base (layer) name. If there is any extension */ -/* on the passed in filename we will strip it off. */ -/* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszLayer)+5); - strcpy( pszBasename, pszLayer ); - for( i = strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - -/* -------------------------------------------------------------------- */ -/* Open the .shp and .shx files. Note that files pulled from */ -/* a PC to Unix with upper case filenames won't work! */ -/* -------------------------------------------------------------------- */ - pszFullname = (char *) malloc(strlen(pszBasename) + 5); - sprintf( pszFullname, "%s.shp", pszBasename ); - psSHP->fpSHP = fopen(pszFullname, pszAccess ); - if( psSHP->fpSHP == NULL ) - { - sprintf( pszFullname, "%s.SHP", pszBasename ); - psSHP->fpSHP = fopen(pszFullname, pszAccess ); - } - - if( psSHP->fpSHP == NULL ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_OpenFailed, - "Unable to open %s.shp or %s.SHP.", - pszBasename, pszBasename ); -#endif - free( psSHP ); - free( pszBasename ); - free( pszFullname ); - return( NULL ); - } - - sprintf( pszFullname, "%s.shx", pszBasename ); - psSHP->fpSHX = fopen(pszFullname, pszAccess ); - if( psSHP->fpSHX == NULL ) - { - sprintf( pszFullname, "%s.SHX", pszBasename ); - psSHP->fpSHX = fopen(pszFullname, pszAccess ); - } - - if( psSHP->fpSHX == NULL ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_OpenFailed, - "Unable to open %s.shx or %s.SHX.", - pszBasename, pszBasename ); -#endif - fclose( psSHP->fpSHP ); - free( psSHP ); - free( pszBasename ); - free( pszFullname ); - return( NULL ); - } - - free( pszFullname ); - free( pszBasename ); - -/* -------------------------------------------------------------------- */ -/* Read the file size from the SHP file. */ -/* -------------------------------------------------------------------- */ - pabyBuf = (uchar *) malloc(100); - fread( pabyBuf, 100, 1, psSHP->fpSHP ); - - psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256 - + pabyBuf[25] * 256 * 256 - + pabyBuf[26] * 256 - + pabyBuf[27]) * 2; - -/* -------------------------------------------------------------------- */ -/* Read SHX file Header info */ -/* -------------------------------------------------------------------- */ - if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 - || pabyBuf[0] != 0 - || pabyBuf[1] != 0 - || pabyBuf[2] != 0x27 - || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_AppDefined, - ".shx file is unreadable, or corrupt." ); -#endif - fclose( psSHP->fpSHP ); - fclose( psSHP->fpSHX ); - free( psSHP ); - - return( NULL ); - } - - psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256 - + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256; - psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8; - - psSHP->nShapeType = pabyBuf[32]; - - if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_AppDefined, - "Record count in .shp header is %d, which seems\n" - "unreasonable. Assuming header is corrupt.", - psSHP->nRecords ); -#endif - fclose( psSHP->fpSHP ); - fclose( psSHP->fpSHX ); - free( psSHP ); - - return( NULL ); - } - -/* -------------------------------------------------------------------- */ -/* Read the bounds. */ -/* -------------------------------------------------------------------- */ - if( bBigEndian ) SwapWord( 8, pabyBuf+36 ); - memcpy( &dValue, pabyBuf+36, 8 ); - psSHP->adBoundsMin[0] = dValue; - - if( bBigEndian ) SwapWord( 8, pabyBuf+44 ); - memcpy( &dValue, pabyBuf+44, 8 ); - psSHP->adBoundsMin[1] = dValue; - - if( bBigEndian ) SwapWord( 8, pabyBuf+52 ); - memcpy( &dValue, pabyBuf+52, 8 ); - psSHP->adBoundsMax[0] = dValue; - - if( bBigEndian ) SwapWord( 8, pabyBuf+60 ); - memcpy( &dValue, pabyBuf+60, 8 ); - psSHP->adBoundsMax[1] = dValue; - - if( bBigEndian ) SwapWord( 8, pabyBuf+68 ); /* z */ - memcpy( &dValue, pabyBuf+68, 8 ); - psSHP->adBoundsMin[2] = dValue; - - if( bBigEndian ) SwapWord( 8, pabyBuf+76 ); - memcpy( &dValue, pabyBuf+76, 8 ); - psSHP->adBoundsMax[2] = dValue; - - if( bBigEndian ) SwapWord( 8, pabyBuf+84 ); /* z */ - memcpy( &dValue, pabyBuf+84, 8 ); - psSHP->adBoundsMin[3] = dValue; - - if( bBigEndian ) SwapWord( 8, pabyBuf+92 ); - memcpy( &dValue, pabyBuf+92, 8 ); - psSHP->adBoundsMax[3] = dValue; - - free( pabyBuf ); - -/* -------------------------------------------------------------------- */ -/* Read the .shx file to get the offsets to each record in */ -/* the .shp file. */ -/* -------------------------------------------------------------------- */ - psSHP->nMaxRecords = psSHP->nRecords; - - psSHP->panRecOffset = - (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); - psSHP->panRecSize = - (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); - - pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) ); - if( fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) != psSHP->nRecords ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_AppDefined, - "Failed to read all values for %d records in .shx file.", - psSHP->nRecords ); -#endif - /* SHX is short or unreadable for some reason. */ - fclose( psSHP->fpSHP ); - fclose( psSHP->fpSHX ); - free( psSHP->panRecOffset ); - free( psSHP->panRecSize ); - free( psSHP ); - - return( NULL ); - } - - for( i = 0; i < psSHP->nRecords; i++ ) - { - int32 nOffset, nLength; - - memcpy( &nOffset, pabyBuf + i * 8, 4 ); - if( !bBigEndian ) SwapWord( 4, &nOffset ); - - memcpy( &nLength, pabyBuf + i * 8 + 4, 4 ); - if( !bBigEndian ) SwapWord( 4, &nLength ); - - psSHP->panRecOffset[i] = nOffset*2; - psSHP->panRecSize[i] = nLength*2; - } - free( pabyBuf ); - - return( psSHP ); -} - -/************************************************************************/ -/* SHPClose() */ -/* */ -/* Close the .shp and .shx files. */ -/************************************************************************/ - -void SHPAPI_CALL -SHPClose(SHPHandle psSHP ) - -{ - if( psSHP == NULL ) - return; - -/* -------------------------------------------------------------------- */ -/* Update the header if we have modified anything. */ -/* -------------------------------------------------------------------- */ - if( psSHP->bUpdated ) - SHPWriteHeader( psSHP ); - -/* -------------------------------------------------------------------- */ -/* Free all resources, and close files. */ -/* -------------------------------------------------------------------- */ - free( psSHP->panRecOffset ); - free( psSHP->panRecSize ); - - fclose( psSHP->fpSHX ); - fclose( psSHP->fpSHP ); - - if( psSHP->pabyRec != NULL ) - { - free( psSHP->pabyRec ); - } - - free( psSHP ); -} - -/************************************************************************/ -/* SHPGetInfo() */ -/* */ -/* Fetch general information about the shape file. */ -/************************************************************************/ - -void SHPAPI_CALL -SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType, - double * padfMinBound, double * padfMaxBound ) - -{ - int i; - - if( psSHP == NULL ) - return; - - if( pnEntities != NULL ) - *pnEntities = psSHP->nRecords; - - if( pnShapeType != NULL ) - *pnShapeType = psSHP->nShapeType; - - for( i = 0; i < 4; i++ ) - { - if( padfMinBound != NULL ) - padfMinBound[i] = psSHP->adBoundsMin[i]; - if( padfMaxBound != NULL ) - padfMaxBound[i] = psSHP->adBoundsMax[i]; - } -} - -/************************************************************************/ -/* SHPCreate() */ -/* */ -/* Create a new shape file and return a handle to the open */ -/* shape file with read/write access. */ -/************************************************************************/ - -SHPHandle SHPAPI_CALL -SHPCreate( const char * pszLayer, int nShapeType ) - -{ - char *pszBasename, *pszFullname; - int i; - FILE *fpSHP, *fpSHX; - uchar abyHeader[100]; - int32 i32; - double dValue; - -/* -------------------------------------------------------------------- */ -/* Establish the byte order on this system. */ -/* -------------------------------------------------------------------- */ - i = 1; - if( *((uchar *) &i) == 1 ) - bBigEndian = FALSE; - else - bBigEndian = TRUE; - -/* -------------------------------------------------------------------- */ -/* Compute the base (layer) name. If there is any extension */ -/* on the passed in filename we will strip it off. */ -/* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszLayer)+5); - strcpy( pszBasename, pszLayer ); - for( i = strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - -/* -------------------------------------------------------------------- */ -/* Open the two files so we can write their headers. */ -/* -------------------------------------------------------------------- */ - pszFullname = (char *) malloc(strlen(pszBasename) + 5); - sprintf( pszFullname, "%s.shp", pszBasename ); - fpSHP = fopen(pszFullname, "wb" ); - if( fpSHP == NULL ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_AppDefined, - "Failed to create file %s.", - pszFullname ); -#endif - return( NULL ); - } - - sprintf( pszFullname, "%s.shx", pszBasename ); - fpSHX = fopen(pszFullname, "wb" ); - if( fpSHX == NULL ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_AppDefined, - "Failed to create file %s.", - pszFullname ); -#endif - return( NULL ); - } - - free( pszFullname ); - free( pszBasename ); - -/* -------------------------------------------------------------------- */ -/* Prepare header block for .shp file. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < 100; i++ ) - abyHeader[i] = 0; - - abyHeader[2] = 0x27; /* magic cookie */ - abyHeader[3] = 0x0a; - - i32 = 50; /* file size */ - ByteCopy( &i32, abyHeader+24, 4 ); - if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); - - i32 = 1000; /* version */ - ByteCopy( &i32, abyHeader+28, 4 ); - if( bBigEndian ) SwapWord( 4, abyHeader+28 ); - - i32 = nShapeType; /* shape type */ - ByteCopy( &i32, abyHeader+32, 4 ); - if( bBigEndian ) SwapWord( 4, abyHeader+32 ); - - dValue = 0.0; /* set bounds */ - ByteCopy( &dValue, abyHeader+36, 8 ); - ByteCopy( &dValue, abyHeader+44, 8 ); - ByteCopy( &dValue, abyHeader+52, 8 ); - ByteCopy( &dValue, abyHeader+60, 8 ); - -/* -------------------------------------------------------------------- */ -/* Write .shp file header. */ -/* -------------------------------------------------------------------- */ - if( fwrite( abyHeader, 100, 1, fpSHP ) != 1 ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_AppDefined, - "Failed to write .shp header." ); -#endif - return NULL; - } - -/* -------------------------------------------------------------------- */ -/* Prepare, and write .shx file header. */ -/* -------------------------------------------------------------------- */ - i32 = 50; /* file size */ - ByteCopy( &i32, abyHeader+24, 4 ); - if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); - - if( fwrite( abyHeader, 100, 1, fpSHX ) != 1 ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_AppDefined, - "Failed to write .shx header." ); -#endif - return NULL; - } - -/* -------------------------------------------------------------------- */ -/* Close the files, and then open them as regular existing files. */ -/* -------------------------------------------------------------------- */ - fclose( fpSHP ); - fclose( fpSHX ); - - return( SHPOpen( pszLayer, "r+b" ) ); -} - -/************************************************************************/ -/* _SHPSetBounds() */ -/* */ -/* Compute a bounds rectangle for a shape, and set it into the */ -/* indicated location in the record. */ -/************************************************************************/ - -static void _SHPSetBounds( uchar * pabyRec, SHPObject * psShape ) - -{ - ByteCopy( &(psShape->dfXMin), pabyRec + 0, 8 ); - ByteCopy( &(psShape->dfYMin), pabyRec + 8, 8 ); - ByteCopy( &(psShape->dfXMax), pabyRec + 16, 8 ); - ByteCopy( &(psShape->dfYMax), pabyRec + 24, 8 ); - - if( bBigEndian ) - { - SwapWord( 8, pabyRec + 0 ); - SwapWord( 8, pabyRec + 8 ); - SwapWord( 8, pabyRec + 16 ); - SwapWord( 8, pabyRec + 24 ); - } -} - -/************************************************************************/ -/* SHPComputeExtents() */ -/* */ -/* Recompute the extents of a shape. Automatically done by */ -/* SHPCreateObject(). */ -/************************************************************************/ - -void SHPAPI_CALL -SHPComputeExtents( SHPObject * psObject ) - -{ - int i; - -/* -------------------------------------------------------------------- */ -/* Build extents for this object. */ -/* -------------------------------------------------------------------- */ - if( psObject->nVertices > 0 ) - { - psObject->dfXMin = psObject->dfXMax = psObject->padfX[0]; - psObject->dfYMin = psObject->dfYMax = psObject->padfY[0]; - psObject->dfZMin = psObject->dfZMax = psObject->padfZ[0]; - psObject->dfMMin = psObject->dfMMax = psObject->padfM[0]; - } - - for( i = 0; i < psObject->nVertices; i++ ) - { - psObject->dfXMin = MIN(psObject->dfXMin, psObject->padfX[i]); - psObject->dfYMin = MIN(psObject->dfYMin, psObject->padfY[i]); - psObject->dfZMin = MIN(psObject->dfZMin, psObject->padfZ[i]); - psObject->dfMMin = MIN(psObject->dfMMin, psObject->padfM[i]); - - psObject->dfXMax = MAX(psObject->dfXMax, psObject->padfX[i]); - psObject->dfYMax = MAX(psObject->dfYMax, psObject->padfY[i]); - psObject->dfZMax = MAX(psObject->dfZMax, psObject->padfZ[i]); - psObject->dfMMax = MAX(psObject->dfMMax, psObject->padfM[i]); - } -} - -/************************************************************************/ -/* SHPCreateObject() */ -/* */ -/* Create a shape object. It should be freed with */ -/* SHPDestroyObject(). */ -/************************************************************************/ - -SHPObject SHPAPI_CALL1(*) -SHPCreateObject( int nSHPType, int nShapeId, int nParts, - int * panPartStart, int * panPartType, - int nVertices, double * padfX, double * padfY, - double * padfZ, double * padfM ) - -{ - SHPObject *psObject; - int i, bHasM, bHasZ; - - psObject = (SHPObject *) calloc(1,sizeof(SHPObject)); - psObject->nSHPType = nSHPType; - psObject->nShapeId = nShapeId; - -/* -------------------------------------------------------------------- */ -/* Establish whether this shape type has M, and Z values. */ -/* -------------------------------------------------------------------- */ - if( nSHPType == SHPT_ARCM - || nSHPType == SHPT_POINTM - || nSHPType == SHPT_POLYGONM - || nSHPType == SHPT_MULTIPOINTM ) - { - bHasM = TRUE; - bHasZ = FALSE; - } - else if( nSHPType == SHPT_ARCZ - || nSHPType == SHPT_POINTZ - || nSHPType == SHPT_POLYGONZ - || nSHPType == SHPT_MULTIPOINTZ - || nSHPType == SHPT_MULTIPATCH ) - { - bHasM = TRUE; - bHasZ = TRUE; - } - else - { - bHasM = FALSE; - bHasZ = FALSE; - } - -/* -------------------------------------------------------------------- */ -/* Capture parts. Note that part type is optional, and */ -/* defaults to ring. */ -/* -------------------------------------------------------------------- */ - if( nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON - || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM - || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ - || nSHPType == SHPT_MULTIPATCH ) - { - psObject->nParts = MAX(1,nParts); - - psObject->panPartStart = (int *) - malloc(sizeof(int) * psObject->nParts); - psObject->panPartType = (int *) - malloc(sizeof(int) * psObject->nParts); - - psObject->panPartStart[0] = 0; - psObject->panPartType[0] = SHPP_RING; - - for( i = 0; i < nParts; i++ ) - { - psObject->panPartStart[i] = panPartStart[i]; - if( panPartType != NULL ) - psObject->panPartType[i] = panPartType[i]; - else - psObject->panPartType[i] = SHPP_RING; - } - } - -/* -------------------------------------------------------------------- */ -/* Capture vertices. Note that Z and M are optional, but X and */ -/* Y are not. */ -/* -------------------------------------------------------------------- */ - if( nVertices > 0 ) - { - psObject->padfX = (double *) calloc(sizeof(double),nVertices); - psObject->padfY = (double *) calloc(sizeof(double),nVertices); - psObject->padfZ = (double *) calloc(sizeof(double),nVertices); - psObject->padfM = (double *) calloc(sizeof(double),nVertices); - - assert( padfX != NULL ); - assert( padfY != NULL ); - - for( i = 0; i < nVertices; i++ ) - { - psObject->padfX[i] = padfX[i]; - psObject->padfY[i] = padfY[i]; - if( padfZ != NULL && bHasZ ) - psObject->padfZ[i] = padfZ[i]; - if( padfM != NULL && bHasM ) - psObject->padfM[i] = padfM[i]; - } - } - -/* -------------------------------------------------------------------- */ -/* Compute the extents. */ -/* -------------------------------------------------------------------- */ - psObject->nVertices = nVertices; - SHPComputeExtents( psObject ); - - return( psObject ); -} - -/************************************************************************/ -/* SHPCreateSimpleObject() */ -/* */ -/* Create a simple (common) shape object. Destroy with */ -/* SHPDestroyObject(). */ -/************************************************************************/ - -SHPObject SHPAPI_CALL1(*) -SHPCreateSimpleObject( int nSHPType, int nVertices, - double * padfX, double * padfY, - double * padfZ ) - -{ - return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL, - nVertices, padfX, padfY, padfZ, NULL ) ); -} - -/************************************************************************/ -/* SHPWriteObject() */ -/* */ -/* Write out the vertices of a new structure. Note that it is */ -/* only possible to write vertices at the end of the file. */ -/************************************************************************/ - -int SHPAPI_CALL -SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) - -{ - int nRecordOffset, i, nRecordSize=0; - uchar *pabyRec; - int32 i32; - - psSHP->bUpdated = TRUE; - -/* -------------------------------------------------------------------- */ -/* Ensure that shape object matches the type of the file it is */ -/* being written to. */ -/* -------------------------------------------------------------------- */ - assert( psObject->nSHPType == psSHP->nShapeType - || psObject->nSHPType == SHPT_NULL ); - -/* -------------------------------------------------------------------- */ -/* Ensure that -1 is used for appends. Either blow an */ -/* assertion, or if they are disabled, set the shapeid to -1 */ -/* for appends. */ -/* -------------------------------------------------------------------- */ - assert( nShapeId == -1 - || (nShapeId >= 0 && nShapeId < psSHP->nRecords) ); - - if( nShapeId != -1 && nShapeId >= psSHP->nRecords ) - nShapeId = -1; - -/* -------------------------------------------------------------------- */ -/* Add the new entity to the in memory index. */ -/* -------------------------------------------------------------------- */ - if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords ) - { - psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100); - - psSHP->panRecOffset = (int *) - SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords ); - psSHP->panRecSize = (int *) - SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords ); - } - -/* -------------------------------------------------------------------- */ -/* Initialize record. */ -/* -------------------------------------------------------------------- */ - pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) - + psObject->nParts * 8 + 128); - -/* -------------------------------------------------------------------- */ -/* Extract vertices for a Polygon or Arc. */ -/* -------------------------------------------------------------------- */ - if( psObject->nSHPType == SHPT_POLYGON - || psObject->nSHPType == SHPT_POLYGONZ - || psObject->nSHPType == SHPT_POLYGONM - || psObject->nSHPType == SHPT_ARC - || psObject->nSHPType == SHPT_ARCZ - || psObject->nSHPType == SHPT_ARCM - || psObject->nSHPType == SHPT_MULTIPATCH ) - { - int32 nPoints, nParts; - int i; - - nPoints = psObject->nVertices; - nParts = psObject->nParts; - - _SHPSetBounds( pabyRec + 12, psObject ); - - if( bBigEndian ) SwapWord( 4, &nPoints ); - if( bBigEndian ) SwapWord( 4, &nParts ); - - ByteCopy( &nPoints, pabyRec + 40 + 8, 4 ); - ByteCopy( &nParts, pabyRec + 36 + 8, 4 ); - - nRecordSize = 52; - - /* - * Write part start positions. - */ - ByteCopy( psObject->panPartStart, pabyRec + 44 + 8, - 4 * psObject->nParts ); - for( i = 0; i < psObject->nParts; i++ ) - { - if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i ); - nRecordSize += 4; - } - - /* - * Write multipatch part types if needed. - */ - if( psObject->nSHPType == SHPT_MULTIPATCH ) - { - memcpy( pabyRec + nRecordSize, psObject->panPartType, - 4*psObject->nParts ); - for( i = 0; i < psObject->nParts; i++ ) - { - if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize ); - nRecordSize += 4; - } - } - - /* - * Write the (x,y) vertex values. - */ - for( i = 0; i < psObject->nVertices; i++ ) - { - ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 ); - ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 ); - - if( bBigEndian ) - SwapWord( 8, pabyRec + nRecordSize ); - - if( bBigEndian ) - SwapWord( 8, pabyRec + nRecordSize + 8 ); - - nRecordSize += 2 * 8; - } - - /* - * Write the Z coordinates (if any). - */ - if( psObject->nSHPType == SHPT_POLYGONZ - || psObject->nSHPType == SHPT_ARCZ - || psObject->nSHPType == SHPT_MULTIPATCH ) - { - ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - for( i = 0; i < psObject->nVertices; i++ ) - { - ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - } - } - - /* - * Write the M values, if any. - */ - if( psObject->nSHPType == SHPT_POLYGONM - || psObject->nSHPType == SHPT_ARCM -#ifndef DISABLE_MULTIPATCH_MEASURE - || psObject->nSHPType == SHPT_MULTIPATCH -#endif - || psObject->nSHPType == SHPT_POLYGONZ - || psObject->nSHPType == SHPT_ARCZ ) - { - ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - for( i = 0; i < psObject->nVertices; i++ ) - { - ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - } - } - } - -/* -------------------------------------------------------------------- */ -/* Extract vertices for a MultiPoint. */ -/* -------------------------------------------------------------------- */ - else if( psObject->nSHPType == SHPT_MULTIPOINT - || psObject->nSHPType == SHPT_MULTIPOINTZ - || psObject->nSHPType == SHPT_MULTIPOINTM ) - { - int32 nPoints; - int i; - - nPoints = psObject->nVertices; - - _SHPSetBounds( pabyRec + 12, psObject ); - - if( bBigEndian ) SwapWord( 4, &nPoints ); - ByteCopy( &nPoints, pabyRec + 44, 4 ); - - for( i = 0; i < psObject->nVertices; i++ ) - { - ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 ); - ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 ); - - if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 ); - if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 ); - } - - nRecordSize = 48 + 16 * psObject->nVertices; - - if( psObject->nSHPType == SHPT_MULTIPOINTZ ) - { - ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - for( i = 0; i < psObject->nVertices; i++ ) - { - ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - } - } - - if( psObject->nSHPType == SHPT_MULTIPOINTZ - || psObject->nSHPType == SHPT_MULTIPOINTM ) - { - ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - - for( i = 0; i < psObject->nVertices; i++ ) - { - ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - } - } - } - -/* -------------------------------------------------------------------- */ -/* Write point. */ -/* -------------------------------------------------------------------- */ - else if( psObject->nSHPType == SHPT_POINT - || psObject->nSHPType == SHPT_POINTZ - || psObject->nSHPType == SHPT_POINTM ) - { - ByteCopy( psObject->padfX, pabyRec + 12, 8 ); - ByteCopy( psObject->padfY, pabyRec + 20, 8 ); - - if( bBigEndian ) SwapWord( 8, pabyRec + 12 ); - if( bBigEndian ) SwapWord( 8, pabyRec + 20 ); - - nRecordSize = 28; - - if( psObject->nSHPType == SHPT_POINTZ ) - { - ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - } - - if( psObject->nSHPType == SHPT_POINTZ - || psObject->nSHPType == SHPT_POINTM ) - { - ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 ); - if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); - nRecordSize += 8; - } - } - -/* -------------------------------------------------------------------- */ -/* Not much to do for null geometries. */ -/* -------------------------------------------------------------------- */ - else if( psObject->nSHPType == SHPT_NULL ) - { - nRecordSize = 12; - } - - else - { - /* unknown type */ - assert( FALSE ); - } - -/* -------------------------------------------------------------------- */ -/* Establish where we are going to put this record. If we are */ -/* rewriting and existing record, and it will fit, then put it */ -/* back where the original came from. Otherwise write at the end. */ -/* -------------------------------------------------------------------- */ - if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 ) - { - if( nShapeId == -1 ) - nShapeId = psSHP->nRecords++; - - psSHP->panRecOffset[nShapeId] = nRecordOffset = psSHP->nFileSize; - psSHP->panRecSize[nShapeId] = nRecordSize-8; - psSHP->nFileSize += nRecordSize; - } - else - { - nRecordOffset = psSHP->panRecOffset[nShapeId]; - } - -/* -------------------------------------------------------------------- */ -/* Set the shape type, record number, and record size. */ -/* -------------------------------------------------------------------- */ - i32 = nShapeId+1; /* record # */ - if( !bBigEndian ) SwapWord( 4, &i32 ); - ByteCopy( &i32, pabyRec, 4 ); - - i32 = (nRecordSize-8)/2; /* record size */ - if( !bBigEndian ) SwapWord( 4, &i32 ); - ByteCopy( &i32, pabyRec + 4, 4 ); - - i32 = psObject->nSHPType; /* shape type */ - if( bBigEndian ) SwapWord( 4, &i32 ); - ByteCopy( &i32, pabyRec + 8, 4 ); - -/* -------------------------------------------------------------------- */ -/* Write out record. */ -/* -------------------------------------------------------------------- */ - if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 - || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_FileIO, - "Error in fseek() or fwrite() writing object to .shp file." ); -#endif - free( pabyRec ); - return -1; - } - - free( pabyRec ); - -/* -------------------------------------------------------------------- */ -/* Expand file wide bounds based on this shape. */ -/* -------------------------------------------------------------------- */ - if( psSHP->adBoundsMin[0] == 0.0 - && psSHP->adBoundsMax[0] == 0.0 - && psSHP->adBoundsMin[1] == 0.0 - && psSHP->adBoundsMax[1] == 0.0 ) - { - if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 ) - { - psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0; - psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0; - psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0; - psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0; - } - else - { - psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0]; - psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0]; - psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0]; - psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0]; - } - } - - for( i = 0; i < psObject->nVertices; i++ ) - { - psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]); - psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]); - psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]); - psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]); - psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]); - psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]); - psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]); - psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]); - } - - return( nShapeId ); -} - -/************************************************************************/ -/* SHPReadObject() */ -/* */ -/* Read the vertices, parts, and other non-attribute information */ -/* for one shape. */ -/************************************************************************/ - -SHPObject SHPAPI_CALL1(*) -SHPReadObject( SHPHandle psSHP, int hEntity ) - -{ - SHPObject *psShape; - -/* -------------------------------------------------------------------- */ -/* Validate the record/entity number. */ -/* -------------------------------------------------------------------- */ - if( hEntity < 0 || hEntity >= psSHP->nRecords ) - return( NULL ); - -/* -------------------------------------------------------------------- */ -/* Ensure our record buffer is large enough. */ -/* -------------------------------------------------------------------- */ - if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize ) - { - psSHP->nBufSize = psSHP->panRecSize[hEntity]+8; - psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize); - } - -/* -------------------------------------------------------------------- */ -/* Read the record. */ -/* -------------------------------------------------------------------- */ - if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 - || fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, - psSHP->fpSHP ) != 1 ) - { -#ifdef USE_CPL - CPLError( CE_Failure, CPLE_FileIO, - "Error in fseek() or fread() reading object from .shp file." ); -#endif - return NULL; - } - -/* -------------------------------------------------------------------- */ -/* Allocate and minimally initialize the object. */ -/* -------------------------------------------------------------------- */ - psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); - psShape->nShapeId = hEntity; - - memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 ); - if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) ); - -/* ==================================================================== */ -/* Extract vertices for a Polygon or Arc. */ -/* ==================================================================== */ - if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC - || psShape->nSHPType == SHPT_POLYGONZ - || psShape->nSHPType == SHPT_POLYGONM - || psShape->nSHPType == SHPT_ARCZ - || psShape->nSHPType == SHPT_ARCM - || psShape->nSHPType == SHPT_MULTIPATCH ) - { - int32 nPoints, nParts; - int i, nOffset; - -/* -------------------------------------------------------------------- */ -/* Get the X/Y bounds. */ -/* -------------------------------------------------------------------- */ - memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); - memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); - memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); - memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); - - if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); - -/* -------------------------------------------------------------------- */ -/* Extract part/point count, and build vertex and part arrays */ -/* to proper size. */ -/* -------------------------------------------------------------------- */ - memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 ); - memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 ); - - if( bBigEndian ) SwapWord( 4, &nPoints ); - if( bBigEndian ) SwapWord( 4, &nParts ); - - psShape->nVertices = nPoints; - psShape->padfX = (double *) calloc(nPoints,sizeof(double)); - psShape->padfY = (double *) calloc(nPoints,sizeof(double)); - psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); - psShape->padfM = (double *) calloc(nPoints,sizeof(double)); - - psShape->nParts = nParts; - psShape->panPartStart = (int *) calloc(nParts,sizeof(int)); - psShape->panPartType = (int *) calloc(nParts,sizeof(int)); - - for( i = 0; i < nParts; i++ ) - psShape->panPartType[i] = SHPP_RING; - -/* -------------------------------------------------------------------- */ -/* Copy out the part array from the record. */ -/* -------------------------------------------------------------------- */ - memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts ); - for( i = 0; i < nParts; i++ ) - { - if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); - } - - nOffset = 44 + 8 + 4*nParts; - -/* -------------------------------------------------------------------- */ -/* If this is a multipatch, we will also have parts types. */ -/* -------------------------------------------------------------------- */ - if( psShape->nSHPType == SHPT_MULTIPATCH ) - { - memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts ); - for( i = 0; i < nParts; i++ ) - { - if( bBigEndian ) SwapWord( 4, psShape->panPartType+i ); - } - - nOffset += 4*nParts; - } - -/* -------------------------------------------------------------------- */ -/* Copy out the vertices from the record. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < nPoints; i++ ) - { - memcpy(psShape->padfX + i, - psSHP->pabyRec + nOffset + i * 16, - 8 ); - - memcpy(psShape->padfY + i, - psSHP->pabyRec + nOffset + i * 16 + 8, - 8 ); - - if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); - if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); - } - - nOffset += 16*nPoints; - -/* -------------------------------------------------------------------- */ -/* If we have a Z coordinate, collect that now. */ -/* -------------------------------------------------------------------- */ - if( psShape->nSHPType == SHPT_POLYGONZ - || psShape->nSHPType == SHPT_ARCZ - || psShape->nSHPType == SHPT_MULTIPATCH ) - { - memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); - memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); - - if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); - - for( i = 0; i < nPoints; i++ ) - { - memcpy( psShape->padfZ + i, - psSHP->pabyRec + nOffset + 16 + i*8, 8 ); - if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); - } - - nOffset += 16 + 8*nPoints; - } - -/* -------------------------------------------------------------------- */ -/* If we have a M measure value, then read it now. We assume */ -/* that the measure can be present for any shape if the size is */ -/* big enough, but really it will only occur for the Z shapes */ -/* (options), and the M shapes. */ -/* -------------------------------------------------------------------- */ - if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) - { - memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); - memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); - - if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); - - for( i = 0; i < nPoints; i++ ) - { - memcpy( psShape->padfM + i, - psSHP->pabyRec + nOffset + 16 + i*8, 8 ); - if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); - } - } - - } - -/* ==================================================================== */ -/* Extract vertices for a MultiPoint. */ -/* ==================================================================== */ - else if( psShape->nSHPType == SHPT_MULTIPOINT - || psShape->nSHPType == SHPT_MULTIPOINTM - || psShape->nSHPType == SHPT_MULTIPOINTZ ) - { - int32 nPoints; - int i, nOffset; - - memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); - if( bBigEndian ) SwapWord( 4, &nPoints ); - - psShape->nVertices = nPoints; - psShape->padfX = (double *) calloc(nPoints,sizeof(double)); - psShape->padfY = (double *) calloc(nPoints,sizeof(double)); - psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); - psShape->padfM = (double *) calloc(nPoints,sizeof(double)); - - for( i = 0; i < nPoints; i++ ) - { - memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); - memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); - - if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); - if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); - } - - nOffset = 48 + 16*nPoints; - -/* -------------------------------------------------------------------- */ -/* Get the X/Y bounds. */ -/* -------------------------------------------------------------------- */ - memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); - memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); - memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); - memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); - - if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); - -/* -------------------------------------------------------------------- */ -/* If we have a Z coordinate, collect that now. */ -/* -------------------------------------------------------------------- */ - if( psShape->nSHPType == SHPT_MULTIPOINTZ ) - { - memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); - memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); - - if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); - - for( i = 0; i < nPoints; i++ ) - { - memcpy( psShape->padfZ + i, - psSHP->pabyRec + nOffset + 16 + i*8, 8 ); - if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); - } - - nOffset += 16 + 8*nPoints; - } - -/* -------------------------------------------------------------------- */ -/* If we have a M measure value, then read it now. We assume */ -/* that the measure can be present for any shape if the size is */ -/* big enough, but really it will only occur for the Z shapes */ -/* (options), and the M shapes. */ -/* -------------------------------------------------------------------- */ - if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) - { - memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); - memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); - - if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); - if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); - - for( i = 0; i < nPoints; i++ ) - { - memcpy( psShape->padfM + i, - psSHP->pabyRec + nOffset + 16 + i*8, 8 ); - if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); - } - } - } - -/* ==================================================================== */ -/* Extract vertices for a point. */ -/* ==================================================================== */ - else if( psShape->nSHPType == SHPT_POINT - || psShape->nSHPType == SHPT_POINTM - || psShape->nSHPType == SHPT_POINTZ ) - { - int nOffset; - - psShape->nVertices = 1; - psShape->padfX = (double *) calloc(1,sizeof(double)); - psShape->padfY = (double *) calloc(1,sizeof(double)); - psShape->padfZ = (double *) calloc(1,sizeof(double)); - psShape->padfM = (double *) calloc(1,sizeof(double)); - - memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); - memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); - - if( bBigEndian ) SwapWord( 8, psShape->padfX ); - if( bBigEndian ) SwapWord( 8, psShape->padfY ); - - nOffset = 20 + 8; - -/* -------------------------------------------------------------------- */ -/* If we have a Z coordinate, collect that now. */ -/* -------------------------------------------------------------------- */ - if( psShape->nSHPType == SHPT_POINTZ ) - { - memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 ); - - if( bBigEndian ) SwapWord( 8, psShape->padfZ ); - - nOffset += 8; - } - -/* -------------------------------------------------------------------- */ -/* If we have a M measure value, then read it now. We assume */ -/* that the measure can be present for any shape if the size is */ -/* big enough, but really it will only occur for the Z shapes */ -/* (options), and the M shapes. */ -/* -------------------------------------------------------------------- */ - if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 ) - { - memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 ); - - if( bBigEndian ) SwapWord( 8, psShape->padfM ); - } - -/* -------------------------------------------------------------------- */ -/* Since no extents are supplied in the record, we will apply */ -/* them from the single vertex. */ -/* -------------------------------------------------------------------- */ - psShape->dfXMin = psShape->dfXMax = psShape->padfX[0]; - psShape->dfYMin = psShape->dfYMax = psShape->padfY[0]; - psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0]; - psShape->dfMMin = psShape->dfMMax = psShape->padfM[0]; - } - - return( psShape ); -} - -/************************************************************************/ -/* SHPTypeName() */ -/************************************************************************/ - -const char SHPAPI_CALL1(*) -SHPTypeName( int nSHPType ) - -{ - switch( nSHPType ) - { - case SHPT_NULL: - return "NullShape"; - - case SHPT_POINT: - return "Point"; - - case SHPT_ARC: - return "Arc"; - - case SHPT_POLYGON: - return "Polygon"; - - case SHPT_MULTIPOINT: - return "MultiPoint"; - - case SHPT_POINTZ: - return "PointZ"; - - case SHPT_ARCZ: - return "ArcZ"; - - case SHPT_POLYGONZ: - return "PolygonZ"; - - case SHPT_MULTIPOINTZ: - return "MultiPointZ"; - - case SHPT_POINTM: - return "PointM"; - - case SHPT_ARCM: - return "ArcM"; - - case SHPT_POLYGONM: - return "PolygonM"; - - case SHPT_MULTIPOINTM: - return "MultiPointM"; - - case SHPT_MULTIPATCH: - return "MultiPatch"; - - default: - return "UnknownShapeType"; - } -} - -/************************************************************************/ -/* SHPPartTypeName() */ -/************************************************************************/ - -const char SHPAPI_CALL1(*) -SHPPartTypeName( int nPartType ) - -{ - switch( nPartType ) - { - case SHPP_TRISTRIP: - return "TriangleStrip"; - - case SHPP_TRIFAN: - return "TriangleFan"; - - case SHPP_OUTERRING: - return "OuterRing"; - - case SHPP_INNERRING: - return "InnerRing"; - - case SHPP_FIRSTRING: - return "FirstRing"; - - case SHPP_RING: - return "Ring"; - - default: - return "UnknownPartType"; - } -} - -/************************************************************************/ -/* SHPDestroyObject() */ -/************************************************************************/ - -void SHPAPI_CALL -SHPDestroyObject( SHPObject * psShape ) - -{ - if( psShape == NULL ) - return; - - if( psShape->padfX != NULL ) - free( psShape->padfX ); - if( psShape->padfY != NULL ) - free( psShape->padfY ); - if( psShape->padfZ != NULL ) - free( psShape->padfZ ); - if( psShape->padfM != NULL ) - free( psShape->padfM ); - - if( psShape->panPartStart != NULL ) - free( psShape->panPartStart ); - if( psShape->panPartType != NULL ) - free( psShape->panPartType ); - - free( psShape ); -} - -/************************************************************************/ -/* SHPRewindObject() */ -/* */ -/* Reset the winding of polygon objects to adhere to the */ -/* specification. */ -/************************************************************************/ - -int SHPAPI_CALL -SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ) - -{ - int iOpRing, bAltered = 0; - -/* -------------------------------------------------------------------- */ -/* Do nothing if this is not a polygon object. */ -/* -------------------------------------------------------------------- */ - if( psObject->nSHPType != SHPT_POLYGON - && psObject->nSHPType != SHPT_POLYGONZ - && psObject->nSHPType != SHPT_POLYGONM ) - return 0; - - if( psObject->nVertices == 0 || psObject->nParts == 0 ) - return 0; - -/* -------------------------------------------------------------------- */ -/* Process each of the rings. */ -/* -------------------------------------------------------------------- */ - for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ ) - { - int bInner, iVert, nVertCount, nVertStart, iCheckRing; - double dfSum, dfTestX, dfTestY; - -/* -------------------------------------------------------------------- */ -/* Determine if this ring is an inner ring or an outer ring */ -/* relative to all the other rings. For now we assume the */ -/* first ring is outer and all others are inner, but eventually */ -/* we need to fix this to handle multiple island polygons and */ -/* unordered sets of rings. */ -/* -------------------------------------------------------------------- */ - dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]]; - dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]]; - - bInner = FALSE; - for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ ) - { - int iEdge; - - if( iCheckRing == iOpRing ) - continue; - - nVertStart = psObject->panPartStart[iCheckRing]; - - if( iCheckRing == psObject->nParts-1 ) - nVertCount = psObject->nVertices - - psObject->panPartStart[iCheckRing]; - else - nVertCount = psObject->panPartStart[iCheckRing+1] - - psObject->panPartStart[iCheckRing]; - - for( iEdge = 0; iEdge < nVertCount; iEdge++ ) - { - int iNext; - - if( iEdge < nVertCount-1 ) - iNext = iEdge+1; - else - iNext = 0; - - if( (psObject->padfY[iEdge+nVertStart] < dfTestY - && psObject->padfY[iNext+nVertStart] >= dfTestY) - || (psObject->padfY[iNext+nVertStart] < dfTestY - && psObject->padfY[iEdge+nVertStart] >= dfTestY) ) - { - if( psObject->padfX[iEdge+nVertStart] - + (dfTestY - psObject->padfY[iEdge+nVertStart]) - / (psObject->padfY[iNext+nVertStart] - - psObject->padfY[iEdge+nVertStart]) - * (psObject->padfX[iNext+nVertStart] - - psObject->padfX[iEdge+nVertStart]) < dfTestX ) - bInner = !bInner; - } - } - } - -/* -------------------------------------------------------------------- */ -/* Determine the current order of this ring so we will know if */ -/* it has to be reversed. */ -/* -------------------------------------------------------------------- */ - nVertStart = psObject->panPartStart[iOpRing]; - - if( iOpRing == psObject->nParts-1 ) - nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing]; - else - nVertCount = psObject->panPartStart[iOpRing+1] - - psObject->panPartStart[iOpRing]; - - dfSum = 0.0; - for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ ) - { - dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1] - - psObject->padfY[iVert] * psObject->padfX[iVert+1]; - } - - dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart] - - psObject->padfY[iVert] * psObject->padfX[nVertStart]; - -/* -------------------------------------------------------------------- */ -/* Reverse if necessary. */ -/* -------------------------------------------------------------------- */ - if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) ) - { - int i; - - bAltered++; - for( i = 0; i < nVertCount/2; i++ ) - { - double dfSaved; - - /* Swap X */ - dfSaved = psObject->padfX[nVertStart+i]; - psObject->padfX[nVertStart+i] = - psObject->padfX[nVertStart+nVertCount-i-1]; - psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved; - - /* Swap Y */ - dfSaved = psObject->padfY[nVertStart+i]; - psObject->padfY[nVertStart+i] = - psObject->padfY[nVertStart+nVertCount-i-1]; - psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved; - - /* Swap Z */ - if( psObject->padfZ ) - { - dfSaved = psObject->padfZ[nVertStart+i]; - psObject->padfZ[nVertStart+i] = - psObject->padfZ[nVertStart+nVertCount-i-1]; - psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved; - } - - /* Swap M */ - if( psObject->padfM ) - { - dfSaved = psObject->padfM[nVertStart+i]; - psObject->padfM[nVertStart+i] = - psObject->padfM[nVertStart+nVertCount-i-1]; - psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved; - } - } - } - } - - return bAltered; -} diff --git a/pyshapelib/shapelib/shptree.c b/pyshapelib/shapelib/shptree.c deleted file mode 100644 index 5f69d3b84..000000000 --- a/pyshapelib/shapelib/shptree.c +++ /dev/null @@ -1,686 +0,0 @@ -/****************************************************************************** - * $Id$ - * - * Project: Shapelib - * Purpose: Implementation of quadtree building and searching functions. - * Author: Frank Warmerdam, warmerdam@pobox.com - * - ****************************************************************************** - * Copyright (c) 1999, Frank Warmerdam - * - * This software is available under the following "MIT Style" license, - * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This - * option is discussed in more detail in shapelib.html. - * - * -- - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************** - * - * $Log$ - * Revision 1.1 2005/08/14 21:40:30 jswhit - * inclusion of pyshapelib - * - * Revision 1.2 2003/10/02 15:15:16 bh - * - * Update to shapelib 1.2.10 - * - * Revision 1.9 2003/01/28 15:53:41 warmerda - * Avoid build warnings. - * - * Revision 1.8 2002/05/07 13:07:45 warmerda - * use qsort() - patch from Bernhard Herzog - * - * Revision 1.7 2002/01/15 14:36:07 warmerda - * updated email address - * - * Revision 1.6 2001/05/23 13:36:52 warmerda - * added use of SHPAPI_CALL - * - * Revision 1.5 1999/11/05 14:12:05 warmerda - * updated license terms - * - * Revision 1.4 1999/06/02 18:24:21 warmerda - * added trimming code - * - * Revision 1.3 1999/06/02 17:56:12 warmerda - * added quad'' subnode support for trees - * - * Revision 1.2 1999/05/18 19:11:11 warmerda - * Added example searching capability - * - * Revision 1.1 1999/05/18 17:49:20 warmerda - * New - * - */ - -static char rcsid[] = - "$Id$"; - -#include "shapefil.h" - -#include -#include -#include -#include - -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif - - -/* -------------------------------------------------------------------- */ -/* If the following is 0.5, nodes will be split in half. If it */ -/* is 0.6 then each subnode will contain 60% of the parent */ -/* node, with 20% representing overlap. This can be help to */ -/* prevent small objects on a boundary from shifting too high */ -/* up the tree. */ -/* -------------------------------------------------------------------- */ - -#define SHP_SPLIT_RATIO 0.55 - -/************************************************************************/ -/* SfRealloc() */ -/* */ -/* A realloc cover function that will access a NULL pointer as */ -/* a valid input. */ -/************************************************************************/ - -static void * SfRealloc( void * pMem, int nNewSize ) - -{ - if( pMem == NULL ) - return( (void *) malloc(nNewSize) ); - else - return( (void *) realloc(pMem,nNewSize) ); -} - -/************************************************************************/ -/* SHPTreeNodeInit() */ -/* */ -/* Initialize a tree node. */ -/************************************************************************/ - -static SHPTreeNode *SHPTreeNodeCreate( double * padfBoundsMin, - double * padfBoundsMax ) - -{ - SHPTreeNode *psTreeNode; - - psTreeNode = (SHPTreeNode *) malloc(sizeof(SHPTreeNode)); - - psTreeNode->nShapeCount = 0; - psTreeNode->panShapeIds = NULL; - psTreeNode->papsShapeObj = NULL; - - psTreeNode->nSubNodes = 0; - - if( padfBoundsMin != NULL ) - memcpy( psTreeNode->adfBoundsMin, padfBoundsMin, sizeof(double) * 4 ); - - if( padfBoundsMax != NULL ) - memcpy( psTreeNode->adfBoundsMax, padfBoundsMax, sizeof(double) * 4 ); - - return psTreeNode; -} - - -/************************************************************************/ -/* SHPCreateTree() */ -/************************************************************************/ - -SHPTree SHPAPI_CALL1(*) -SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth, - double *padfBoundsMin, double *padfBoundsMax ) - -{ - SHPTree *psTree; - - if( padfBoundsMin == NULL && hSHP == NULL ) - return NULL; - -/* -------------------------------------------------------------------- */ -/* Allocate the tree object */ -/* -------------------------------------------------------------------- */ - psTree = (SHPTree *) malloc(sizeof(SHPTree)); - - psTree->hSHP = hSHP; - psTree->nMaxDepth = nMaxDepth; - psTree->nDimension = nDimension; - -/* -------------------------------------------------------------------- */ -/* If no max depth was defined, try to select a reasonable one */ -/* that implies approximately 8 shapes per node. */ -/* -------------------------------------------------------------------- */ - if( psTree->nMaxDepth == 0 && hSHP != NULL ) - { - int nMaxNodeCount = 1; - int nShapeCount; - - SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL ); - while( nMaxNodeCount*4 < nShapeCount ) - { - psTree->nMaxDepth += 1; - nMaxNodeCount = nMaxNodeCount * 2; - } - } - -/* -------------------------------------------------------------------- */ -/* Allocate the root node. */ -/* -------------------------------------------------------------------- */ - psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax ); - -/* -------------------------------------------------------------------- */ -/* Assign the bounds to the root node. If none are passed in, */ -/* use the bounds of the provided file otherwise the create */ -/* function will have already set the bounds. */ -/* -------------------------------------------------------------------- */ - if( padfBoundsMin == NULL ) - { - SHPGetInfo( hSHP, NULL, NULL, - psTree->psRoot->adfBoundsMin, - psTree->psRoot->adfBoundsMax ); - } - -/* -------------------------------------------------------------------- */ -/* If we have a file, insert all it's shapes into the tree. */ -/* -------------------------------------------------------------------- */ - if( hSHP != NULL ) - { - int iShape, nShapeCount; - - SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL ); - - for( iShape = 0; iShape < nShapeCount; iShape++ ) - { - SHPObject *psShape; - - psShape = SHPReadObject( hSHP, iShape ); - SHPTreeAddShapeId( psTree, psShape ); - SHPDestroyObject( psShape ); - } - } - - return psTree; -} - -/************************************************************************/ -/* SHPDestroyTreeNode() */ -/************************************************************************/ - -static void SHPDestroyTreeNode( SHPTreeNode * psTreeNode ) - -{ - int i; - - for( i = 0; i < psTreeNode->nSubNodes; i++ ) - { - if( psTreeNode->apsSubNode[i] != NULL ) - SHPDestroyTreeNode( psTreeNode->apsSubNode[i] ); - } - - if( psTreeNode->panShapeIds != NULL ) - free( psTreeNode->panShapeIds ); - - if( psTreeNode->papsShapeObj != NULL ) - { - for( i = 0; i < psTreeNode->nShapeCount; i++ ) - { - if( psTreeNode->papsShapeObj[i] != NULL ) - SHPDestroyObject( psTreeNode->papsShapeObj[i] ); - } - - free( psTreeNode->papsShapeObj ); - } - - free( psTreeNode ); -} - -/************************************************************************/ -/* SHPDestroyTree() */ -/************************************************************************/ - -void SHPAPI_CALL -SHPDestroyTree( SHPTree * psTree ) - -{ - SHPDestroyTreeNode( psTree->psRoot ); - free( psTree ); -} - -/************************************************************************/ -/* SHPCheckBoundsOverlap() */ -/* */ -/* Do the given boxes overlap at all? */ -/************************************************************************/ - -int SHPAPI_CALL -SHPCheckBoundsOverlap( double * padfBox1Min, double * padfBox1Max, - double * padfBox2Min, double * padfBox2Max, - int nDimension ) - -{ - int iDim; - - for( iDim = 0; iDim < nDimension; iDim++ ) - { - if( padfBox2Max[iDim] < padfBox1Min[iDim] ) - return FALSE; - - if( padfBox1Max[iDim] < padfBox2Min[iDim] ) - return FALSE; - } - - return TRUE; -} - -/************************************************************************/ -/* SHPCheckObjectContained() */ -/* */ -/* Does the given shape fit within the indicated extents? */ -/************************************************************************/ - -static int SHPCheckObjectContained( SHPObject * psObject, int nDimension, - double * padfBoundsMin, double * padfBoundsMax ) - -{ - if( psObject->dfXMin < padfBoundsMin[0] - || psObject->dfXMax > padfBoundsMax[0] ) - return FALSE; - - if( psObject->dfYMin < padfBoundsMin[1] - || psObject->dfYMax > padfBoundsMax[1] ) - return FALSE; - - if( nDimension == 2 ) - return TRUE; - - if( psObject->dfZMin < padfBoundsMin[2] - || psObject->dfZMax < padfBoundsMax[2] ) - return FALSE; - - if( nDimension == 3 ) - return TRUE; - - if( psObject->dfMMin < padfBoundsMin[3] - || psObject->dfMMax < padfBoundsMax[3] ) - return FALSE; - - return TRUE; -} - -/************************************************************************/ -/* SHPTreeSplitBounds() */ -/* */ -/* Split a region into two subregion evenly, cutting along the */ -/* longest dimension. */ -/************************************************************************/ - -void SHPAPI_CALL -SHPTreeSplitBounds( double *padfBoundsMinIn, double *padfBoundsMaxIn, - double *padfBoundsMin1, double * padfBoundsMax1, - double *padfBoundsMin2, double * padfBoundsMax2 ) - -{ -/* -------------------------------------------------------------------- */ -/* The output bounds will be very similar to the input bounds, */ -/* so just copy over to start. */ -/* -------------------------------------------------------------------- */ - memcpy( padfBoundsMin1, padfBoundsMinIn, sizeof(double) * 4 ); - memcpy( padfBoundsMax1, padfBoundsMaxIn, sizeof(double) * 4 ); - memcpy( padfBoundsMin2, padfBoundsMinIn, sizeof(double) * 4 ); - memcpy( padfBoundsMax2, padfBoundsMaxIn, sizeof(double) * 4 ); - -/* -------------------------------------------------------------------- */ -/* Split in X direction. */ -/* -------------------------------------------------------------------- */ - if( (padfBoundsMaxIn[0] - padfBoundsMinIn[0]) - > (padfBoundsMaxIn[1] - padfBoundsMinIn[1]) ) - { - double dfRange = padfBoundsMaxIn[0] - padfBoundsMinIn[0]; - - padfBoundsMax1[0] = padfBoundsMinIn[0] + dfRange * SHP_SPLIT_RATIO; - padfBoundsMin2[0] = padfBoundsMaxIn[0] - dfRange * SHP_SPLIT_RATIO; - } - -/* -------------------------------------------------------------------- */ -/* Otherwise split in Y direction. */ -/* -------------------------------------------------------------------- */ - else - { - double dfRange = padfBoundsMaxIn[1] - padfBoundsMinIn[1]; - - padfBoundsMax1[1] = padfBoundsMinIn[1] + dfRange * SHP_SPLIT_RATIO; - padfBoundsMin2[1] = padfBoundsMaxIn[1] - dfRange * SHP_SPLIT_RATIO; - } -} - -/************************************************************************/ -/* SHPTreeNodeAddShapeId() */ -/************************************************************************/ - -static int -SHPTreeNodeAddShapeId( SHPTreeNode * psTreeNode, SHPObject * psObject, - int nMaxDepth, int nDimension ) - -{ - int i; - -/* -------------------------------------------------------------------- */ -/* If there are subnodes, then consider wiether this object */ -/* will fit in them. */ -/* -------------------------------------------------------------------- */ - if( nMaxDepth > 1 && psTreeNode->nSubNodes > 0 ) - { - for( i = 0; i < psTreeNode->nSubNodes; i++ ) - { - if( SHPCheckObjectContained(psObject, nDimension, - psTreeNode->apsSubNode[i]->adfBoundsMin, - psTreeNode->apsSubNode[i]->adfBoundsMax)) - { - return SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[i], - psObject, nMaxDepth-1, - nDimension ); - } - } - } - -/* -------------------------------------------------------------------- */ -/* Otherwise, consider creating four subnodes if could fit into */ -/* them, and adding to the appropriate subnode. */ -/* -------------------------------------------------------------------- */ -#if MAX_SUBNODE == 4 - else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 ) - { - double adfBoundsMinH1[4], adfBoundsMaxH1[4]; - double adfBoundsMinH2[4], adfBoundsMaxH2[4]; - double adfBoundsMin1[4], adfBoundsMax1[4]; - double adfBoundsMin2[4], adfBoundsMax2[4]; - double adfBoundsMin3[4], adfBoundsMax3[4]; - double adfBoundsMin4[4], adfBoundsMax4[4]; - - SHPTreeSplitBounds( psTreeNode->adfBoundsMin, - psTreeNode->adfBoundsMax, - adfBoundsMinH1, adfBoundsMaxH1, - adfBoundsMinH2, adfBoundsMaxH2 ); - - SHPTreeSplitBounds( adfBoundsMinH1, adfBoundsMaxH1, - adfBoundsMin1, adfBoundsMax1, - adfBoundsMin2, adfBoundsMax2 ); - - SHPTreeSplitBounds( adfBoundsMinH2, adfBoundsMaxH2, - adfBoundsMin3, adfBoundsMax3, - adfBoundsMin4, adfBoundsMax4 ); - - if( SHPCheckObjectContained(psObject, nDimension, - adfBoundsMin1, adfBoundsMax1) - || SHPCheckObjectContained(psObject, nDimension, - adfBoundsMin2, adfBoundsMax2) - || SHPCheckObjectContained(psObject, nDimension, - adfBoundsMin3, adfBoundsMax3) - || SHPCheckObjectContained(psObject, nDimension, - adfBoundsMin4, adfBoundsMax4) ) - { - psTreeNode->nSubNodes = 4; - psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1, - adfBoundsMax1 ); - psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2, - adfBoundsMax2 ); - psTreeNode->apsSubNode[2] = SHPTreeNodeCreate( adfBoundsMin3, - adfBoundsMax3 ); - psTreeNode->apsSubNode[3] = SHPTreeNodeCreate( adfBoundsMin4, - adfBoundsMax4 ); - - /* recurse back on this node now that it has subnodes */ - return( SHPTreeNodeAddShapeId( psTreeNode, psObject, - nMaxDepth, nDimension ) ); - } - } -#endif /* MAX_SUBNODE == 4 */ - -/* -------------------------------------------------------------------- */ -/* Otherwise, consider creating two subnodes if could fit into */ -/* them, and adding to the appropriate subnode. */ -/* -------------------------------------------------------------------- */ -#if MAX_SUBNODE == 2 - else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 ) - { - double adfBoundsMin1[4], adfBoundsMax1[4]; - double adfBoundsMin2[4], adfBoundsMax2[4]; - - SHPTreeSplitBounds( psTreeNode->adfBoundsMin, psTreeNode->adfBoundsMax, - adfBoundsMin1, adfBoundsMax1, - adfBoundsMin2, adfBoundsMax2 ); - - if( SHPCheckObjectContained(psObject, nDimension, - adfBoundsMin1, adfBoundsMax1)) - { - psTreeNode->nSubNodes = 2; - psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1, - adfBoundsMax1 ); - psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2, - adfBoundsMax2 ); - - return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[0], psObject, - nMaxDepth - 1, nDimension ) ); - } - else if( SHPCheckObjectContained(psObject, nDimension, - adfBoundsMin2, adfBoundsMax2) ) - { - psTreeNode->nSubNodes = 2; - psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1, - adfBoundsMax1 ); - psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2, - adfBoundsMax2 ); - - return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[1], psObject, - nMaxDepth - 1, nDimension ) ); - } - } -#endif /* MAX_SUBNODE == 2 */ - -/* -------------------------------------------------------------------- */ -/* If none of that worked, just add it to this nodes list. */ -/* -------------------------------------------------------------------- */ - psTreeNode->nShapeCount++; - - psTreeNode->panShapeIds = - SfRealloc( psTreeNode->panShapeIds, - sizeof(int) * psTreeNode->nShapeCount ); - psTreeNode->panShapeIds[psTreeNode->nShapeCount-1] = psObject->nShapeId; - - if( psTreeNode->papsShapeObj != NULL ) - { - psTreeNode->papsShapeObj = - SfRealloc( psTreeNode->papsShapeObj, - sizeof(void *) * psTreeNode->nShapeCount ); - psTreeNode->papsShapeObj[psTreeNode->nShapeCount-1] = NULL; - } - - return TRUE; -} - -/************************************************************************/ -/* SHPTreeAddShapeId() */ -/* */ -/* Add a shape to the tree, but don't keep a pointer to the */ -/* object data, just keep the shapeid. */ -/************************************************************************/ - -int SHPAPI_CALL -SHPTreeAddShapeId( SHPTree * psTree, SHPObject * psObject ) - -{ - return( SHPTreeNodeAddShapeId( psTree->psRoot, psObject, - psTree->nMaxDepth, psTree->nDimension ) ); -} - -/************************************************************************/ -/* SHPTreeCollectShapesIds() */ -/* */ -/* Work function implementing SHPTreeFindLikelyShapes() on a */ -/* tree node by tree node basis. */ -/************************************************************************/ - -void SHPAPI_CALL -SHPTreeCollectShapeIds( SHPTree *hTree, SHPTreeNode * psTreeNode, - double * padfBoundsMin, double * padfBoundsMax, - int * pnShapeCount, int * pnMaxShapes, - int ** ppanShapeList ) - -{ - int i; - -/* -------------------------------------------------------------------- */ -/* Does this node overlap the area of interest at all? If not, */ -/* return without adding to the list at all. */ -/* -------------------------------------------------------------------- */ - if( !SHPCheckBoundsOverlap( psTreeNode->adfBoundsMin, - psTreeNode->adfBoundsMax, - padfBoundsMin, - padfBoundsMax, - hTree->nDimension ) ) - return; - -/* -------------------------------------------------------------------- */ -/* Grow the list to hold the shapes on this node. */ -/* -------------------------------------------------------------------- */ - if( *pnShapeCount + psTreeNode->nShapeCount > *pnMaxShapes ) - { - *pnMaxShapes = (*pnShapeCount + psTreeNode->nShapeCount) * 2 + 20; - *ppanShapeList = (int *) - SfRealloc(*ppanShapeList,sizeof(int) * *pnMaxShapes); - } - -/* -------------------------------------------------------------------- */ -/* Add the local nodes shapeids to the list. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < psTreeNode->nShapeCount; i++ ) - { - (*ppanShapeList)[(*pnShapeCount)++] = psTreeNode->panShapeIds[i]; - } - -/* -------------------------------------------------------------------- */ -/* Recurse to subnodes if they exist. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < psTreeNode->nSubNodes; i++ ) - { - if( psTreeNode->apsSubNode[i] != NULL ) - SHPTreeCollectShapeIds( hTree, psTreeNode->apsSubNode[i], - padfBoundsMin, padfBoundsMax, - pnShapeCount, pnMaxShapes, - ppanShapeList ); - } -} - -/************************************************************************/ -/* SHPTreeFindLikelyShapes() */ -/* */ -/* Find all shapes within tree nodes for which the tree node */ -/* bounding box overlaps the search box. The return value is */ -/* an array of shapeids terminated by a -1. The shapeids will */ -/* be in order, as hopefully this will result in faster (more */ -/* sequential) reading from the file. */ -/************************************************************************/ - -/* helper for qsort */ -static int -compare_ints( const void * a, const void * b) -{ - return (*(int*)a) - (*(int*)b); -} - -int SHPAPI_CALL1(*) -SHPTreeFindLikelyShapes( SHPTree * hTree, - double * padfBoundsMin, double * padfBoundsMax, - int * pnShapeCount ) - -{ - int *panShapeList=NULL, nMaxShapes = 0; - -/* -------------------------------------------------------------------- */ -/* Perform the search by recursive descent. */ -/* -------------------------------------------------------------------- */ - *pnShapeCount = 0; - - SHPTreeCollectShapeIds( hTree, hTree->psRoot, - padfBoundsMin, padfBoundsMax, - pnShapeCount, &nMaxShapes, - &panShapeList ); - -/* -------------------------------------------------------------------- */ -/* Sort the id array */ -/* -------------------------------------------------------------------- */ - - qsort(panShapeList, *pnShapeCount, sizeof(int), compare_ints); - - return panShapeList; -} - -/************************************************************************/ -/* SHPTreeNodeTrim() */ -/* */ -/* This is the recurve version of SHPTreeTrimExtraNodes() that */ -/* walks the tree cleaning it up. */ -/************************************************************************/ - -static int SHPTreeNodeTrim( SHPTreeNode * psTreeNode ) - -{ - int i; - -/* -------------------------------------------------------------------- */ -/* Trim subtrees, and free subnodes that come back empty. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < psTreeNode->nSubNodes; i++ ) - { - if( SHPTreeNodeTrim( psTreeNode->apsSubNode[i] ) ) - { - SHPDestroyTreeNode( psTreeNode->apsSubNode[i] ); - - psTreeNode->apsSubNode[i] = - psTreeNode->apsSubNode[psTreeNode->nSubNodes-1]; - - psTreeNode->nSubNodes--; - - i--; /* process the new occupant of this subnode entry */ - } - } - -/* -------------------------------------------------------------------- */ -/* We should be trimmed if we have no subnodes, and no shapes. */ -/* -------------------------------------------------------------------- */ - return( psTreeNode->nSubNodes == 0 && psTreeNode->nShapeCount == 0 ); -} - -/************************************************************************/ -/* SHPTreeTrimExtraNodes() */ -/* */ -/* Trim empty nodes from the tree. Note that we never trim an */ -/* empty root node. */ -/************************************************************************/ - -void SHPAPI_CALL -SHPTreeTrimExtraNodes( SHPTree * hTree ) - -{ - SHPTreeNodeTrim( hTree->psRoot ); -} - diff --git a/pyshapelib/shapelib_wrap.c b/pyshapelib/shapelib_wrap.c deleted file mode 100644 index 3f4746831..000000000 --- a/pyshapelib/shapelib_wrap.c +++ /dev/null @@ -1,1411 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3u-20050630-1524 (Alpha 5) - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -#define SWIGPYTHON -/*********************************************************************** - * common.swg - * - * This file contains generic SWIG runtime support for pointer - * type checking as well as a few commonly used macros to control - * external linkage. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (c) 1999-2000, The University of Chicago - * - * This file may be freely redistributed without license or fee provided - * this copyright message remains intact. - ************************************************************************/ - -#include - -#if defined(_WIN32) || defined(__WIN32__) -# if defined(_MSC_VER) -# if defined(STATIC_LINKED) -# define SWIGEXPORT(a) a -# else -# define SWIGEXPORT(a) __declspec(dllexport) a -# endif -# else -# if defined(__BORLANDC__) -# define SWIGEXPORT(a) a _export -# else -# define SWIGEXPORT(a) a -# endif -#endif -#else -# define SWIGEXPORT(a) a -#endif - -#ifdef SWIG_GLOBAL -#define SWIGRUNTIME(a) SWIGEXPORT(a) -#else -#define SWIGRUNTIME(a) static a -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct swig_type_info { - char *name; - void *(*converter)(void *); - char *str; - struct swig_type_info *next; - struct swig_type_info *prev; -} swig_type_info; - -#ifdef SWIG_NOINCLUDE -SWIGEXPORT(swig_type_info *) SWIG_TypeRegister(swig_type_info *); -SWIGEXPORT(swig_type_info *) SWIG_TypeCheck(char *c, swig_type_info *); -SWIGEXPORT(void *) SWIG_TypeCast(swig_type_info *, void *); -#else - -static swig_type_info *swig_type_list = 0; - -/* Register a type mapping with the type-checking */ -SWIGRUNTIME(swig_type_info *) -SWIG_TypeRegister(swig_type_info *ti) -{ - swig_type_info *tc, *head, *ret, *next; - /* Check to see if this type has already been registered */ - tc = swig_type_list; - while (tc) { - if (strcmp(tc->name, ti->name) == 0) { - /* Already exists in the table. Just add additional types to the list */ - head = tc; - next = tc->next; - goto l1; - } - tc = tc->prev; - } - head = ti; - next = 0; - - /* Place in list */ - ti->prev = swig_type_list; - swig_type_list = ti; - - /* Build linked lists */ - l1: - ret = head; - tc = ti + 1; - /* Patch up the rest of the links */ - while (tc->name) { - head->next = tc; - tc->prev = head; - head = tc; - tc++; - } - head->next = next; - return ret; -} - -/* Check the typename */ -SWIGRUNTIME(swig_type_info *) -SWIG_TypeCheck(char *c, swig_type_info *ty) -{ - swig_type_info *s; - if (!ty) return 0; /* Void pointer */ - s = ty->next; /* First element always just a name */ - while (s) { - if (strcmp(s->name,c) == 0) { - if (s == ty->next) return s; - /* Move s to the top of the linked list */ - s->prev->next = s->next; - if (s->next) { - s->next->prev = s->prev; - } - /* Insert s as second element in the list */ - s->next = ty->next; - if (ty->next) ty->next->prev = s; - ty->next = s; - return s; - } - s = s->next; - } - return 0; -} - -/* Cast a pointer (needed for C++ inheritance */ -SWIGRUNTIME(void *) -SWIG_TypeCast(swig_type_info *ty, void *ptr) -{ - if ((!ty) || (!ty->converter)) return ptr; - return (*ty->converter)(ptr); -} - -/* Search for a swig_type_info structure */ -SWIGRUNTIME(void *) -SWIG_TypeQuery(const char *name) { - swig_type_info *ty = swig_type_list; - while (ty) { - if (ty->str && (strcmp(name,ty->str) == 0)) return ty; - if (ty->name && (strcmp(name,ty->name) == 0)) return ty; - ty = ty->prev; - } - return 0; -} - -#endif - -#ifdef __cplusplus -} -#endif - - - -/*********************************************************************** - * python.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - ************************************************************************/ - -#include -#include "Python.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SWIG_PY_INT 1 -#define SWIG_PY_FLOAT 2 -#define SWIG_PY_STRING 3 -#define SWIG_PY_POINTER 4 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef SWIG_NOINCLUDE - -SWIGEXPORT(PyObject *) SWIG_newvarlink(); -SWIGEXPORT(void) SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *)); -SWIGEXPORT(int) SWIG_ConvertPtr(PyObject *, void **, swig_type_info *, int); -SWIGEXPORT(void) SWIG_MakePtr(char *c, void *, swig_type_info *); -SWIGEXPORT(PyObject *) SWIG_NewPointerObj(void *, swig_type_info *); -SWIGEXPORT(void) SWIG_InstallConstants(PyObject *d, swig_const_info constants[]); - -#else - -/* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - -typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; -} swig_globalvar; - -typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; -} swig_varlinkobject; - -static PyObject * -swig_varlink_repr(swig_varlinkobject *v) { - v = v; - return PyString_FromString(""); -} - -static int -swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) { - swig_globalvar *var; - flags = flags; - fprintf(fp,"Global variables { "); - for (var = v->vars; var; var=var->next) { - fprintf(fp,"%s", var->name); - if (var->next) fprintf(fp,", "); - } - fprintf(fp," }\n"); - return 0; -} - -static PyObject * -swig_varlink_getattr(swig_varlinkobject *v, char *n) { - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - return (*var->get_attr)(); - } - var = var->next; - } - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - return NULL; -} - -static int -swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - return (*var->set_attr)(p); - } - var = var->next; - } - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - return 1; -} - -statichere PyTypeObject varlinktype = { - PyObject_HEAD_INIT(0) - 0, - "swigvarlink", /* Type name */ - sizeof(swig_varlinkobject), /* Basic size */ - 0, /* Itemsize */ - 0, /* Deallocator */ - (printfunc) swig_varlink_print, /* Print */ - (getattrfunc) swig_varlink_getattr, /* get attr */ - (setattrfunc) swig_varlink_setattr, /* Set attr */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_mapping*/ - 0, /* tp_hash */ -}; - -/* Create a variable linking object for use later */ -SWIGRUNTIME(PyObject *) -SWIG_newvarlink(void) { - swig_varlinkobject *result = 0; - result = PyMem_NEW(swig_varlinkobject,1); - varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ - result->ob_type = &varlinktype; - result->vars = 0; - result->ob_refcnt = 0; - Py_XINCREF((PyObject *) result); - return ((PyObject*) result); -} - -SWIGRUNTIME(void) -SWIG_addvarlink(PyObject *p, char *name, - PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v; - swig_globalvar *gv; - v= (swig_varlinkobject *) p; - gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - gv->name = (char *) malloc(strlen(name)+1); - strcpy(gv->name,name); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - v->vars = gv; -} -/* Convert a pointer value */ -SWIGRUNTIME(int) -SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { - unsigned long p; - register int d; - swig_type_info *tc; - char *c; - static PyObject *SWIG_this = 0; - int newref = 0; - - if (!obj || (obj == Py_None)) { - *ptr = 0; - return 0; - } -#ifdef SWIG_COBJECT_TYPES - if (!(PyCObject_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_InternFromString("this"); - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyCObject_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - *ptr = PyCObject_AsVoidPtr(obj); - c = (char *) PyCObject_GetDesc(obj); - if (newref) Py_DECREF(obj); - goto cobject; -#else - if (!(PyString_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_InternFromString("this"); - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyString_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - c = PyString_AsString(obj); - p = 0; - /* Pointer values must start with leading underscore */ - if (*c != '_') { - *ptr = (void *) 0; - if (strcmp(c,"NULL") == 0) { - if (newref) Py_DECREF(obj); - return 0; - } else { - if (newref) Py_DECREF(obj); - goto type_error; - } - } - c++; - /* Extract hex value from pointer */ - while ((d = *c)) { - if ((d >= '0') && (d <= '9')) - p = (p << 4) + (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - p = (p << 4) + (d - ('a'-10)); - else - break; - c++; - } - *ptr = (void *) p; - if (newref) Py_DECREF(obj); -#endif - -#ifdef SWIG_COBJECT_TYPES -cobject: -#endif - - if (ty) { - tc = SWIG_TypeCheck(c,ty); - if (!tc) goto type_error; - *ptr = SWIG_TypeCast(tc,(void*)p); - } - return 0; - -type_error: - - if (flags) { - if (ty) { - char *temp = (char *) malloc(64+strlen(ty->name)); - sprintf(temp,"Type error. Expected %s", ty->name); - PyErr_SetString(PyExc_TypeError, temp); - free((char *) temp); - } else { - PyErr_SetString(PyExc_TypeError,"Expected a pointer"); - } - } - return -1; -} - -/* Take a pointer and convert it to a string */ -SWIGRUNTIME(void) -SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty) { - static char hex[17] = "0123456789abcdef"; - unsigned long p, s; - char result[32], *r; - r = result; - p = (unsigned long) ptr; - if (p > 0) { - while (p > 0) { - s = p & 0xf; - *(r++) = hex[s]; - p = p >> 4; - } - *r = '_'; - while (r >= result) - *(c++) = *(r--); - strcpy (c, ty->name); - } else { - strcpy (c, "NULL"); - } -} - -/* Create a new pointer object */ -SWIGRUNTIME(PyObject *) -SWIG_NewPointerObj(void *ptr, swig_type_info *type) { - char result[512]; - PyObject *robj; - if (!ptr) { - Py_INCREF(Py_None); - return Py_None; - } -#ifdef SWIG_COBJECT_TYPES - robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, type->name, NULL); -#else - SWIG_MakePtr(result,ptr,type); - robj = PyString_FromString(result); -#endif - return robj; -} - -/* Install Constants */ -SWIGRUNTIME(void) -SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { - int i; - PyObject *obj; - for (i = 0; constants[i].type; i++) { - switch(constants[i].type) { - case SWIG_PY_INT: - obj = PyInt_FromLong(constants[i].lvalue); - break; - case SWIG_PY_FLOAT: - obj = PyFloat_FromDouble(constants[i].dvalue); - break; - case SWIG_PY_STRING: - obj = PyString_FromString((char *) constants[i].pvalue); - break; - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d,constants[i].name,obj); - Py_DECREF(obj); - } - } -} - -#endif - -#ifdef __cplusplus -} -#endif - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_ShapeFile swig_types[0] -#define SWIGTYPE_p_SHPObject swig_types[1] -static swig_type_info *swig_types[3]; - -/* -------- TYPES TABLE (END) -------- */ - - -/*----------------------------------------------- - @(target):= shapelibc.so - ------------------------------------------------*/ -#define SWIG_init initshapelibc - -#define SWIG_name "shapelibc" - - -/* import the shapelib headefile. */ -#include "shapefil.h" -#include "pyshapelib_api.h" - -/* - * Rename a few shapelib functions that are effectively methods with - * preprocessor macros so that they have the names that swig expects - * (e.g. the destructor of SHPObject has to be called delete_SHPObject) - */ - -#define delete_SHPObject SHPDestroyObject - -/* - * The extents() method of SHPObject. - * - * Return the extents as a tuple of two 4-element lists with the min. - * and max. values of x, y, z, m. - */ -static PyObject * -SHPObject_extents(SHPObject *object) -{ - return Py_BuildValue("[dddd][dddd]", - object->dfXMin, object->dfYMin, object->dfZMin, - object->dfMMin, - object->dfXMax, object->dfYMax, object->dfZMax, - object->dfMMax); -} - - -/* - * The vertices() method of SHPObject. - * - * Return the x and y coords of the vertices as a list of lists of - * tuples. - */ - -static PyObject* build_vertex_list(SHPObject *object, int index, int length); - -static PyObject* -SHPObject_vertices(SHPObject *object) -{ - PyObject *result = NULL; - PyObject *part = NULL; - int part_idx, vertex_idx; - int length = 0; - - - if (object->nParts > 0) - { - /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */ - - result = PyList_New(object->nParts); - if (!result) - return NULL; - - for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; - part_idx++) - { - if (part_idx < object->nParts - 1) - length = (object->panPartStart[part_idx + 1] - - object->panPartStart[part_idx]); - else - length = object->nVertices - object->panPartStart[part_idx]; - - part = build_vertex_list(object, vertex_idx, length); - if (!part) - goto fail; - - if (PyList_SetItem(result, part_idx, part) < 0) - goto fail; - - vertex_idx += length; - } - } - else - { - /* only one part. usual for SHPT_POINT */ - result = build_vertex_list(object, 0, object->nVertices); - } - - return result; - - fail: - Py_XDECREF(part); - Py_DECREF(result); - return NULL; -} - - -/* Return the length coordinates of the shape object starting at vertex - * index as a Python-list of tuples. Helper function for - * SHPObject_vertices. - */ -static PyObject* -build_vertex_list(SHPObject *object, int index, int length) -{ - int i; - PyObject * list; - PyObject * vertex = NULL; - - list = PyList_New(length); - if (!list) - return NULL; - - for (i = 0; i < length; i++, index++) - { - vertex = Py_BuildValue("dd", object->padfX[index], - object->padfY[index]); - if (!vertex) - goto fail; - if (PyList_SetItem(list, i, vertex) < 0) - goto fail; - } - - return list; - - fail: - Py_XDECREF(vertex); - Py_DECREF(list); - return NULL; -} - - - - - -/* The constructor of SHPObject. parts is a list of lists of tuples - * describing the parts and their vertices just likethe output of the - * vertices() method. part_type_list is the list of part-types and may - * be NULL. For the meaning of the part-types and their default value - * see the Shaplib documentation. - */ -SHPObject * new_SHPObject(int type, int id, PyObject * parts, - PyObject * part_type_list) -{ - /* arrays to hold thex and y coordinates of the vertices */ - double *xs = NULL, *ys = NULL; - /* number of all vertices of all parts */ - int num_vertices; - /* number of parts in the list parts */ - int num_parts; - /* start index of in xs and ys of the part currently worked on */ - int part_start; - /* array of start indices in xs and ys as expected by shapelib */ - int *part_starts = NULL; - - /* generic counter */ - int i; - - /* array of part types. holds the converted content of - * part_type_list. Stays NULL of part_type_list is NULL - */ - int *part_types = NULL; - - /* temporary python objects referring to the the list items being - * worked on. - */ - PyObject * part = NULL, *tuple = NULL; - - /* The result object */ - SHPObject *result; - - num_parts = PySequence_Length(parts); - num_vertices = 0; - - /* parts and part_types have to have the same lengths */ - if (part_type_list - && PySequence_Length(parts) != PySequence_Length(part_type_list)) - { - PyErr_SetString(PyExc_TypeError, - "parts and part_types have to have the same lengths"); - return NULL; - } - - /* determine how many vertices there are altogether */ - for (i = 0; i < num_parts; i++) - { - PyObject * part = PySequence_GetItem(parts, i); - if (!part) - return NULL; - num_vertices += PySequence_Length(part); - Py_DECREF(part); - } - - /* allocate the memory for the various arrays and check for memory - errors */ - xs = malloc(num_vertices * sizeof(double)); - ys = malloc(num_vertices * sizeof(double)); - part_starts = malloc(num_parts * sizeof(int)); - if (part_type_list) - part_types = malloc(num_parts * sizeof(int)); - - if (!xs || !ys || !part_starts || (part_type_list && !part_types)) - { - PyErr_NoMemory(); - goto fail; - } - - /* convert the part types */ - if (part_type_list) - { - for (i = 0; i < num_parts; i++) - { - PyObject * otype = PySequence_GetItem(part_type_list, i); - if (!otype) - return NULL; - part_types[i] = PyInt_AsLong(otype); - Py_DECREF(otype); - } - } - - /* convert the list of parts */ - part_start = 0; - for (i = 0; i < num_parts; i++) - { - int j, length; - - part = PySequence_GetItem(parts, i); - length = PySequence_Length(part); - part_starts[i] = part_start; - - for (j = 0; j < length; j++) - { - tuple = PySequence_GetItem(part, j); - if (!tuple) - goto fail; - - if (!PyArg_ParseTuple(tuple, "dd", xs + part_start + j, - ys + part_start + j)) - { - goto fail; - } - Py_DECREF(tuple); - tuple = NULL; - } - Py_DECREF(part); - part = NULL; - part_start += length; - } - - result = SHPCreateObject(type, id, num_parts, part_starts, part_types, - num_vertices, xs, ys, NULL, NULL); - free(xs); - free(ys); - free(part_starts); - free(part_types); - return result; - - fail: - free(xs); - free(ys); - free(part_starts); - free(part_types); - Py_XDECREF(part); - Py_XDECREF(tuple); - return NULL; -} - - -static PyObject* l_output_helper(PyObject* target, PyObject* o) { - PyObject* o2; - if (!target) { - target = o; - } else if (target == Py_None) { - Py_DECREF(Py_None); - target = o; - } else { - if (!PyList_Check(target)) { - o2 = target; - target = PyList_New(0); - PyList_Append(target, o2); - Py_XDECREF(o2); - } - PyList_Append(target,o); - Py_XDECREF(o); - } - return target; -} - -static PyObject* t_output_helper(PyObject* target, PyObject* o) { - PyObject* o2; - PyObject* o3; - - if (!target) { - target = o; - } else if (target == Py_None) { - Py_DECREF(Py_None); - target = o; - } else { - if (!PyTuple_Check(target)) { - o2 = target; - target = PyTuple_New(1); - PyTuple_SetItem(target, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SetItem(o3, 0, o); - - o2 = target; - target = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return target; -} - -#define SWIG_MemoryError 1 -#define SWIG_IOError 2 -#define SWIG_RuntimeError 3 -#define SWIG_IndexError 4 -#define SWIG_TypeError 5 -#define SWIG_DivisionByZero 6 -#define SWIG_OverflowError 7 -#define SWIG_SyntaxError 8 -#define SWIG_ValueError 9 -#define SWIG_SystemError 10 -#define SWIG_UnknownError 99 - -static void _SWIG_exception(int code, char *msg) { - switch(code) { - case SWIG_MemoryError: - PyErr_SetString(PyExc_MemoryError,msg); - break; - case SWIG_IOError: - PyErr_SetString(PyExc_IOError,msg); - break; - case SWIG_RuntimeError: - PyErr_SetString(PyExc_RuntimeError,msg); - break; - case SWIG_IndexError: - PyErr_SetString(PyExc_IndexError,msg); - break; - case SWIG_TypeError: - PyErr_SetString(PyExc_TypeError,msg); - break; - case SWIG_DivisionByZero: - PyErr_SetString(PyExc_ZeroDivisionError,msg); - break; - case SWIG_OverflowError: - PyErr_SetString(PyExc_OverflowError,msg); - break; - case SWIG_SyntaxError: - PyErr_SetString(PyExc_SyntaxError,msg); - break; - case SWIG_ValueError: - PyErr_SetString(PyExc_ValueError,msg); - break; - case SWIG_SystemError: - PyErr_SetString(PyExc_SystemError,msg); - break; - default: - PyErr_SetString(PyExc_RuntimeError,msg); - break; - } -} - -#define SWIG_exception(a,b) { _SWIG_exception(a,b); return NULL; } - - typedef struct { - SHPHandle handle; - } ShapeFile; - -#define NOCHECK_delete_ShapeFile -#define NOCHECK_ShapeFile_close - - ShapeFile * open_ShapeFile(const char *filename, const char * mode) { - ShapeFile * self = malloc(sizeof(ShapeFile)); - if (self) - self->handle = SHPOpen(filename, mode); - return self; - } - - ShapeFile * create_ShapeFile(const char *filename, int type) { - ShapeFile * self = malloc(sizeof(ShapeFile)); - if (self) - self->handle = SHPCreate(filename, type); - return self; - } - - static PyShapeLibAPI the_api = { - SHPReadObject, - SHPDestroyObject, - SHPCreateTree, - SHPDestroyTree, - SHPTreeFindLikelyShapes - }; - - PyObject * c_api() { - return PyCObject_FromVoidPtr(&the_api, NULL); - } -#ifdef __cplusplus -extern "C" { -#endif -static PyObject *_wrap_open(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg0 ; - char *arg1 = "rb" ; - ShapeFile *result ; - - if(!PyArg_ParseTuple(args,"s|s:open",&arg0,&arg1)) return NULL; - { - result = (ShapeFile *)open_ShapeFile((char const *)arg0,(char const *)arg1); - ; - if (!result) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!result->handle) - { - SWIG_exception(SWIG_IOError, "open_ShapeFile failed"); - } - }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ShapeFile); - return resultobj; -} - - -static PyObject *_wrap_create(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg0 ; - int arg1 ; - ShapeFile *result ; - - if(!PyArg_ParseTuple(args,"si:create",&arg0,&arg1)) return NULL; - { - result = (ShapeFile *)create_ShapeFile((char const *)arg0,arg1); - ; - if (!result) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!result->handle) - { - SWIG_exception(SWIG_IOError, "create_ShapeFile failed"); - } - }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ShapeFile); - return resultobj; -} - - -static PyObject *_wrap_c_api(PyObject *self, PyObject *args) { - PyObject *resultobj; - PyObject *result ; - - if(!PyArg_ParseTuple(args,":c_api")) return NULL; - result = (PyObject *)c_api(); - { - resultobj = result; - } - return resultobj; -} - - -static PyObject *_wrap_type_name(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg0 ; - char *result ; - - if(!PyArg_ParseTuple(args,"i:type_name",&arg0)) return NULL; - result = (char *)SHPTypeName(arg0); - resultobj = PyString_FromString(result); - return resultobj; -} - - -static PyObject *_wrap_part_type_name(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg0 ; - char *result ; - - if(!PyArg_ParseTuple(args,"i:part_type_name",&arg0)) return NULL; - result = (char *)SHPPartTypeName(arg0); - resultobj = PyString_FromString(result); - return resultobj; -} - - -static PyObject *_wrap_SHPObject_type_get(PyObject *self, PyObject *args) { - PyObject *resultobj; - SHPObject *arg0 ; - PyObject * argo0 =0 ; - int result ; - - if(!PyArg_ParseTuple(args,"O:SHPObject_type_get",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_SHPObject,1)) == -1) return NULL; - result = (int ) (arg0->nSHPType); - resultobj = PyInt_FromLong((long)result); - return resultobj; -} - - -static PyObject *_wrap_SHPObject_id_get(PyObject *self, PyObject *args) { - PyObject *resultobj; - SHPObject *arg0 ; - PyObject * argo0 =0 ; - int result ; - - if(!PyArg_ParseTuple(args,"O:SHPObject_id_get",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_SHPObject,1)) == -1) return NULL; - result = (int ) (arg0->nShapeId); - resultobj = PyInt_FromLong((long)result); - return resultobj; -} - - -static PyObject *_wrap_new_SHPObject(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg0 ; - int arg1 ; - PyObject *arg2 ; - PyObject *arg3 = NULL ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - SHPObject *result ; - - if(!PyArg_ParseTuple(args,"iiO|O:new_SHPObject",&arg0,&arg1,&obj2,&obj3)) return NULL; - { - arg2 = obj2; - } - if (obj3) - { - arg3 = obj3; - } - { - result = (SHPObject *)new_SHPObject(arg0,arg1,arg2,arg3); - ; - if (PyErr_Occurred()) - return NULL; - }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_SHPObject); - return resultobj; -} - - -static PyObject *_wrap_delete_SHPObject(PyObject *self, PyObject *args) { - PyObject *resultobj; - SHPObject *arg0 ; - PyObject * argo0 =0 ; - - if(!PyArg_ParseTuple(args,"O:delete_SHPObject",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_SHPObject,1)) == -1) return NULL; - delete_SHPObject(arg0); - Py_INCREF(Py_None); - resultobj = Py_None; - return resultobj; -} - - -static PyObject *_wrap_SHPObject_extents(PyObject *self, PyObject *args) { - PyObject *resultobj; - SHPObject *arg0 ; - PyObject * argo0 =0 ; - PyObject *result ; - - if(!PyArg_ParseTuple(args,"O:SHPObject_extents",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_SHPObject,1)) == -1) return NULL; - result = (PyObject *)SHPObject_extents(arg0); - { - resultobj = result; - } - return resultobj; -} - - -static PyObject *_wrap_SHPObject_vertices(PyObject *self, PyObject *args) { - PyObject *resultobj; - SHPObject *arg0 ; - PyObject * argo0 =0 ; - PyObject *result ; - - if(!PyArg_ParseTuple(args,"O:SHPObject_vertices",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_SHPObject,1)) == -1) return NULL; - result = (PyObject *)SHPObject_vertices(arg0); - { - resultobj = result; - } - return resultobj; -} - - -ShapeFile * new_ShapeFile(char *file,char *mode) { - { - ShapeFile * self = malloc(sizeof(ShapeFile)); - if (self) - self->handle = SHPOpen(file, mode); - return self; - } -} - - -static PyObject *_wrap_new_ShapeFile(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg0 ; - char *arg1 = "rb" ; - ShapeFile *result ; - - if(!PyArg_ParseTuple(args,"s|s:new_ShapeFile",&arg0,&arg1)) return NULL; - { - result = (ShapeFile *)new_ShapeFile(arg0,arg1); - ; - if (!result) - { - SWIG_exception(SWIG_MemoryError, "no memory"); - } - else if (!result->handle) - { - SWIG_exception(SWIG_IOError, "new_ShapeFile failed"); - } - }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ShapeFile); - return resultobj; -} - - -void delete_ShapeFile(ShapeFile *self) { - { - if (self->handle) - SHPClose(self->handle); - free(self); - } -} - - -static PyObject *_wrap_delete_ShapeFile(PyObject *self, PyObject *args) { - PyObject *resultobj; - ShapeFile *arg0 ; - PyObject * argo0 =0 ; - - if(!PyArg_ParseTuple(args,"O:delete_ShapeFile",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_ShapeFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_delete_ShapeFile - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "shapefile already closed"); - #endif - } - delete_ShapeFile(arg0); - Py_INCREF(Py_None); - resultobj = Py_None; - return resultobj; -} - - -void ShapeFile_close(ShapeFile *self) { - { - if (self->handle) - { - SHPClose(self->handle); - self->handle = NULL; - } - } -} - - -static PyObject *_wrap_ShapeFile_close(PyObject *self, PyObject *args) { - PyObject *resultobj; - ShapeFile *arg0 ; - PyObject * argo0 =0 ; - - if(!PyArg_ParseTuple(args,"O:ShapeFile_close",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_ShapeFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_ShapeFile_close - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "shapefile already closed"); - #endif - } - ShapeFile_close(arg0); - Py_INCREF(Py_None); - resultobj = Py_None; - return resultobj; -} - - -void ShapeFile_info(ShapeFile *self,int *output_entities,int *output_type,double *output_min_bounds,double *output_max_bounds) { - { - SHPGetInfo(self->handle, output_entities, output_type, - output_min_bounds, output_max_bounds); - } -} - - -static PyObject *_wrap_ShapeFile_info(PyObject *self, PyObject *args) { - PyObject *resultobj; - ShapeFile *arg0 ; - int *arg1 ; - int *arg2 ; - double *arg3 ; - double *arg4 ; - int temp ; - int temp0 ; - double temp1[4] ; - double temp2[4] ; - PyObject * argo0 =0 ; - - { - arg1 = &temp; - } - { - arg2 = &temp0; - } - { - arg3 = temp1; - } - { - arg4 = temp2; - } - if(!PyArg_ParseTuple(args,"O:ShapeFile_info",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_ShapeFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_ShapeFile_info - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "shapefile already closed"); - #endif - } - ShapeFile_info(arg0,arg1,arg2,arg3,arg4); - Py_INCREF(Py_None); - resultobj = Py_None; - { - PyObject *o; - o = PyInt_FromLong((long) (*arg1)); - resultobj = t_output_helper(resultobj, o); - } - { - PyObject *o; - o = PyInt_FromLong((long) (*arg2)); - resultobj = t_output_helper(resultobj, o); - } - { - PyObject * list = Py_BuildValue("[dddd]", - arg3[0], arg3[1], - arg3[2], arg3[3]); - resultobj = t_output_helper(resultobj,list); - } - { - PyObject * list = Py_BuildValue("[dddd]", - arg4[0], arg4[1], - arg4[2], arg4[3]); - resultobj = t_output_helper(resultobj,list); - } - return resultobj; -} - - -SHPObject * ShapeFile_read_object(ShapeFile *self,int i) { - { - return SHPReadObject(self->handle, i); - } -} - - -static PyObject *_wrap_ShapeFile_read_object(PyObject *self, PyObject *args) { - PyObject *resultobj; - ShapeFile *arg0 ; - int arg1 ; - PyObject * argo0 =0 ; - SHPObject *result ; - - if(!PyArg_ParseTuple(args,"Oi:ShapeFile_read_object",&argo0,&arg1)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_ShapeFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_ShapeFile_read_object - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "shapefile already closed"); - #endif - } - result = (SHPObject *)ShapeFile_read_object(arg0,arg1); - resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_SHPObject); - return resultobj; -} - - -int ShapeFile_write_object(ShapeFile *self,int iShape,SHPObject *psObject) { - { - return SHPWriteObject(self->handle, iShape, psObject); - } -} - - -static PyObject *_wrap_ShapeFile_write_object(PyObject *self, PyObject *args) { - PyObject *resultobj; - ShapeFile *arg0 ; - int arg1 ; - SHPObject *arg2 ; - PyObject * argo0 =0 ; - PyObject * argo2 =0 ; - int result ; - - if(!PyArg_ParseTuple(args,"OiO:ShapeFile_write_object",&argo0,&arg1,&argo2)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_ShapeFile,1)) == -1) return NULL; - if ((SWIG_ConvertPtr(argo2,(void **) &arg2,SWIGTYPE_p_SHPObject,1)) == -1) return NULL; - { - #ifndef NOCHECK_ShapeFile_write_object - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "shapefile already closed"); - #endif - } - result = (int )ShapeFile_write_object(arg0,arg1,arg2); - resultobj = PyInt_FromLong((long)result); - return resultobj; -} - - -PyObject * ShapeFile_cobject(ShapeFile *self) { - { - return PyCObject_FromVoidPtr(self->handle, NULL); - } -} - - -static PyObject *_wrap_ShapeFile_cobject(PyObject *self, PyObject *args) { - PyObject *resultobj; - ShapeFile *arg0 ; - PyObject * argo0 =0 ; - PyObject *result ; - - if(!PyArg_ParseTuple(args,"O:ShapeFile_cobject",&argo0)) return NULL; - if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_ShapeFile,1)) == -1) return NULL; - { - #ifndef NOCHECK_ShapeFile_cobject - if (!arg0 || !arg0->handle) - SWIG_exception(SWIG_TypeError, "shapefile already closed"); - #endif - } - result = (PyObject *)ShapeFile_cobject(arg0); - { - resultobj = result; - } - return resultobj; -} - - -static PyMethodDef shapelibcMethods[] = { - { "open", _wrap_open, METH_VARARGS }, - { "create", _wrap_create, METH_VARARGS }, - { "c_api", _wrap_c_api, METH_VARARGS }, - { "type_name", _wrap_type_name, METH_VARARGS }, - { "part_type_name", _wrap_part_type_name, METH_VARARGS }, - { "SHPObject_type_get", _wrap_SHPObject_type_get, METH_VARARGS }, - { "SHPObject_id_get", _wrap_SHPObject_id_get, METH_VARARGS }, - { "new_SHPObject", _wrap_new_SHPObject, METH_VARARGS }, - { "delete_SHPObject", _wrap_delete_SHPObject, METH_VARARGS }, - { "SHPObject_extents", _wrap_SHPObject_extents, METH_VARARGS }, - { "SHPObject_vertices", _wrap_SHPObject_vertices, METH_VARARGS }, - { "new_ShapeFile", _wrap_new_ShapeFile, METH_VARARGS }, - { "delete_ShapeFile", _wrap_delete_ShapeFile, METH_VARARGS }, - { "ShapeFile_close", _wrap_ShapeFile_close, METH_VARARGS }, - { "ShapeFile_info", _wrap_ShapeFile_info, METH_VARARGS }, - { "ShapeFile_read_object", _wrap_ShapeFile_read_object, METH_VARARGS }, - { "ShapeFile_write_object", _wrap_ShapeFile_write_object, METH_VARARGS }, - { "ShapeFile_cobject", _wrap_ShapeFile_cobject, METH_VARARGS }, - { NULL, NULL } -}; - -#ifdef __cplusplus -} -#endif - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_ShapeFile[] = {{"_p_ShapeFile", 0, "ShapeFile *"},{"_p_ShapeFile"},{0}}; -static swig_type_info _swigt__p_SHPObject[] = {{"_p_SHPObject", 0, "SHPObject *"},{"_p_SHPObject"},{0}}; - -static swig_type_info *swig_types_initial[] = { -_swigt__p_ShapeFile, -_swigt__p_SHPObject, -0 -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { - { SWIG_PY_INT, "SHPT_NULL", (long) 0, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_POINT", (long) 1, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_ARC", (long) 3, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_POLYGON", (long) 5, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_MULTIPOINT", (long) 8, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_POINTZ", (long) 11, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_ARCZ", (long) 13, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_POLYGONZ", (long) 15, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_MULTIPOINTZ", (long) 18, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_POINTM", (long) 21, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_ARCM", (long) 23, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_POLYGONM", (long) 25, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_MULTIPOINTM", (long) 28, 0, 0, 0}, - { SWIG_PY_INT, "SHPT_MULTIPATCH", (long) 31, 0, 0, 0}, - { SWIG_PY_INT, "SHPP_TRISTRIP", (long) 0, 0, 0, 0}, - { SWIG_PY_INT, "SHPP_TRIFAN", (long) 1, 0, 0, 0}, - { SWIG_PY_INT, "SHPP_OUTERRING", (long) 2, 0, 0, 0}, - { SWIG_PY_INT, "SHPP_INNERRING", (long) 3, 0, 0, 0}, - { SWIG_PY_INT, "SHPP_FIRSTRING", (long) 4, 0, 0, 0}, - { SWIG_PY_INT, "SHPP_RING", (long) 5, 0, 0, 0}, -{0}}; - -static PyObject *SWIG_globals; -#ifdef __cplusplus -extern "C" -#endif -SWIGEXPORT(void) initshapelibc(void) { - PyObject *m, *d; - int i; - SWIG_globals = SWIG_newvarlink(); - m = Py_InitModule("shapelibc", shapelibcMethods); - d = PyModule_GetDict(m); - for (i = 0; swig_types_initial[i]; i++) { - swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); - } - SWIG_InstallConstants(d,swig_const_table); -} - diff --git a/pyshapelib/shptreemodule.c b/pyshapelib/shptreemodule.c deleted file mode 100644 index 78797dd01..000000000 --- a/pyshapelib/shptreemodule.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright (c) 2001, 2002 by Intevation GmbH - * Authors: - * Bernhard Herzog - * - * This program is free software under the GPL (>=v2) - * Read the file COPYING coming with Thuban for details. - */ - -/* Python wrapper for the shapelib SHPTree */ - -#include -#include - -#include "pyshapelib_api.h" - -PyShapeLibAPI * api; - -typedef struct { - PyObject_HEAD - SHPTree * tree; -} SHPTreeObject; - -extern PyTypeObject SHPTreeType; - -#define SHPTree_Check(v) ((v)->ob_type == &SHPTreeType) - -/* Create a new python wrapper object from a SHPTree pointer */ -static PyObject * -SHPTreeObject_FromSHPTree(SHPTree* tree) -{ - SHPTreeObject * self = PyObject_NEW(SHPTreeObject, &SHPTreeType); - if (!self) - return NULL; - - self->tree = tree; - - return (PyObject *)self; -} - -/* Deallocate the SHPTree wrapper. */ -static void -shptree_dealloc(SHPTreeObject * self) -{ - api->SHPDestroyTree(self->tree); - PyMem_DEL(self); -} - -/* Return the repr of the wrapper */ -static PyObject * -shptree_repr(SHPTreeObject * self) -{ - char buf[1000]; - sprintf(buf, "", (unsigned long)self); - return PyString_FromString(buf); -} - -static PyObject * -shptree_find_shapes(SHPTreeObject * self, PyObject * args) -{ - double min[4] = {0, 0, 0, 0}; - double max[4] = {0, 0, 0, 0}; - int count, idx; - int * ids; - PyObject * list = NULL, *temp = NULL; - - if (!PyArg_ParseTuple(args, "(dd)(dd)", min + 0, min + 1, - max + 0, max + 1)) - return NULL; - - ids = api->SHPTreeFindLikelyShapes(self->tree, min, max, &count); - - list = PyList_New(count); - if (!list) - goto fail; - - /* Turn the returned array of indices into a python list of ints. */ - for (idx = 0; idx < count; idx++) - { - temp = PyInt_FromLong(ids[idx]); - if (!temp) - goto fail; - - if (PyList_SetItem(list, idx, temp) == -1) - { - /* temp's refcount has already be decreased. Set temp to - * NULL so that the fail code doesn't do it again - */ - temp = NULL; - goto fail; - } - } - - free(ids); - return list; - - fail: - free(ids); - Py_XDECREF(list); - Py_XDECREF(temp); - return NULL; -} - - -static struct PyMethodDef shptree_methods[] = { - {"find_shapes", (PyCFunction)shptree_find_shapes, METH_VARARGS}, - {NULL, NULL} -}; - -static PyObject * -shptree_getattr(PyObject * self, char * name) -{ - return Py_FindMethod(shptree_methods, self, name); -} - - -PyTypeObject SHPTreeType = { - PyObject_HEAD_INIT(NULL) - 0, - "SHPTree", - sizeof(SHPTreeObject), - 0, - (destructor)shptree_dealloc, /*tp_dealloc*/ - (printfunc)NULL, /*tp_print*/ - shptree_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - (reprfunc)shptree_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ -}; - - - -static PyObject * -shptree_from_shapefile(PyObject * self, PyObject * args) -{ - SHPTree * tree; - SHPHandle handle; - PyObject * cobject; - int dimension, max_depth; - - if (!PyArg_ParseTuple(args, "O!ii", &PyCObject_Type, &cobject, - &dimension, &max_depth)) - return NULL; - - handle = PyCObject_AsVoidPtr(cobject); - - tree = api->SHPCreateTree(handle, dimension, max_depth, NULL, NULL); - - /* apparently SHPCreateTree doesn't do any error checking, so we - * have to assume that tree is valid at this point. */ - return SHPTreeObject_FromSHPTree(tree); -} - - -static PyMethodDef module_functions[] = { - {"SHPTree", shptree_from_shapefile, METH_VARARGS}, - { NULL, NULL } -}; - - -void -initshptree() -{ - SHPTreeType.ob_type = &PyType_Type; - - Py_InitModule("shptree", module_functions); - PYSHAPELIB_IMPORT_API(api); -} diff --git a/pyshapelib/testdbf.py b/pyshapelib/testdbf.py deleted file mode 100644 index d13c76263..000000000 --- a/pyshapelib/testdbf.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2003 by Intevation GmbH -# Authors: -# Bernhard Herzog -# -# This program is free software under the LGPL (>=v2) -# Read the file COPYING coming with the software for details. - -"""Test cases for the dbflib python bindings""" - -__version__ = "$Revision$" -# $Source$ -# $Id$ - -import unittest -import dbflib - -class TestDBF(unittest.TestCase): - - def test_add_field(self): - """Test whethe add_field reports exceptions""" - dbf = dbflib.create("test.dbf") - # For strings the precision parameter must be 0 - self.assertRaises(RuntimeError, - dbf.add_field, "str", dbflib.FTString, 10, 5) - - -if __name__ == "__main__": - unittest.main() diff --git a/pyshapelib/testfile.dbf b/pyshapelib/testfile.dbf deleted file mode 100644 index a78f786fa..000000000 Binary files a/pyshapelib/testfile.dbf and /dev/null differ diff --git a/pyshapelib/testfile.shp b/pyshapelib/testfile.shp deleted file mode 100644 index 036d85d23..000000000 Binary files a/pyshapelib/testfile.shp and /dev/null differ diff --git a/pyshapelib/testfile.shx b/pyshapelib/testfile.shx deleted file mode 100644 index 442fd9f24..000000000 Binary files a/pyshapelib/testfile.shx and /dev/null differ diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 87ec0a2e6..000000000 --- a/setup.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[provide_packages] -# By default, basemap checks for a few dependencies and -# installs them if missing. This feature can be turned off -# by uncommenting the following lines. Acceptible values are: -# True: install, overwrite an existing installation -# False: do not install -# auto: install only if the package is unavailable. This -# is the default behavior -pyshapelib = auto diff --git a/setup.py b/setup.py index f008bc976..89a127efd 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,3 @@ -# basemap build options can be modified with the setup.cfg file. See -# setup.cfg for more information. import sys, glob, os, numpy, subprocess major, minor1, minor2, s, tmp = sys.version_info if major==2 and minor1<4 or major<2: @@ -12,23 +10,6 @@ except ImportError: from distutils.command.build_py import build_py -def dbf_macros(): - """Return the macros to define when compiling the dbflib wrapper. - - The returned list specifies one macro, HAVE_UPDATE_HEADER, which is - '1' if the dbflib version we will be compiling with has the - DBFUpdateHeader function and '0' otherwise. To check whether - DBFUpdateHeader is available, we scan shapefil.h for the string - 'DBFUpdateHeader'. - """ - f = open(convert_path("pyshapelib/shapelib/shapefil.h")) - contents = f.read() - f.close() - if contents.find("DBFUpdateHeader") >= 0: - return [("HAVE_UPDATE_HEADER", "1")] - else: - return [("HAVE_UPDATE_HEADER", "0")] - def checkversion(GEOS_dir): """check geos C-API header file (geos_c.h)""" try: @@ -105,70 +86,6 @@ def checkversion(GEOS_dir): include_dirs=geos_include_dirs, libraries=['geos_c','geos'])) -# check setup.cfg file to see how to install auxilliary packages. -options = {} -if os.path.exists("setup.cfg"): - try: - import ConfigParser - except ImportError: - import configparser as ConfigParser - config = ConfigParser.SafeConfigParser() - config.read("setup.cfg") - try: options['provide_pyshapelib'] = config.getboolean("provide_packages", "pyshapelib") - except: options['provide_pyshapelib'] = 'auto' -else: - options['provide_pyshapelib'] = 'auto' - - -provide_pyshapelib = options['provide_pyshapelib'] -if provide_pyshapelib == 'auto': - sys.stdout.write('checking to see if pyshapelib installed ..\n') - try: - import shapelib - import dbflib - except ImportError: - sys.stdout.write('shapelib/dbflib not installed, will be installed\n') - packages = packages + ['shapelib','dbflib'] - package_dirs['shapelib'] = os.path.join('lib','shapelib') - package_dirs['dbflib'] = os.path.join('lib','dbflib') - extensions = extensions + \ - [Extension("shapelibc", - ["pyshapelib/shapelib_wrap.c", - "pyshapelib/shapelib/shpopen.c", - "pyshapelib/shapelib/shptree.c"], - include_dirs = ["pyshapelib/shapelib"]), - Extension("shptree", - ["pyshapelib/shptreemodule.c"], - include_dirs = ["pyshapelib/shapelib"]), - Extension("dbflibc", - ["pyshapelib/dbflib_wrap.c", - "pyshapelib/shapelib/dbfopen.c"], - include_dirs = ["pyshapelib/shapelib"], - define_macros = dbf_macros()) ] - else: - sys.stdout.write('pyshapelib installed\n') -elif provide_pyshapelib: # force install of shapelib - sys.stdout.write('forcing install of included pyshapelib\n') - packages = packages + ['shapelib','dbflib'] - package_dirs['shapelib'] = os.path.join('lib','shapelib') - package_dirs['dbflib'] = os.path.join('lib','dbflib') - extensions = extensions + \ - [Extension("shapelibc", - ["pyshapelib/shapelib_wrap.c", - "pyshapelib/shapelib/shpopen.c", - "pyshapelib/shapelib/shptree.c"], - include_dirs = ["pyshapelib/shapelib"]), - Extension("shptree", - ["pyshapelib/shptreemodule.c"], - include_dirs = ["pyshapelib/shapelib"]), - Extension("dbflibc", - ["pyshapelib/dbflib_wrap.c", - "pyshapelib/shapelib/dbfopen.c"], - include_dirs = ["pyshapelib/shapelib"], - define_macros = dbf_macros()) ] -else: - sys.stdout.write( 'will not install pyshapelib\n') - # Specify all the required mpl data # create pyproj binary datum shift grid files. pathout =\ diff --git a/setupegg.py b/setupegg.py deleted file mode 100644 index ba315c872..000000000 --- a/setupegg.py +++ /dev/null @@ -1,8 +0,0 @@ -""" -Poor man's setuptools script... -""" - -from setuptools import setup -execfile('setup.py', - {'additional_params' : - {'namespace_packages' : ['mpl_toolkits']}})