[spatialite-tools] 01/08: Imported Upstream version 4.4.0~rc1
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Sat May 7 13:34:43 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch experimental
in repository spatialite-tools.
commit 58e2179a513a1b01dbf1e8236cf45c4cd5202213
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat May 7 14:37:29 2016 +0200
Imported Upstream version 4.4.0~rc1
---
Makefile-static-MinGW | 53 +-
Makefile.am | 5 +-
Makefile.in | 22 +-
configure | 20 +-
configure.ac | 2 +-
makefile.vc | 10 +-
shp_sanitize.c | 4321 +++++++++++++++++++++++++++++++++++++++++++++++++
spatialite_osm_map.c | 99 +-
8 files changed, 4440 insertions(+), 92 deletions(-)
diff --git a/Makefile-static-MinGW b/Makefile-static-MinGW
index d278685..f5b74f4 100644
--- a/Makefile-static-MinGW
+++ b/Makefile-static-MinGW
@@ -11,7 +11,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
./static_bin/spatialite_osm_map.exe ./static_bin/spatialite_gml.exe \
./static_bin/spatialite_osm_raw.exe ./static_bin/spatialite_osm_filter.exe \
./static_bin/spatialite_convert.exe ./static_bin/spatialite_dxf.exe \
- ./static_bin/spatialite_osm_overpass.exe \
+ ./static_bin/spatialite_osm_overpass.exe ./static_bin/shp_sanitize.exe \
./static_bin/spatialite_xml_collapse.exe \
./static_bin/spatialite_xml_validator.exe \
./static_bin/spatialite_xml_load.exe \
@@ -21,7 +21,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) shell.o -o ./static_bin/spatialite.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -38,7 +38,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
./static_bin/spatialite_tool.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -55,7 +55,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
./static_bin/spatialite_convert.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -72,7 +72,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
./static_bin/spatialite_dxf.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -88,7 +88,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_network.o -o ./static_bin/spatialite_network.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -104,7 +104,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) shp_doctor.o -o ./static_bin/shp_doctor.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -116,11 +116,27 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
-lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc
strip --strip-all ./static_bin/shp_doctor.exe
+./static_bin/shp_sanitize.exe: shp_sanitize.o
+ $(GG) shp_sanitize.o -o ./static_bin/shp_sanitize.exe \
+ /usr/local/lib/libspatialite.a \
+ /usr/local/lib/libsqlite3.a \
+ /usr/local/lib/librttopo.a \
+ /usr/local/lib/libxml2.a \
+ /usr/local/lib/liblzma.a \
+ /usr/local/lib/libproj.a \
+ /usr/local/lib/libgeos_c.a \
+ /usr/local/lib/libgeos.a \
+ /usr/local/lib/libfreexl.a \
+ /usr/local/lib/libz.a \
+ /usr/local/lib/libiconv.a \
+ -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc
+ strip --strip-all ./static_bin/shp_sanitize.exe
+
./static_bin/exif_loader.exe: exif_loader.o
$(GG) exif_loader.o -o ./static_bin/exif_loader.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -136,7 +152,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_osm_net.o -o ./static_bin/spatialite_osm_net.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -154,7 +170,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_osm_map.o -o ./static_bin/spatialite_osm_map.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -172,7 +188,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_gml.o -o ./static_bin/spatialite_gml.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -189,7 +205,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_osm_raw.o -o ./static_bin/spatialite_osm_raw.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -207,7 +223,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_osm_filter.o -o ./static_bin/spatialite_osm_filter.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -223,7 +239,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_osm_overpass.o -o ./static_bin/spatialite_osm_overpass.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -239,7 +255,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_xml_collapse.o -o ./static_bin/spatialite_xml_collapse.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -264,7 +280,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_xml_load.o -o ./static_bin/spatialite_xml_load.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -281,7 +297,7 @@ all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \
$(GG) spatialite_xml_print.o -o ./static_bin/spatialite_xml_print.exe \
/usr/local/lib/libspatialite.a \
/usr/local/lib/libsqlite3.a \
- /usr/local/lib/liblwgeom.a \
+ /usr/local/lib/librttopo.a \
/usr/local/lib/libxml2.a \
/usr/local/lib/liblzma.a \
/usr/local/lib/libproj.a \
@@ -304,6 +320,9 @@ spatialite_network.o:
shp_doctor.o:
$(CC) $(CFLAGS) shp_doctor.c -c
+
+shp_sanitize.o:
+ $(CC) $(CFLAGS) shp_sanitize.c -c
exif_loader.o:
$(CC) $(CFLAGS) exif_loader.c -c
diff --git a/Makefile.am b/Makefile.am
index 1bc4c7e..eb4ce16 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ if NO_READOSM
bin_PROGRAMS = spatialite \
spatialite_tool \
spatialite_network \
- shp_doctor \
+ shp_doctor shp_sanitize \
exif_loader \
spatialite_osm_filter \
spatialite_gml \
@@ -19,7 +19,7 @@ else
bin_PROGRAMS = spatialite \
spatialite_tool \
spatialite_network \
- shp_doctor \
+ shp_doctor shp_sanitize \
exif_loader \
spatialite_osm_net \
spatialite_osm_map \
@@ -42,6 +42,7 @@ spatialite_SOURCES = shell.c
spatialite_tool_SOURCES = spatialite_tool.c
spatialite_network_SOURCES = spatialite_network.c
shp_doctor_SOURCES = shp_doctor.c
+shp_sanitize_SOURCES = shp_sanitize.c
exif_loader_SOURCES = exif_loader.c
spatialite_xml_validator_SOURCES = spatialite_xml_validator.c
spatialite_xml_load_SOURCES = spatialite_xml_load.c
diff --git a/Makefile.in b/Makefile.in
index 13d46a6..4f30813 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -91,7 +91,8 @@ host_triplet = @host@
@NO_READOSM_FALSE at bin_PROGRAMS = spatialite$(EXEEXT) \
@NO_READOSM_FALSE@ spatialite_tool$(EXEEXT) \
@NO_READOSM_FALSE@ spatialite_network$(EXEEXT) \
- at NO_READOSM_FALSE@ shp_doctor$(EXEEXT) exif_loader$(EXEEXT) \
+ at NO_READOSM_FALSE@ shp_doctor$(EXEEXT) shp_sanitize$(EXEEXT) \
+ at NO_READOSM_FALSE@ exif_loader$(EXEEXT) \
@NO_READOSM_FALSE@ spatialite_osm_net$(EXEEXT) \
@NO_READOSM_FALSE@ spatialite_osm_map$(EXEEXT) \
@NO_READOSM_FALSE@ spatialite_osm_raw$(EXEEXT) \
@@ -107,7 +108,8 @@ host_triplet = @host@
@NO_READOSM_TRUE at bin_PROGRAMS = spatialite$(EXEEXT) \
@NO_READOSM_TRUE@ spatialite_tool$(EXEEXT) \
@NO_READOSM_TRUE@ spatialite_network$(EXEEXT) \
- at NO_READOSM_TRUE@ shp_doctor$(EXEEXT) exif_loader$(EXEEXT) \
+ at NO_READOSM_TRUE@ shp_doctor$(EXEEXT) shp_sanitize$(EXEEXT) \
+ at NO_READOSM_TRUE@ exif_loader$(EXEEXT) \
@NO_READOSM_TRUE@ spatialite_osm_filter$(EXEEXT) \
@NO_READOSM_TRUE@ spatialite_gml$(EXEEXT) \
@NO_READOSM_TRUE@ spatialite_convert$(EXEEXT) \
@@ -147,6 +149,10 @@ am_shp_doctor_OBJECTS = shp_doctor.$(OBJEXT)
shp_doctor_OBJECTS = $(am_shp_doctor_OBJECTS)
shp_doctor_LDADD = $(LDADD)
shp_doctor_DEPENDENCIES =
+am_shp_sanitize_OBJECTS = shp_sanitize.$(OBJEXT)
+shp_sanitize_OBJECTS = $(am_shp_sanitize_OBJECTS)
+shp_sanitize_LDADD = $(LDADD)
+shp_sanitize_DEPENDENCIES =
am_spatialite_OBJECTS = shell.$(OBJEXT)
spatialite_OBJECTS = $(am_spatialite_OBJECTS)
spatialite_DEPENDENCIES =
@@ -245,7 +251,8 @@ am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(exif_loader_SOURCES) $(shp_doctor_SOURCES) \
- $(spatialite_SOURCES) spatialite_convert.c spatialite_dxf.c \
+ $(shp_sanitize_SOURCES) $(spatialite_SOURCES) \
+ spatialite_convert.c spatialite_dxf.c \
$(spatialite_gml_SOURCES) $(spatialite_network_SOURCES) \
$(spatialite_osm_filter_SOURCES) $(spatialite_osm_map_SOURCES) \
$(spatialite_osm_net_SOURCES) \
@@ -255,7 +262,8 @@ SOURCES = $(exif_loader_SOURCES) $(shp_doctor_SOURCES) \
$(spatialite_xml_load_SOURCES) $(spatialite_xml_print_SOURCES) \
$(spatialite_xml_validator_SOURCES)
DIST_SOURCES = $(exif_loader_SOURCES) $(shp_doctor_SOURCES) \
- $(spatialite_SOURCES) spatialite_convert.c spatialite_dxf.c \
+ $(shp_sanitize_SOURCES) $(spatialite_SOURCES) \
+ spatialite_convert.c spatialite_dxf.c \
$(spatialite_gml_SOURCES) $(spatialite_network_SOURCES) \
$(spatialite_osm_filter_SOURCES) \
$(am__spatialite_osm_map_SOURCES_DIST) \
@@ -454,6 +462,7 @@ spatialite_SOURCES = shell.c
spatialite_tool_SOURCES = spatialite_tool.c
spatialite_network_SOURCES = spatialite_network.c
shp_doctor_SOURCES = shp_doctor.c
+shp_sanitize_SOURCES = shp_sanitize.c
exif_loader_SOURCES = exif_loader.c
spatialite_xml_validator_SOURCES = spatialite_xml_validator.c
spatialite_xml_load_SOURCES = spatialite_xml_load.c
@@ -612,6 +621,10 @@ shp_doctor$(EXEEXT): $(shp_doctor_OBJECTS) $(shp_doctor_DEPENDENCIES) $(EXTRA_sh
@rm -f shp_doctor$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(shp_doctor_OBJECTS) $(shp_doctor_LDADD) $(LIBS)
+shp_sanitize$(EXEEXT): $(shp_sanitize_OBJECTS) $(shp_sanitize_DEPENDENCIES) $(EXTRA_shp_sanitize_DEPENDENCIES)
+ @rm -f shp_sanitize$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(shp_sanitize_OBJECTS) $(shp_sanitize_LDADD) $(LIBS)
+
spatialite$(EXEEXT): $(spatialite_OBJECTS) $(spatialite_DEPENDENCIES) $(EXTRA_spatialite_DEPENDENCIES)
@rm -f spatialite$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(spatialite_OBJECTS) $(spatialite_LDADD) $(LIBS)
@@ -681,6 +694,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/exif_loader.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shell.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shp_doctor.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shp_sanitize.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/spatialite_convert.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/spatialite_dxf.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/spatialite_gml.Po at am__quote@
diff --git a/configure b/configure
index a8835b2..825df87 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for spatialite-tools 4.4.0-RC0.
+# Generated by GNU Autoconf 2.69 for spatialite-tools 4.4.0-RC1.
#
# Report bugs to <a.furieri at lqt.it>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='spatialite-tools'
PACKAGE_TARNAME='spatialite-tools'
-PACKAGE_VERSION='4.4.0-RC0'
-PACKAGE_STRING='spatialite-tools 4.4.0-RC0'
+PACKAGE_VERSION='4.4.0-RC1'
+PACKAGE_STRING='spatialite-tools 4.4.0-RC1'
PACKAGE_BUGREPORT='a.furieri at lqt.it'
PACKAGE_URL=''
@@ -1358,7 +1358,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures spatialite-tools 4.4.0-RC0 to adapt to many kinds of systems.
+\`configure' configures spatialite-tools 4.4.0-RC1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1429,7 +1429,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of spatialite-tools 4.4.0-RC0:";;
+ short | recursive ) echo "Configuration of spatialite-tools 4.4.0-RC1:";;
esac
cat <<\_ACEOF
@@ -1566,7 +1566,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-spatialite-tools configure 4.4.0-RC0
+spatialite-tools configure 4.4.0-RC1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2156,7 +2156,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by spatialite-tools $as_me 4.4.0-RC0, which was
+It was created by spatialite-tools $as_me 4.4.0-RC1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3027,7 +3027,7 @@ fi
# Define the identity of the package.
PACKAGE='spatialite-tools'
- VERSION='4.4.0-RC0'
+ VERSION='4.4.0-RC1'
cat >>confdefs.h <<_ACEOF
@@ -18871,7 +18871,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by spatialite-tools $as_me 4.4.0-RC0, which was
+This file was extended by spatialite-tools $as_me 4.4.0-RC1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -18937,7 +18937,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-spatialite-tools config.status 4.4.0-RC0
+spatialite-tools config.status 4.4.0-RC1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 7fff3ec..ed864ac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT(spatialite-tools, 4.4.0-RC0, a.furieri at lqt.it)
+AC_INIT(spatialite-tools, 4.4.0-RC1, a.furieri at lqt.it)
AC_LANG(C)
AC_CONFIG_MACRO_DIR([m4])
diff --git a/makefile.vc b/makefile.vc
index 33c85d2..53ef751 100644
--- a/makefile.vc
+++ b/makefile.vc
@@ -7,6 +7,7 @@
SPATIALITE_EXE = spatialite.exe
EXIF_LOADER_EXE = exif_loader.exe
SHP_DOCTOR_EXE = shp_doctor.exe
+SHP_SANITIZE_EXE = shp_sanitize.exe
SPATIALITE_NETWORK_EXE = spatialite_network.exe
SPATIALITE_TOOL_EXE = spatialite_tool.exe
SPATIALITE_OSM_NET_EXE = spatialite_osm_net.exe
@@ -23,7 +24,7 @@ all: $(SPATIALITE_EXE) $(SHP_DOCTOR_EXE) $(SPATIALITE_TOOL_EXE) \
$(SPATIALITE_NETWORK_EXE) $(EXIF_LOADER_EXE) \
$(SPATIALITE_OSM_NET_EXE) $(SPATIALITE_OSM_MAP_EXE) \
$(SPATIALITE_GML_EXE) $(SPATIALITE_OSM_RAW_EXE) \
- $(SPATIALITE_OSM_FILTER_EXE)
+ $(SPATIALITE_OSM_FILTER_EXE) $(SHP_SANITIZE_EXE)
$(SPATIALITE_EXE): shell.obj
cl shell.obj C:\OSGeo4W\lib\proj_i.lib \
@@ -47,6 +48,13 @@ $(SHP_DOCTOR_EXE): shp_doctor.obj
if exist $(SHP_DOCTOR_EXE).manifest mt -manifest \
$(SHP_DOCTOR_EXE).manifest -outputresource:$(SHP_DOCTOR_EXE);1
+$(SHP_SANITIZE_EXE): shp_sanitize.obj
+ cl shp_sanitize.obj C:\OSGeo4W\lib\proj_i.lib \
+ C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \
+ C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib
+ if exist $(SHP_SANITIZE_EXE).manifest mt -manifest \
+ $(SHP_SANITIZE_EXE).manifest -outputresource:$(SHP_SANITIZE_EXE);1
+
$(SPATIALITE_NETWORK_EXE): spatialite_network.obj
cl spatialite_network.obj C:\OSGeo4W\lib\proj_i.lib \
C:\OSGeo4W\lib\iconv.lib \
diff --git a/shp_sanitize.c b/shp_sanitize.c
new file mode 100644
index 0000000..f56105f
--- /dev/null
+++ b/shp_sanitize.c
@@ -0,0 +1,4321 @@
+/*
+/ shp_sanitize
+/
+/ an analysis / sanitizing tool for broken SHAPEFILES
+/
+/ version 1.0, 2016 April 25
+/
+/ Author: Sandro Furieri a.furieri at lqt.it
+/
+/ Copyright (C) 2016 Alessandro Furieri
+/
+/ This program is free software: you can redistribute it and/or modify
+/ it under the terms of the GNU General Public License as published by
+/ the Free Software Foundation, either version 3 of the License, or
+/ (at your option) any later version.
+/
+/ This program is distributed in the hope that it will be useful,
+/ but WITHOUT ANY WARRANTY; without even the implied warranty of
+/ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+/ GNU General Public License for more details.
+/
+/ You should have received a copy of the GNU General Public License
+/ along with this program. If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+/* MSVC strictly requires this include [off_t] */
+#include <sys/types.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <sys/types.h>
+#if defined(_WIN32) && !defined(__MINGW32__)
+#include <io.h>
+#include <direct.h>
+#else
+#include <dirent.h>
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+#include "config-msvc.h"
+#else
+#include "config.h"
+#endif
+
+#ifdef SPATIALITE_AMALGAMATION
+#include <spatialite/sqlite3.h>
+#else
+#include <sqlite3.h>
+#endif
+
+#include <spatialite/gaiageo.h>
+#include <spatialite.h>
+
+#define ARG_NONE 0
+#define ARG_IN_DIR 1
+#define ARG_OUT_DIR 2
+
+#define SUFFIX_DISCARD 0
+#define SUFFIX_SHP 1
+#define SUFFIX_SHX 2
+#define SUFFIX_DBF 3
+
+#define SHAPEFILE_NO_DATA 1e-38
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+#define strcasecmp _stricmp
+#endif /* not WIN32 */
+
+struct shp_entry
+{
+/* an item of the SHP list */
+ char *base_name;
+ char *file_name;
+ int has_shp;
+ int has_shx;
+ int has_dbf;
+ struct shp_entry *next;
+};
+
+struct shp_list
+{
+/* the SHP list */
+ struct shp_entry *first;
+ struct shp_entry *last;
+};
+
+static struct shp_list *
+alloc_shp_list (void)
+{
+/* allocating an empty SHP list */
+ struct shp_list *list = malloc (sizeof (struct shp_list));
+ list->first = NULL;
+ list->last = NULL;
+ return list;
+}
+
+static void
+free_shp_list (struct shp_list *list)
+{
+/* memory cleanup: freeing an SHP list */
+ struct shp_entry *pi;
+ struct shp_entry *pin;
+ if (list == NULL)
+ return;
+
+ pi = list->first;
+ while (pi != NULL)
+ {
+ pin = pi->next;
+ if (pi->base_name != NULL)
+ sqlite3_free (pi->base_name);
+ if (pi->file_name != NULL)
+ sqlite3_free (pi->file_name);
+ free (pi);
+ pi = pin;
+ }
+ free (list);
+}
+
+static void
+do_add_shapefile (struct shp_list *list, char *base_name, char *file_name,
+ int suffix)
+{
+/* adding a possible SHP to the list */
+ struct shp_entry *pi;
+ if (list == NULL)
+ return;
+
+ pi = list->first;
+ while (pi != NULL)
+ {
+ /* searching if already defined */
+ if (strcmp (pi->base_name, base_name) == 0)
+ {
+ switch (suffix)
+ {
+ case SUFFIX_SHP:
+ pi->has_shp = 1;
+ break;
+ case SUFFIX_SHX:
+ pi->has_shx = 1;
+ break;
+ case SUFFIX_DBF:
+ pi->has_dbf = 1;
+ break;
+ };
+ sqlite3_free (base_name);
+ sqlite3_free (file_name);
+ return;
+ }
+ pi = pi->next;
+ }
+
+/* adding a new SHP entry */
+ pi = malloc (sizeof (struct shp_entry));
+ pi->base_name = base_name;
+ pi->file_name = file_name;
+ pi->has_shp = 0;
+ pi->has_shx = 0;
+ pi->has_dbf = 0;
+ pi->next = NULL;
+
+ switch (suffix)
+ {
+ case SUFFIX_SHP:
+ pi->has_shp = 1;
+ break;
+ case SUFFIX_SHX:
+ pi->has_shx = 1;
+ break;
+ case SUFFIX_DBF:
+ pi->has_dbf = 1;
+ break;
+ };
+
+ if (list->first == NULL)
+ list->first = pi;
+ if (list->last != NULL)
+ list->last->next = pi;
+ list->last = pi;
+}
+
+static int
+test_valid_shp (struct shp_entry *p)
+{
+/* testing for a valid SHP candidate */
+ if (p == NULL)
+ return 0;
+ if (p->has_shp && p->has_shx && p->has_dbf)
+ return 1;
+ return 0;
+}
+
+static gaiaShapefilePtr
+allocShapefile ()
+{
+/* allocates and initializes the Shapefile object */
+ gaiaShapefilePtr shp = malloc (sizeof (gaiaShapefile));
+ shp->endian_arch = 1;
+ shp->Path = NULL;
+ shp->Shape = -1;
+ shp->EffectiveType = GAIA_UNKNOWN;
+ shp->EffectiveDims = GAIA_XY;
+ shp->flShp = NULL;
+ shp->flShx = NULL;
+ shp->flDbf = NULL;
+ shp->Dbf = NULL;
+ shp->ShpBfsz = 0;
+ shp->BufShp = NULL;
+ shp->BufDbf = NULL;
+ shp->DbfHdsz = 0;
+ shp->DbfReclen = 0;
+ shp->DbfSize = 0;
+ shp->DbfRecno = 0;
+ shp->ShpSize = 0;
+ shp->ShxSize = 0;
+ shp->MinX = DBL_MAX;
+ shp->MinY = DBL_MAX;
+ shp->MaxX = -DBL_MAX;
+ shp->MaxY = -DBL_MAX;
+ shp->Valid = 0;
+ shp->IconvObj = NULL;
+ shp->LastError = NULL;
+ return shp;
+}
+
+static void
+freeShapefile (gaiaShapefilePtr shp)
+{
+/* frees all memory allocations related to the Shapefile object */
+ if (shp->Path)
+ free (shp->Path);
+ if (shp->flShp)
+ fclose (shp->flShp);
+ if (shp->flShx)
+ fclose (shp->flShx);
+ if (shp->flDbf)
+ fclose (shp->flDbf);
+ if (shp->Dbf)
+ gaiaFreeDbfList (shp->Dbf);
+ if (shp->BufShp)
+ free (shp->BufShp);
+ if (shp->BufDbf)
+ free (shp->BufDbf);
+ if (shp->LastError)
+ free (shp->LastError);
+ free (shp);
+}
+
+static void
+openShpRead (gaiaShapefilePtr shp, const char *path, double *MinX, double *MinY,
+ double *MaxX, double *MaxY, int *mismatching)
+{
+/* trying to open the shapefile and initial checkings */
+ FILE *fl_shx = NULL;
+ FILE *fl_shp = NULL;
+ FILE *fl_dbf = NULL;
+ char xpath[1024];
+ int rd;
+ unsigned char buf_shx[256];
+ unsigned char *buf_shp = NULL;
+ int buf_size = 1024;
+ int shape;
+ unsigned char bf[1024];
+ int dbf_size;
+ int dbf_reclen = 0;
+ int off_dbf;
+ int ind;
+ char field_name[2048];
+ char *sys_err;
+ char errMsg[1024];
+ double minx;
+ double miny;
+ double maxx;
+ double maxy;
+ int len;
+ int endian_arch = gaiaEndianArch ();
+ gaiaDbfListPtr dbf_list = NULL;
+ if (shp->flShp != NULL || shp->flShx != NULL || shp->flDbf != NULL)
+ {
+ sprintf (errMsg,
+ "attempting to reopen an already opened Shapefile\n");
+ goto unsupported_conversion;
+ }
+ sprintf (xpath, "%s.shx", path);
+ fl_shx = fopen (xpath, "rb");
+ if (!fl_shx)
+ {
+ sys_err = strerror (errno);
+ sprintf (errMsg, "unable to open '%s' for reading: %s", xpath,
+ sys_err);
+ goto no_file;
+ }
+ sprintf (xpath, "%s.shp", path);
+ fl_shp = fopen (xpath, "rb");
+ if (!fl_shp)
+ {
+ sys_err = strerror (errno);
+ sprintf (errMsg, "unable to open '%s' for reading: %s", xpath,
+ sys_err);
+ goto no_file;
+ }
+ sprintf (xpath, "%s.dbf", path);
+ fl_dbf = fopen (xpath, "rb");
+ if (!fl_dbf)
+ {
+ sys_err = strerror (errno);
+ sprintf (errMsg, "unable to open '%s' for reading: %s", xpath,
+ sys_err);
+ goto no_file;
+ }
+/* reading SHX file header */
+ rd = fread (buf_shx, sizeof (unsigned char), 100, fl_shx);
+ if (rd != 100)
+ goto error;
+ if (gaiaImport32 (buf_shx + 0, GAIA_BIG_ENDIAN, endian_arch) != 9994) /* checks the SHX magic number */
+ goto error;
+ *MinX = gaiaImport64 (buf_shx + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ *MinY = gaiaImport64 (buf_shx + 44, GAIA_LITTLE_ENDIAN, endian_arch);
+ *MaxX = gaiaImport64 (buf_shx + 52, GAIA_LITTLE_ENDIAN, endian_arch);
+ *MaxY = gaiaImport64 (buf_shx + 60, GAIA_LITTLE_ENDIAN, endian_arch);
+/* reading SHP file header */
+ buf_shp = malloc (sizeof (unsigned char) * buf_size);
+ rd = fread (buf_shp, sizeof (unsigned char), 100, fl_shp);
+ if (rd != 100)
+ goto error;
+ if (gaiaImport32 (buf_shp + 0, GAIA_BIG_ENDIAN, endian_arch) != 9994) /* checks the SHP magic number */
+ goto error;
+ minx = gaiaImport64 (buf_shp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ miny = gaiaImport64 (buf_shp + 44, GAIA_LITTLE_ENDIAN, endian_arch);
+ maxx = gaiaImport64 (buf_shp + 52, GAIA_LITTLE_ENDIAN, endian_arch);
+ maxy = gaiaImport64 (buf_shp + 60, GAIA_LITTLE_ENDIAN, endian_arch);
+ *mismatching = 0;
+ if (*MinX != minx || *MinY != miny || *MaxX != maxx || *MaxY != maxy)
+ {
+ fprintf (stderr,
+ "\t\tHEADERS: found mismatching BBOX between .shx and .shp\n");
+ *mismatching = 1;
+ }
+ shape = gaiaImport32 (buf_shp + 32, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (shape == GAIA_SHP_POINT || shape == GAIA_SHP_POINTZ
+ || shape == GAIA_SHP_POINTM || shape == GAIA_SHP_POLYLINE
+ || shape == GAIA_SHP_POLYLINEZ || shape == GAIA_SHP_POLYLINEM
+ || shape == GAIA_SHP_POLYGON || shape == GAIA_SHP_POLYGONZ
+ || shape == GAIA_SHP_POLYGONM || shape == GAIA_SHP_MULTIPOINT
+ || shape == GAIA_SHP_MULTIPOINTZ || shape == GAIA_SHP_MULTIPOINTM)
+ ;
+ else
+ goto unsupported;
+/* reading DBF file header */
+ rd = fread (bf, sizeof (unsigned char), 32, fl_dbf);
+ if (rd != 32)
+ goto error;
+ switch (*bf)
+ {
+ /* checks the DBF magic number */
+ case 0x03:
+ case 0x83:
+ break;
+ case 0x02:
+ case 0xF8:
+ sprintf (errMsg, "'%s'\ninvalid magic number %02x [FoxBASE format]",
+ path, *bf);
+ goto dbf_bad_magic;
+ case 0xF5:
+ sprintf (errMsg,
+ "'%s'\ninvalid magic number %02x [FoxPro 2.x (or earlier) format]",
+ path, *bf);
+ goto dbf_bad_magic;
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ sprintf (errMsg,
+ "'%s'\ninvalid magic number %02x [Visual FoxPro format]",
+ path, *bf);
+ goto dbf_bad_magic;
+ case 0x43:
+ case 0x63:
+ case 0xBB:
+ case 0xCB:
+ sprintf (errMsg, "'%s'\ninvalid magic number %02x [dBASE IV format]",
+ path, *bf);
+ goto dbf_bad_magic;
+ default:
+ sprintf (errMsg, "'%s'\ninvalid magic number %02x [unknown format]",
+ path, *bf);
+ goto dbf_bad_magic;
+ };
+ dbf_size = gaiaImport16 (bf + 8, GAIA_LITTLE_ENDIAN, endian_arch);
+ dbf_reclen = gaiaImport16 (bf + 10, GAIA_LITTLE_ENDIAN, endian_arch);
+ dbf_size--;
+ off_dbf = 0;
+ dbf_list = gaiaAllocDbfList ();
+ for (ind = 32; ind < dbf_size; ind += 32)
+ {
+ /* fetches DBF fields definitions */
+ rd = fread (bf, sizeof (unsigned char), 32, fl_dbf);
+ if (rd != 32)
+ goto error;
+ if (*(bf + 11) == 'M')
+ {
+ /* skipping any MEMO field */
+ memcpy (field_name, bf, 11);
+ field_name[11] = '\0';
+ off_dbf += *(bf + 16);
+ fprintf (stderr,
+ "WARNING: column \"%s\" is of the MEMO type and will be ignored\n",
+ field_name);
+ continue;
+ }
+ memcpy (field_name, bf, 11);
+ field_name[11] = '\0';
+ gaiaAddDbfField (dbf_list, field_name, *(bf + 11), off_dbf,
+ *(bf + 16), *(bf + 17));
+ off_dbf += *(bf + 16);
+ }
+ if (!gaiaIsValidDbfList (dbf_list))
+ {
+ /* invalid DBF */
+ goto illegal_dbf;
+ }
+ len = strlen (path);
+ shp->Path = malloc (len + 1);
+ strcpy (shp->Path, path);
+ shp->ReadOnly = 1;
+ shp->Shape = shape;
+ switch (shape)
+ {
+ /* setting up a prudential geometry type */
+ case GAIA_SHP_POINT:
+ case GAIA_SHP_POINTZ:
+ case GAIA_SHP_POINTM:
+ shp->EffectiveType = GAIA_POINT;
+ break;
+ case GAIA_SHP_POLYLINE:
+ case GAIA_SHP_POLYLINEZ:
+ case GAIA_SHP_POLYLINEM:
+ shp->EffectiveType = GAIA_MULTILINESTRING;
+ break;
+ case GAIA_SHP_POLYGON:
+ case GAIA_SHP_POLYGONZ:
+ case GAIA_SHP_POLYGONM:
+ shp->EffectiveType = GAIA_MULTIPOLYGON;
+ break;
+ case GAIA_SHP_MULTIPOINT:
+ case GAIA_SHP_MULTIPOINTZ:
+ case GAIA_SHP_MULTIPOINTM:
+ shp->EffectiveType = GAIA_MULTIPOINT;
+ break;
+ }
+ switch (shape)
+ {
+ /* setting up a prudential dimension model */
+ case GAIA_SHP_POINTZ:
+ case GAIA_SHP_POLYLINEZ:
+ case GAIA_SHP_POLYGONZ:
+ case GAIA_SHP_MULTIPOINTZ:
+ shp->EffectiveDims = GAIA_XY_Z_M;
+ break;
+ case GAIA_SHP_POINTM:
+ case GAIA_SHP_POLYLINEM:
+ case GAIA_SHP_POLYGONM:
+ case GAIA_SHP_MULTIPOINTM:
+ shp->EffectiveDims = GAIA_XY_M;
+ break;
+ default:
+ shp->EffectiveDims = GAIA_XY;
+ break;
+ }
+ shp->flShp = fl_shp;
+ shp->flShx = fl_shx;
+ shp->flDbf = fl_dbf;
+ shp->Dbf = dbf_list;
+/* saving the SHP buffer */
+ shp->BufShp = buf_shp;
+ shp->ShpBfsz = buf_size;
+/* allocating DBF buffer */
+ shp->BufDbf = malloc (sizeof (unsigned char) * dbf_reclen);
+ shp->DbfHdsz = dbf_size + 1;
+ shp->DbfReclen = dbf_reclen;
+ shp->Valid = 1;
+ shp->endian_arch = endian_arch;
+ return;
+ unsupported_conversion:
+/* illegal charset */
+ if (shp->LastError)
+ free (shp->LastError);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ return;
+ no_file:
+/* one of shapefile's files can't be accessed */
+ if (shp->LastError)
+ free (shp->LastError);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ if (fl_shx)
+ fclose (fl_shx);
+ if (fl_shp)
+ fclose (fl_shp);
+ if (fl_dbf)
+ fclose (fl_dbf);
+ return;
+ dbf_bad_magic:
+/* the DBF has an invalid magin number */
+ if (shp->LastError)
+ free (shp->LastError);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ gaiaFreeDbfList (dbf_list);
+ if (buf_shp)
+ free (buf_shp);
+ fclose (fl_shx);
+ fclose (fl_shp);
+ fclose (fl_dbf);
+ return;
+ error:
+/* the shapefile is invalid or corrupted */
+ if (shp->LastError)
+ free (shp->LastError);
+ sprintf (errMsg, "'%s' is corrupted / has invalid format", path);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ gaiaFreeDbfList (dbf_list);
+ if (buf_shp)
+ free (buf_shp);
+ fclose (fl_shx);
+ fclose (fl_shp);
+ fclose (fl_dbf);
+ return;
+ unsupported:
+/* the shapefile has an unrecognized shape type */
+ if (shp->LastError)
+ free (shp->LastError);
+ sprintf (errMsg, "'%s' shape=%d is not supported", path, shape);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ gaiaFreeDbfList (dbf_list);
+ if (buf_shp)
+ free (buf_shp);
+ fclose (fl_shx);
+ fclose (fl_shp);
+ if (fl_dbf)
+ fclose (fl_dbf);
+ return;
+ illegal_dbf:
+/* the DBF-file contains unsupported data types */
+ if (shp->LastError)
+ free (shp->LastError);
+ sprintf (errMsg, "'%s.dbf' contains unsupported data types", path);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ gaiaFreeDbfList (dbf_list);
+ if (buf_shp)
+ free (buf_shp);
+ fclose (fl_shx);
+ fclose (fl_shp);
+ if (fl_dbf)
+ fclose (fl_dbf);
+ return;
+}
+
+static int
+readShpEntity (gaiaShapefilePtr shp, int current_row, int *shplen, double *minx,
+ double *miny, double *maxx, double *maxy)
+{
+/* trying to read an entity from shapefile */
+ unsigned char buf[512];
+ int len;
+ int rd;
+ int skpos;
+ int offset;
+ int off_shp;
+ int sz;
+ char errMsg[1024];
+ int shape;
+ int endian_arch = gaiaEndianArch ();
+
+/* positioning and reading the SHX file */
+ offset = 100 + (current_row * 8); /* 100 bytes for the header + current row displacement; each SHX row = 8 bytes */
+ skpos = fseek (shp->flShx, offset, SEEK_SET);
+ if (skpos != 0)
+ goto eof;
+ rd = fread (buf, sizeof (unsigned char), 8, shp->flShx);
+ if (rd != 8)
+ goto eof;
+ off_shp = gaiaImport32 (buf, GAIA_BIG_ENDIAN, shp->endian_arch);
+/* positioning and reading the DBF file */
+ offset = shp->DbfHdsz + (current_row * shp->DbfReclen);
+ skpos = fseek (shp->flDbf, offset, SEEK_SET);
+ if (skpos != 0)
+ goto error;
+ rd = fread (shp->BufDbf, sizeof (unsigned char), shp->DbfReclen,
+ shp->flDbf);
+ if (rd != shp->DbfReclen)
+ goto error;
+ if (*(shp->BufDbf) == '*')
+ goto dbf_deleted;
+/* positioning and reading corresponding SHP entity - geometry */
+ offset = off_shp * 2;
+ skpos = fseek (shp->flShp, offset, SEEK_SET);
+ if (skpos != 0)
+ goto error;
+ rd = fread (buf, sizeof (unsigned char), 8, shp->flShp);
+ if (rd != 8)
+ goto error;
+ sz = gaiaImport32 (buf + 4, GAIA_BIG_ENDIAN, shp->endian_arch);
+ if ((sz * 2) > shp->ShpBfsz)
+ {
+ /* current buffer is too small; we need to allocate a bigger buffer */
+ free (shp->BufShp);
+ shp->ShpBfsz = sz * 2;
+ shp->BufShp = malloc (sizeof (unsigned char) * shp->ShpBfsz);
+ }
+ /* reading the raw Geometry */
+ rd = fread (shp->BufShp, sizeof (unsigned char), sz * 2, shp->flShp);
+ if (rd != sz * 2)
+ goto error;
+ *shplen = rd;
+
+/* retrieving the feature's BBOX */
+ shape = gaiaImport32 (shp->BufShp + 0, GAIA_LITTLE_ENDIAN, endian_arch);
+ *minx = DBL_MAX;
+ *miny = DBL_MAX;
+ *maxx = DBL_MAX;
+ *maxy = DBL_MAX;
+ if (shape == GAIA_SHP_POINT || shape == GAIA_SHP_POINTZ
+ || shape == GAIA_SHP_POINTM)
+ {
+ *minx =
+ gaiaImport64 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN, endian_arch);
+ *maxx = *minx;
+ *miny =
+ gaiaImport64 (shp->BufShp + 12, GAIA_LITTLE_ENDIAN, endian_arch);
+ *maxy = *miny;
+ }
+ if (shape == GAIA_SHP_POLYLINE || shape == GAIA_SHP_POLYLINEZ
+ || shape == GAIA_SHP_POLYLINEM || shape == GAIA_SHP_POLYGON
+ || shape == GAIA_SHP_POLYGONZ || shape == GAIA_SHP_POLYGONM
+ || shape == GAIA_SHP_MULTIPOINT || shape == GAIA_SHP_MULTIPOINTZ
+ || shape == GAIA_SHP_MULTIPOINTM)
+ {
+ *minx =
+ gaiaImport64 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN, endian_arch);
+ *miny =
+ gaiaImport64 (shp->BufShp + 12, GAIA_LITTLE_ENDIAN, endian_arch);
+ *maxx =
+ gaiaImport64 (shp->BufShp + 20, GAIA_LITTLE_ENDIAN, endian_arch);
+ *maxy =
+ gaiaImport64 (shp->BufShp + 28, GAIA_LITTLE_ENDIAN, endian_arch);
+ }
+ return 1;
+
+ eof:
+ if (shp->LastError)
+ free (shp->LastError);
+ shp->LastError = NULL;
+ return 0;
+ error:
+ if (shp->LastError)
+ free (shp->LastError);
+ sprintf (errMsg, "'%s' is corrupted / has invalid format", shp->Path);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ return 0;
+ dbf_deleted:
+ if (shp->LastError)
+ free (shp->LastError);
+ shp->LastError = NULL;
+ return -1;
+}
+
+struct shp_ring_item
+{
+/* a RING item [to be reassembled into a (Multi)Polygon] */
+ gaiaRingPtr Ring;
+ int IsExterior;
+ gaiaRingPtr Mother;
+ struct shp_ring_item *Next;
+};
+
+struct shp_ring_collection
+{
+/* a collection of RING items */
+ struct shp_ring_item *First;
+ struct shp_ring_item *Last;
+};
+
+static void
+shp_free_rings (struct shp_ring_collection *ringsColl)
+{
+/* memory cleanup: rings collection */
+ struct shp_ring_item *p;
+ struct shp_ring_item *pN;
+ p = ringsColl->First;
+ while (p)
+ {
+ pN = p->Next;
+ if (p->Ring)
+ gaiaFreeRing (p->Ring);
+ free (p);
+ p = pN;
+ }
+}
+
+static void
+shp_add_ring (struct shp_ring_collection *ringsColl, gaiaRingPtr ring)
+{
+/* inserting a ring into the rings collection */
+ struct shp_ring_item *p = malloc (sizeof (struct shp_ring_item));
+ p->Ring = ring;
+ gaiaMbrRing (ring);
+ gaiaClockwise (ring);
+/* accordingly to SHP rules interior/exterior depends on direction */
+ p->IsExterior = ring->Clockwise;
+ p->Mother = NULL;
+ p->Next = NULL;
+/* updating the linked list */
+ if (ringsColl->First == NULL)
+ ringsColl->First = p;
+ if (ringsColl->Last != NULL)
+ ringsColl->Last->Next = p;
+ ringsColl->Last = p;
+}
+
+static int
+shp_check_rings (gaiaRingPtr exterior, gaiaRingPtr candidate)
+{
+/*
+/ speditively checks if the candidate could be an interior Ring
+/ contained into the exterior Ring
+*/
+ double z;
+ double m;
+ double x0;
+ double y0;
+ double x1;
+ double y1;
+ int mid;
+ int ret0;
+ int ret1;
+ if (candidate->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (candidate->Coords, 0, &x0, &y0, &z);
+ }
+ else if (candidate->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (candidate->Coords, 0, &x0, &y0, &m);
+ }
+ else if (candidate->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (candidate->Coords, 0, &x0, &y0, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (candidate->Coords, 0, &x0, &y0);
+ }
+ mid = candidate->Points / 2;
+ if (candidate->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (candidate->Coords, mid, &x1, &y1, &z);
+ }
+ else if (candidate->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (candidate->Coords, mid, &x1, &y1, &m);
+ }
+ else if (candidate->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (candidate->Coords, mid, &x1, &y1, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (candidate->Coords, mid, &x1, &y1);
+ }
+
+/* testing if the first point falls on the exterior ring surface */
+ ret0 = gaiaIsPointOnRingSurface (exterior, x0, y0);
+/* testing if the second point falls on the exterior ring surface */
+ ret1 = gaiaIsPointOnRingSurface (exterior, x1, y1);
+ if (ret0 || ret1)
+ return 1;
+ return 0;
+}
+
+static int
+shp_mbr_contains (gaiaRingPtr r1, gaiaRingPtr r2)
+{
+/* checks if the first Ring contains the second one - MBR based */
+ int ok_1 = 0;
+ int ok_2 = 0;
+ int ok_3 = 0;
+ int ok_4 = 0;
+ if (r2->MinX >= r1->MinX && r2->MinX <= r1->MaxX)
+ ok_1 = 1;
+ if (r2->MaxX >= r1->MinX && r2->MaxX <= r1->MaxX)
+ ok_2 = 1;
+ if (r2->MinY >= r1->MinY && r2->MinY <= r1->MaxY)
+ ok_3 = 1;
+ if (r2->MaxY >= r1->MinY && r2->MaxY <= r1->MaxY)
+ ok_4 = 1;
+ if (ok_1 && ok_2 && ok_3 && ok_4)
+ return 1;
+ return 0;
+}
+
+static void
+shp_arrange_rings (struct shp_ring_collection *ringsColl)
+{
+/*
+/ arranging Rings so to associate any interior ring
+/ to the containing exterior ring
+*/
+ struct shp_ring_item *pInt;
+ struct shp_ring_item *pExt;
+ pExt = ringsColl->First;
+ while (pExt != NULL)
+ {
+ /* looping on Exterior Rings */
+ if (pExt->IsExterior)
+ {
+ pInt = ringsColl->First;
+ while (pInt != NULL)
+ {
+ /* looping on Interior Rings */
+ if (pInt->IsExterior == 0 && pInt->Mother == NULL
+ && shp_mbr_contains (pExt->Ring, pInt->Ring))
+ {
+ /* ok, matches */
+ if (shp_check_rings (pExt->Ring, pInt->Ring))
+ pInt->Mother = pExt->Ring;
+ }
+ pInt = pInt->Next;
+ }
+ }
+ pExt = pExt->Next;
+ }
+ pExt = ringsColl->First;
+ while (pExt != NULL)
+ {
+ if (pExt->IsExterior == 0 && pExt->Mother == NULL)
+ {
+ /* orphan ring: promoting to Exterior */
+ pExt->IsExterior = 1;
+ }
+ pExt = pExt->Next;
+ }
+}
+
+static void
+shp_build_area (struct shp_ring_collection *ringsColl, gaiaGeomCollPtr geom)
+{
+/* building the final (Multi)Polygon Geometry */
+ gaiaPolygonPtr polyg;
+ struct shp_ring_item *pExt;
+ struct shp_ring_item *pInt;
+ pExt = ringsColl->First;
+ while (pExt != NULL)
+ {
+ if (pExt->IsExterior)
+ {
+ /* creating a new Polygon */
+ polyg = gaiaInsertPolygonInGeomColl (geom, pExt->Ring);
+ pInt = ringsColl->First;
+ while (pInt != NULL)
+ {
+ if (pExt->Ring == pInt->Mother)
+ {
+ /* adding an interior ring to current POLYGON */
+ gaiaAddRingToPolyg (polyg, pInt->Ring);
+ /* releasing Ring ownership */
+ pInt->Ring = NULL;
+ }
+ pInt = pInt->Next;
+ }
+ /* releasing Ring ownership */
+ pExt->Ring = NULL;
+ }
+ pExt = pExt->Next;
+ }
+}
+
+static gaiaGeomCollPtr
+do_parse_geometry (const unsigned char *bufshp, int buflen, int eff_dims,
+ int eff_type, int *nullshape)
+{
+/* attempting to parse a Geometry from the SHP */
+ gaiaGeomCollPtr geom = NULL;
+ int shape;
+ double x;
+ double y;
+ double z;
+ double m;
+ int points;
+ int n;
+ int n1;
+ int base;
+ int baseZ;
+ int baseM;
+ int start;
+ int end;
+ int iv;
+ int ind;
+ int max_size;
+ int min_size;
+ int hasM;
+ int sz;
+ gaiaLinestringPtr line = NULL;
+ gaiaRingPtr ring = NULL;
+ int endian_arch = gaiaEndianArch ();
+ struct shp_ring_collection ringsColl;
+/* initializing the RING collection */
+ ringsColl.First = NULL;
+ ringsColl.Last = NULL;
+
+ shape = gaiaImport32 (bufshp + 0, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (shape == GAIA_SHP_NULL)
+ {
+ *nullshape = 1;
+ return NULL;
+ }
+ *nullshape = 0;
+
+ if (shape == GAIA_SHP_POINT)
+ {
+ /* shape point */
+ x = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (eff_dims == GAIA_XY_Z)
+ {
+ geom = gaiaAllocGeomCollXYZ ();
+ gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ geom = gaiaAllocGeomCollXYM ();
+ gaiaAddPointToGeomCollXYM (geom, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ geom = gaiaAllocGeomCollXYZM ();
+ gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, 0.0);
+ }
+ else
+ {
+ geom = gaiaAllocGeomColl ();
+ gaiaAddPointToGeomColl (geom, x, y);
+ }
+ geom->DeclaredType = GAIA_POINT;
+ }
+ if (shape == GAIA_SHP_POINTZ)
+ {
+ /* shape point Z */
+ x = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch);
+ z = gaiaImport64 (bufshp + 20, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (buflen == 28)
+ m = 0.0;
+ else
+ m = gaiaImport64 (bufshp + 28, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (eff_dims == GAIA_XY_Z)
+ {
+ geom = gaiaAllocGeomCollXYZ ();
+ gaiaAddPointToGeomCollXYZ (geom, x, y, z);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ geom = gaiaAllocGeomCollXYM ();
+ gaiaAddPointToGeomCollXYM (geom, x, y, m);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ geom = gaiaAllocGeomCollXYZM ();
+ gaiaAddPointToGeomCollXYZM (geom, x, y, z, m);
+ }
+ else
+ {
+ geom = gaiaAllocGeomColl ();
+ gaiaAddPointToGeomColl (geom, x, y);
+ }
+ geom->DeclaredType = GAIA_POINT;
+ }
+ if (shape == GAIA_SHP_POINTM)
+ {
+ /* shape point M */
+ x = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch);
+ m = gaiaImport64 (bufshp + 20, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (eff_dims == GAIA_XY_Z)
+ {
+ geom = gaiaAllocGeomCollXYZ ();
+ gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ geom = gaiaAllocGeomCollXYM ();
+ gaiaAddPointToGeomCollXYM (geom, x, y, m);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ geom = gaiaAllocGeomCollXYZM ();
+ gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, m);
+ }
+ else
+ {
+ geom = gaiaAllocGeomColl ();
+ gaiaAddPointToGeomColl (geom, x, y);
+ }
+ geom->DeclaredType = GAIA_POINT;
+ }
+ if (shape == GAIA_SHP_POLYLINE)
+ {
+ /* shape polyline */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch);
+ base = 44 + (n * 4);
+ start = 0;
+ for (ind = 0; ind < n; ind++)
+ {
+ if (ind < (n - 1))
+ end =
+ gaiaImport32 (bufshp + 44 + ((ind + 1) * 4),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ end = n1;
+ points = end - start;
+ if (eff_dims == GAIA_XY_Z)
+ line = gaiaAllocLinestringXYZ (points);
+ else if (eff_dims == GAIA_XY_M)
+ line = gaiaAllocLinestringXYM (points);
+ else if (eff_dims == GAIA_XY_Z_M)
+ line = gaiaAllocLinestringXYZM (points);
+ else
+ line = gaiaAllocLinestring (points);
+ points = 0;
+ for (iv = start; iv < end; iv++)
+ {
+ x = gaiaImport64 (bufshp + base + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + base + (iv * 16) +
+ 8, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (eff_dims == GAIA_XY_Z)
+ {
+ gaiaSetPointXYZ (line->Coords, points, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ gaiaSetPointXYM (line->Coords, points, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ gaiaSetPointXYZM (line->Coords, points, x, y,
+ 0.0, 0.0);
+ }
+ else
+ {
+ gaiaSetPoint (line->Coords, points, x, y);
+ }
+ start++;
+ points++;
+ }
+ if (!geom)
+ {
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ if (eff_type == GAIA_LINESTRING)
+ geom->DeclaredType = GAIA_LINESTRING;
+ else
+ geom->DeclaredType = GAIA_MULTILINESTRING;
+ }
+ gaiaInsertLinestringInGeomColl (geom, line);
+ }
+ }
+ if (shape == GAIA_SHP_POLYLINEZ)
+ {
+ /* shape polyline Z */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch);
+ hasM = 0;
+ max_size = 38 + (2 * n) + (n1 * 16); /* size [in 16 bits words !!!] ZM */
+ min_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] Z-only */
+ sz = buflen / 2;
+ if (sz < min_size)
+ goto error;
+ if (sz == max_size)
+ hasM = 1;
+ base = 44 + (n * 4);
+ baseZ = base + (n1 * 16) + 16;
+ baseM = baseZ + (n1 * 8) + 16;
+ start = 0;
+ for (ind = 0; ind < n; ind++)
+ {
+ if (ind < (n - 1))
+ end =
+ gaiaImport32 (bufshp + 44 + ((ind + 1) * 4),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ end = n1;
+ points = end - start;
+ if (eff_dims == GAIA_XY_Z)
+ line = gaiaAllocLinestringXYZ (points);
+ else if (eff_dims == GAIA_XY_M)
+ line = gaiaAllocLinestringXYM (points);
+ else if (eff_dims == GAIA_XY_Z_M)
+ line = gaiaAllocLinestringXYZM (points);
+ else
+ line = gaiaAllocLinestring (points);
+ points = 0;
+ for (iv = start; iv < end; iv++)
+ {
+ x = gaiaImport64 (bufshp + base + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + base + (iv * 16) +
+ 8, GAIA_LITTLE_ENDIAN, endian_arch);
+ z = gaiaImport64 (bufshp + baseZ + (iv * 8),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ if (hasM)
+ m = gaiaImport64 (bufshp + baseM +
+ (iv * 8), GAIA_LITTLE_ENDIAN,
+ endian_arch);
+ else
+ m = 0.0;
+ if (m < SHAPEFILE_NO_DATA)
+ m = 0.0;
+ if (eff_dims == GAIA_XY_Z)
+ {
+ gaiaSetPointXYZ (line->Coords, points, x, y, z);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ gaiaSetPointXYM (line->Coords, points, x, y, m);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ gaiaSetPointXYZM (line->Coords, points, x, y, z, m);
+ }
+ else
+ {
+ gaiaSetPoint (line->Coords, points, x, y);
+ }
+ start++;
+ points++;
+ }
+ if (!geom)
+ {
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ if (eff_type == GAIA_LINESTRING)
+ geom->DeclaredType = GAIA_LINESTRING;
+ else
+ geom->DeclaredType = GAIA_MULTILINESTRING;
+ }
+ gaiaInsertLinestringInGeomColl (geom, line);
+ }
+ }
+ if (shape == GAIA_SHP_POLYLINEM)
+ {
+ /* shape polyline M */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch);
+ hasM = 0;
+ max_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] M */
+ min_size = 22 + (2 * n) + (n1 * 8); /* size [in 16 bits words !!!] no-M */
+ sz = buflen / 2;
+ if (sz < min_size)
+ goto error;
+ if (sz == max_size)
+ hasM = 1;
+ base = 44 + (n * 4);
+ baseM = base + (n1 * 16) + 16;
+ start = 0;
+ for (ind = 0; ind < n; ind++)
+ {
+ if (ind < (n - 1))
+ end =
+ gaiaImport32 (bufshp + 44 + ((ind + 1) * 4),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ end = n1;
+ points = end - start;
+ if (eff_dims == GAIA_XY_Z)
+ line = gaiaAllocLinestringXYZ (points);
+ else if (eff_dims == GAIA_XY_M)
+ line = gaiaAllocLinestringXYM (points);
+ else if (eff_dims == GAIA_XY_Z_M)
+ line = gaiaAllocLinestringXYZM (points);
+ else
+ line = gaiaAllocLinestring (points);
+ points = 0;
+ for (iv = start; iv < end; iv++)
+ {
+ x = gaiaImport64 (bufshp + base + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + base + (iv * 16) +
+ 8, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (hasM)
+ m = gaiaImport64 (bufshp + baseM +
+ (iv * 8), GAIA_LITTLE_ENDIAN,
+ endian_arch);
+ else
+ m = 0.0;
+ if (m < SHAPEFILE_NO_DATA)
+ m = 0.0;
+ if (eff_dims == GAIA_XY_Z)
+ {
+ gaiaSetPointXYZ (line->Coords, points, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ gaiaSetPointXYM (line->Coords, points, x, y, m);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ gaiaSetPointXYZM (line->Coords, points, x, y,
+ 0.0, m);
+ }
+ else
+ {
+ gaiaSetPoint (line->Coords, points, x, y);
+ }
+ start++;
+ points++;
+ }
+ if (!geom)
+ {
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ if (eff_type == GAIA_LINESTRING)
+ geom->DeclaredType = GAIA_LINESTRING;
+ else
+ geom->DeclaredType = GAIA_MULTILINESTRING;
+ }
+ gaiaInsertLinestringInGeomColl (geom, line);
+ }
+ }
+ if (shape == GAIA_SHP_POLYGON)
+ {
+ /* shape polygon */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch);
+ base = 44 + (n * 4);
+ start = 0;
+ for (ind = 0; ind < n; ind++)
+ {
+ if (ind < (n - 1))
+ end =
+ gaiaImport32 (bufshp + 44 + ((ind + 1) * 4),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ end = n1;
+ points = end - start;
+ if (eff_dims == GAIA_XY_Z)
+ ring = gaiaAllocRingXYZ (points);
+ else if (eff_dims == GAIA_XY_M)
+ ring = gaiaAllocRingXYM (points);
+ else if (eff_dims == GAIA_XY_Z_M)
+ ring = gaiaAllocRingXYZM (points);
+ else
+ ring = gaiaAllocRing (points);
+ points = 0;
+ for (iv = start; iv < end; iv++)
+ {
+ x = gaiaImport64 (bufshp + base + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + base + (iv * 16) +
+ 8, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (eff_dims == GAIA_XY_Z)
+ {
+ gaiaSetPointXYZ (ring->Coords, points, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ gaiaSetPointXYM (ring->Coords, points, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ gaiaSetPointXYZM (ring->Coords, points, x, y,
+ 0.0, 0.0);
+ }
+ else
+ {
+ gaiaSetPoint (ring->Coords, points, x, y);
+ }
+ start++;
+ points++;
+ }
+ shp_add_ring (&ringsColl, ring);
+ }
+ shp_arrange_rings (&ringsColl);
+ /* allocating the final geometry */
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ if (eff_type == GAIA_POLYGON)
+ geom->DeclaredType = GAIA_POLYGON;
+ else
+ geom->DeclaredType = GAIA_MULTIPOLYGON;
+ shp_build_area (&ringsColl, geom);
+ }
+ if (shape == GAIA_SHP_POLYGONZ)
+ {
+ /* shape polygon Z */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch);
+ hasM = 0;
+ max_size = 38 + (2 * n) + (n1 * 16); /* size [in 16 bits words !!!] ZM */
+ min_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] Z-only */
+ sz = buflen / 2;
+ if (sz < min_size)
+ goto error;
+ if (sz == max_size)
+ hasM = 1;
+ base = 44 + (n * 4);
+ baseZ = base + (n1 * 16) + 16;
+ baseM = baseZ + (n1 * 8) + 16;
+ start = 0;
+ for (ind = 0; ind < n; ind++)
+ {
+ if (ind < (n - 1))
+ end =
+ gaiaImport32 (bufshp + 44 + ((ind + 1) * 4),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ end = n1;
+ points = end - start;
+ if (eff_dims == GAIA_XY_Z)
+ ring = gaiaAllocRingXYZ (points);
+ else if (eff_dims == GAIA_XY_M)
+ ring = gaiaAllocRingXYM (points);
+ else if (eff_dims == GAIA_XY_Z_M)
+ ring = gaiaAllocRingXYZM (points);
+ else
+ ring = gaiaAllocRing (points);
+ points = 0;
+ for (iv = start; iv < end; iv++)
+ {
+ x = gaiaImport64 (bufshp + base + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + base + (iv * 16) +
+ 8, GAIA_LITTLE_ENDIAN, endian_arch);
+ z = gaiaImport64 (bufshp + baseZ + (iv * 8),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ if (hasM)
+ m = gaiaImport64 (bufshp + baseM +
+ (iv * 8), GAIA_LITTLE_ENDIAN,
+ endian_arch);
+ else
+ m = 0.0;
+ if (m < SHAPEFILE_NO_DATA)
+ m = 0.0;
+ if (eff_dims == GAIA_XY_Z)
+ {
+ gaiaSetPointXYZ (ring->Coords, points, x, y, z);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ gaiaSetPointXYM (ring->Coords, points, x, y, m);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ gaiaSetPointXYZM (ring->Coords, points, x, y, z, m);
+ }
+ else
+ {
+ gaiaSetPoint (ring->Coords, points, x, y);
+ }
+ start++;
+ points++;
+ }
+ shp_add_ring (&ringsColl, ring);
+ }
+ shp_arrange_rings (&ringsColl);
+ /* allocating the final geometry */
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ if (eff_type == GAIA_POLYGON)
+ geom->DeclaredType = GAIA_POLYGON;
+ else
+ geom->DeclaredType = GAIA_MULTIPOLYGON;
+ shp_build_area (&ringsColl, geom);
+ }
+ if (shape == GAIA_SHP_POLYGONM)
+ {
+ /* shape polygon M */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch);
+ hasM = 0;
+ max_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] M */
+ min_size = 22 + (2 * n) + (n1 * 8); /* size [in 16 bits words !!!] no-M */
+ sz = buflen / 2;
+ if (sz < min_size)
+ goto error;
+ if (sz == max_size)
+ hasM = 1;
+ base = 44 + (n * 4);
+ baseM = base + (n1 * 16) + 16;
+ start = 0;
+ for (ind = 0; ind < n; ind++)
+ {
+ if (ind < (n - 1))
+ end =
+ gaiaImport32 (bufshp + 44 + ((ind + 1) * 4),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ end = n1;
+ points = end - start;
+ if (eff_dims == GAIA_XY_Z)
+ ring = gaiaAllocRingXYZ (points);
+ else if (eff_dims == GAIA_XY_M)
+ ring = gaiaAllocRingXYM (points);
+ else if (eff_dims == GAIA_XY_Z_M)
+ ring = gaiaAllocRingXYZM (points);
+ else
+ ring = gaiaAllocRing (points);
+ points = 0;
+ for (iv = start; iv < end; iv++)
+ {
+ x = gaiaImport64 (bufshp + base + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + base + (iv * 16) +
+ 8, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (hasM)
+ m = gaiaImport64 (bufshp + baseM +
+ (iv * 8), GAIA_LITTLE_ENDIAN,
+ endian_arch);
+ m = 0.0;
+ if (m < SHAPEFILE_NO_DATA)
+ m = 0.0;
+ if (eff_dims == GAIA_XY_Z)
+ {
+ gaiaSetPointXYZ (ring->Coords, points, x, y, 0.0);
+ }
+ else if (eff_dims == GAIA_XY_M)
+ {
+ gaiaSetPointXYM (ring->Coords, points, x, y, m);
+ }
+ else if (eff_dims == GAIA_XY_Z_M)
+ {
+ gaiaSetPointXYZM (ring->Coords, points, x, y,
+ 0.0, m);
+ }
+ else
+ {
+ gaiaSetPoint (ring->Coords, points, x, y);
+ }
+ start++;
+ points++;
+ }
+ shp_add_ring (&ringsColl, ring);
+ }
+ shp_arrange_rings (&ringsColl);
+ /* allocating the final geometry */
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ if (eff_type == GAIA_POLYGON)
+ geom->DeclaredType = GAIA_POLYGON;
+ else
+ geom->DeclaredType = GAIA_MULTIPOLYGON;
+ shp_build_area (&ringsColl, geom);
+ }
+ if (shape == GAIA_SHP_MULTIPOINT)
+ {
+ /* shape multipoint */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ geom->DeclaredType = GAIA_MULTIPOINT;
+ for (iv = 0; iv < n; iv++)
+ {
+ x = gaiaImport64 (bufshp + 40 + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + 40 + (iv * 16) + 8,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ if (eff_dims == GAIA_XY_Z)
+ gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
+ else if (eff_dims == GAIA_XY_M)
+ gaiaAddPointToGeomCollXYM (geom, x, y, 0.0);
+ else if (eff_dims == GAIA_XY_Z_M)
+ gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, 0.0);
+ else
+ gaiaAddPointToGeomColl (geom, x, y);
+ }
+ }
+ if (shape == GAIA_SHP_MULTIPOINTZ)
+ {
+ /* shape multipoint Z */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ hasM = 0;
+ max_size = 36 + (n * 16); /* size [in 16 bits words !!!] ZM */
+ min_size = 28 + (n * 12); /* size [in 16 bits words !!!] Z-only */
+ sz = buflen / 2;
+ if (sz < min_size)
+ goto error;
+ if (sz == max_size)
+ hasM = 1;
+ baseZ = 40 + (n * 16) + 16;
+ baseM = baseZ + (n * 8) + 16;
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ geom->DeclaredType = GAIA_MULTIPOINT;
+ for (iv = 0; iv < n; iv++)
+ {
+ x = gaiaImport64 (bufshp + 40 + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + 40 + (iv * 16) + 8,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ z = gaiaImport64 (bufshp + baseZ + (iv * 8),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ if (hasM)
+ m = gaiaImport64 (bufshp + baseM + (iv * 8),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ m = 0.0;
+ if (m < SHAPEFILE_NO_DATA)
+ m = 0.0;
+ if (eff_dims == GAIA_XY_Z)
+ gaiaAddPointToGeomCollXYZ (geom, x, y, z);
+ else if (eff_dims == GAIA_XY_M)
+ gaiaAddPointToGeomCollXYM (geom, x, y, m);
+ else if (eff_dims == GAIA_XY_Z_M)
+ gaiaAddPointToGeomCollXYZM (geom, x, y, z, m);
+ else
+ gaiaAddPointToGeomColl (geom, x, y);
+ }
+ }
+ if (shape == GAIA_SHP_MULTIPOINTM)
+ {
+ /* shape multipoint M */
+ n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
+ hasM = 0;
+ max_size = 28 + (n * 12); /* size [in 16 bits words !!!] M */
+ min_size = 20 + (n * 8); /* size [in 16 bits words !!!] no-M */
+ sz = buflen / 2;
+ if (sz < min_size)
+ goto error;
+ if (sz == max_size)
+ hasM = 1;
+ baseM = 40 + (n * 16) + 16;
+ if (eff_dims == GAIA_XY_Z)
+ geom = gaiaAllocGeomCollXYZ ();
+ else if (eff_dims == GAIA_XY_M)
+ geom = gaiaAllocGeomCollXYM ();
+ else if (eff_dims == GAIA_XY_Z_M)
+ geom = gaiaAllocGeomCollXYZM ();
+ else
+ geom = gaiaAllocGeomColl ();
+ geom->DeclaredType = GAIA_MULTIPOINT;
+ for (iv = 0; iv < n; iv++)
+ {
+ x = gaiaImport64 (bufshp + 40 + (iv * 16),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ y = gaiaImport64 (bufshp + 40 + (iv * 16) + 8,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ if (hasM)
+ m = gaiaImport64 (bufshp + baseM + (iv * 8),
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ else
+ m = 0.0;
+ if (m < SHAPEFILE_NO_DATA)
+ m = 0.0;
+ if (eff_dims == GAIA_XY_Z)
+ gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
+ else if (eff_dims == GAIA_XY_M)
+ gaiaAddPointToGeomCollXYM (geom, x, y, m);
+ else if (eff_dims == GAIA_XY_Z_M)
+ gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, m);
+ else
+ gaiaAddPointToGeomColl (geom, x, y);
+ }
+ }
+
+ if (geom != NULL)
+ gaiaMbrGeometry (geom);
+ shp_free_rings (&ringsColl);
+ return geom;
+
+ error:
+ fprintf (stderr, "\tcorrupted shapefile / invalid format");
+ shp_free_rings (&ringsColl);
+ return NULL;
+}
+
+static int
+do_read_shp (const void *cache, const char *shp_path, int validate, int esri,
+ int *invalid)
+{
+/* reading some Shapefile and testing for validity */
+ int current_row;
+ gaiaShapefilePtr shp = NULL;
+ int ret;
+ double minx;
+ double miny;
+ double maxx;
+ double maxy;
+ double MinX = DBL_MAX;
+ double MinY = DBL_MAX;
+ double MaxX = 0.0 - DBL_MAX;
+ double MaxY = 0.0 - DBL_MAX;
+ double hMinX;
+ double hMinY;
+ double hMaxX;
+ double hMaxY;
+ int mismatching;
+
+ *invalid = 0;
+ shp = allocShapefile ();
+ openShpRead (shp, shp_path, &hMinX, &hMinY, &hMaxX, &hMaxY, &mismatching);
+ if (!(shp->Valid))
+ {
+ char extra[512];
+ *extra = '\0';
+ if (shp->LastError)
+ sprintf (extra, "\n\tcause: %s\n", shp->LastError);
+ fprintf (stderr,
+ "\terror: cannot open shapefile '%s'%s", shp_path, extra);
+ freeShapefile (shp);
+ return 0;
+ }
+ if (mismatching)
+ *invalid += 1;
+
+ current_row = 0;
+ while (1)
+ {
+ /* reading rows from shapefile */
+ int shplen;
+ ret =
+ readShpEntity (shp, current_row, &shplen, &minx, &miny, &maxx,
+ &maxy);
+ if (ret < 0)
+ {
+ /* found a DBF deleted record */
+ fprintf (stderr, "\t\trow #%d: logical deletion found\n",
+ current_row);
+ current_row++;
+ *invalid += 1;
+ continue;
+ }
+ if (!ret)
+ {
+ if (!(shp->LastError)) /* normal SHP EOF */
+ break;
+ fprintf (stderr, "\tERROR: %s\n", shp->LastError);
+ goto stop;
+ }
+
+ if (validate)
+ {
+ int nullshape;
+ gaiaGeomCollPtr geom =
+ do_parse_geometry (shp->BufShp, shplen, shp->EffectiveDims,
+ shp->EffectiveType, &nullshape);
+ if (nullshape)
+ ;
+ else
+ {
+ if (geom == NULL)
+ {
+ fprintf (stderr,
+ "\t\trow #%d: unable to get a Geometry\n",
+ current_row);
+ *invalid += 1;
+ }
+ else
+ {
+ if (geom->MinX != minx || geom->MinY != miny
+ || geom->MaxX != maxx || geom->MaxY != maxy)
+ {
+ fprintf (stderr,
+ "\t\trow #%d: mismatching BBOX\n",
+ current_row);
+ *invalid += 1;
+ }
+ if (esri)
+ {
+ /* checking invalid geometries in ESRI mode */
+ gaiaGeomCollPtr detail;
+ detail =
+ gaiaIsValidDetailEx_r (cache, geom, 1);
+ if (detail == NULL)
+ {
+ /* extra checks */
+ int extra = 0;
+ if (gaiaIsToxic_r (cache, geom))
+ extra = 1;
+ if (gaiaIsNotClosedGeomColl_r
+ (cache, geom))
+ extra = 1;
+ if (extra)
+ {
+ char *reason =
+ gaiaIsValidReason_r (cache,
+ geom);
+ if (reason == NULL)
+ fprintf (stderr,
+ "\t\trow #%d: invalid Geometry (unknown reason)\n",
+ current_row);
+ else
+ {
+ fprintf (stderr,
+ "\t\trow #%d: %s\n",
+ current_row,
+ reason);
+ free (reason);
+ }
+ *invalid += 1;
+ }
+ }
+ else
+ {
+ char *reason =
+ gaiaIsValidReason_r (cache, geom);
+ if (reason == NULL)
+ fprintf (stderr,
+ "\t\trow #%d: invalid Geometry (unknown reason)\n",
+ current_row);
+ else
+ {
+ fprintf (stderr,
+ "\t\trow #%d: %s\n",
+ current_row, reason);
+ free (reason);
+ }
+ *invalid += 1;
+ gaiaFreeGeomColl (detail);
+ }
+ }
+ else
+ {
+ /* checking invalid geometries in ISO/OGC mode */
+ if (gaiaIsValid_r (cache, geom) != 1)
+ {
+ char *reason =
+ gaiaIsValidReason_r (cache, geom);
+ if (reason == NULL)
+ fprintf (stderr,
+ "\t\trow #%d: invalid Geometry (unknown reason)\n",
+ current_row);
+ else
+ {
+ fprintf (stderr,
+ "\t\trow #%d: %s\n",
+ current_row, reason);
+ free (reason);
+ }
+ *invalid += 1;
+ }
+ }
+ gaiaFreeGeomColl (geom);
+ }
+ }
+ }
+ if (minx != DBL_MAX && miny != DBL_MAX && maxx != DBL_MAX
+ && maxy != DBL_MAX)
+ {
+ if (minx < MinX)
+ MinX = minx;
+ if (miny < MinY)
+ MinY = miny;
+ if (maxx > MaxX)
+ MaxX = maxx;
+ if (maxy > MaxY)
+ MaxY = maxy;
+ }
+ current_row++;
+ }
+ freeShapefile (shp);
+
+ if (MinX != hMinX || MinY != hMinY || MaxX != hMaxX || MaxY != hMaxY)
+ {
+ fprintf (stderr, "\t\tHEADERS: found invalid BBOX\n");
+ *invalid += 1;
+ }
+
+ return 1;
+
+ stop:
+ freeShapefile (shp);
+ fprintf (stderr, "\tMalformed shapefile: quitting\n");
+ return 0;
+}
+
+static void
+do_clen_files (const char *out_path, const char *name)
+{
+/* removing an invalid Shapefile (not properly repaired) */
+ char path[1024];
+
+ sprintf (path, "%s/%s.shx", out_path, name);
+#ifdef _WIN32
+ _unlink (path);
+#else
+ unlink (path);
+#endif
+
+ sprintf (path, "%s/%s.shp", out_path, name);
+#ifdef _WIN32
+ _unlink (path);
+#else
+ unlink (path);
+#endif
+
+ sprintf (path, "%s/%s.dbf", out_path, name);
+#ifdef _WIN32
+ _unlink (path);
+#else
+ unlink (path);
+#endif
+}
+
+static void
+openShpWrite (gaiaShapefilePtr shp, const char *path, int shape,
+ gaiaDbfListPtr dbf_list)
+{
+/* trying to create the shapefile */
+ FILE *fl_shx = NULL;
+ FILE *fl_shp = NULL;
+ FILE *fl_dbf = NULL;
+ char xpath[1024];
+ unsigned char *buf_shp = NULL;
+ int buf_size = 1024;
+ unsigned char *dbf_buf = NULL;
+ gaiaDbfFieldPtr fld;
+ char *sys_err;
+ char errMsg[1024];
+ short dbf_reclen = 0;
+ int shp_size = 0;
+ int shx_size = 0;
+ unsigned short dbf_size = 0;
+ int len;
+ int endian_arch = gaiaEndianArch ();
+ char buf[2048];
+ if (shp->flShp != NULL || shp->flShx != NULL || shp->flDbf != NULL)
+ {
+ sprintf (errMsg,
+ "attempting to reopen an already opened Shapefile\n");
+ goto unsupported_conversion;
+ }
+ buf_shp = malloc (buf_size);
+/* trying to open shapefile files */
+ sprintf (xpath, "%s.shx", path);
+ fl_shx = fopen (xpath, "wb");
+ if (!fl_shx)
+ {
+ sys_err = strerror (errno);
+ sprintf (errMsg, "unable to open '%s' for writing: %s", xpath,
+ sys_err);
+ goto no_file;
+ }
+ sprintf (xpath, "%s.shp", path);
+ fl_shp = fopen (xpath, "wb");
+ if (!fl_shp)
+ {
+ sys_err = strerror (errno);
+ sprintf (errMsg, "unable to open '%s' for writing: %s", xpath,
+ sys_err);
+ goto no_file;
+ }
+ sprintf (xpath, "%s.dbf", path);
+ fl_dbf = fopen (xpath, "wb");
+ if (!fl_dbf)
+ {
+ sys_err = strerror (errno);
+ sprintf (errMsg, "unable to open '%s' for writing: %s", xpath,
+ sys_err);
+ goto no_file;
+ }
+/* allocating DBF buffer */
+ dbf_reclen = 1; /* an extra byte is needed because in DBF rows first byte is a marker for deletion */
+ fld = dbf_list->First;
+ while (fld)
+ {
+ /* computing the DBF record length */
+ dbf_reclen += fld->Length;
+ fld = fld->Next;
+ }
+ dbf_buf = malloc (dbf_reclen);
+/* writing an empty SHP file header */
+ memset (buf_shp, 0, 100);
+ fwrite (buf_shp, 1, 100, fl_shp);
+ shp_size = 50; /* note: shapefile [SHP and SHX] counts sizes in WORDS of 16 bits, not in bytes of 8 bits !!!! */
+/* writing an empty SHX file header */
+ memset (buf_shp, 0, 100);
+ fwrite (buf_shp, 1, 100, fl_shx);
+ shx_size = 50;
+/* writing the DBF file header */
+ memset (buf_shp, '\0', 32);
+ fwrite (buf_shp, 1, 32, fl_dbf);
+ dbf_size = 32; /* note: DBF counts sizes in bytes */
+ fld = dbf_list->First;
+ while (fld)
+ {
+ /* exporting DBF Fields specifications */
+ memset (buf_shp, 0, 32);
+ strcpy (buf, fld->Name);
+ memcpy (buf_shp, buf, strlen (buf));
+ *(buf_shp + 11) = fld->Type;
+ *(buf_shp + 16) = fld->Length;
+ *(buf_shp + 17) = fld->Decimals;
+ fwrite (buf_shp, 1, 32, fl_dbf);
+ dbf_size += 32;
+ fld = fld->Next;
+ }
+ fwrite ("\r", 1, 1, fl_dbf); /* this one is a special DBF delimiter that closes file header */
+ dbf_size++;
+/* setting up the SHP struct */
+ len = strlen (path);
+ shp->Path = malloc (len + 1);
+ strcpy (shp->Path, path);
+ shp->ReadOnly = 0;
+ shp->Shape = shape;
+ shp->flShp = fl_shp;
+ shp->flShx = fl_shx;
+ shp->flDbf = fl_dbf;
+ shp->Dbf = dbf_list;
+ shp->BufShp = buf_shp;
+ shp->ShpBfsz = buf_size;
+ shp->BufDbf = dbf_buf;
+ shp->DbfHdsz = dbf_size + 1;
+ shp->DbfReclen = dbf_reclen;
+ shp->DbfSize = dbf_size;
+ shp->DbfRecno = 0;
+ shp->ShpSize = shp_size;
+ shp->ShxSize = shx_size;
+ shp->MinX = DBL_MAX;
+ shp->MinY = DBL_MAX;
+ shp->MaxX = -DBL_MAX;
+ shp->MaxY = -DBL_MAX;
+ shp->Valid = 1;
+ shp->endian_arch = endian_arch;
+ return;
+ unsupported_conversion:
+/* illegal charset */
+ if (shp->LastError)
+ free (shp->LastError);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ return;
+ no_file:
+/* one of shapefile's files can't be created/opened */
+ if (shp->LastError)
+ free (shp->LastError);
+ len = strlen (errMsg);
+ shp->LastError = malloc (len + 1);
+ strcpy (shp->LastError, errMsg);
+ if (buf_shp)
+ free (buf_shp);
+ if (fl_shx)
+ fclose (fl_shx);
+ if (fl_shp)
+ fclose (fl_shp);
+ if (fl_dbf)
+ fclose (fl_dbf);
+ return;
+}
+
+static int
+writeShpEntity (gaiaShapefilePtr shp, const unsigned char *bufshp, int shplen,
+ const unsigned char *bufdbf, int dbflen)
+{
+/* trying to write an entity into shapefile */
+ unsigned char buf[64];
+ int endian_arch = shp->endian_arch;
+ int shape;
+ double minx;
+ double maxx;
+ double miny;
+ double maxy;
+
+/* inserting entity in SHX file */
+ gaiaExport32 (buf, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
+ gaiaExport32 (buf + 4, shplen / 2, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
+ fwrite (buf, 1, 8, shp->flShx);
+ (shp->ShxSize) += 4; /* updating current SHX file position [in 16 bits words !!!] */
+
+/* inserting entity in SHP file */
+ gaiaExport32 (buf, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, shplen / 2, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ fwrite (buf, 1, 8, shp->flShp);
+ (shp->ShpSize) += 4;
+ fwrite (bufshp, 1, shplen, shp->flShp);
+ (shp->ShpSize) += shplen / 2; /* updating current SHP file position [in 16 bits words !!!] */
+
+/* inserting entity in DBF file */
+ fwrite (bufdbf, 1, dbflen, shp->flDbf);
+ (shp->DbfRecno)++;
+
+/* updating the full extent BBOX */
+ shape = gaiaImport32 (bufshp + 0, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (shape == GAIA_SHP_POINT || shape == GAIA_SHP_POINTZ
+ || shape == GAIA_SHP_POINTM)
+ {
+ minx = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch);
+ maxx = minx;
+ miny = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch);
+ maxy = miny;
+ if (minx < shp->MinX)
+ shp->MinX = minx;
+ if (maxx > shp->MaxX)
+ shp->MaxX = maxx;
+ if (miny < shp->MinY)
+ shp->MinY = miny;
+ if (maxy > shp->MaxY)
+ shp->MaxY = maxy;
+ }
+ if (shape == GAIA_SHP_POLYLINE || shape == GAIA_SHP_POLYLINEZ
+ || shape == GAIA_SHP_POLYLINEM || shape == GAIA_SHP_POLYGON
+ || shape == GAIA_SHP_POLYGONZ || shape == GAIA_SHP_POLYGONM
+ || shape == GAIA_SHP_MULTIPOINT || shape == GAIA_SHP_MULTIPOINTZ
+ || shape == GAIA_SHP_MULTIPOINTM)
+ {
+ minx = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch);
+ miny = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch);
+ maxx = gaiaImport64 (bufshp + 20, GAIA_LITTLE_ENDIAN, endian_arch);
+ maxy = gaiaImport64 (bufshp + 28, GAIA_LITTLE_ENDIAN, endian_arch);
+ if (minx < shp->MinX)
+ shp->MinX = minx;
+ if (maxx > shp->MaxX)
+ shp->MaxX = maxx;
+ if (miny < shp->MinY)
+ shp->MinY = miny;
+ if (maxy > shp->MaxY)
+ shp->MaxY = maxy;
+ }
+ return 1;
+}
+
+static int
+check_geometry (gaiaGeomCollPtr geom, int shape)
+{
+/* cheching the geometry type and dims */
+ int pts = 0;
+ int lns = 0;
+ int pgs = 0;
+ gaiaPointPtr pt;
+ gaiaLinestringPtr ln;
+ gaiaPolygonPtr pg;
+
+ pt = geom->FirstPoint;
+ while (pt != NULL)
+ {
+ pts++;
+ pt = pt->Next;
+ }
+ ln = geom->FirstLinestring;
+ while (ln != NULL)
+ {
+ lns++;
+ ln = ln->Next;
+ }
+ pg = geom->FirstPolygon;
+ while (pg != NULL)
+ {
+ pgs++;
+ pg = pg->Next;
+ }
+
+ if (pts == 1 && lns == 0 && pgs == 0)
+ {
+ if (shape == GAIA_SHP_POINT && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_POINTZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_POINTM && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTM
+ && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+ if (pts > 1 && lns == 0 && pgs == 0)
+ {
+ if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTM
+ && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+ if (pts == 0 && lns > 0 && pgs == 0)
+ {
+ if (shape == GAIA_SHP_POLYLINE && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_POLYLINEZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_POLYLINEM && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+ if (pts == 0 && lns == 0 && pgs > 0)
+ {
+ if (shape == GAIA_SHP_POLYGON && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_POLYGONZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_POLYGONM && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+check_geometry_verbose (gaiaGeomCollPtr geom, int shape, char **expected,
+ char **actual)
+{
+/* cheching the geometry type and dims - verbose */
+ int pts = 0;
+ int lns = 0;
+ int pgs = 0;
+ gaiaPointPtr pt;
+ gaiaLinestringPtr ln;
+ gaiaPolygonPtr pg;
+ const char *str;
+ int len;
+
+ *expected = NULL;
+ *actual = NULL;
+ pt = geom->FirstPoint;
+ while (pt != NULL)
+ {
+ pts++;
+ pt = pt->Next;
+ }
+ ln = geom->FirstLinestring;
+ while (ln != NULL)
+ {
+ lns++;
+ ln = ln->Next;
+ }
+ pg = geom->FirstPolygon;
+ while (pg != NULL)
+ {
+ pgs++;
+ pg = pg->Next;
+ }
+
+ if (pts == 1 && lns == 0 && pgs == 0)
+ {
+ if (shape == GAIA_SHP_POINT && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_POINTZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_POINTM && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTM
+ && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+ if (pts > 1 && lns == 0 && pgs == 0)
+ {
+ if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_MULTIPOINTM
+ && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+ if (pts == 0 && lns > 0 && pgs == 0)
+ {
+ if (shape == GAIA_SHP_POLYLINE && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_POLYLINEZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_POLYLINEM && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+ if (pts == 0 && lns == 0 && pgs > 0)
+ {
+ if (shape == GAIA_SHP_POLYGON && geom->DimensionModel == GAIA_XY)
+ return 1;
+ if (shape == GAIA_SHP_POLYGONZ
+ && (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M))
+ return 1;
+ if (shape == GAIA_SHP_POLYGONM && geom->DimensionModel == GAIA_XY_M)
+ return 1;
+ }
+
+ switch (shape)
+ {
+ case GAIA_SHP_POINT:
+ str = "POINT";
+ break;
+ case GAIA_SHP_POINTZ:
+ str = "POINT-M";
+ break;
+ case GAIA_SHP_POINTM:
+ str = "POINT-Z";
+ break;
+ case GAIA_SHP_POLYLINE:
+ str = "POLYLINE";
+ break;
+ case GAIA_SHP_POLYLINEZ:
+ str = "POLYLINE-Z";
+ break;
+ case GAIA_SHP_POLYLINEM:
+ str = "POLYLINE-M";
+ break;
+ case GAIA_SHP_POLYGON:
+ str = "POLYGON";
+ break;
+ case GAIA_SHP_POLYGONZ:
+ str = "POLYGON-Z";
+ break;
+ case GAIA_SHP_POLYGONM:
+ str = "POLYGON-M";
+ break;
+ case GAIA_SHP_MULTIPOINT:
+ str = "MULTIPOINT";
+ break;
+ case GAIA_SHP_MULTIPOINTZ:
+ str = "MULTIPOINT-Z";
+ break;
+ case GAIA_SHP_MULTIPOINTM:
+ str = "MULTIPOINT-M";
+ break;
+ default:
+ str = "UNKNOWN";
+ break;
+ };
+ len = strlen (str);
+ *expected = malloc (len + 1);
+ strcpy (*expected, str);
+
+ str = "UNKNOWN";
+ if (pts == 1 && lns == 0 && pgs == 0)
+ {
+ if (geom->DimensionModel == GAIA_XY)
+ str = "POINT";
+ if (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M)
+ str = "POINT-Z";
+ if (geom->DimensionModel == GAIA_XY_M)
+ str = "POINT-M";
+ }
+ if (pts > 1 && lns == 0 && pgs == 0)
+ {
+ if (geom->DimensionModel == GAIA_XY)
+ str = "MULTIPOINT";
+ if (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M)
+ str = "MULTIPOINT-Z";
+ if (geom->DimensionModel == GAIA_XY_M)
+ str = "MULTIPOINT-M";
+ }
+ if (pts == 0 && lns > 0 && pgs == 0)
+ {
+ if (geom->DimensionModel == GAIA_XY)
+ str = "POLYLINE";
+ if (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M)
+ str = "POLYLINE-Z";
+ if (geom->DimensionModel == GAIA_XY_M)
+ str = "POLYLINE-M";
+ }
+ if (pts == 0 && lns == 0 && pgs > 0)
+ {
+ if (geom->DimensionModel == GAIA_XY)
+ str = "POLYGON";
+ if (geom->DimensionModel == GAIA_XY_Z
+ || geom->DimensionModel == GAIA_XY_Z_M)
+ str = "POLYGON-Z";
+ return 1;
+ if (geom->DimensionModel == GAIA_XY_M)
+ str = "POLYGON-M";
+ return 1;
+ }
+ len = strlen (str);
+ *actual = malloc (len + 1);
+ strcpy (*actual, str);
+
+ return 0;
+}
+
+static void
+gaiaSaneClockwise (gaiaPolygonPtr polyg)
+{
+/*
+/ when exporting POLYGONs to SHAPEFILE, we must guarantee that:
+/ - all EXTERIOR RING must be clockwise
+/ - all INTERIOR RING must be anti-clockwise
+/
+/ this function checks for the above conditions,
+/ and if needed inverts the rings
+*/
+ int ib;
+ int iv;
+ int iv2;
+ double x;
+ double y;
+ double z;
+ double m;
+ gaiaRingPtr new_ring;
+ gaiaRingPtr ring = polyg->Exterior;
+ gaiaClockwise (ring);
+ if (!(ring->Clockwise))
+ {
+ /* exterior ring needs inversion */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ new_ring = gaiaAllocRingXYZ (ring->Points);
+ else if (ring->DimensionModel == GAIA_XY_M)
+ new_ring = gaiaAllocRingXYM (ring->Points);
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ new_ring = gaiaAllocRingXYZM (ring->Points);
+ else
+ new_ring = gaiaAllocRing (ring->Points);
+ iv2 = 0;
+ for (iv = ring->Points - 1; iv >= 0; iv--)
+ {
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
+ gaiaSetPointXYZ (new_ring->Coords, iv2, x, y, z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
+ gaiaSetPointXYM (new_ring->Coords, iv2, x, y, m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
+ gaiaSetPointXYZM (new_ring->Coords, iv2, x, y, z, m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ gaiaSetPoint (new_ring->Coords, iv2, x, y);
+ }
+ iv2++;
+ }
+ polyg->Exterior = new_ring;
+ gaiaFreeRing (ring);
+ }
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ ring = polyg->Interiors + ib;
+ gaiaClockwise (ring);
+ if (ring->Clockwise)
+ {
+ /* interior ring needs inversion */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ new_ring = gaiaAllocRingXYZ (ring->Points);
+ else if (ring->DimensionModel == GAIA_XY_M)
+ new_ring = gaiaAllocRingXYM (ring->Points);
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ new_ring = gaiaAllocRingXYZM (ring->Points);
+ else
+ new_ring = gaiaAllocRing (ring->Points);
+ iv2 = 0;
+ for (iv = ring->Points - 1; iv >= 0; iv--)
+ {
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
+ gaiaSetPointXYZ (new_ring->Coords, iv2, x, y, z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
+ gaiaSetPointXYM (new_ring->Coords, iv2, x, y, m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
+ gaiaSetPointXYZM (new_ring->Coords, iv2, x, y,
+ z, m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ gaiaSetPoint (new_ring->Coords, iv2, x, y);
+ }
+ iv2++;
+ }
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (new_ring->Coords, iv, &x, &y, &z);
+ gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (new_ring->Coords, iv, &x, &y, &m);
+ gaiaSetPointXYM (ring->Coords, iv, x, y, m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (new_ring->Coords, iv, &x, &y,
+ &z, &m);
+ gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
+ }
+ else
+ {
+ gaiaGetPoint (new_ring->Coords, iv, &x, &y);
+ gaiaSetPoint (ring->Coords, iv, x, y);
+ }
+ }
+ gaiaFreeRing (new_ring);
+ }
+ }
+}
+
+static int
+do_export_geometry (gaiaGeomCollPtr geom, unsigned char **bufshp, int *buflen,
+ int xshape, int recno, int rowno, int eff_dims)
+{
+/* attempting to encode a Geometry */
+ unsigned char *buf;
+ int iv;
+ int tot_ln;
+ int tot_v;
+ int tot_pts;
+ int this_size;
+ int ix;
+ double x;
+ double y;
+ double z;
+ double m;
+ int hasM;
+ double minZ;
+ double maxZ;
+ double minM;
+ double maxM;
+ int endian_arch = gaiaEndianArch ();
+
+ if (geom == NULL)
+ {
+ /* exporting a NULL Shape */
+ *buflen = 12;
+ buf = malloc (12);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, 2, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_NULL, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = NULL */
+ *bufshp = buf;
+ return 1;
+ }
+
+ if (!check_geometry (geom, xshape))
+ {
+ /* mismatching Geometry type */
+ fprintf (stderr, "\tinput row #%d: mismatching Geometry type\n",
+ rowno);
+ return 0;
+ }
+
+ if (xshape == GAIA_SHP_POINT)
+ {
+ /* this one is expected to be a POINT */
+ gaiaPointPtr pt = geom->FirstPoint;
+ *buflen = 28;
+ buf = malloc (28);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, 10, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POINT, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT */
+ gaiaExport64 (buf + 12, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */
+ gaiaExport64 (buf + 20, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POINTZ)
+ {
+ /* this one is expected to be a POINT Z */
+ gaiaPointPtr pt = geom->FirstPoint;
+ *buflen = 42;
+ buf = malloc (42);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, 18, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POINTZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT Z */
+ gaiaExport64 (buf + 12, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */
+ gaiaExport64 (buf + 20, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */
+ gaiaExport64 (buf + 28, pt->Z, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Z coordinate */
+ gaiaExport64 (buf + 36, pt->M, GAIA_LITTLE_ENDIAN, endian_arch); /* exports M coordinate */
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POINTM)
+ {
+ /* this one is expected to be a POINT M */
+ gaiaPointPtr pt = geom->FirstPoint;
+ *buflen = 36;
+ buf = malloc (36);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, 14, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POINTM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT M */
+ gaiaExport64 (buf + 12, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */
+ gaiaExport64 (buf + 20, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */
+ gaiaExport64 (buf + 28, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports M coordinate */
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POLYLINE)
+ {
+ /* this one is expected to be a LINESTRING / MULTILINESTRING */
+ gaiaLinestringPtr line;
+ tot_ln = 0;
+ tot_v = 0;
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* computes # lines and total # points */
+ tot_v += line->Points;
+ tot_ln++;
+ line = line->Next;
+ }
+ this_size = 26 + (2 * tot_ln) + (tot_v * 8); /* size [in 16 bits words !!!] for this SHP entity */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POLYLINE, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */
+ gaiaExport32 (buf + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ tot_v = 0; /* resets points counter */
+ ix = 52; /* sets current buffer offset */
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports start point index for each line */
+ gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += line->Points;
+ ix += 4;
+ line = line->Next;
+ }
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports points for each line */
+ for (iv = 0; iv < line->Points; iv++)
+ {
+ /* exports a POINT [x,y] */
+ if (line->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
+ }
+ else if (line->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
+ }
+ else if (line->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (line->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ line = line->Next;
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POLYLINEZ)
+ {
+ /* this one is expected to be a LINESTRING / MULTILINESTRING Z */
+ gaiaLinestringPtr line;
+ gaiaZRangeGeometry (geom, &minZ, &maxZ);
+ gaiaMRangeGeometry (geom, &minM, &maxM);
+ tot_ln = 0;
+ tot_v = 0;
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* computes # lines and total # points */
+ tot_v += line->Points;
+ tot_ln++;
+ line = line->Next;
+ }
+ hasM = 0;
+ if (eff_dims == GAIA_XY_M || eff_dims == GAIA_XY_Z_M)
+ hasM = 1;
+ if (hasM)
+ this_size = 42 + (2 * tot_ln) + (tot_v * 16); /* size [in 16 bits words !!!] ZM */
+ else
+ this_size = 34 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] Z-only */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POLYLINEZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE Z */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */
+ gaiaExport32 (buf + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ tot_v = 0; /* resets points counter */
+ ix = 52; /* sets current buffer offset */
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports start point index for each line */
+ gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += line->Points;
+ ix += 4;
+ line = line->Next;
+ }
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports points for each line */
+ for (iv = 0; iv < line->Points; iv++)
+ {
+ /* exports a POINT [x,y] */
+ if (line->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
+ }
+ else if (line->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
+ }
+ else if (line->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (line->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ line = line->Next;
+ }
+ /* exporting the Z-range [min/max] */
+ gaiaExport64 (buf + ix, minZ, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxZ, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports Z-values for each line */
+ for (iv = 0; iv < line->Points; iv++)
+ {
+ /* exports Z-value */
+ z = 0.0;
+ if (line->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
+ }
+ else if (line->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
+ }
+ else if (line->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (line->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, z,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ line = line->Next;
+ }
+ if (hasM)
+ {
+ /* exporting the M-range [min/max] */
+ gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports M-values for each line */
+ for (iv = 0; iv < line->Points; iv++)
+ {
+ /* exports M-value */
+ m = 0.0;
+ if (line->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (line->Coords, iv,
+ &x, &y, &z);
+ }
+ else if (line->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (line->Coords, iv,
+ &x, &y, &m);
+ }
+ else if (line->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (line->Coords, iv,
+ &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (line->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, m,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ line = line->Next;
+ }
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POLYLINEM)
+ {
+ /* this one is expected to be a LINESTRING / MULTILINESTRING M */
+ gaiaLinestringPtr line;
+ gaiaMRangeGeometry (geom, &minM, &maxM);
+ tot_ln = 0;
+ tot_v = 0;
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* computes # lines and total # points */
+ tot_v += line->Points;
+ tot_ln++;
+ line = line->Next;
+ }
+ this_size = 34 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] for this SHP entity */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POLYLINEM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE M */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */
+ gaiaExport32 (buf + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ tot_v = 0; /* resets points counter */
+ ix = 52; /* sets current buffer offset */
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports start point index for each line */
+ gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += line->Points;
+ ix += 4;
+ line = line->Next;
+ }
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports points for each line */
+ for (iv = 0; iv < line->Points; iv++)
+ {
+ /* exports a POINT [x,y] */
+ if (line->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
+ }
+ else if (line->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
+ }
+ else if (line->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (line->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ line = line->Next;
+ }
+ /* exporting the M-range [min/max] */
+ gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ line = geom->FirstLinestring;
+ while (line)
+ {
+ /* exports M-values for each line */
+ for (iv = 0; iv < line->Points; iv++)
+ {
+ /* exports M-value */
+ m = 0.0;
+ if (line->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
+ }
+ else if (line->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
+ }
+ else if (line->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (line->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, m,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ line = line->Next;
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POLYGON)
+ {
+ /* this one is expected to be a POLYGON or a MULTIPOLYGON */
+ gaiaPolygonPtr polyg;
+ gaiaRingPtr ring;
+ int ib;
+ tot_ln = 0;
+ tot_v = 0;
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* computes # rings and total # points */
+ gaiaSaneClockwise (polyg); /* we must assure that exterior ring is clockwise, and interior rings are anti-clockwise */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ tot_v += ring->Points;
+ tot_ln++;
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ tot_v += ring->Points;
+ tot_ln++;
+ }
+ polyg = polyg->Next;
+ }
+ this_size = 26 + (2 * tot_ln) + (tot_v * 8); /* size [in 16 bits words !!!] for this SHP entity */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POLYGON, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */
+ gaiaExport32 (buf + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ tot_v = 0; /* resets points counter */
+ ix = 52; /* sets current buffer offset */
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports start point index for each line */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += ring->Points;
+ ix += 4;
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ gaiaExport32 (buf + ix, tot_v,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += ring->Points;
+ ix += 4;
+ }
+ polyg = polyg->Next;
+ }
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports points for each ring */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports a POINT [x,y] - exterior ring */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports a POINT [x,y] - interior ring */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv,
+ &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv,
+ &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv,
+ &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ }
+ polyg = polyg->Next;
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POLYGONZ)
+ {
+ /* this one is expected to be a POLYGON or a MULTIPOLYGON Z */
+ gaiaPolygonPtr polyg;
+ gaiaRingPtr ring;
+ int ib;
+ gaiaZRangeGeometry (geom, &minZ, &maxZ);
+ gaiaMRangeGeometry (geom, &minM, &maxM);
+ tot_ln = 0;
+ tot_v = 0;
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* computes # rings and total # points */
+ gaiaSaneClockwise (polyg); /* we must assure that exterior ring is clockwise, and interior rings are anti-clockwise */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ tot_v += ring->Points;
+ tot_ln++;
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ tot_v += ring->Points;
+ tot_ln++;
+ }
+ polyg = polyg->Next;
+ }
+ hasM = 0;
+ if (eff_dims == GAIA_XY_M || eff_dims == GAIA_XY_Z_M)
+ hasM = 1;
+ if (hasM)
+ this_size = 42 + (2 * tot_ln) + (tot_v * 16); /* size [in 16 bits words !!!] ZM */
+ else
+ this_size = 34 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] Z-only */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POLYGONZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON Z */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */
+ gaiaExport32 (buf + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ tot_v = 0; /* resets points counter */
+ ix = 52; /* sets current buffer offset */
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports start point index for each line */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += ring->Points;
+ ix += 4;
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ gaiaExport32 (buf + ix, tot_v,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += ring->Points;
+ ix += 4;
+ }
+ polyg = polyg->Next;
+ }
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports points for each ring */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports a POINT [x,y] - exterior ring */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports a POINT [x,y] - interior ring */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv,
+ &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv,
+ &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv,
+ &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ }
+ polyg = polyg->Next;
+ }
+ /* exporting the Z-range [min/max] */
+ gaiaExport64 (buf + ix, minZ, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxZ, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports Z-values for each ring */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports Z-values - exterior ring */
+ z = 0.0;
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, z,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports Z-values - interior ring */
+ z = 0.0;
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv,
+ &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv,
+ &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv,
+ &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, z,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ }
+ polyg = polyg->Next;
+ }
+ if (hasM)
+ {
+ /* exporting the M-range [min/max] */
+ gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports M-values for each ring */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports M-values - exterior ring */
+ m = 0.0;
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv,
+ &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv,
+ &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv,
+ &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, m,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports M-values - interior ring */
+ m = 0.0;
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords,
+ iv, &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords,
+ iv, &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords,
+ iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, m,
+ GAIA_LITTLE_ENDIAN,
+ endian_arch);
+ ix += 8;
+ }
+ }
+ polyg = polyg->Next;
+ }
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_POLYGONM)
+ {
+ /* this one is expected to be a POLYGON or a MULTIPOLYGON M */
+ gaiaPolygonPtr polyg;
+ gaiaRingPtr ring;
+ int ib;
+ gaiaMRangeGeometry (geom, &minM, &maxM);
+ tot_ln = 0;
+ tot_v = 0;
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* computes # rings and total # points */
+ gaiaSaneClockwise (polyg); /* we must assure that exterior ring is clockwise, and interior rings are anti-clockwise */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ tot_v += ring->Points;
+ tot_ln++;
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ tot_v += ring->Points;
+ tot_ln++;
+ }
+ polyg = polyg->Next;
+ }
+ this_size = 34 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] for this SHP entity */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_POLYGONM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON M */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */
+ gaiaExport32 (buf + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ tot_v = 0; /* resets points counter */
+ ix = 52; /* sets current buffer offset */
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports start point index for each line */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += ring->Points;
+ ix += 4;
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ gaiaExport32 (buf + ix, tot_v,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ tot_v += ring->Points;
+ ix += 4;
+ }
+ polyg = polyg->Next;
+ }
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports points for each ring */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports a POINT [x,y] - exterior ring */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports a POINT [x,y] - interior ring */
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv,
+ &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv,
+ &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv,
+ &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, x,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, y,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ }
+ polyg = polyg->Next;
+ }
+ /* exporting the M-range [min/max] */
+ gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ polyg = geom->FirstPolygon;
+ while (polyg)
+ {
+ /* exports M-values for each ring */
+ ring = polyg->Exterior; /* this one is the exterior ring */
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports M-values - exterior ring */
+ m = 0.0;
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, m,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ for (ib = 0; ib < polyg->NumInteriors; ib++)
+ {
+ /* that ones are the interior rings */
+ ring = polyg->Interiors + ib;
+ for (iv = 0; iv < ring->Points; iv++)
+ {
+ /* exports M-values - interior ring */
+ m = 0.0;
+ if (ring->DimensionModel == GAIA_XY_Z)
+ {
+ gaiaGetPointXYZ (ring->Coords, iv,
+ &x, &y, &z);
+ }
+ else if (ring->DimensionModel == GAIA_XY_M)
+ {
+ gaiaGetPointXYM (ring->Coords, iv,
+ &x, &y, &m);
+ }
+ else if (ring->DimensionModel == GAIA_XY_Z_M)
+ {
+ gaiaGetPointXYZM (ring->Coords, iv,
+ &x, &y, &z, &m);
+ }
+ else
+ {
+ gaiaGetPoint (ring->Coords, iv, &x, &y);
+ }
+ gaiaExport64 (buf + ix, m,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ }
+ }
+ polyg = polyg->Next;
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_MULTIPOINT)
+ {
+ /* this one is expected to be a MULTIPOINT */
+ gaiaPointPtr pt;
+ tot_pts = 0;
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* computes # points */
+ tot_pts++;
+ pt = pt->Next;
+ }
+ this_size = 24 + (tot_pts * 8); /* size [in 16 bits words !!!] for this SHP entity */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_MULTIPOINT, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ ix = 48; /* sets current buffer offset */
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* exports each point */
+ gaiaExport64 (buf + ix, pt->X, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = pt->Next;
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_MULTIPOINTZ)
+ {
+ /* this one is expected to be a MULTIPOINT Z */
+ gaiaPointPtr pt;
+ gaiaZRangeGeometry (geom, &minZ, &maxZ);
+ gaiaMRangeGeometry (geom, &minM, &maxM);
+ tot_pts = 0;
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* computes # points */
+ tot_pts++;
+ pt = pt->Next;
+ }
+ hasM = 0;
+ if (eff_dims == GAIA_XY_M || eff_dims == GAIA_XY_Z_M)
+ hasM = 1;
+ if (hasM)
+ this_size = 40 + (tot_pts * 16); /* size [in 16 bits words !!!] ZM */
+ else
+ this_size = 32 + (tot_pts * 12); /* size [in 16 bits words !!!] Z-only */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_MULTIPOINTZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT Z */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ ix = 48; /* sets current buffer offset */
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* exports each point */
+ gaiaExport64 (buf + ix, pt->X, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = pt->Next;
+ }
+ /* exporting the Z-range [min/max] */
+ gaiaExport64 (buf + ix, minZ, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxZ, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* exports Z-values */
+ gaiaExport64 (buf + ix, pt->Z, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = pt->Next;
+ }
+ if (hasM)
+ {
+ /* exporting the M-range [min/max] */
+ gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* exports M-values */
+ gaiaExport64 (buf + ix, pt->M,
+ GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = pt->Next;
+ }
+ }
+ *bufshp = buf;
+ return 1;
+ }
+ if (xshape == GAIA_SHP_MULTIPOINTM)
+ {
+ /* this one is expected to be a MULTIPOINT M */
+ gaiaPointPtr pt;
+ gaiaMRangeGeometry (geom, &minM, &maxM);
+ tot_pts = 0;
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* computes # points */
+ tot_pts++;
+ pt = pt->Next;
+ }
+ this_size = 32 + (tot_pts * 12); /* size [in 16 bits words !!!] for this SHP entity */
+ *buflen = this_size * 2;
+ buf = malloc (this_size * 2);
+ gaiaExport32 (buf, recno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
+ gaiaExport32 (buf + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
+ gaiaExport32 (buf + 8, GAIA_SHP_MULTIPOINTM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT M */
+ gaiaExport64 (buf + 12, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
+ gaiaExport64 (buf + 20, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 28, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport64 (buf + 36, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch);
+ gaiaExport32 (buf + 44, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
+ ix = 48; /* sets current buffer offset */
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* exports each point */
+ gaiaExport64 (buf + ix, pt->X, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = pt->Next;
+ }
+ /* exporting the M-range [min/max] */
+ gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = geom->FirstPoint;
+ while (pt)
+ {
+ /* exports M-values */
+ gaiaExport64 (buf + ix, pt->M, GAIA_LITTLE_ENDIAN, endian_arch);
+ ix += 8;
+ pt = pt->Next;
+ }
+ *bufshp = buf;
+ return 1;
+ }
+
+ fprintf (stderr,
+ "\tinput row #%d: unable to export a consistent Geometry\n",
+ rowno);
+ return 0;
+}
+
+static int
+do_repair_shapefile (const void *cache, const char *shp_path,
+ const char *out_path, int validate, int esri, int force,
+ int *repair_failed)
+{
+/* repairing some Shapefile */
+ int current_row;
+ gaiaShapefilePtr shp_in = NULL;
+ gaiaShapefilePtr shp_out = NULL;
+ int ret;
+ gaiaDbfListPtr dbf_list = NULL;
+ gaiaDbfFieldPtr in_fld;
+ double minx;
+ double miny;
+ double maxx;
+ double maxy;
+ double hMinX;
+ double hMinY;
+ double hMaxX;
+ double hMaxY;
+ int mismatching;
+
+ *repair_failed = 0;
+
+/* opening the INPUT SHP */
+ shp_in = allocShapefile ();
+ openShpRead (shp_in, shp_path, &hMinX, &hMinY, &hMaxX, &hMaxY,
+ &mismatching);
+ if (!(shp_in->Valid))
+ {
+ char extra[512];
+ *extra = '\0';
+ if (shp_in->LastError)
+ sprintf (extra, "\n\t\tcause: %s\n", shp_in->LastError);
+ fprintf (stderr,
+ "\t\terror: cannot open shapefile '%s'%s", shp_path, extra);
+ freeShapefile (shp_in);
+ return 0;
+ }
+
+/* preparing the DBF fields list - OUTPUT */
+ dbf_list = gaiaAllocDbfList ();
+ in_fld = shp_in->Dbf->First;
+ while (in_fld)
+ {
+ /* adding a DBF field - OUTPUT */
+ gaiaAddDbfField (dbf_list, in_fld->Name, in_fld->Type, in_fld->Offset,
+ in_fld->Length, in_fld->Decimals);
+ in_fld = in_fld->Next;
+ }
+
+/* creating the OUTPUT SHP */
+ shp_out = allocShapefile ();
+ openShpWrite (shp_out, out_path, shp_in->Shape, dbf_list);
+ if (!(shp_out->Valid))
+ {
+ char extra[512];
+ *extra = '\0';
+ if (shp_out->LastError)
+ sprintf (extra, "\n\t\tcause: %s\n", shp_out->LastError);
+ fprintf (stderr,
+ "\t\terror: cannot open shapefile '%s'%s", out_path, extra);
+ freeShapefile (shp_in);
+ freeShapefile (shp_out);
+ gaiaFreeDbfList (dbf_list);
+ return 0;
+ }
+
+ current_row = 0;
+ while (1)
+ {
+ /* reading rows from shapefile */
+ int shplen;
+ ret =
+ readShpEntity (shp_in, current_row, &shplen, &minx, &miny, &maxx,
+ &maxy);
+ if (ret < 0)
+ {
+ /* found a DBF deleted record */
+ current_row++;
+ continue;
+ }
+ if (!ret)
+ {
+ if (!(shp_in->LastError)) /* normal SHP EOF */
+ break;
+ fprintf (stderr, "\t\tERROR: %s\n", shp_in->LastError);
+ goto stop;
+ }
+ if (validate || force)
+ {
+ /* attempting to rearrange geometries */
+ unsigned char *bufshp;
+ int buflen;
+ int nullshape;
+ gaiaGeomCollPtr geom =
+ do_parse_geometry (shp_in->BufShp, shplen,
+ shp_in->EffectiveDims,
+ shp_in->EffectiveType, &nullshape);
+ if (nullshape)
+ goto default_null;
+ if (geom == NULL)
+ {
+ fprintf (stderr,
+ "\t\tinput row #%d: unexpected NULL geometry\n",
+ current_row);
+ *repair_failed = 1;
+ goto default_null;
+ }
+
+ if (validate)
+ {
+ /* testing for invalid Geometries */
+ int is_invalid = 0;
+ if (esri)
+ {
+ /* checking invalid geometries in ESRI mode */
+ gaiaGeomCollPtr detail;
+ detail = gaiaIsValidDetailEx_r (cache, geom, 1);
+ if (detail == NULL)
+ {
+ /* extra checks */
+ int extra = 0;
+ if (gaiaIsToxic_r (cache, geom))
+ extra = 1;
+ if (gaiaIsNotClosedGeomColl_r (cache, geom))
+ extra = 1;
+ if (extra)
+ is_invalid = 1;
+ }
+ else
+ {
+ is_invalid = 1;
+ gaiaFreeGeomColl (detail);
+ }
+ }
+ else
+ {
+ /* checking invalid geometries in ISO/OGC mode */
+ if (gaiaIsValid_r (cache, geom) != 1)
+ is_invalid = 1;
+ }
+
+ if (is_invalid)
+ {
+ /* attempting to repair an invalid Geometry */
+ char *expected;
+ char *actual;
+ gaiaGeomCollPtr discarded;
+ gaiaGeomCollPtr result =
+ gaiaMakeValid (cache, geom);
+ if (result == NULL)
+ {
+ fprintf (stderr,
+ "\t\tinput row #%d: unexpected MakeValid failure\n",
+ current_row);
+ gaiaFreeGeomColl (geom);
+ *repair_failed = 1;
+ goto default_null;
+ }
+ discarded = gaiaMakeValidDiscarded (cache, geom);
+ if (discarded != NULL)
+ {
+ fprintf (stderr,
+ "\t\tinput row #%d: MakeValid reports discarded elements\n",
+ current_row);
+ gaiaFreeGeomColl (result);
+ gaiaFreeGeomColl (discarded);
+ gaiaFreeGeomColl (geom);
+ *repair_failed = 1;
+ goto default_null;
+ }
+ if (!check_geometry_verbose
+ (result, shp_in->Shape, &expected, &actual))
+ {
+ fprintf (stderr,
+ "\t\tinput row #%d: MakeValid returned an invalid SHAPE (expected %s, got %s)\n",
+ current_row, expected, actual);
+ free (expected);
+ free (actual);
+ gaiaFreeGeomColl (result);
+ gaiaFreeGeomColl (geom);
+ *repair_failed = 1;
+ goto default_null;
+ }
+ gaiaFreeGeomColl (geom);
+ geom = result;
+ }
+
+ if (!do_export_geometry
+ (geom, &bufshp, &buflen, shp_in->Shape,
+ shp_out->DbfRecno, current_row,
+ shp_out->EffectiveDims))
+ {
+ gaiaFreeGeomColl (geom);
+ goto stop;
+ }
+ gaiaFreeGeomColl (geom);
+ }
+ else
+ {
+ if (!do_export_geometry
+ (geom, &bufshp, &buflen, shp_in->Shape,
+ shp_out->DbfRecno, current_row,
+ shp_out->EffectiveDims))
+ {
+ gaiaFreeGeomColl (geom);
+ goto stop;
+ }
+ gaiaFreeGeomColl (geom);
+ }
+ goto ok_geom;
+
+ default_null:
+ /* exporting a NULL shape */
+ do_export_geometry
+ (NULL, &bufshp, &buflen, shp_in->Shape,
+ shp_out->DbfRecno, current_row, shp_out->EffectiveDims);
+
+ ok_geom:
+ ret = writeShpEntity
+ (shp_out, bufshp, buflen, shp_in->BufDbf,
+ shp_in->DbfReclen);
+ free (bufshp);
+ if (!ret)
+ goto stop;
+ }
+ else
+ {
+ /* passing geometries exactly as they were */
+ if (!writeShpEntity
+ (shp_out, shp_in->BufShp, shplen, shp_in->BufDbf,
+ shp_in->DbfReclen))
+ goto stop;
+ }
+ current_row++;
+ }
+ gaiaFlushShpHeaders (shp_out);
+ freeShapefile (shp_in);
+ freeShapefile (shp_out);
+ return 1;
+
+ stop:
+ freeShapefile (shp_in);
+ freeShapefile (shp_out);
+ fprintf (stderr,
+ "\t\tMalformed shapefile, impossible to repair: quitting\n");
+ return 0;
+}
+
+static int
+do_test_shapefile (const void *cache, const char *shp_path, int validate,
+ int esri, int *invalid)
+{
+/* testing a Shapefile for validity */
+ int n_invalid;
+
+ fprintf (stderr, "\nVerifying %s.shp\n", shp_path);
+ *invalid = 0;
+ if (!do_read_shp (cache, shp_path, validate, esri, &n_invalid))
+ return 0;
+ if (n_invalid)
+ {
+ fprintf (stderr, "\tfound %d invalidit%s: cleaning required.\n",
+ n_invalid, (n_invalid > 1) ? "ies" : "y");
+ *invalid = 1;
+ }
+ else
+ fprintf (stderr, "\tfound to be already valid.\n");
+ return 1;
+}
+
+static int
+check_extension (const char *file_name)
+{
+/* checks the file extension */
+ const char *mark = NULL;
+ int len = strlen (file_name);
+ const char *p = file_name + len - 1;
+
+ while (p >= file_name)
+ {
+ if (*p == '.')
+ mark = p;
+ p--;
+ }
+ if (mark == NULL)
+ return SUFFIX_DISCARD;
+ if (strcasecmp (mark, ".shp") == 0)
+ return SUFFIX_SHP;
+ if (strcasecmp (mark, ".shx") == 0)
+ return SUFFIX_SHX;
+ if (strcasecmp (mark, ".dbf") == 0)
+ return SUFFIX_DBF;
+ return SUFFIX_DISCARD;
+}
+
+static int
+do_scan_dir (const void *cache, const char *in_dir, const char *out_dir,
+ int *n_shp, int *r_shp, int *x_shp, int validate, int esri,
+ int force)
+{
+/* scanning a directory and searching for Shapefiles to be checked */
+ struct shp_entry *p_shp;
+ struct shp_list *list = alloc_shp_list ();
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+/* Visual Studio .NET */
+ struct _finddata_t c_file;
+ intptr_t hFile;
+ char *path;
+ char *name;
+ int len;
+ int ret;
+ if (_chdir (in_dir) < 0)
+ goto error;
+ if ((hFile = _findfirst ("*.shp", &c_file)) == -1L)
+ ;
+ else
+ {
+ while (1)
+ {
+ if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+ || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+ {
+ name = sqlite3_mprintf ("%s", c_file.name);
+ len = strlen (name);
+ name[len - 4] = '\0';
+ path = sqlite3_mprintf ("%s/%s", in_dir, name);
+ do_add_shapefile (list, path, name, SUFFIX_SHP);
+ }
+ if (_findnext (hFile, &c_file) != 0)
+ break;
+ }
+ _findclose (hFile);
+ if ((hFile = _findfirst ("*.shx", &c_file)) == -1L)
+ ;
+ else
+ {
+ while (1)
+ {
+ if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+ || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+ {
+ name = sqlite3_mprintf ("%s", c_file.name);
+ len = strlen (name);
+ name[len - 4] = '\0';
+ path = sqlite3_mprintf ("%s/%s", in_dir, name);
+ do_add_shapefile (list, path, name, SUFFIX_SHX);
+ }
+ if (_findnext (hFile, &c_file) != 0)
+ break;
+ }
+ _findclose (hFile);
+ if ((hFile = _findfirst ("*.dbf", &c_file)) == -1L)
+ ;
+ else
+ {
+ while (1)
+ {
+ if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+ || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+ {
+ name = sqlite3_mprintf ("%s", c_file.name);
+ len = strlen (name);
+ name[len - 4] = '\0';
+ path =
+ sqlite3_mprintf ("%s/%s", in_dir, name);
+ do_add_shapefile (list, path, name,
+ SUFFIX_DBF);
+ }
+ if (_findnext (hFile, &c_file) != 0)
+ break;
+ }
+ _findclose (hFile);
+ }
+ }
+ }
+#else
+/* not Visual Studio .NET */
+ char *path;
+ char *name;
+ struct dirent *entry;
+ int len;
+ int suffix;
+ DIR *dir = opendir (in_dir);
+ if (!dir)
+ goto error;
+ while (1)
+ {
+ /* extracting the SHP candidates */
+ entry = readdir (dir);
+ if (!entry)
+ break;
+ suffix = check_extension (entry->d_name);
+ if (suffix == SUFFIX_DISCARD)
+ continue;
+ path = sqlite3_mprintf ("%s/%s", in_dir, entry->d_name);
+ len = strlen (path);
+ path[len - 4] = '\0';
+ name = sqlite3_mprintf ("%s", entry->d_name);
+ len = strlen (name);
+ name[len - 4] = '\0';
+ do_add_shapefile (list, path, name, suffix);
+ }
+ closedir (dir);
+#endif
+
+ p_shp = list->first;
+ while (p_shp != NULL)
+ {
+ if (test_valid_shp (p_shp))
+ {
+ int invalid;
+ if (!do_test_shapefile
+ (cache, p_shp->base_name, validate, esri, &invalid))
+ goto error;
+ *n_shp += 1;
+ if (invalid)
+ *x_shp += 1;
+ if ((invalid || force) && out_dir != NULL)
+ {
+ /* attempting to repair */
+ int repair_failed;
+ int ret;
+ char *out_path = sqlite3_mprintf ("%s/%s", out_dir,
+ p_shp->file_name);
+ fprintf (stderr, "\tAttempting to repair: %s.shp\n",
+ out_path);
+ ret =
+ do_repair_shapefile (cache, p_shp->base_name,
+ out_path, validate, esri, force,
+ &repair_failed);
+ sqlite3_free (out_path);
+ if (!ret)
+ goto error;
+ if (repair_failed)
+ {
+ do_clen_files (out_dir, p_shp->base_name);
+ fprintf (stderr,
+ "\tFAILURE: automatic repair is impossible, manual repair required.\n");
+ }
+ else
+ {
+ *r_shp += 1;
+ fprintf (stderr, "\tOK, successfully repaired.\n");
+ }
+ }
+ }
+ p_shp = p_shp->next;
+ }
+
+ free_shp_list (list);
+ return 1;
+
+ error:
+ free_shp_list (list);
+ fprintf (stderr, "Unable to access \"%s\"\n", in_dir);
+ return 0;
+}
+
+static void
+do_help ()
+{
+/* printing the argument list */
+ fprintf (stderr, "\n\nusage: shp_sanitize ARGLIST\n");
+ fprintf (stderr,
+ "=================================================================\n");
+ fprintf (stderr,
+ "-h or --help print this help message\n");
+ fprintf (stderr,
+ "-idir or --in-dir dir-path directory expected to contain\n"
+ " all SHP to be checked\n");
+ fprintf (stderr,
+ "-odir or --out-dir dir-path <optional> directory where to\n"
+ " store all repaired SHPs\n\n");
+ fprintf (stderr,
+ "======================= optional args ===========================\n"
+ "-geom or --invalid-geoms checks for invalid Geometries\n"
+ "-esri or --esri-flag tolerates ESRI-like inner holes\n"
+ "-force or --force-repair unconditionally repair\n\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+/* the MAIN function simply perform arguments checking */
+ int i;
+ int error = 0;
+ int next_arg = ARG_NONE;
+ char *in_dir = NULL;
+ char *out_dir = NULL;
+ int validate = 0;
+ int esri = 0;
+ int force = 0;
+ int n_shp = 0;
+ int r_shp = 0;
+ int x_shp = 0;
+ const void *cache;
+
+ for (i = 1; i < argc; i++)
+ {
+ /* parsing the invocation arguments */
+ if (next_arg != ARG_NONE)
+ {
+ switch (next_arg)
+ {
+ case ARG_IN_DIR:
+ in_dir = argv[i];
+ break;
+ case ARG_OUT_DIR:
+ out_dir = argv[i];
+ break;
+ };
+ next_arg = ARG_NONE;
+ continue;
+ }
+ if (strcasecmp (argv[i], "--help") == 0
+ || strcmp (argv[i], "-h") == 0)
+ {
+ do_help ();
+ return -1;
+ }
+ if (strcasecmp (argv[i], "-idir") == 0
+ || strcasecmp (argv[i], "--in-dir") == 0)
+ {
+ next_arg = ARG_IN_DIR;
+ continue;
+ }
+ if (strcasecmp (argv[i], "-odir") == 0
+ || strcasecmp (argv[i], "--out-dir") == 0)
+ {
+ next_arg = ARG_OUT_DIR;
+ continue;
+ }
+ if (strcasecmp (argv[i], "-geom") == 0
+ || strcasecmp (argv[i], "--invalid-geoms") == 0)
+ {
+ validate = 1;
+ continue;
+ }
+ if (strcasecmp (argv[i], "-esri") == 0
+ || strcasecmp (argv[i], "--esri-flag") == 0)
+ {
+ esri = 1;
+ continue;
+ }
+ if (strcasecmp (argv[i], "-force") == 0
+ || strcasecmp (argv[i], "--force-repair") == 0)
+ {
+ force = 1;
+ continue;
+ }
+ fprintf (stderr, "unknown argument: %s\n", argv[i]);
+ error = 1;
+ }
+ if (error)
+ {
+ do_help ();
+ return -1;
+ }
+/* checking the arguments */
+ if (!in_dir)
+ {
+ fprintf (stderr, "did you forget setting the --in-dir argument ?\n");
+ error = 1;
+ }
+ if (error)
+ {
+ do_help ();
+ return -1;
+ }
+
+ if (out_dir != NULL)
+ {
+#ifdef _WIN32
+ if (_mkdir (out_dir) != 0)
+#else
+ if (mkdir (out_dir, 0777) != 0)
+#endif
+ {
+ fprintf (stderr,
+ "ERROR: unable to create the output directory\n%s\n%s\n\n",
+ out_dir, strerror (errno));
+ return -1;
+ }
+ }
+
+ cache = spatialite_alloc_connection ();
+ spatialite_set_silent_mode (cache);
+ fprintf (stderr, "\nInput dir: %s\n", in_dir);
+ if (out_dir != NULL)
+ {
+ fprintf (stderr, "Output dir: %s\n", out_dir);
+ if (force)
+ fprintf (stderr, "Unconditionally repairing all Shapefiles\n");
+ }
+ else
+ fprintf (stderr, "Only a diagnostic report will be reported\n");
+ if (validate)
+ {
+ fprintf (stderr, "Checking for invalid geometries (%s mode)\n",
+ esri ? "ESRI" : "ISO/OGC");
+ }
+
+ if (!do_scan_dir
+ (cache, in_dir, out_dir, &n_shp, &r_shp, &x_shp, validate, esri, force))
+ {
+ fprintf (stderr,
+ "\n... quitting ... some unexpected error occurred\n");
+ spatialite_cleanup_ex (cache);
+ return -1;
+ }
+
+ fprintf (stderr, "\n===========================================\n");
+ fprintf (stderr, "%d Shapefil%s ha%s been inspected.\n", n_shp,
+ (n_shp > 1) ? "es" : "e", (n_shp > 1) ? "ve" : "s");
+ fprintf (stderr, "%d malformed Shapefil%s ha%s been identified.\n", x_shp,
+ (x_shp > 1) ? "es" : "e", (x_shp > 1) ? "ve" : "s");
+ fprintf (stderr, "%d Shapefil%s ha%s been repaired.\n\n", r_shp,
+ (r_shp > 1) ? "es" : "e", (r_shp > 1) ? "ve" : "s");
+
+ spatialite_cleanup_ex (cache);
+ return 0;
+}
diff --git a/spatialite_osm_map.c b/spatialite_osm_map.c
index d75b0c2..9a23e12 100644
--- a/spatialite_osm_map.c
+++ b/spatialite_osm_map.c
@@ -367,11 +367,10 @@ point_layer_insert (struct aux_params *params, const char *layer_name,
ret = sqlite3_step (layer->ins_point_stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_POINT %s\n",
- layer_name);
- sqlite3_finalize (layer->ins_point_stmt);
- layer->ins_point_stmt = NULL;
- return 0;
+ fprintf (stderr,
+ "sqlite3_step() error: INS_POINT %s (%s)\n",
+ layer_name, sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -406,10 +405,9 @@ point_generic_insert (struct aux_params *params, const readosm_node * node,
ret = sqlite3_step (params->ins_generic_point_stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POINT\n");
- sqlite3_finalize (params->ins_generic_point_stmt);
- params->ins_generic_point_stmt = NULL;
- return 0;
+ fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POINT (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -468,10 +466,9 @@ address_insert (struct aux_params *params, const readosm_node * node,
ret = sqlite3_step (params->ins_addresses_stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_ADDRESSES\n");
- sqlite3_finalize (params->ins_addresses_stmt);
- params->ins_addresses_stmt = NULL;
- return 0;
+ fprintf (stderr, "sqlite3_step() error: INS_ADDRESSES (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -490,10 +487,9 @@ tmp_nodes_insert (struct aux_params *params, const readosm_node * node)
ret = sqlite3_step (params->ins_tmp_nodes_stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_TMP_NODES\n");
- sqlite3_finalize (params->ins_tmp_nodes_stmt);
- params->ins_tmp_nodes_stmt = NULL;
- return 0;
+ fprintf (stderr, "sqlite3_step() error: INS_TMP_NODES (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
static int
@@ -808,11 +804,9 @@ line_layer_insert (struct aux_params *params, const char *layer_name,
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
fprintf (stderr,
- "sqlite3_step() error: INS_LINESTRING %s\n",
- layer_name);
- sqlite3_finalize (layer->ins_linestring_stmt);
- layer->ins_linestring_stmt = NULL;
- return 0;
+ "sqlite3_step() error: INS_LINESTRING %s (%s)\n",
+ layer_name, sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -862,11 +856,9 @@ polygon_layer_insert (struct aux_params *params, const char *layer_name,
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
fprintf (stderr,
- "sqlite3_step() error: INS_POLYGON %s\n",
- layer_name);
- sqlite3_finalize (layer->ins_polygon_stmt);
- layer->ins_polygon_stmt = NULL;
- return 0;
+ "sqlite3_step() error: INS_POLYGON %s (%s)\n",
+ layer_name, sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -894,10 +886,10 @@ line_generic_insert (struct aux_params *params, sqlite3_int64 id,
ret = sqlite3_step (params->ins_generic_linestring_stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_GENERIC_LINESTRING\n");
- sqlite3_finalize (params->ins_generic_linestring_stmt);
- params->ins_generic_linestring_stmt = NULL;
- return 0;
+ fprintf (stderr,
+ "sqlite3_step() error: INS_GENERIC_LINESTRING (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -922,10 +914,9 @@ polygon_generic_insert (struct aux_params *params, sqlite3_int64 id,
ret = sqlite3_step (params->ins_generic_polygon_stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POLYGON\n");
- sqlite3_finalize (params->ins_generic_polygon_stmt);
- params->ins_generic_polygon_stmt = NULL;
- return 0;
+ fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POLYGON (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -947,10 +938,9 @@ tmp_ways_insert (struct aux_params *params, sqlite3_int64 id, int area,
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_TMP_WAYS\n");
- sqlite3_finalize (params->ins_tmp_ways_stmt);
- params->ins_tmp_ways_stmt = NULL;
- return 0;
+ fprintf (stderr, "sqlite3_step() error: INS_TMP_WAYS (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
static int
@@ -1422,11 +1412,9 @@ multiline_layer_insert (struct aux_params *params, const char *layer_name,
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
fprintf (stderr,
- "sqlite3_step() error: INS_MULTILINESTRING %s\n",
- layer_name);
- sqlite3_finalize (layer->ins_linestring_stmt);
- layer->ins_linestring_stmt = NULL;
- return 0;
+ "sqlite3_step() error: INS_MULTILINESTRING %s (%s)\n",
+ layer_name, sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -1821,11 +1809,9 @@ multipolygon_layer_insert (struct aux_params *params, const char *layer_name,
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
fprintf (stderr,
- "sqlite3_step() error: INS_MULTIPOLYGON %s\n",
- layer_name);
- sqlite3_finalize (layer->ins_polygon_stmt);
- layer->ins_polygon_stmt = NULL;
- return 0;
+ "sqlite3_step() error: INS_MULTIPOLYGON %s (%s)\n",
+ layer_name, sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -1864,10 +1850,9 @@ multiline_generic_insert (struct aux_params *params,
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
fprintf (stderr,
- "sqlite3_step() error: INS_GENERIC_MULTILINESTRING\n");
- sqlite3_finalize (params->ins_generic_linestring_stmt);
- params->ins_generic_linestring_stmt = NULL;
- return 0;
+ "sqlite3_step() error: INS_GENERIC_MULTILINESTRING (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
@@ -1903,10 +1888,10 @@ multipolygon_generic_insert (struct aux_params *params,
ret = sqlite3_step (params->ins_generic_polygon_stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
- fprintf (stderr, "sqlite3_step() error: INS_GENERIC_MULTIPOLYGON\n");
- sqlite3_finalize (params->ins_generic_polygon_stmt);
- params->ins_generic_polygon_stmt = NULL;
- return 0;
+ fprintf (stderr,
+ "sqlite3_step() error: INS_GENERIC_MULTIPOLYGON (%s)\n",
+ sqlite3_errmsg (params->db_handle));
+ return 1;
}
return 1;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/spatialite-tools.git
More information about the Pkg-grass-devel
mailing list